Upgrading to XState v5: event meta - or alternatives #4870
-
Hello! I have a project that is currently using XState v4 that I would like to upgrade. In my project, I have an event bus actor: an actor which other actors can subscribe to and publish events. assignSubscription: assign({
subscriptions: (context, { data }, meta) => {
assert(meta._event.origin, "Event must have origin");
const { subscriptions } = context;
const eventSubscriptions = subscriptions[data.type] ?? [];
eventSubscriptions.push({
origin: meta._event.origin,
pattern: data.pattern,
});
subscriptions[data.type] = eventSubscriptions;
return subscriptions;
},
}), The actor worked by storing the My question is: is If it helps, I have provided the full event-bus state machine file below. event-bus.ts
import { assert } from "@/utils/assert";
import { isMatching, type P } from "ts-pattern";
import { assign, createMachine, interpret, sendTo } from "xstate";
import { pure } from "xstate/lib/actions";
type Context = {
subscriptions: Record<
string,
{ origin: string; pattern?: P.Pattern<Record<string, unknown>> }[]
>;
};
type Events =
| {
type: "PUBLISH";
data: Record<string, unknown> & {
type: string;
};
}
| {
type: "SUBSCRIBE";
data: {
type: string;
pattern?: P.Pattern<Record<string, unknown>>;
};
};
const eventBusStateMachine = createMachine(
{
id: "Event Bus",
tsTypes: {} as import("./event-bus.typegen").Typegen0,
schema: {
context: {} as Context,
events: {} as Events,
},
context: {
subscriptions: {},
},
predictableActionArguments: true,
initial: "Listening",
states: {
Listening: {
on: {
PUBLISH: {
actions: ["sendEvent"],
},
SUBSCRIBE: {
actions: ["assignSubscription"],
},
},
},
},
},
{
actions: {
sendEvent: pure((context, { data }) => {
const subscriptions = context.subscriptions[data.type] ?? [];
const matchedSubscriptions = subscriptions.filter(({ pattern }) => {
if (pattern == null) {
return true;
}
return isMatching(pattern, data);
});
return matchedSubscriptions.map(({ origin }) => sendTo(origin, data));
}),
assignSubscription: assign({
subscriptions: (context, { data }, meta) => {
assert(meta._event.origin, "Event must have origin");
const { subscriptions } = context;
const eventSubscriptions = subscriptions[data.type] ?? [];
eventSubscriptions.push({
origin: meta._event.origin,
pattern: data.pattern,
});
subscriptions[data.type] = eventSubscriptions;
return subscriptions;
},
}),
},
},
);
export const eventBusActor = interpret(eventBusStateMachine).start(); |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
XState v5 no longer has assign({
subscriptions: ({ context, event }) => ({
event.sender; // property name is custom
// ...
})
})
// other machine
actions: sendTo('parentMachine', ({ self }) => ({
type: 'someEvent',
sender: self
}) Also, XState now has a built-in event emitter, which may be useful to you: https://stately.ai/docs/event-emitter |
Beta Was this translation helpful? Give feedback.
XState v5 no longer has
_event.origin
(or SCXML events in general) as that was part of our API simplification. Events should now explicitly pass a self-reference if they want event consumers know where it came from:Also, XState now has a built-in event emitter, which may be useful to you: https://stately.ai/docs/event-emitter