xstate
Version:
Finite State Machines and Statecharts for the Modern Web.
134 lines (130 loc) • 3.96 kB
JavaScript
import { W as ProcessingStatus, R as resolveReferencedActor, c as createActor, Y as cloneMachineSnapshot, T as executingCustomAction } from './raise-78b8dcb8.development.esm.js';
function createSpawner(actorScope, {
machine,
context
}, event, spawnedChildren) {
const spawn = (src, options) => {
if (typeof src === 'string') {
const logic = resolveReferencedActor(machine, src);
if (!logic) {
throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
}
const actorRef = createActor(logic, {
id: options?.id,
parent: actorScope.self,
syncSnapshot: options?.syncSnapshot,
input: typeof options?.input === 'function' ? options.input({
context,
event,
self: actorScope.self
}) : options?.input,
src,
systemId: options?.systemId
});
spawnedChildren[actorRef.id] = actorRef;
return actorRef;
} else {
const actorRef = createActor(src, {
id: options?.id,
parent: actorScope.self,
syncSnapshot: options?.syncSnapshot,
input: options?.input,
src,
systemId: options?.systemId
});
return actorRef;
}
};
return (src, options) => {
const actorRef = spawn(src, options); // TODO: fix types
spawnedChildren[actorRef.id] = actorRef;
actorScope.defer(() => {
if (actorRef._processingStatus === ProcessingStatus.Stopped) {
return;
}
actorRef.start();
});
return actorRef;
};
}
function resolveAssign(actorScope, snapshot, actionArgs, actionParams, {
assignment
}) {
if (!snapshot.context) {
throw new Error('Cannot assign to undefined `context`. Ensure that `context` is defined in the machine config.');
}
const spawnedChildren = {};
const assignArgs = {
context: snapshot.context,
event: actionArgs.event,
spawn: createSpawner(actorScope, snapshot, actionArgs.event, spawnedChildren),
self: actorScope.self,
system: actorScope.system
};
let partialUpdate = {};
if (typeof assignment === 'function') {
partialUpdate = assignment(assignArgs, actionParams);
} else {
for (const key of Object.keys(assignment)) {
const propAssignment = assignment[key];
partialUpdate[key] = typeof propAssignment === 'function' ? propAssignment(assignArgs, actionParams) : propAssignment;
}
}
const updatedContext = Object.assign({}, snapshot.context, partialUpdate);
return [cloneMachineSnapshot(snapshot, {
context: updatedContext,
children: Object.keys(spawnedChildren).length ? {
...snapshot.children,
...spawnedChildren
} : snapshot.children
}), undefined, undefined];
}
/**
* Updates the current context of the machine.
*
* @example
*
* ```ts
* import { createMachine, assign } from 'xstate';
*
* const countMachine = createMachine({
* context: {
* count: 0,
* message: ''
* },
* on: {
* inc: {
* actions: assign({
* count: ({ context }) => context.count + 1
* })
* },
* updateMessage: {
* actions: assign(({ context, event }) => {
* return {
* message: event.message.trim()
* };
* })
* }
* }
* });
* ```
*
* @param assignment An object that represents the partial context to update, or
* a function that returns an object that represents the partial context to
* update.
*/
function assign(assignment) {
if (executingCustomAction) {
console.warn('Custom actions should not call `assign()` directly, as it is not imperative. See https://stately.ai/docs/actions#built-in-actions for more details.');
}
function assign(_args, _params) {
{
throw new Error(`This isn't supposed to be called`);
}
}
assign.type = 'xstate.assign';
assign.assignment = assignment;
assign.resolve = resolveAssign;
return assign;
}
export { assign as a };