xstate 6.0.0-alpha.12 → 6.0.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{StateMachine-8a9e6cb4.development.esm.js → StateMachine-193c2d4d.development.esm.js} +42 -1
- package/dist/{StateMachine-7af634f9.cjs.js → StateMachine-1b26c5de.cjs.js} +42 -1
- package/dist/{StateMachine-c7e1996c.development.cjs.js → StateMachine-3120a7ff.development.cjs.js} +42 -1
- package/dist/{StateMachine-97ef0e5e.esm.js → StateMachine-614c0f36.esm.js} +42 -1
- package/dist/declarations/src/StateMachine.d.ts +1 -0
- package/dist/declarations/src/fsm.d.ts +74 -0
- package/dist/declarations/src/index.d.ts +1 -0
- package/dist/declarations/src/setup.d.ts +29 -10
- package/dist/declarations/src/types.d.ts +9 -3
- package/dist/declarations/src/types.v6.d.ts +5 -5
- package/dist/{index-3d018b1e.development.cjs.js → index-08d86676.development.cjs.js} +21 -15
- package/dist/{index-698a3320.cjs.js → index-32631949.cjs.js} +21 -15
- package/dist/{index-45856a94.esm.js → index-603c1cda.esm.js} +18 -16
- package/dist/{index-be3d4c2d.development.esm.js → index-7081e0c9.development.esm.js} +18 -16
- package/dist/xstate-actors.cjs.js +1 -1
- package/dist/xstate-actors.development.cjs.js +1 -1
- package/dist/xstate-actors.development.esm.js +1 -1
- package/dist/xstate-actors.esm.js +1 -1
- package/dist/xstate-graph.cjs.js +2 -2
- package/dist/xstate-graph.development.cjs.js +2 -2
- package/dist/xstate-graph.development.esm.js +2 -2
- package/dist/xstate-graph.esm.js +2 -2
- package/dist/xstate-graph.umd.min.js +1 -1
- package/dist/xstate-graph.umd.min.js.map +1 -1
- package/dist/xstate.cjs.js +336 -2
- package/dist/xstate.cjs.mjs +1 -0
- package/dist/xstate.development.cjs.js +336 -2
- package/dist/xstate.development.cjs.mjs +1 -0
- package/dist/xstate.development.esm.js +339 -6
- package/dist/xstate.esm.js +339 -6
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var dist_xstateActors = require('./index-
|
|
6
|
-
var StateMachine = require('./StateMachine-
|
|
5
|
+
var dist_xstateActors = require('./index-08d86676.development.cjs.js');
|
|
6
|
+
var StateMachine = require('./StateMachine-3120a7ff.development.cjs.js');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Asserts that the given event object is of the specified type or types. Throws
|
|
@@ -91,6 +91,339 @@ function createStateConfig(config) {
|
|
|
91
91
|
return config;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
const emptyImplementations = {
|
|
95
|
+
actions: {},
|
|
96
|
+
actorSources: {},
|
|
97
|
+
guards: {},
|
|
98
|
+
delays: {}
|
|
99
|
+
};
|
|
100
|
+
const emptyExecutableActions = [];
|
|
101
|
+
const emptyRawActions = [];
|
|
102
|
+
const builtInActionSet = new Set(Object.values(dist_xstateActors.builtInActions));
|
|
103
|
+
function toArray(value) {
|
|
104
|
+
return value === undefined ? [] : Array.isArray(value) ? value : [value];
|
|
105
|
+
}
|
|
106
|
+
function resolveContext(context, input) {
|
|
107
|
+
return typeof context === 'function' ? context({
|
|
108
|
+
input
|
|
109
|
+
}) : context ?? {};
|
|
110
|
+
}
|
|
111
|
+
function resolveTransitionContext(context, args) {
|
|
112
|
+
return typeof context === 'function' ? context(args) : context;
|
|
113
|
+
}
|
|
114
|
+
function resolveInput(input, context, event) {
|
|
115
|
+
return typeof input === 'function' ? input({
|
|
116
|
+
context,
|
|
117
|
+
event
|
|
118
|
+
}) : input;
|
|
119
|
+
}
|
|
120
|
+
function mergeContextPatch(context, patch) {
|
|
121
|
+
for (const key of Object.keys(patch)) {
|
|
122
|
+
if (!Object.prototype.hasOwnProperty.call(context, key) || !Object.is(context[key], patch[key])) {
|
|
123
|
+
return {
|
|
124
|
+
...context,
|
|
125
|
+
...patch
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return context;
|
|
130
|
+
}
|
|
131
|
+
function createSnapshot(value, context, input, machine, stateInput) {
|
|
132
|
+
return {
|
|
133
|
+
status: 'active',
|
|
134
|
+
output: undefined,
|
|
135
|
+
error: undefined,
|
|
136
|
+
value,
|
|
137
|
+
context,
|
|
138
|
+
input,
|
|
139
|
+
children: {},
|
|
140
|
+
_stateInput: stateInput,
|
|
141
|
+
machine
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function cloneSnapshot(snapshot, value, context, stateInput) {
|
|
145
|
+
return {
|
|
146
|
+
status: snapshot.status,
|
|
147
|
+
output: snapshot.output,
|
|
148
|
+
error: snapshot.error,
|
|
149
|
+
value,
|
|
150
|
+
context,
|
|
151
|
+
input: snapshot.input,
|
|
152
|
+
children: snapshot.children,
|
|
153
|
+
_stateInput: stateInput,
|
|
154
|
+
machine: snapshot.machine
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function stopSnapshot(snapshot) {
|
|
158
|
+
return {
|
|
159
|
+
status: 'stopped',
|
|
160
|
+
output: undefined,
|
|
161
|
+
error: undefined,
|
|
162
|
+
value: snapshot.value,
|
|
163
|
+
context: snapshot.context,
|
|
164
|
+
input: undefined,
|
|
165
|
+
children: snapshot.children,
|
|
166
|
+
_stateInput: snapshot._stateInput,
|
|
167
|
+
machine: snapshot.machine
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function assertNoStringTransitions(config) {
|
|
171
|
+
for (const [stateKey, stateConfig] of Object.entries(config.states)) {
|
|
172
|
+
for (const [eventType, transitionConfig] of Object.entries(stateConfig.on ?? {})) {
|
|
173
|
+
for (const transition of toArray(transitionConfig)) {
|
|
174
|
+
if (typeof transition === 'string') {
|
|
175
|
+
const target = transition;
|
|
176
|
+
throw new Error(`Invalid transition for "${stateKey}.${eventType}": use { target: "${target}" } instead of a string target.`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function resolveSimpleEnqueuedActions(rawActions) {
|
|
183
|
+
const executableActions = [];
|
|
184
|
+
for (const action of rawActions) {
|
|
185
|
+
if (!action || typeof action !== 'object' || !('action' in action) || typeof action.action !== 'function' || builtInActionSet.has(action.action) || '_special' in action.action) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
executableActions.push({
|
|
189
|
+
type: action.action.name || '(anonymous)',
|
|
190
|
+
params: undefined,
|
|
191
|
+
args: action.args,
|
|
192
|
+
exec: action.args.length ? action.action.bind(null, ...action.args) : action.action
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
return executableActions;
|
|
196
|
+
}
|
|
197
|
+
function createFSM(config) {
|
|
198
|
+
const machine = {
|
|
199
|
+
id: config.id ?? '(fsm)',
|
|
200
|
+
implementations: emptyImplementations
|
|
201
|
+
};
|
|
202
|
+
assertNoStringTransitions(config);
|
|
203
|
+
const runActions = (snapshot, event, actorScope, rawActions) => {
|
|
204
|
+
if (!rawActions?.length) {
|
|
205
|
+
return [snapshot, emptyExecutableActions];
|
|
206
|
+
}
|
|
207
|
+
const simpleExecutableActions = resolveSimpleEnqueuedActions(rawActions);
|
|
208
|
+
if (simpleExecutableActions) {
|
|
209
|
+
return [snapshot, simpleExecutableActions];
|
|
210
|
+
}
|
|
211
|
+
return dist_xstateActors.resolveActionsWithContext(snapshot, event, actorScope, rawActions);
|
|
212
|
+
};
|
|
213
|
+
const runStateActions = (snapshot, event, actorScope, actionsConfig, stateInput, internalQueue) => {
|
|
214
|
+
if (!actionsConfig) {
|
|
215
|
+
return [snapshot, emptyExecutableActions];
|
|
216
|
+
}
|
|
217
|
+
const actions = [];
|
|
218
|
+
const enq = dist_xstateActors.createTransitionEnqueue(actorScope, actions, internalQueue, true);
|
|
219
|
+
let context;
|
|
220
|
+
const actionCount = Array.isArray(actionsConfig) ? actionsConfig.length : 1;
|
|
221
|
+
for (let i = 0; i < actionCount; i++) {
|
|
222
|
+
const action = Array.isArray(actionsConfig) ? actionsConfig[i] : actionsConfig;
|
|
223
|
+
const result = action({
|
|
224
|
+
context: context ?? snapshot.context,
|
|
225
|
+
event: event,
|
|
226
|
+
input: stateInput,
|
|
227
|
+
value: snapshot.value,
|
|
228
|
+
self: actorScope.self,
|
|
229
|
+
system: actorScope.system,
|
|
230
|
+
parent: actorScope.self._parent,
|
|
231
|
+
children: snapshot.children
|
|
232
|
+
}, enq);
|
|
233
|
+
if (result?.context !== undefined) {
|
|
234
|
+
const currentContext = context ?? snapshot.context;
|
|
235
|
+
const nextContext = mergeContextPatch(currentContext, result.context);
|
|
236
|
+
if (nextContext !== currentContext) {
|
|
237
|
+
context = nextContext;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const nextSnapshot = context !== undefined ? cloneSnapshot(snapshot, snapshot.value, context, snapshot._stateInput) : snapshot;
|
|
242
|
+
return runActions(nextSnapshot, event, actorScope, actions);
|
|
243
|
+
};
|
|
244
|
+
const selectTransition = (snapshot, event, actorScope, internalQueue) => {
|
|
245
|
+
const state = config.states[snapshot.value];
|
|
246
|
+
const transitionsConfig = state?.on?.[event.type];
|
|
247
|
+
if (!transitionsConfig) {
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
250
|
+
const transitionCount = Array.isArray(transitionsConfig) ? transitionsConfig.length : 1;
|
|
251
|
+
for (let i = 0; i < transitionCount; i++) {
|
|
252
|
+
const transition = Array.isArray(transitionsConfig) ? transitionsConfig[i] : transitionsConfig;
|
|
253
|
+
const args = {
|
|
254
|
+
context: snapshot.context,
|
|
255
|
+
event,
|
|
256
|
+
input: snapshot.input,
|
|
257
|
+
value: snapshot.value,
|
|
258
|
+
self: actorScope.self,
|
|
259
|
+
system: actorScope.system,
|
|
260
|
+
parent: actorScope.self._parent,
|
|
261
|
+
children: snapshot.children
|
|
262
|
+
};
|
|
263
|
+
if (typeof transition === 'function') {
|
|
264
|
+
const actions = [];
|
|
265
|
+
const enq = dist_xstateActors.createTransitionEnqueue(actorScope, actions, internalQueue, true);
|
|
266
|
+
const result = transition(args, enq);
|
|
267
|
+
if (!result) {
|
|
268
|
+
if (actions.length) {
|
|
269
|
+
return {
|
|
270
|
+
actions
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
target: result.target,
|
|
277
|
+
context: result.context,
|
|
278
|
+
input: result.input,
|
|
279
|
+
actions
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
if ('guard' in transition && transition.guard && !transition.guard(args)) {
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
target: transition.target,
|
|
287
|
+
context: resolveTransitionContext(transition.context, args),
|
|
288
|
+
input: transition.input,
|
|
289
|
+
actions: 'actions' in transition && transition.actions ? toArray(transition.actions) : emptyRawActions
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
return undefined;
|
|
293
|
+
};
|
|
294
|
+
const transition = (snapshot, event, actorScope) => {
|
|
295
|
+
if (snapshot.status !== 'active') {
|
|
296
|
+
return [snapshot, []];
|
|
297
|
+
}
|
|
298
|
+
if (event.type === dist_xstateActors.XSTATE_STOP) {
|
|
299
|
+
return [stopSnapshot(snapshot), emptyExecutableActions];
|
|
300
|
+
}
|
|
301
|
+
const stateConfig = config.states[snapshot.value];
|
|
302
|
+
const directTransition = stateConfig?.on?.[event.type];
|
|
303
|
+
if (!directTransition) {
|
|
304
|
+
return [snapshot, emptyExecutableActions];
|
|
305
|
+
}
|
|
306
|
+
if (!Array.isArray(directTransition) && typeof directTransition !== 'function' && !('guard' in directTransition) && !('actions' in directTransition && directTransition.actions) && typeof directTransition.input !== 'function') {
|
|
307
|
+
const target = directTransition.target ?? snapshot.value;
|
|
308
|
+
const stateChanged = target !== snapshot.value;
|
|
309
|
+
if (stateChanged && (stateConfig.exit || config.states[target]?.entry)) ; else {
|
|
310
|
+
const hasContext = directTransition.context !== undefined;
|
|
311
|
+
const hasInput = directTransition.input !== undefined;
|
|
312
|
+
const resolvedContext = resolveTransitionContext(directTransition.context, {
|
|
313
|
+
context: snapshot.context,
|
|
314
|
+
event,
|
|
315
|
+
input: snapshot.input,
|
|
316
|
+
value: snapshot.value,
|
|
317
|
+
self: actorScope.self,
|
|
318
|
+
system: actorScope.system,
|
|
319
|
+
parent: actorScope.self._parent,
|
|
320
|
+
children: snapshot.children
|
|
321
|
+
});
|
|
322
|
+
const context = hasContext && resolvedContext ? mergeContextPatch(snapshot.context, resolvedContext) : snapshot.context;
|
|
323
|
+
if (!stateChanged && context === snapshot.context && !hasInput && snapshot._stateInput === undefined) {
|
|
324
|
+
return [snapshot, emptyExecutableActions];
|
|
325
|
+
}
|
|
326
|
+
return [cloneSnapshot(snapshot, target, context, hasInput ? resolveInput(directTransition.input, context, event) : undefined), emptyExecutableActions];
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
if (typeof directTransition === 'function' && directTransition.length < 2 && !stateConfig?.exit) {
|
|
330
|
+
const result = directTransition({
|
|
331
|
+
context: snapshot.context,
|
|
332
|
+
event,
|
|
333
|
+
input: snapshot.input,
|
|
334
|
+
value: snapshot.value,
|
|
335
|
+
self: actorScope.self,
|
|
336
|
+
system: actorScope.system,
|
|
337
|
+
parent: actorScope.self._parent,
|
|
338
|
+
children: snapshot.children
|
|
339
|
+
}, undefined);
|
|
340
|
+
if (result) {
|
|
341
|
+
const target = result.target ?? snapshot.value;
|
|
342
|
+
if (!config.states[target]?.entry) {
|
|
343
|
+
const hasContext = result.context !== undefined;
|
|
344
|
+
const hasInput = result.input !== undefined;
|
|
345
|
+
const context = hasContext && result.context ? mergeContextPatch(snapshot.context, result.context) : snapshot.context;
|
|
346
|
+
if (target === snapshot.value && context === snapshot.context && !hasInput && snapshot._stateInput === undefined) {
|
|
347
|
+
return [snapshot, emptyExecutableActions];
|
|
348
|
+
}
|
|
349
|
+
return [cloneSnapshot(snapshot, target, context, hasInput ? resolveInput(result.input, context, event) : undefined), emptyExecutableActions];
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
let nextSnapshot = snapshot;
|
|
354
|
+
const executableActions = [];
|
|
355
|
+
const internalQueue = [event];
|
|
356
|
+
let iterations = 0;
|
|
357
|
+
while (internalQueue.length) {
|
|
358
|
+
if (++iterations > 1000) {
|
|
359
|
+
throw new Error('FSM microstep count exceeded 1000');
|
|
360
|
+
}
|
|
361
|
+
const nextEvent = internalQueue.shift();
|
|
362
|
+
const selected = selectTransition(nextSnapshot, nextEvent, actorScope, internalQueue);
|
|
363
|
+
if (!selected) {
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
const nextValue = selected.target ?? nextSnapshot.value;
|
|
367
|
+
const stateChanged = nextValue !== nextSnapshot.value;
|
|
368
|
+
if (stateChanged) {
|
|
369
|
+
const [exited, exitActions] = runStateActions(nextSnapshot, nextEvent, actorScope, config.states[nextSnapshot.value]?.exit, nextSnapshot._stateInput, internalQueue);
|
|
370
|
+
nextSnapshot = exited;
|
|
371
|
+
executableActions.push(...exitActions);
|
|
372
|
+
}
|
|
373
|
+
let context = nextSnapshot.context;
|
|
374
|
+
if (selected.context !== undefined) {
|
|
375
|
+
context = mergeContextPatch(context, selected.context);
|
|
376
|
+
}
|
|
377
|
+
const hasInput = selected.input !== undefined;
|
|
378
|
+
const stateInput = hasInput ? resolveInput(selected.input, context, nextEvent) : undefined;
|
|
379
|
+
if (stateChanged || context !== nextSnapshot.context || hasInput || nextSnapshot._stateInput !== undefined) {
|
|
380
|
+
nextSnapshot = cloneSnapshot(nextSnapshot, nextValue, context, stateInput);
|
|
381
|
+
}
|
|
382
|
+
const [afterTransition, transitionActions] = runActions(nextSnapshot, nextEvent, actorScope, selected.actions);
|
|
383
|
+
nextSnapshot = afterTransition;
|
|
384
|
+
executableActions.push(...transitionActions);
|
|
385
|
+
if (stateChanged) {
|
|
386
|
+
const [entered, entryActions] = runStateActions(nextSnapshot, nextEvent, actorScope, config.states[nextValue]?.entry, stateInput, internalQueue);
|
|
387
|
+
nextSnapshot = entered;
|
|
388
|
+
executableActions.push(...entryActions);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return [nextSnapshot, executableActions];
|
|
392
|
+
};
|
|
393
|
+
const logic = {
|
|
394
|
+
id: config.id,
|
|
395
|
+
config,
|
|
396
|
+
transition,
|
|
397
|
+
initialTransition: (input, actorScope) => {
|
|
398
|
+
const context = resolveContext(config.context, input);
|
|
399
|
+
const snapshot = createSnapshot(config.initial, context, input, machine);
|
|
400
|
+
const internalQueue = [];
|
|
401
|
+
let [nextSnapshot, actions] = runStateActions(snapshot, {
|
|
402
|
+
type: dist_xstateActors.XSTATE_INIT
|
|
403
|
+
}, actorScope, config.states[config.initial]?.entry, undefined, internalQueue);
|
|
404
|
+
if (!actions.length) {
|
|
405
|
+
actions = [];
|
|
406
|
+
}
|
|
407
|
+
while (internalQueue.length) {
|
|
408
|
+
const [raisedSnapshot, raisedActions] = transition(nextSnapshot, internalQueue.shift(), actorScope);
|
|
409
|
+
nextSnapshot = raisedSnapshot;
|
|
410
|
+
actions.push(...raisedActions);
|
|
411
|
+
}
|
|
412
|
+
return [nextSnapshot, actions];
|
|
413
|
+
},
|
|
414
|
+
getInitialSnapshot: (actorScope, input) => logic.initialTransition(input, actorScope)[0],
|
|
415
|
+
getPersistedSnapshot: ({
|
|
416
|
+
machine: _,
|
|
417
|
+
...snapshot
|
|
418
|
+
}) => snapshot,
|
|
419
|
+
restoreSnapshot: snapshot => ({
|
|
420
|
+
...snapshot,
|
|
421
|
+
machine: machine
|
|
422
|
+
})
|
|
423
|
+
};
|
|
424
|
+
return logic;
|
|
425
|
+
}
|
|
426
|
+
|
|
94
427
|
function delayToMs(delay) {
|
|
95
428
|
const parsedDelay = dist_xstateActors.parseDelayToMilliseconds(delay);
|
|
96
429
|
if (parsedDelay !== undefined) return parsedDelay;
|
|
@@ -2322,6 +2655,7 @@ exports.StateNode = StateMachine.StateNode;
|
|
|
2322
2655
|
exports.SimulatedClock = SimulatedClock;
|
|
2323
2656
|
exports.SpecialTargets = SpecialTargets;
|
|
2324
2657
|
exports.assertEvent = assertEvent;
|
|
2658
|
+
exports.createFSM = createFSM;
|
|
2325
2659
|
exports.createMachine = createMachine;
|
|
2326
2660
|
exports.createMachineFromConfig = createMachineFromConfig;
|
|
2327
2661
|
exports.createStateConfig = createStateConfig;
|