Skip to content

Commit

Permalink
Fixed an issue with interpreters started using a persisted state not …
Browse files Browse the repository at this point in the history
…being "resolved" in full (#3140)
  • Loading branch information
Andarist committed Mar 10, 2022
1 parent 7b45fda commit 502ffe9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/hot-trees-occur.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'xstate': patch
---

Fixed an issue with interpreters started using a persisted state not being "resolved" in full. This could cause some things, such as `after` transitions, not being executed correctly after starting an interpreter like this.
6 changes: 6 additions & 0 deletions packages/core/src/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,12 @@ export class Interpreter<
return this;
}

// yes, it's a hack but we need the related cache to be populated for some things to work (like delayed transitions)
// this is usually called by `machine.getInitialState` but if we rehydrate from a state we might bypass this call
// we also don't want to call this method here as it resolves the full initial state which might involve calling assign actions
// and that could potentially lead to some unwanted side-effects (even such as creating some rogue actors)
(this.machine as any)._init();

registry.register(this.sessionId, this as Actor);
this.initialized = true;
this.status = InterpreterStatus.Running;
Expand Down
36 changes: 35 additions & 1 deletion packages/core/test/after.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createMachine, interpret } from '../src';
import { createMachine, interpret, State } from '../src';
import { after, cancel, send, actionTypes } from '../src/actions';
import { toSCXMLEvent } from '../src/utils';

Expand Down Expand Up @@ -170,6 +170,40 @@ describe('delayed transitions', () => {
.start(machine.getInitialState('withAfter'));
});

it('should execute an after transition after starting from a persisted state', (done) => {
const createMyMachine = () =>
createMachine({
initial: 'A',
states: {
A: {
on: {
NEXT: 'B'
}
},
B: {
after: {
1: 'C'
}
},
C: {
type: 'final'
}
}
});

let service = interpret(createMyMachine()).start();

const persistedState = State.create(
JSON.parse(JSON.stringify(service.state))
);

service = interpret(createMyMachine()).start(persistedState);

service.send({ type: 'NEXT' });

service.onDone(() => done());
});

describe('delay expressions', () => {
type Events =
| { type: 'ACTIVATE'; delay: number }
Expand Down

0 comments on commit 502ffe9

Please sign in to comment.