xstate
xstate copied to clipboard
Bug: system.get(id) not working after restoring a snapshot
XState version
XState version 5
Description
After restoring the snapshot an error appears, when using actor.send with the reference determined by system.get(id).
TypeError: this.logic.transition is not a function
This error appaers only after serializing the snapshot!
The code for the test program is:
"use strict";
const { createMachine, createActor } = require('xstate');
const { v4: uuid } = require("uuid");
const { ParentMachine } = require("./parent");
const parentMachine = createMachine(ParentMachine);
const parent = createActor(parentMachine, { id: "parent", systemId: "parent" });
const childId = uuid();
console.log("Child Id", childId);
parent.start();
parent.send({ type: "start", childId });
parent.send({ type: "tick", id: childId });
const snapshot = parent.getPersistedSnapshot();
parent.stop();
console.log("Snapshot", snapshot);
const restored = JSON.parse(JSON.stringify(snapshot));
console.log("Snapshot", restored);
const parentRestored = createActor(parentMachine, { id: "parent", systemId: "parent", snapshot: restored });
parentRestored.start();
parentRestored.send({ type: "tick", id: childId });
parentRestored.send({ type: "stop" });
The machine defintion of the parent machine:
"use strict";
const { createMachine, assign } = require('xstate');
const { ChildMachine } = require("./child");
const ParentMachine = {
id: "parent",
initial: "idle",
context: {
count: 0,
child: null
},
entry: [
({ context }) => console.log("ParentMachine created", context)
],
states: {
idle: {
on: {
start: {
target: "running",
actions: [
assign(({ spawn, event }) => {
const machine = createMachine(ChildMachine);
const id = event.childId;
const child = spawn(machine, { id, systemId: id });
return { child };
})
]
}
}
},
running: {
on: {
tick: {
actions: [
assign({ count: ctx => ctx.count + 1 }),
({ system, event }) => {
console.log("ParentMachine tick", { event });
const child = system.get(event.id);
if (child) child.send(event);
}
]
},
stop: {
target: "final"
}
}
},
final: {
type: "final"
}
}
};
module.exports = {
ParentMachine
};
The machine definition of the child machine:
"use strict";
const { assign } = require('xstate');
const ChildMachine = {
initial: "running",
context: {
count: 0
},
entry: [
({ context }) => console.log("ChildMachine created", context)
],
states: {
running: {
on: {
tick: {
actions: [
assign({ count: ({ context }) => (context.count + 1) }),
({ event }) => console.log("ChildMachine tick", event)
]
},
stop: {
target: "final"
}
}
},
final: {
type: "final"
}
}
};
module.exports = {
ChildMachine
};
Expected result
The spawned actor should be also reachable by systemId after restoring a serialized snapshot.
Actual result
After restoring the snapshot an error appears, when using actor.send with the reference determined by system.get(id).
TypeError: this.logic.transition is not a function
at Actor._process (C:\Daten\node\modules\imicros-core\node_modules\xstate\dist\raise-40b1a1f5.cjs.js:814:30)
at Mailbox.flush (C:\Daten\node\modules\imicros-core\node_modules\xstate\dist\raise-40b1a1f5.cjs.js:45:12)
at Mailbox.enqueue (C:\Daten\node\modules\imicros-core\node_modules\xstate\dist\raise-40b1a1f5.cjs.js:37:12)
at Actor._send (C:\Daten\node\modules\imicros-core\node_modules\xstate\dist\raise-40b1a1f5.cjs.js:935:18)
at Object._relay (C:\Daten\node\modules\imicros-core\node_modules\xstate\dist\raise-40b1a1f5.cjs.js:229:14)
at Actor.send (C:\Daten\node\modules\imicros-core\node_modules\xstate\dist\raise-40b1a1f5.cjs.js:944:17)
at ParentMachine.states.running.on.tick.actions (C:\Daten\node\modules\imicros-core\dev\flow\parent.js:42:46)
at executeAction (C:\Daten\node\modules\imicros-core\node_modules\xstate\dist\raise-40b1a1f5.cjs.js:2233:7)
at resolveAndExecuteActionsWithContext (C:\Daten\node\modules\imicros-core\node_modules\xstate\dist\raise-40b1a1f5.cjs.js:2237:9)
at resolveActionsAndContext (C:\Daten\node\modules\imicros-core\node_modules\xstate\dist\raise-40b1a1f5.cjs.js:2268:21)
Reproduction
see provided code above...
Additional context
No response
Can you please put the code in a repo or on StackBlitz? Would make it easier to debug.
Hope, this is what you want: https://stackblitz.com/edit/stackblitz-starters-otrd6j?file=index.js