Skip to content

Commit

Permalink
feat(core): add actor ID to DoneActorEvent, ErrorActorEvent (#4942)
Browse files Browse the repository at this point in the history
* feat(core): add actor ID to DoneActorEvent, ErrorActorEvent

This changes `DoneActorEvent` (`xstate.done.actor.*`) and `ErrorActorEvent` (`xstate.error.actor.*`) to have an `actorId` prop which is equal to the ID of the Actor associated with the event.

Previously, this information was only available by extracting it from the `type` property of the event object using string operations.

* chore: review changes

use `AnyEventObject` instead of `DoneActorEvent` in `invoke.test.ts`

Co-authored-by: David Khourshid <davidkpiano@gmail.com>

* chore: add changeset for #4942

---------

Co-authored-by: David Khourshid <davidkpiano@gmail.com>
  • Loading branch information
boneskull and davidkpiano authored Jun 21, 2024
1 parent c58b36d commit 9caaa1f
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/giant-bananas-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'xstate': minor
---

`DoneActorEvent` and `ErrorActorEvent` now contain property `actorId`, which refers to the ID of the actor the event refers to.
5 changes: 3 additions & 2 deletions packages/core/src/eventUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,16 @@ export function createDoneActorEvent(
): DoneActorEvent {
return {
type: `xstate.done.actor.${invokeId}`,
output
output,
actorId: invokeId
};
}

export function createErrorActorEvent(
id: string,
error?: unknown
): ErrorActorEvent {
return { type: `xstate.error.actor.${id}`, error };
return { type: `xstate.error.actor.${id}`, error, actorId: id };
}

export function createInitEvent(input: unknown) {
Expand Down
14 changes: 10 additions & 4 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1656,14 +1656,20 @@ export type Transitions<
TEvent extends EventObject
> = Array<TransitionDefinition<TContext, TEvent>>;

export interface DoneActorEvent<TOutput = unknown> {
type: `xstate.done.actor.${string}`;
export interface DoneActorEvent<TOutput = unknown, TId extends string = string>
extends EventObject {
type: `xstate.done.actor.${TId}`;
output: TOutput;
actorId: TId;
}

export interface ErrorActorEvent<TErrorData = unknown> extends EventObject {
type: `xstate.error.actor.${string}`;
export interface ErrorActorEvent<
TErrorData = unknown,
TId extends string = string
> extends EventObject {
type: `xstate.error.actor.${TId}`;
error: TErrorData;
actorId: TId;
}

export interface SnapshotEvent<
Expand Down
4 changes: 4 additions & 0 deletions packages/core/test/inspect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ describe('inspect', () => {
},
{
"event": {
"actorId": "0.(machine).loading",
"output": 42,
"type": "xstate.done.actor.0.(machine).loading",
},
Expand Down Expand Up @@ -396,6 +397,7 @@ describe('inspect', () => {
},
{
"event": {
"actorId": "child",
"output": undefined,
"type": "xstate.done.actor.child",
},
Expand All @@ -406,6 +408,7 @@ describe('inspect', () => {
{
"actorId": "x:1",
"event": {
"actorId": "child",
"output": undefined,
"type": "xstate.done.actor.child",
},
Expand All @@ -418,6 +421,7 @@ describe('inspect', () => {
{
"actorId": "x:2",
"event": {
"actorId": "0.(machine).loading",
"output": 42,
"type": "xstate.done.actor.0.(machine).loading",
},
Expand Down
19 changes: 14 additions & 5 deletions packages/core/test/invoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import {
createActor,
sendParent,
Snapshot,
ActorRef
ActorRef,
AnyEventObject
} from '../src/index.ts';
import { sleep } from '@xstate-repo/jest-utils';

Expand Down Expand Up @@ -3081,7 +3082,7 @@ describe('invoke', () => {
});

it('xstate.done.actor events should have unique names when invokee is a machine with an id property', (done) => {
const actual: string[] = [];
const actual: AnyEventObject[] = [];

const childMachine = createMachine({
id: 'child',
Expand Down Expand Up @@ -3121,7 +3122,7 @@ describe('invoke', () => {
on: {
'*': {
actions: ({ event }) => {
actual.push(event.type);
actual.push(event);
}
}
}
Expand All @@ -3132,8 +3133,16 @@ describe('invoke', () => {
// check within a macrotask so all promise-induced microtasks have a chance to resolve first
setTimeout(() => {
expect(actual).toEqual([
'xstate.done.actor.0.(machine).first.fetch',
'xstate.done.actor.0.(machine).second.fetch'
{
type: 'xstate.done.actor.0.(machine).first.fetch',
output: undefined,
actorId: '0.(machine).first.fetch'
},
{
type: 'xstate.done.actor.0.(machine).second.fetch',
output: undefined,
actorId: '0.(machine).second.fetch'
}
]);
done();
}, 100);
Expand Down

0 comments on commit 9caaa1f

Please sign in to comment.