xstate 6.0.0-alpha.64 → 6.0.0-alpha.65
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/README.md +27 -0
- package/dist/{createActor-521c8805.development.cjs.js → createActor-1df42c9e.development.cjs.js} +205 -31
- package/dist/{createActor-8493caa9.esm.js → createActor-4629a290.esm.js} +133 -28
- package/dist/{createActor-bd2527dc.development.esm.js → createActor-8f57b47b.development.esm.js} +205 -31
- package/dist/{createActor-29adb8a4.cjs.js → createActor-b987e971.cjs.js} +133 -28
- package/dist/declarations/src/State.d.ts +25 -3
- package/dist/declarations/src/StateMachine.d.ts +20 -7
- package/dist/declarations/src/actors/promise.d.ts +5 -5
- package/dist/declarations/src/createMachine.d.ts +5 -3
- package/dist/declarations/src/createMachineFromConfig.d.ts +13 -2
- package/dist/declarations/src/eventTypes.d.ts +8 -0
- package/dist/declarations/src/graph/index.d.ts +1 -0
- package/dist/declarations/src/graph/types.d.ts +20 -2
- package/dist/declarations/src/machineVersions.d.ts +2 -2
- package/dist/declarations/src/serialize.d.ts +7 -2
- package/dist/declarations/src/setup.d.ts +60 -19
- package/dist/declarations/src/types.d.ts +44 -23
- package/dist/declarations/src/types.v6.d.ts +9 -7
- package/dist/declarations/src/utils.d.ts +9 -0
- package/dist/{effectDescriptor-6dbc400a.cjs.js → effectDescriptor-4cf24593.cjs.js} +1 -1
- package/dist/{effectDescriptor-85ea06c9.esm.js → effectDescriptor-973fc1ba.esm.js} +1 -1
- package/dist/{effectDescriptor-62b53c6d.development.cjs.js → effectDescriptor-b2b7deaa.development.cjs.js} +1 -1
- package/dist/{effectDescriptor-f76948fc.development.esm.js → effectDescriptor-c4671afc.development.esm.js} +1 -1
- package/dist/{index-5587e13b.cjs.js → index-0cf33789.development.cjs.js} +29 -14
- package/dist/{index-b0dc2b39.esm.js → index-15382daf.development.esm.js} +29 -14
- package/dist/{index-90ebf5ae.development.esm.js → index-52ad3d45.esm.js} +29 -14
- package/dist/{index-2afc57c3.development.cjs.js → index-f201d440.cjs.js} +29 -14
- package/dist/xstate-actors.cjs.js +2 -2
- package/dist/xstate-actors.development.cjs.js +2 -2
- package/dist/xstate-actors.development.esm.js +2 -2
- package/dist/xstate-actors.esm.js +2 -2
- package/dist/xstate-actors.umd.min.js +1 -1
- package/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/xstate-durable.cjs.js +2 -2
- package/dist/xstate-durable.development.cjs.js +2 -2
- package/dist/xstate-durable.development.esm.js +2 -2
- package/dist/xstate-durable.esm.js +2 -2
- package/dist/xstate-durable.umd.min.js +1 -1
- package/dist/xstate-durable.umd.min.js.map +1 -1
- package/dist/xstate-graph.cjs.js +8 -4
- package/dist/xstate-graph.cjs.mjs +1 -0
- package/dist/xstate-graph.development.cjs.js +8 -4
- package/dist/xstate-graph.development.cjs.mjs +1 -0
- package/dist/xstate-graph.development.esm.js +8 -4
- package/dist/xstate-graph.esm.js +8 -4
- package/dist/xstate-graph.umd.min.js +1 -1
- package/dist/xstate-graph.umd.min.js.map +1 -1
- package/dist/xstate-validation.cjs.js +24 -7
- package/dist/xstate-validation.development.cjs.js +24 -7
- package/dist/xstate-validation.development.esm.js +24 -7
- package/dist/xstate-validation.esm.js +24 -7
- package/dist/xstate-validation.umd.min.js +1 -1
- package/dist/xstate-validation.umd.min.js.map +1 -1
- package/dist/xstate.cjs.js +475 -257
- package/dist/xstate.development.cjs.js +497 -260
- package/dist/xstate.development.esm.js +499 -262
- package/dist/xstate.esm.js +477 -259
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -527,7 +527,8 @@ function withActorScope(args, actorScope) {
|
|
|
527
527
|
}
|
|
528
528
|
|
|
529
529
|
function execCustomEffect() {
|
|
530
|
-
|
|
530
|
+
const result = this.action?.(...this.args);
|
|
531
|
+
return result;
|
|
531
532
|
}
|
|
532
533
|
function execEmitEffect(runtime = this.source.system) {
|
|
533
534
|
return runtime.emitEvent(this.source, this.event);
|
|
@@ -1049,6 +1050,13 @@ function createTransitionEnqueue(actorScope, actions, internalEvents, actorSubsc
|
|
|
1049
1050
|
props[key] = guard(props[key]);
|
|
1050
1051
|
}
|
|
1051
1052
|
const enqueue = createEnqueueObject(props, guard((action, ...args) => {
|
|
1053
|
+
// A named action is `undefined` when it has no implementation. Skip it:
|
|
1054
|
+
// an `{ action, args }` record without a function would be emitted as
|
|
1055
|
+
// an event. Speculative passes (`can()`, conflict resolution) run with
|
|
1056
|
+
// `createActors: false`; warn only when the transition really runs.
|
|
1057
|
+
if (typeof action !== 'function') {
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1052
1060
|
pushBuiltInAction(actions, action, ...args);
|
|
1053
1061
|
}));
|
|
1054
1062
|
enqueueClosers.set(enqueue, () => {
|
|
@@ -2266,6 +2274,10 @@ function getDelayedTransitions(stateNode) {
|
|
|
2266
2274
|
}));
|
|
2267
2275
|
}
|
|
2268
2276
|
function formatTransition(stateNode, descriptor, transitionConfig) {
|
|
2277
|
+
const removedKey = getRemovedTransitionKey(transitionConfig);
|
|
2278
|
+
if (removedKey) {
|
|
2279
|
+
throw new Error(`Transition "${descriptor || 'always'}" in state "${stateNode.id}" uses ${removedKey}, which was removed in v6. Use a transition function.`);
|
|
2280
|
+
}
|
|
2269
2281
|
const normalizedTarget = normalizeTarget(transitionConfig.target);
|
|
2270
2282
|
const reenter = transitionConfig.reenter ?? false;
|
|
2271
2283
|
const target = resolveTarget(stateNode, normalizedTarget);
|
|
@@ -2276,14 +2288,46 @@ function formatTransition(stateNode, descriptor, transitionConfig) {
|
|
|
2276
2288
|
source: stateNode,
|
|
2277
2289
|
reenter,
|
|
2278
2290
|
eventType: descriptor,
|
|
2279
|
-
toJSON: () => (
|
|
2280
|
-
...transition,
|
|
2281
|
-
source: `#${stateNode.id}`,
|
|
2282
|
-
target: target ? target.map(t => `#${t.id}`) : undefined
|
|
2283
|
-
})
|
|
2291
|
+
toJSON: () => transitionDefinitionToJSON(transition)
|
|
2284
2292
|
};
|
|
2285
2293
|
return transition;
|
|
2286
2294
|
}
|
|
2295
|
+
function transitionDefinitionToJSON(transition) {
|
|
2296
|
+
const {
|
|
2297
|
+
definition: _,
|
|
2298
|
+
...serializableTransition
|
|
2299
|
+
} = transition;
|
|
2300
|
+
return {
|
|
2301
|
+
...serializableTransition,
|
|
2302
|
+
source: `#${transition.source.id}`,
|
|
2303
|
+
target: transition.target?.map(target => `#${target.id}`)
|
|
2304
|
+
};
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
/**
|
|
2308
|
+
* Returns the v5 key of a transition object that v6 would misread, in every
|
|
2309
|
+
* build: `cond` is never read, so the transition would always be taken,
|
|
2310
|
+
* transition `actions` would not run as written, and only a function `guard`
|
|
2311
|
+
* can be called. Development builds explain each key earlier, in
|
|
2312
|
+
* `diagnoseAuthorConfig`. Compiled configs (JSON, SCXML) never set them.
|
|
2313
|
+
*/
|
|
2314
|
+
function getRemovedTransitionKey(transitionConfig) {
|
|
2315
|
+
const {
|
|
2316
|
+
cond,
|
|
2317
|
+
actions,
|
|
2318
|
+
guard
|
|
2319
|
+
} = transitionConfig;
|
|
2320
|
+
if (cond !== undefined) {
|
|
2321
|
+
return '"cond"';
|
|
2322
|
+
}
|
|
2323
|
+
if (actions !== undefined) {
|
|
2324
|
+
return '"actions"';
|
|
2325
|
+
}
|
|
2326
|
+
if (guard !== undefined && typeof guard !== 'function') {
|
|
2327
|
+
return 'an object-form "guard"';
|
|
2328
|
+
}
|
|
2329
|
+
return undefined;
|
|
2330
|
+
}
|
|
2287
2331
|
function isStateNodeDescendantOf(stateNode, ancestor) {
|
|
2288
2332
|
for (let current = stateNode.parent; current; current = current.parent) {
|
|
2289
2333
|
if (current === ancestor) {
|
|
@@ -2626,12 +2670,18 @@ function removeConflictingTransitions(enabledTransitions, stateNodeSet, snapshot
|
|
|
2626
2670
|
}
|
|
2627
2671
|
function createTransitionResultResolver(snapshot, event, actorScope, resolveActions, selectionResults) {
|
|
2628
2672
|
let cache;
|
|
2629
|
-
return transition => {
|
|
2630
|
-
if (!transition.to) {
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2673
|
+
return (transition, applied) => {
|
|
2674
|
+
if (!transition.to && !applied) {
|
|
2675
|
+
// An object transition's targets are static, so reading them must not
|
|
2676
|
+
// run its `context` and `input` mappers
|
|
2677
|
+
return {
|
|
2678
|
+
targets: transition.target,
|
|
2679
|
+
context: undefined,
|
|
2680
|
+
reenter: transition.reenter,
|
|
2681
|
+
actions: undefined,
|
|
2682
|
+
internalEvents: undefined,
|
|
2683
|
+
input: undefined
|
|
2684
|
+
};
|
|
2635
2685
|
}
|
|
2636
2686
|
let result = cache?.get(transition);
|
|
2637
2687
|
if (!result) {
|
|
@@ -2859,13 +2909,20 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
|
|
|
2859
2909
|
children: args.children,
|
|
2860
2910
|
actions: args.actions,
|
|
2861
2911
|
actors: args.actors,
|
|
2912
|
+
guards: currentSnapshot.machine.sources.guards,
|
|
2913
|
+
delays: currentSnapshot.machine.sources.delays,
|
|
2862
2914
|
input,
|
|
2863
2915
|
stateNode
|
|
2864
2916
|
}, actorScope) : {
|
|
2865
2917
|
...args,
|
|
2918
|
+
guards: currentSnapshot.machine.sources.guards,
|
|
2919
|
+
delays: currentSnapshot.machine.sources.delays,
|
|
2866
2920
|
input,
|
|
2867
2921
|
stateNode
|
|
2868
|
-
},
|
|
2922
|
+
},
|
|
2923
|
+
// This function runs during action resolution, where enqueued
|
|
2924
|
+
// effects are no longer collected.
|
|
2925
|
+
enqueue), '_special' in transitionFn ? {
|
|
2869
2926
|
_special: true
|
|
2870
2927
|
} : {});
|
|
2871
2928
|
return [[wrappedAction], undefined, undefined];
|
|
@@ -2903,7 +2960,7 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
|
|
|
2903
2960
|
}
|
|
2904
2961
|
for (const exitStateNode of statesToExit) {
|
|
2905
2962
|
const stateInput = getStateInput(currentSnapshot, exitStateNode.id);
|
|
2906
|
-
const [exitActions, nextContext, internalEvents] = exitStateNode.exit ? getStateActionsAndContext(exitStateNode.exit, nextState.context,
|
|
2963
|
+
const [exitActions, nextContext, internalEvents] = exitStateNode.exit ? getStateActionsAndContext(exitStateNode.exit, nextState.context, nextState.children, stateInput, 'exit', exitStateNode) : [[], undefined, undefined];
|
|
2907
2964
|
if (internalEvents?.length) {
|
|
2908
2965
|
internalQueue.push(...internalEvents);
|
|
2909
2966
|
}
|
|
@@ -2933,11 +2990,20 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
|
|
|
2933
2990
|
let context = nextState.context;
|
|
2934
2991
|
const transitionActions = [];
|
|
2935
2992
|
const internalEvents = [];
|
|
2993
|
+
const resolvedTransitions = [];
|
|
2936
2994
|
for (const t of filteredTransitions) {
|
|
2937
|
-
|
|
2938
|
-
|
|
2995
|
+
const res = getCurrentTransitionResult(t, true);
|
|
2996
|
+
if (t.to) {
|
|
2997
|
+
const resolvedTransition = {
|
|
2998
|
+
...t,
|
|
2999
|
+
target: res.targets,
|
|
3000
|
+
definition: t
|
|
3001
|
+
};
|
|
3002
|
+
resolvedTransition.toJSON = () => transitionDefinitionToJSON(resolvedTransition);
|
|
3003
|
+
resolvedTransitions.push(resolvedTransition);
|
|
3004
|
+
} else {
|
|
3005
|
+
resolvedTransitions.push(t);
|
|
2939
3006
|
}
|
|
2940
|
-
const res = getCurrentTransitionResult(t);
|
|
2941
3007
|
if (res.context !== undefined) {
|
|
2942
3008
|
context = mergeContextPatch(context, res.context);
|
|
2943
3009
|
}
|
|
@@ -3093,7 +3159,7 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
|
|
|
3093
3159
|
const {
|
|
3094
3160
|
targets,
|
|
3095
3161
|
input
|
|
3096
|
-
} = getCurrentTransitionResult(transition);
|
|
3162
|
+
} = getCurrentTransitionResult(transition, true);
|
|
3097
3163
|
if (input && targets) {
|
|
3098
3164
|
for (const targetNode of targets.filter(targetNode => enteredTargetsByTransition.get(transition)?.has(targetNode))) {
|
|
3099
3165
|
stateInputMap[targetNode.id] = input;
|
|
@@ -3102,12 +3168,12 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
|
|
|
3102
3168
|
}
|
|
3103
3169
|
}
|
|
3104
3170
|
const completedNodes = new Set();
|
|
3105
|
-
const children = {
|
|
3106
|
-
...nextState.children
|
|
3107
|
-
};
|
|
3108
3171
|
for (const stateNodeToEnter of [...statesToEnter].sort((a, b) => a.order - b.order)) {
|
|
3109
3172
|
mutStateNodeSet.add(stateNodeToEnter);
|
|
3110
3173
|
const actions = [];
|
|
3174
|
+
// Read the children for each state: the entry actions of the states
|
|
3175
|
+
// entered before this one may have spawned or stopped children.
|
|
3176
|
+
let children = nextState.children;
|
|
3111
3177
|
|
|
3112
3178
|
// Final states are inert, so (as in SCXML) their invocations never
|
|
3113
3179
|
// start.
|
|
@@ -3146,7 +3212,10 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
|
|
|
3146
3212
|
args: [actor]
|
|
3147
3213
|
});
|
|
3148
3214
|
if (invokeDef.id) {
|
|
3149
|
-
children
|
|
3215
|
+
children = {
|
|
3216
|
+
...children,
|
|
3217
|
+
[invokeDef.id]: actor
|
|
3218
|
+
};
|
|
3150
3219
|
}
|
|
3151
3220
|
}
|
|
3152
3221
|
if (invoked) {
|
|
@@ -3266,7 +3335,12 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
|
|
|
3266
3335
|
nextStateNodesToExit.forEach(stateNode => {
|
|
3267
3336
|
if (stateNode.exit) {
|
|
3268
3337
|
const stateInput = getStateInput(nextState, stateNode.id);
|
|
3269
|
-
const [exitActions
|
|
3338
|
+
const [exitActions, nextContext, nextInternalEvents] = getStateActionsAndContext(stateNode.exit, nextState.context, nextState.children, stateInput, 'exit', stateNode);
|
|
3339
|
+
if (nextContext) {
|
|
3340
|
+
nextState = cloneMachineSnapshot(nextState, {
|
|
3341
|
+
context: nextContext
|
|
3342
|
+
});
|
|
3343
|
+
}
|
|
3270
3344
|
allExitActions.push(...exitActions);
|
|
3271
3345
|
if (nextInternalEvents?.length) {
|
|
3272
3346
|
internalQueue.push(...nextInternalEvents);
|
|
@@ -3287,14 +3361,14 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
|
|
|
3287
3361
|
// If context was changed (e.g. by entry actions during self-transition),
|
|
3288
3362
|
// clone to ensure reference inequality for eventless transition re-evaluation
|
|
3289
3363
|
if (nextState.context !== originalContext) {
|
|
3290
|
-
return [nextState === currentSnapshot ? cloneMachineSnapshot(nextState) : nextState, executableActions];
|
|
3364
|
+
return [nextState === currentSnapshot ? cloneMachineSnapshot(nextState) : nextState, executableActions, resolvedTransitions];
|
|
3291
3365
|
}
|
|
3292
|
-
return [nextState, executableActions];
|
|
3366
|
+
return [nextState, executableActions, resolvedTransitions];
|
|
3293
3367
|
}
|
|
3294
3368
|
return [cloneMachineSnapshot(nextState, {
|
|
3295
3369
|
_nodes: nextStateNodes,
|
|
3296
3370
|
historyValue
|
|
3297
|
-
}), executableActions];
|
|
3371
|
+
}), executableActions, resolvedTransitions];
|
|
3298
3372
|
}
|
|
3299
3373
|
}
|
|
3300
3374
|
|
|
@@ -3404,6 +3478,15 @@ class InfiniteTransitionError extends Error {
|
|
|
3404
3478
|
}
|
|
3405
3479
|
}
|
|
3406
3480
|
function macrostep(snapshot, event, actorScope, internalQueue, initialMicrosteps = []) {
|
|
3481
|
+
// A done, error or stopped snapshot processes no events, as in an actor:
|
|
3482
|
+
// every event is unhandled. The initial macrostep passes `initialMicrosteps`
|
|
3483
|
+
// and may start from a snapshot that is already done.
|
|
3484
|
+
if (snapshot.status !== 'active' && !initialMicrosteps.length) {
|
|
3485
|
+
return {
|
|
3486
|
+
snapshot,
|
|
3487
|
+
microsteps: [[snapshot, [], []]]
|
|
3488
|
+
};
|
|
3489
|
+
}
|
|
3407
3490
|
let nextSnapshot = snapshot;
|
|
3408
3491
|
const microsteps = initialMicrosteps.slice();
|
|
3409
3492
|
// Whether a transition handled the external event. A handled event always
|
|
@@ -3472,6 +3555,7 @@ function macrostep(snapshot, event, actorScope, internalQueue, initialMicrosteps
|
|
|
3472
3555
|
};
|
|
3473
3556
|
}
|
|
3474
3557
|
function addMicrostep(step, transitions) {
|
|
3558
|
+
transitions = step[2] ?? transitions;
|
|
3475
3559
|
// collect microsteps; their transitions are surfaced on the enclosing
|
|
3476
3560
|
// '@xstate.transition' event via its `microsteps[]` facet (there is no
|
|
3477
3561
|
// standalone microstep event) and returned by `getMicrosteps()`
|
|
@@ -3882,6 +3966,17 @@ function isMachineSnapshot(value) {
|
|
|
3882
3966
|
return !!value && typeof value === 'object' && 'machine' in value && 'value' in value;
|
|
3883
3967
|
}
|
|
3884
3968
|
|
|
3969
|
+
/**
|
|
3970
|
+
* The values that `snapshot.matches(...)` accepts for a state value: a state
|
|
3971
|
+
* key, a dot-delimited path to a descendant state, or a partial state value.
|
|
3972
|
+
* Non-literal state values accept any value.
|
|
3973
|
+
*/
|
|
3974
|
+
|
|
3975
|
+
/**
|
|
3976
|
+
* `unknown` if `matches(...)` accepts `TTestStateValue` for `TStateValue`,
|
|
3977
|
+
* otherwise `never`. Non-literal test values are always accepted.
|
|
3978
|
+
*/
|
|
3979
|
+
|
|
3885
3980
|
/** @public */
|
|
3886
3981
|
|
|
3887
3982
|
const machineSnapshotMatches = function matches(testValue) {
|
|
@@ -4382,7 +4477,14 @@ function getAllOwnEventDescriptors(snapshot) {
|
|
|
4382
4477
|
return [...new Set([...snapshot.nodes.flatMap(sn => sn.ownEvents)])];
|
|
4383
4478
|
}
|
|
4384
4479
|
|
|
4385
|
-
/**
|
|
4480
|
+
/**
|
|
4481
|
+
* Returns one event per transition of the active state nodes of `snapshot`,
|
|
4482
|
+
* including the internal events for invoked actors (`xstate.done.actor`,
|
|
4483
|
+
* `xstate.error.actor`) and delayed transitions (`xstate.after`). Graph
|
|
4484
|
+
* traversal sends these when the `events` option is not given.
|
|
4485
|
+
*
|
|
4486
|
+
* @public
|
|
4487
|
+
*/
|
|
4386
4488
|
function getAllOwnEvents(snapshot) {
|
|
4387
4489
|
const events = snapshot.nodes.flatMap(stateNode => [...stateNode.transitions.values()].flatMap(transitions => transitions.map(transition => {
|
|
4388
4490
|
const event = {
|
|
@@ -5931,7 +6033,10 @@ class Actor {
|
|
|
5931
6033
|
const [nextSnapshot, effects] = nextState;
|
|
5932
6034
|
if (nextSnapshot === previousSnapshot && !effects.length &&
|
|
5933
6035
|
// State machine snapshots only; other logic may ignore events freely.
|
|
5934
|
-
'machine' in previousSnapshot &&
|
|
6036
|
+
'machine' in previousSnapshot && (
|
|
6037
|
+
// `xstate.route` is sent by users, so a route that matches nothing is
|
|
6038
|
+
// reported like any other unhandled event.
|
|
6039
|
+
!event.type.startsWith('xstate.') || event.type === 'xstate.route')) {
|
|
5935
6040
|
this._reportUnhandledEvent(event);
|
|
5936
6041
|
}
|
|
5937
6042
|
snapshot = nextSnapshot;
|