Skip to content

Commit

Permalink
Fixed an issue with not executing actions in response to received **b…
Browse files Browse the repository at this point in the history
…atched** events when using `predictableActionArguments` (#3563)
  • Loading branch information
Andarist committed Sep 1, 2022
1 parent 95a6a06 commit e3c7a9c
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/silver-jokes-juggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'xstate': patch
---

Fixed an issue with not executing actions in response to received **batched** events when using `predictableActionArguments`.
17 changes: 13 additions & 4 deletions packages/core/src/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,8 @@ export class Interpreter<
return;
}

const exec = !!this.machine.config.predictableActionArguments && this._exec;

this.scheduler.schedule(() => {
let nextState = this.state;
let batchChanged = false;
Expand All @@ -783,13 +785,20 @@ export class Interpreter<
this.forward(_event);

nextState = serviceScope.provide(this, () => {
return this.machine.transition(nextState, _event);
return this.machine.transition(
nextState,
_event,
undefined,
exec || undefined
);
});

batchedActions.push(
...(nextState.actions.map((a) =>
bindActionToState(a, nextState)
) as Array<ActionObject<TContext, TEvent>>)
...(this.machine.config.predictableActionArguments
? nextState.actions
: (nextState.actions.map((a) =>
bindActionToState(a, nextState)
) as Array<ActionObject<TContext, TEvent>>))
);

batchChanged = batchChanged || !!nextState.changed;
Expand Down
52 changes: 52 additions & 0 deletions packages/core/test/predictableExec.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -723,4 +723,56 @@ describe('predictableExec', () => {

expect(service.getSnapshot().value).toBe('done');
});

it('should execute actions when sending batched events', () => {
let executed = false;

const machine = createMachine({
predictableActionArguments: true,
initial: 'a',
states: {
a: {
on: {
NEXT: 'b'
}
},
b: {
entry: () => (executed = true)
}
}
});

const service = interpret(machine).start();

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

expect(executed).toBe(true);
});

it('should deliver events sent to other actors when using batched events', () => {
let gotEvent = false;

const machine = createMachine({
predictableActionArguments: true,
invoke: {
id: 'myChild',
src: () => (_sendBack, onReceive) => {
onReceive(() => {
gotEvent = true;
});
}
},
on: {
PING_CHILD: {
actions: send({ type: 'PING' }, { to: 'myChild' })
}
}
});

const service = interpret(machine).start();

service.send([{ type: 'PING_CHILD' }]);

expect(gotEvent).toBe(true);
});
});

0 comments on commit e3c7a9c

Please sign in to comment.