UNPKG

15.6 kBJavaScriptView Raw
1import { __assign, __read, __spreadArray } from './_virtual/_tslib.js';
2import { SpecialTargets, ActionTypes } from './types.js';
3import { init, send as send$1, raise as raise$1, update, log as log$1, cancel as cancel$1, assign as assign$1, error as error$1, stop as stop$1, pure as pure$1, choose as choose$1 } from './actionTypes.js';
4import * as actionTypes from './actionTypes.js';
5export { actionTypes };
6import { toSCXMLEvent, isString, isFunction, toEventObject, getEventType, partition, updateContext, flatten, toArray, toGuard, evaluateGuard, warn, isArray } from './utils.js';
7import { IS_PRODUCTION } from './environment.js';
8
9var initEvent = /*#__PURE__*/toSCXMLEvent({
10 type: init
11});
12function getActionFunction(actionType, actionFunctionMap) {
13 return actionFunctionMap ? actionFunctionMap[actionType] || undefined : undefined;
14}
15function toActionObject(action, actionFunctionMap) {
16 var actionObject;
17
18 if (isString(action) || typeof action === 'number') {
19 var exec = getActionFunction(action, actionFunctionMap);
20
21 if (isFunction(exec)) {
22 actionObject = {
23 type: action,
24 exec: exec
25 };
26 } else if (exec) {
27 actionObject = exec;
28 } else {
29 actionObject = {
30 type: action,
31 exec: undefined
32 };
33 }
34 } else if (isFunction(action)) {
35 actionObject = {
36 // Convert action to string if unnamed
37 type: action.name || action.toString(),
38 exec: action
39 };
40 } else {
41 var exec = getActionFunction(action.type, actionFunctionMap);
42
43 if (isFunction(exec)) {
44 actionObject = __assign(__assign({}, action), {
45 exec: exec
46 });
47 } else if (exec) {
48 var actionType = exec.type || action.type;
49 actionObject = __assign(__assign(__assign({}, exec), action), {
50 type: actionType
51 });
52 } else {
53 actionObject = action;
54 }
55 }
56
57 return actionObject;
58}
59var toActionObjects = function (action, actionFunctionMap) {
60 if (!action) {
61 return [];
62 }
63
64 var actions = isArray(action) ? action : [action];
65 return actions.map(function (subAction) {
66 return toActionObject(subAction, actionFunctionMap);
67 });
68};
69function toActivityDefinition(action) {
70 var actionObject = toActionObject(action);
71 return __assign(__assign({
72 id: isString(action) ? action : actionObject.id
73 }, actionObject), {
74 type: actionObject.type
75 });
76}
77/**
78 * Raises an event. This places the event in the internal event queue, so that
79 * the event is immediately consumed by the machine in the current step.
80 *
81 * @param eventType The event to raise.
82 */
83
84function raise(event) {
85 if (!isString(event)) {
86 return send(event, {
87 to: SpecialTargets.Internal
88 });
89 }
90
91 return {
92 type: raise$1,
93 event: event
94 };
95}
96function resolveRaise(action) {
97 return {
98 type: raise$1,
99 _event: toSCXMLEvent(action.event)
100 };
101}
102/**
103 * Sends an event. This returns an action that will be read by an interpreter to
104 * send the event in the next step, after the current step is finished executing.
105 *
106 * @param event The event to send.
107 * @param options Options to pass into the send event:
108 * - `id` - The unique send event identifier (used with `cancel()`).
109 * - `delay` - The number of milliseconds to delay the sending of the event.
110 * - `to` - The target of this event (by default, the machine the event was sent from).
111 */
112
113function send(event, options) {
114 return {
115 to: options ? options.to : undefined,
116 type: send$1,
117 event: isFunction(event) ? event : toEventObject(event),
118 delay: options ? options.delay : undefined,
119 id: options && options.id !== undefined ? options.id : isFunction(event) ? event.name : getEventType(event)
120 };
121}
122function resolveSend(action, ctx, _event, delaysMap) {
123 var meta = {
124 _event: _event
125 }; // TODO: helper function for resolving Expr
126
127 var resolvedEvent = toSCXMLEvent(isFunction(action.event) ? action.event(ctx, _event.data, meta) : action.event);
128 var resolvedDelay;
129
130 if (isString(action.delay)) {
131 var configDelay = delaysMap && delaysMap[action.delay];
132 resolvedDelay = isFunction(configDelay) ? configDelay(ctx, _event.data, meta) : configDelay;
133 } else {
134 resolvedDelay = isFunction(action.delay) ? action.delay(ctx, _event.data, meta) : action.delay;
135 }
136
137 var resolvedTarget = isFunction(action.to) ? action.to(ctx, _event.data, meta) : action.to;
138 return __assign(__assign({}, action), {
139 to: resolvedTarget,
140 _event: resolvedEvent,
141 event: resolvedEvent.data,
142 delay: resolvedDelay
143 });
144}
145/**
146 * Sends an event to this machine's parent.
147 *
148 * @param event The event to send to the parent machine.
149 * @param options Options to pass into the send event.
150 */
151
152function sendParent(event, options) {
153 return send(event, __assign(__assign({}, options), {
154 to: SpecialTargets.Parent
155 }));
156}
157/**
158 * Sends an event to an actor.
159 *
160 * @param actor The `ActorRef` to send the event to.
161 * @param event The event to send, or an expression that evaluates to the event to send
162 * @param options Send action options
163 * @returns An XState send action object
164 */
165
166function sendTo(actor, event, options) {
167 return send(event, __assign(__assign({}, options), {
168 to: actor
169 }));
170}
171/**
172 * Sends an update event to this machine's parent.
173 */
174
175function sendUpdate() {
176 return sendParent(update);
177}
178/**
179 * Sends an event back to the sender of the original event.
180 *
181 * @param event The event to send back to the sender
182 * @param options Options to pass into the send event
183 */
184
185function respond(event, options) {
186 return send(event, __assign(__assign({}, options), {
187 to: function (_, __, _a) {
188 var _event = _a._event;
189 return _event.origin; // TODO: handle when _event.origin is undefined
190 }
191 }));
192}
193
194var defaultLogExpr = function (context, event) {
195 return {
196 context: context,
197 event: event
198 };
199};
200/**
201 *
202 * @param expr The expression function to evaluate which will be logged.
203 * Takes in 2 arguments:
204 * - `ctx` - the current state context
205 * - `event` - the event that caused this action to be executed.
206 * @param label The label to give to the logged expression.
207 */
208
209
210function log(expr, label) {
211 if (expr === void 0) {
212 expr = defaultLogExpr;
213 }
214
215 return {
216 type: log$1,
217 label: label,
218 expr: expr
219 };
220}
221var resolveLog = function (action, ctx, _event) {
222 return __assign(__assign({}, action), {
223 value: isString(action.expr) ? action.expr : action.expr(ctx, _event.data, {
224 _event: _event
225 })
226 });
227};
228/**
229 * Cancels an in-flight `send(...)` action. A canceled sent action will not
230 * be executed, nor will its event be sent, unless it has already been sent
231 * (e.g., if `cancel(...)` is called after the `send(...)` action's `delay`).
232 *
233 * @param sendId The `id` of the `send(...)` action to cancel.
234 */
235
236var cancel = function (sendId) {
237 return {
238 type: cancel$1,
239 sendId: sendId
240 };
241};
242/**
243 * Starts an activity.
244 *
245 * @param activity The activity to start.
246 */
247
248function start(activity) {
249 var activityDef = toActivityDefinition(activity);
250 return {
251 type: ActionTypes.Start,
252 activity: activityDef,
253 exec: undefined
254 };
255}
256/**
257 * Stops an activity.
258 *
259 * @param actorRef The activity to stop.
260 */
261
262function stop(actorRef) {
263 var activity = isFunction(actorRef) ? actorRef : toActivityDefinition(actorRef);
264 return {
265 type: ActionTypes.Stop,
266 activity: activity,
267 exec: undefined
268 };
269}
270function resolveStop(action, context, _event) {
271 var actorRefOrString = isFunction(action.activity) ? action.activity(context, _event.data) : action.activity;
272 var resolvedActorRef = typeof actorRefOrString === 'string' ? {
273 id: actorRefOrString
274 } : actorRefOrString;
275 var actionObject = {
276 type: ActionTypes.Stop,
277 activity: resolvedActorRef
278 };
279 return actionObject;
280}
281/**
282 * Updates the current context of the machine.
283 *
284 * @param assignment An object that represents the partial context to update.
285 */
286
287var assign = function (assignment) {
288 return {
289 type: assign$1,
290 assignment: assignment
291 };
292};
293function isActionObject(action) {
294 return typeof action === 'object' && 'type' in action;
295}
296/**
297 * Returns an event type that represents an implicit event that
298 * is sent after the specified `delay`.
299 *
300 * @param delayRef The delay in milliseconds
301 * @param id The state node ID where this event is handled
302 */
303
304function after(delayRef, id) {
305 var idSuffix = id ? "#".concat(id) : '';
306 return "".concat(ActionTypes.After, "(").concat(delayRef, ")").concat(idSuffix);
307}
308/**
309 * Returns an event that represents that a final state node
310 * has been reached in the parent state node.
311 *
312 * @param id The final state node's parent state node `id`
313 * @param data The data to pass into the event
314 */
315
316function done(id, data) {
317 var type = "".concat(ActionTypes.DoneState, ".").concat(id);
318 var eventObject = {
319 type: type,
320 data: data
321 };
322
323 eventObject.toString = function () {
324 return type;
325 };
326
327 return eventObject;
328}
329/**
330 * Returns an event that represents that an invoked service has terminated.
331 *
332 * An invoked service is terminated when it has reached a top-level final state node,
333 * but not when it is canceled.
334 *
335 * @param id The final state node ID
336 * @param data The data to pass into the event
337 */
338
339function doneInvoke(id, data) {
340 var type = "".concat(ActionTypes.DoneInvoke, ".").concat(id);
341 var eventObject = {
342 type: type,
343 data: data
344 };
345
346 eventObject.toString = function () {
347 return type;
348 };
349
350 return eventObject;
351}
352function error(id, data) {
353 var type = "".concat(ActionTypes.ErrorPlatform, ".").concat(id);
354 var eventObject = {
355 type: type,
356 data: data
357 };
358
359 eventObject.toString = function () {
360 return type;
361 };
362
363 return eventObject;
364}
365function pure(getActions) {
366 return {
367 type: ActionTypes.Pure,
368 get: getActions
369 };
370}
371/**
372 * Forwards (sends) an event to a specified service.
373 *
374 * @param target The target service to forward the event to.
375 * @param options Options to pass into the send action creator.
376 */
377
378function forwardTo(target, options) {
379 return send(function (_, event) {
380 return event;
381 }, __assign(__assign({}, options), {
382 to: target
383 }));
384}
385/**
386 * Escalates an error by sending it as an event to this machine's parent.
387 *
388 * @param errorData The error data to send, or the expression function that
389 * takes in the `context`, `event`, and `meta`, and returns the error data to send.
390 * @param options Options to pass into the send action creator.
391 */
392
393function escalate(errorData, options) {
394 return sendParent(function (context, event, meta) {
395 return {
396 type: error$1,
397 data: isFunction(errorData) ? errorData(context, event, meta) : errorData
398 };
399 }, __assign(__assign({}, options), {
400 to: SpecialTargets.Parent
401 }));
402}
403function choose(conds) {
404 return {
405 type: ActionTypes.Choose,
406 conds: conds
407 };
408}
409function resolveActions(machine, currentState, currentContext, _event, actions, preserveActionOrder) {
410 if (preserveActionOrder === void 0) {
411 preserveActionOrder = false;
412 }
413
414 var _a = __read(preserveActionOrder ? [[], actions] : partition(actions, function (action) {
415 return action.type === assign$1;
416 }), 2),
417 assignActions = _a[0],
418 otherActions = _a[1];
419
420 var updatedContext = assignActions.length ? updateContext(currentContext, _event, assignActions, currentState) : currentContext;
421 var preservedContexts = preserveActionOrder ? [currentContext] : undefined;
422 var resolvedActions = flatten(otherActions.map(function (actionObject) {
423 var _a;
424
425 switch (actionObject.type) {
426 case raise$1:
427 return resolveRaise(actionObject);
428
429 case send$1:
430 var sendAction = resolveSend(actionObject, updatedContext, _event, machine.options.delays); // TODO: fix ActionTypes.Init
431
432 if (!IS_PRODUCTION) {
433 // warn after resolving as we can create better contextual message here
434 warn(!isString(actionObject.delay) || typeof sendAction.delay === 'number', // tslint:disable-next-line:max-line-length
435 "No delay reference for delay expression '".concat(actionObject.delay, "' was found on machine '").concat(machine.id, "'"));
436 }
437
438 return sendAction;
439
440 case log$1:
441 return resolveLog(actionObject, updatedContext, _event);
442
443 case choose$1:
444 {
445 var chooseAction = actionObject;
446 var matchedActions = (_a = chooseAction.conds.find(function (condition) {
447 var guard = toGuard(condition.cond, machine.options.guards);
448 return !guard || evaluateGuard(machine, guard, updatedContext, _event, currentState);
449 })) === null || _a === void 0 ? void 0 : _a.actions;
450
451 if (!matchedActions) {
452 return [];
453 }
454
455 var _b = __read(resolveActions(machine, currentState, updatedContext, _event, toActionObjects(toArray(matchedActions), machine.options.actions), preserveActionOrder), 2),
456 resolvedActionsFromChoose = _b[0],
457 resolvedContextFromChoose = _b[1];
458
459 updatedContext = resolvedContextFromChoose;
460 preservedContexts === null || preservedContexts === void 0 ? void 0 : preservedContexts.push(updatedContext);
461 return resolvedActionsFromChoose;
462 }
463
464 case pure$1:
465 {
466 var matchedActions = actionObject.get(updatedContext, _event.data);
467
468 if (!matchedActions) {
469 return [];
470 }
471
472 var _c = __read(resolveActions(machine, currentState, updatedContext, _event, toActionObjects(toArray(matchedActions), machine.options.actions), preserveActionOrder), 2),
473 resolvedActionsFromPure = _c[0],
474 resolvedContext = _c[1];
475
476 updatedContext = resolvedContext;
477 preservedContexts === null || preservedContexts === void 0 ? void 0 : preservedContexts.push(updatedContext);
478 return resolvedActionsFromPure;
479 }
480
481 case stop$1:
482 {
483 return resolveStop(actionObject, updatedContext, _event);
484 }
485
486 case assign$1:
487 {
488 updatedContext = updateContext(updatedContext, _event, [actionObject], currentState);
489 preservedContexts === null || preservedContexts === void 0 ? void 0 : preservedContexts.push(updatedContext);
490 break;
491 }
492
493 default:
494 var resolvedActionObject = toActionObject(actionObject, machine.options.actions);
495 var exec_1 = resolvedActionObject.exec;
496
497 if (exec_1 && preservedContexts) {
498 var contextIndex_1 = preservedContexts.length - 1;
499 resolvedActionObject = __assign(__assign({}, resolvedActionObject), {
500 exec: function (_ctx) {
501 var args = [];
502
503 for (var _i = 1; _i < arguments.length; _i++) {
504 args[_i - 1] = arguments[_i];
505 }
506
507 exec_1.apply(void 0, __spreadArray([preservedContexts[contextIndex_1]], __read(args), false));
508 }
509 });
510 }
511
512 return resolvedActionObject;
513 }
514 }).filter(function (a) {
515 return !!a;
516 }));
517 return [resolvedActions, updatedContext];
518}
519
520export { after, assign, cancel, choose, done, doneInvoke, error, escalate, forwardTo, getActionFunction, initEvent, isActionObject, log, pure, raise, resolveActions, resolveLog, resolveRaise, resolveSend, resolveStop, respond, send, sendParent, sendTo, sendUpdate, start, stop, toActionObject, toActionObjects, toActivityDefinition };