xstate 6.0.0-alpha.7 → 6.0.0-alpha.71
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 +206 -67
- package/bin/agent.js +347 -0
- package/bin/xstate.js +52 -0
- package/dist/createActor-2136a8ad.development.cjs.js +7110 -0
- package/dist/createActor-22a0534b.esm.js +6783 -0
- package/dist/createActor-286a0dbb.development.esm.js +6999 -0
- package/dist/createActor-f4978450.cjs.js +6893 -0
- package/dist/declarations/src/SimulatedClock.d.ts +2 -1
- package/dist/declarations/src/State.d.ts +66 -5
- package/dist/declarations/src/StateMachine.d.ts +135 -30
- package/dist/declarations/src/StateNode.d.ts +21 -16
- package/dist/declarations/src/actions.d.ts +11 -6
- package/dist/declarations/src/actors/callback.d.ts +11 -2
- package/dist/declarations/src/actors/index.d.ts +6 -5
- package/dist/declarations/src/actors/listener.d.ts +8 -3
- package/dist/declarations/src/actors/logic.d.ts +42 -52
- package/dist/declarations/src/actors/observable.d.ts +15 -2
- package/dist/declarations/src/actors/promise.d.ts +90 -22
- package/dist/declarations/src/actors/subscription.d.ts +9 -3
- package/dist/declarations/src/assert.d.ts +1 -0
- package/dist/declarations/src/base.types.d.ts +102 -0
- package/dist/declarations/src/createActor.d.ts +104 -27
- package/dist/declarations/src/createMachine.d.ts +37 -16
- package/dist/declarations/src/delay.d.ts +8 -0
- package/dist/declarations/src/durable/index.d.ts +222 -0
- package/dist/declarations/src/effectDescriptor.d.ts +95 -0
- package/dist/declarations/src/eventTypes.d.ts +9 -0
- package/dist/declarations/src/fsm/index.d.ts +2 -0
- package/dist/declarations/src/fsm.d.ts +169 -0
- package/dist/declarations/src/graph/adjacency.d.ts +6 -3
- package/dist/declarations/src/graph/graph.d.ts +6 -3
- package/dist/declarations/src/graph/index.d.ts +2 -3
- package/dist/declarations/src/graph/pathFromEvents.d.ts +5 -2
- package/dist/declarations/src/graph/shortestPaths.d.ts +5 -3
- package/dist/declarations/src/graph/simplePaths.d.ts +5 -3
- package/dist/declarations/src/graph/types.d.ts +113 -59
- package/dist/declarations/src/hotSwap.d.ts +18 -0
- package/dist/declarations/src/index.d.ts +27 -19
- package/dist/declarations/src/inspection.d.ts +24 -1
- package/dist/declarations/src/machineFromJSON.d.ts +171 -0
- package/dist/declarations/src/machineVersion.types.d.ts +53 -0
- package/dist/declarations/src/machineVersions.d.ts +105 -0
- package/dist/declarations/src/mapState.d.ts +2 -0
- package/dist/declarations/src/runtimeHelpers.d.ts +43 -0
- package/dist/declarations/src/schema.types.d.ts +31 -4
- package/dist/declarations/src/serialize.d.ts +39 -27
- package/dist/declarations/src/setup.d.ts +1091 -146
- package/dist/declarations/src/spawn.d.ts +6 -4
- package/dist/declarations/src/stateUtils.d.ts +57 -14
- package/dist/declarations/src/system.d.ts +178 -17
- package/dist/declarations/src/systemTransition.d.ts +108 -0
- package/dist/declarations/src/toPromise.d.ts +1 -0
- package/dist/declarations/src/transition.d.ts +48 -10
- package/dist/declarations/src/transitionActions.d.ts +22 -4
- package/dist/declarations/src/typeUtils.d.ts +52 -0
- package/dist/declarations/src/types.d.ts +842 -297
- package/dist/declarations/src/types.v6.d.ts +543 -101
- package/dist/declarations/src/utils.d.ts +39 -8
- package/dist/declarations/src/validation/index.d.ts +49 -0
- package/dist/declarations/src/validation.types.d.ts +29 -0
- package/dist/declarations/src/waitFor.d.ts +1 -0
- package/dist/effectDescriptor-2ae7e5e3.esm.js +343 -0
- package/dist/effectDescriptor-86f04325.development.esm.js +343 -0
- package/dist/effectDescriptor-a6247f92.cjs.js +351 -0
- package/dist/effectDescriptor-e41e1627.development.cjs.js +351 -0
- package/dist/index-31b3c878.cjs.js +1078 -0
- package/dist/index-5ce9cbf9.development.cjs.js +1078 -0
- package/dist/index-6923de25.development.esm.js +1069 -0
- package/dist/index-74b77771.esm.js +1069 -0
- package/dist/schema.types-0ecd17b8.esm.js +71 -0
- package/dist/schema.types-15a68ddc.cjs.js +74 -0
- package/dist/schema.types-1c16f035.development.cjs.js +74 -0
- package/dist/schema.types-1cd4652e.development.esm.js +71 -0
- package/dist/xstate-actors.cjs.js +5 -6
- package/dist/xstate-actors.cjs.mjs +2 -4
- package/dist/xstate-actors.development.cjs.js +5 -6
- package/dist/xstate-actors.development.cjs.mjs +2 -4
- package/dist/xstate-actors.development.esm.js +2 -1
- package/dist/xstate-actors.esm.js +2 -1
- package/dist/xstate-actors.umd.min.js +1 -1
- package/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/xstate-durable.cjs.d.mts +2 -0
- package/dist/xstate-durable.cjs.d.ts +2 -0
- package/dist/xstate-durable.cjs.js +513 -0
- package/dist/xstate-durable.cjs.mjs +5 -0
- package/dist/xstate-durable.development.cjs.js +513 -0
- package/dist/xstate-durable.development.cjs.mjs +5 -0
- package/dist/xstate-durable.development.esm.js +507 -0
- package/dist/xstate-durable.esm.js +507 -0
- package/dist/xstate-durable.umd.min.js +2 -0
- package/dist/xstate-durable.umd.min.js.map +1 -0
- package/dist/xstate-fsm.cjs.d.mts +2 -0
- package/dist/xstate-fsm.cjs.d.ts +2 -0
- package/dist/xstate-fsm.cjs.js +111 -0
- package/dist/xstate-fsm.cjs.mjs +5 -0
- package/dist/xstate-fsm.development.cjs.js +111 -0
- package/dist/xstate-fsm.development.cjs.mjs +5 -0
- package/dist/xstate-fsm.development.esm.js +105 -0
- package/dist/xstate-fsm.esm.js +105 -0
- package/dist/xstate-fsm.umd.min.js +2 -0
- package/dist/xstate-fsm.umd.min.js.map +1 -0
- package/dist/xstate-graph.cjs.js +172 -457
- package/dist/xstate-graph.cjs.mjs +2 -5
- package/dist/xstate-graph.development.cjs.js +172 -457
- package/dist/xstate-graph.development.cjs.mjs +2 -5
- package/dist/xstate-graph.development.esm.js +170 -451
- package/dist/xstate-graph.esm.js +170 -451
- package/dist/xstate-graph.umd.min.js +1 -1
- package/dist/xstate-graph.umd.min.js.map +1 -1
- package/dist/xstate-validation.cjs.d.mts +2 -0
- package/dist/xstate-validation.cjs.d.ts +2 -0
- package/dist/xstate-validation.cjs.js +330 -0
- package/dist/xstate-validation.cjs.mjs +5 -0
- package/dist/xstate-validation.development.cjs.js +330 -0
- package/dist/xstate-validation.development.cjs.mjs +5 -0
- package/dist/xstate-validation.development.esm.js +324 -0
- package/dist/xstate-validation.esm.js +324 -0
- package/dist/xstate-validation.umd.min.js +2 -0
- package/dist/xstate-validation.umd.min.js.map +1 -0
- package/dist/xstate.cjs.js +4099 -1534
- package/dist/xstate.cjs.mjs +22 -13
- package/dist/xstate.development.cjs.js +4251 -1479
- package/dist/xstate.development.cjs.mjs +22 -13
- package/dist/xstate.development.esm.js +4212 -1449
- package/dist/xstate.esm.js +3996 -1440
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/docs/actions.md +75 -0
- package/docs/actor-logic.md +250 -0
- package/docs/actors.md +64 -0
- package/docs/agents.md +132 -0
- package/docs/api-stability.json +3672 -0
- package/docs/async-logic.md +75 -0
- package/docs/async-requests.md +157 -0
- package/docs/backend-workflows.md +121 -0
- package/docs/cancellation.md +42 -0
- package/docs/cheatsheet.md +561 -0
- package/docs/choice-states.md +109 -0
- package/docs/choose-xstate.md +47 -0
- package/docs/configuration.md +161 -0
- package/docs/context.md +67 -0
- package/docs/create-actor.md +157 -0
- package/docs/data-and-effects.md +48 -0
- package/docs/delays.md +81 -0
- package/docs/durable-execution.md +510 -0
- package/docs/emitted-events.md +146 -0
- package/docs/examples.md +75 -0
- package/docs/faq.md +60 -0
- package/docs/final-states.md +149 -0
- package/docs/forms-and-wizards.md +166 -0
- package/docs/frameworks.md +69 -0
- package/docs/fsm.md +164 -0
- package/docs/glossary.md +68 -0
- package/docs/guards.md +137 -0
- package/docs/history-states.md +159 -0
- package/docs/how-xstate-runs-machines.md +84 -0
- package/docs/index.md +73 -0
- package/docs/input-output.md +69 -0
- package/docs/inspect-actor-systems.md +116 -0
- package/docs/inspection.md +73 -0
- package/docs/internal-events.md +156 -0
- package/docs/invoke.md +354 -0
- package/docs/lifecycle-and-errors.md +48 -0
- package/docs/listen-and-subscribe.md +126 -0
- package/docs/model-based-testing.md +321 -0
- package/docs/modeling.md +40 -0
- package/docs/parallel-states.md +182 -0
- package/docs/persist-and-restore-actors.md +115 -0
- package/docs/persistence.md +325 -0
- package/docs/quick-start.md +55 -0
- package/docs/retries-and-timeouts.md +122 -0
- package/docs/route-states.md +104 -0
- package/docs/scxml.md +91 -0
- package/docs/selectors.md +99 -0
- package/docs/serialization.md +127 -0
- package/docs/setup-and-provide.md +271 -0
- package/docs/snapshots.md +134 -0
- package/docs/spawn.md +220 -0
- package/docs/state-input.md +162 -0
- package/docs/statecharts.md +54 -0
- package/docs/states-events-transitions.md +82 -0
- package/docs/states.md +168 -0
- package/docs/system-transitions.md +170 -0
- package/docs/systems.md +166 -0
- package/docs/testing.md +150 -0
- package/docs/timeouts.md +125 -0
- package/docs/transition-functions.md +89 -0
- package/docs/transitions.md +187 -0
- package/docs/troubleshooting.md +48 -0
- package/docs/tutorial.md +481 -0
- package/docs/typescript.md +211 -0
- package/docs/typestates.md +110 -0
- package/docs/utilities.md +39 -0
- package/docs/why-state-machines.md +59 -0
- package/docs/xstate-v5-to-v6.md +1771 -0
- package/docs/your-first-machine.md +79 -0
- package/durable/package.json +8 -0
- package/fsm/package.json +8 -0
- package/package.json +56 -10
- package/validation/package.json +8 -0
- package/actions/package.json +0 -8
- package/dev/package.json +0 -8
- package/dist/StateMachine-1ff90553.esm.js +0 -729
- package/dist/StateMachine-2b259bff.development.esm.js +0 -746
- package/dist/StateMachine-6673bf76.cjs.js +0 -732
- package/dist/StateMachine-68fe6077.development.cjs.js +0 -749
- package/dist/declarations/src/createMachineFromConfig.d.ts +0 -177
- package/dist/declarations/src/getNextSnapshot.d.ts +0 -37
- package/dist/declarations/src/graph/TestModel.d.ts +0 -70
- package/dist/declarations/src/graph/pathGenerators.d.ts +0 -4
- package/dist/index-87499be0.cjs.js +0 -4415
- package/dist/index-9594f050.development.esm.js +0 -4399
- package/dist/index-aaf74d09.esm.js +0 -4360
- package/dist/index-b063a967.development.cjs.js +0 -4454
- package/guards/package.json +0 -8
- package/invoke/package.json +0 -4
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export * from "./declarations/src/validation/index.js";
|
|
2
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieHN0YXRlLXZhbGlkYXRpb24uY2pzLmQubXRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi9kZWNsYXJhdGlvbnMvc3JjL3ZhbGlkYXRpb24vaW5kZXguZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSJ9
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export * from "./declarations/src/validation/index.js";
|
|
2
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieHN0YXRlLXZhbGlkYXRpb24uY2pzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuL2RlY2xhcmF0aW9ucy9zcmMvdmFsaWRhdGlvbi9pbmRleC5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBIn0=
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var createActor = require('./createActor-f4978450.cjs.js');
|
|
6
|
+
|
|
7
|
+
const actorValidationErrorSymbol = Symbol.for('xstate.actorValidationError');
|
|
8
|
+
|
|
9
|
+
/** @experimental */
|
|
10
|
+
|
|
11
|
+
/** @experimental */
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A structured failure produced by `standardSchemaValidator()`.
|
|
15
|
+
*
|
|
16
|
+
* @experimental
|
|
17
|
+
*/
|
|
18
|
+
class ActorValidationError extends Error {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
super(getMessage(options), {
|
|
21
|
+
cause: options.cause
|
|
22
|
+
});
|
|
23
|
+
this[actorValidationErrorSymbol] = true;
|
|
24
|
+
this.reason = void 0;
|
|
25
|
+
this.boundary = void 0;
|
|
26
|
+
this.logicId = void 0;
|
|
27
|
+
this.stateNodeId = void 0;
|
|
28
|
+
this.eventType = void 0;
|
|
29
|
+
this.eventOrigin = void 0;
|
|
30
|
+
this.childId = void 0;
|
|
31
|
+
this.issues = void 0;
|
|
32
|
+
this.cause = void 0;
|
|
33
|
+
this.name = 'ActorValidationError';
|
|
34
|
+
this.reason = options.reason;
|
|
35
|
+
this.boundary = options.boundary;
|
|
36
|
+
this.logicId = options.logicId;
|
|
37
|
+
this.stateNodeId = options.stateNodeId;
|
|
38
|
+
this.eventType = options.eventType;
|
|
39
|
+
this.eventOrigin = options.eventOrigin;
|
|
40
|
+
this.childId = options.childId;
|
|
41
|
+
this.issues = options.issues;
|
|
42
|
+
this.cause = options.cause;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** @experimental */
|
|
47
|
+
function isActorValidationError(value) {
|
|
48
|
+
return !!(value && typeof value === 'object' && actorValidationErrorSymbol in value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** @experimental */
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Creates a synchronous, assertion-only Standard Schema validator.
|
|
55
|
+
*
|
|
56
|
+
* @experimental
|
|
57
|
+
*/
|
|
58
|
+
function standardSchemaValidator(options = {}) {
|
|
59
|
+
const unknownEvents = options.unknownEvents ?? 'error';
|
|
60
|
+
const unknownEmitted = options.unknownEmitted ?? 'error';
|
|
61
|
+
const checkTarget = target => {
|
|
62
|
+
if (!target.schema) {
|
|
63
|
+
if (target.boundary === 'event' && unknownEvents === 'error') {
|
|
64
|
+
return createError(target, 'unknownEvent');
|
|
65
|
+
}
|
|
66
|
+
if (target.boundary === 'emitted' && unknownEmitted === 'error') {
|
|
67
|
+
return createError(target, 'unknownEmitted');
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
let result;
|
|
72
|
+
try {
|
|
73
|
+
result = target.schema['~standard'].validate(target.value);
|
|
74
|
+
} catch (cause) {
|
|
75
|
+
return createError(target, 'schemaThrew', undefined, cause);
|
|
76
|
+
}
|
|
77
|
+
if (isPromiseLike(result)) {
|
|
78
|
+
void Promise.resolve(result).catch(() => {});
|
|
79
|
+
return createError(target, 'asyncValidationUnsupported');
|
|
80
|
+
}
|
|
81
|
+
if (result.issues) {
|
|
82
|
+
return createError(target, 'invalid', result.issues);
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// Event schemas describe the payload, so `type` is removed before
|
|
88
|
+
// validation. A schema that reports an issue at `type` declares the key
|
|
89
|
+
// itself (e.g. one reused from a discriminated union), so it is checked
|
|
90
|
+
// against the complete event instead.
|
|
91
|
+
const checkEventTarget = (target, event) => {
|
|
92
|
+
const error = checkTarget({
|
|
93
|
+
...target,
|
|
94
|
+
value: getPayload(event)
|
|
95
|
+
});
|
|
96
|
+
return error?.issues?.some(isTypeIssue) ? checkTarget({
|
|
97
|
+
...target,
|
|
98
|
+
value: event
|
|
99
|
+
}) : error;
|
|
100
|
+
};
|
|
101
|
+
const checkEvent = (logic, event, eventOrigin) => {
|
|
102
|
+
const schemas = getSchemas(logic);
|
|
103
|
+
if (event.type.startsWith('xstate.') || event.type.startsWith('@xstate.')) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const eventSchemas = schemas?.events;
|
|
107
|
+
const internalEventSchemas = schemas?.internalEvents;
|
|
108
|
+
const schema = findEventSchema(internalEventSchemas, event.type) ?? findEventSchema(eventSchemas, event.type);
|
|
109
|
+
if (!eventSchemas && !internalEventSchemas) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
return checkEventTarget({
|
|
113
|
+
schema,
|
|
114
|
+
boundary: 'event',
|
|
115
|
+
logicId: getLogicId(logic),
|
|
116
|
+
eventType: event.type,
|
|
117
|
+
eventOrigin
|
|
118
|
+
}, event);
|
|
119
|
+
};
|
|
120
|
+
const checkEmitted = (logic, effects) => {
|
|
121
|
+
const schemas = getSchemas(logic);
|
|
122
|
+
if (!schemas?.emitted) {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
for (const effect of effects) {
|
|
126
|
+
if (effect.kind !== 'emit') {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const error = checkEventTarget({
|
|
130
|
+
schema: schemas.emitted[effect.event.type],
|
|
131
|
+
boundary: 'emitted',
|
|
132
|
+
logicId: getLogicId(logic),
|
|
133
|
+
eventType: effect.event.type
|
|
134
|
+
}, effect.event);
|
|
135
|
+
if (error) {
|
|
136
|
+
return error;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
};
|
|
141
|
+
const checkMachineResult = (machine, snapshot) => {
|
|
142
|
+
let error = checkTarget({
|
|
143
|
+
schema: machine.schemas?.context,
|
|
144
|
+
value: snapshot.context,
|
|
145
|
+
boundary: 'context',
|
|
146
|
+
logicId: machine.id
|
|
147
|
+
});
|
|
148
|
+
if (error) {
|
|
149
|
+
return error;
|
|
150
|
+
}
|
|
151
|
+
for (const stateNode of snapshot.nodes) {
|
|
152
|
+
// the root state node reuses the machine-level `schemas` object, which is
|
|
153
|
+
// already validated above and elsewhere; those are not state-local
|
|
154
|
+
if (stateNode === machine.root) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
error = checkTarget({
|
|
158
|
+
schema: stateNode.schemas?.context,
|
|
159
|
+
value: snapshot.context,
|
|
160
|
+
boundary: 'state.context',
|
|
161
|
+
logicId: machine.id,
|
|
162
|
+
stateNodeId: stateNode.id
|
|
163
|
+
});
|
|
164
|
+
if (error) {
|
|
165
|
+
return error;
|
|
166
|
+
}
|
|
167
|
+
if (stateNode.schemas?.input) {
|
|
168
|
+
error = checkTarget({
|
|
169
|
+
schema: stateNode.schemas.input,
|
|
170
|
+
value: snapshot._stateInputs[stateNode.id],
|
|
171
|
+
boundary: 'state.input',
|
|
172
|
+
logicId: machine.id,
|
|
173
|
+
stateNodeId: stateNode.id
|
|
174
|
+
});
|
|
175
|
+
if (error) {
|
|
176
|
+
return error;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
for (const childId of Object.keys(machine.schemas?.children ?? {})) {
|
|
181
|
+
const child = snapshot.children[childId];
|
|
182
|
+
if (child !== undefined) {
|
|
183
|
+
error = checkTarget({
|
|
184
|
+
schema: machine.schemas.children[childId],
|
|
185
|
+
value: child,
|
|
186
|
+
boundary: 'child',
|
|
187
|
+
logicId: machine.id,
|
|
188
|
+
childId
|
|
189
|
+
});
|
|
190
|
+
if (error) {
|
|
191
|
+
return error;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
for (const timer of snapshot.timers) {
|
|
196
|
+
if (timer.type === '@xstate.raise') {
|
|
197
|
+
error = checkEvent(machine, timer.event, 'raised');
|
|
198
|
+
if (error) {
|
|
199
|
+
return error;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return undefined;
|
|
204
|
+
};
|
|
205
|
+
return {
|
|
206
|
+
check(request) {
|
|
207
|
+
const {
|
|
208
|
+
logic
|
|
209
|
+
} = request;
|
|
210
|
+
const schemas = getSchemas(logic);
|
|
211
|
+
if (request.kind === 'input') {
|
|
212
|
+
return checkTarget({
|
|
213
|
+
schema: schemas?.input,
|
|
214
|
+
value: request.input,
|
|
215
|
+
boundary: 'input',
|
|
216
|
+
logicId: getLogicId(logic)
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
if (request.kind === 'event') {
|
|
220
|
+
return checkEvent(logic, request.event, request.eventOrigin);
|
|
221
|
+
}
|
|
222
|
+
const {
|
|
223
|
+
snapshot,
|
|
224
|
+
effects
|
|
225
|
+
} = request;
|
|
226
|
+
if (isStateMachine(logic)) {
|
|
227
|
+
const error = checkMachineResult(logic, snapshot);
|
|
228
|
+
if (error) {
|
|
229
|
+
return error;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (snapshot.status === 'done') {
|
|
233
|
+
const error = checkTarget({
|
|
234
|
+
schema: schemas?.output,
|
|
235
|
+
value: snapshot.output,
|
|
236
|
+
boundary: 'output',
|
|
237
|
+
logicId: getLogicId(logic)
|
|
238
|
+
});
|
|
239
|
+
if (error) {
|
|
240
|
+
return error;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return checkEmitted(logic, effects);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function createError(request, reason, issues, cause) {
|
|
248
|
+
return new ActorValidationError({
|
|
249
|
+
reason,
|
|
250
|
+
boundary: request.boundary,
|
|
251
|
+
...(request.logicId === undefined ? {} : {
|
|
252
|
+
logicId: request.logicId
|
|
253
|
+
}),
|
|
254
|
+
...(request.stateNodeId === undefined ? {} : {
|
|
255
|
+
stateNodeId: request.stateNodeId
|
|
256
|
+
}),
|
|
257
|
+
...(request.eventType === undefined ? {} : {
|
|
258
|
+
eventType: request.eventType
|
|
259
|
+
}),
|
|
260
|
+
...(request.eventOrigin === undefined ? {} : {
|
|
261
|
+
eventOrigin: request.eventOrigin
|
|
262
|
+
}),
|
|
263
|
+
...(request.childId === undefined ? {} : {
|
|
264
|
+
childId: request.childId
|
|
265
|
+
}),
|
|
266
|
+
...(issues === undefined ? {} : {
|
|
267
|
+
issues
|
|
268
|
+
}),
|
|
269
|
+
...(cause === undefined ? {} : {
|
|
270
|
+
cause
|
|
271
|
+
})
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function isStateMachine(logic) {
|
|
275
|
+
return 'root' in logic && 'schemas' in logic;
|
|
276
|
+
}
|
|
277
|
+
function getSchemas(logic) {
|
|
278
|
+
if (isStateMachine(logic)) {
|
|
279
|
+
return logic.schemas;
|
|
280
|
+
}
|
|
281
|
+
return logic.config?.schemas;
|
|
282
|
+
}
|
|
283
|
+
function findEventSchema(schemas, eventType) {
|
|
284
|
+
if (!schemas) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
if (Object.hasOwn(schemas, eventType)) {
|
|
288
|
+
return schemas[eventType];
|
|
289
|
+
}
|
|
290
|
+
const descriptor = Object.keys(schemas).find(key => createActor.matchesEventDescriptor(eventType, key));
|
|
291
|
+
return descriptor === undefined ? undefined : schemas[descriptor];
|
|
292
|
+
}
|
|
293
|
+
function getLogicId(logic) {
|
|
294
|
+
return 'id' in logic && typeof logic.id === 'string' ? logic.id : undefined;
|
|
295
|
+
}
|
|
296
|
+
function getPayload(event) {
|
|
297
|
+
const {
|
|
298
|
+
type: _,
|
|
299
|
+
...payload
|
|
300
|
+
} = event;
|
|
301
|
+
return payload;
|
|
302
|
+
}
|
|
303
|
+
function isTypeIssue(issue) {
|
|
304
|
+
const segment = issue.path?.[0];
|
|
305
|
+
return (typeof segment === 'object' ? segment.key : segment) === 'type';
|
|
306
|
+
}
|
|
307
|
+
function getMessage(options) {
|
|
308
|
+
const subject = options.eventType !== undefined ? ` "${options.eventType}"` : options.childId !== undefined ? ` "${options.childId}"` : '';
|
|
309
|
+
switch (options.reason) {
|
|
310
|
+
case 'unknownEvent':
|
|
311
|
+
return `Unknown event${subject}`;
|
|
312
|
+
case 'unknownEmitted':
|
|
313
|
+
return `Unknown emitted event${subject}`;
|
|
314
|
+
case 'asyncValidationUnsupported':
|
|
315
|
+
return `Async schema validation is unsupported for ${options.boundary}${subject}`;
|
|
316
|
+
case 'transformationUnsupported':
|
|
317
|
+
return `Schema transformations are unsupported for ${options.boundary}${subject}`;
|
|
318
|
+
case 'schemaThrew':
|
|
319
|
+
return `Schema threw while validating ${options.boundary}${subject}`;
|
|
320
|
+
case 'invalid':
|
|
321
|
+
return `Invalid ${options.boundary}${subject}`;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function isPromiseLike(value) {
|
|
325
|
+
return !!value && typeof value.then === 'function';
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
exports.ActorValidationError = ActorValidationError;
|
|
329
|
+
exports.isActorValidationError = isActorValidationError;
|
|
330
|
+
exports.standardSchemaValidator = standardSchemaValidator;
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var createActor = require('./createActor-2136a8ad.development.cjs.js');
|
|
6
|
+
|
|
7
|
+
const actorValidationErrorSymbol = Symbol.for('xstate.actorValidationError');
|
|
8
|
+
|
|
9
|
+
/** @experimental */
|
|
10
|
+
|
|
11
|
+
/** @experimental */
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A structured failure produced by `standardSchemaValidator()`.
|
|
15
|
+
*
|
|
16
|
+
* @experimental
|
|
17
|
+
*/
|
|
18
|
+
class ActorValidationError extends Error {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
super(getMessage(options), {
|
|
21
|
+
cause: options.cause
|
|
22
|
+
});
|
|
23
|
+
this[actorValidationErrorSymbol] = true;
|
|
24
|
+
this.reason = void 0;
|
|
25
|
+
this.boundary = void 0;
|
|
26
|
+
this.logicId = void 0;
|
|
27
|
+
this.stateNodeId = void 0;
|
|
28
|
+
this.eventType = void 0;
|
|
29
|
+
this.eventOrigin = void 0;
|
|
30
|
+
this.childId = void 0;
|
|
31
|
+
this.issues = void 0;
|
|
32
|
+
this.cause = void 0;
|
|
33
|
+
this.name = 'ActorValidationError';
|
|
34
|
+
this.reason = options.reason;
|
|
35
|
+
this.boundary = options.boundary;
|
|
36
|
+
this.logicId = options.logicId;
|
|
37
|
+
this.stateNodeId = options.stateNodeId;
|
|
38
|
+
this.eventType = options.eventType;
|
|
39
|
+
this.eventOrigin = options.eventOrigin;
|
|
40
|
+
this.childId = options.childId;
|
|
41
|
+
this.issues = options.issues;
|
|
42
|
+
this.cause = options.cause;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** @experimental */
|
|
47
|
+
function isActorValidationError(value) {
|
|
48
|
+
return !!(value && typeof value === 'object' && actorValidationErrorSymbol in value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** @experimental */
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Creates a synchronous, assertion-only Standard Schema validator.
|
|
55
|
+
*
|
|
56
|
+
* @experimental
|
|
57
|
+
*/
|
|
58
|
+
function standardSchemaValidator(options = {}) {
|
|
59
|
+
const unknownEvents = options.unknownEvents ?? 'error';
|
|
60
|
+
const unknownEmitted = options.unknownEmitted ?? 'error';
|
|
61
|
+
const checkTarget = target => {
|
|
62
|
+
if (!target.schema) {
|
|
63
|
+
if (target.boundary === 'event' && unknownEvents === 'error') {
|
|
64
|
+
return createError(target, 'unknownEvent');
|
|
65
|
+
}
|
|
66
|
+
if (target.boundary === 'emitted' && unknownEmitted === 'error') {
|
|
67
|
+
return createError(target, 'unknownEmitted');
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
let result;
|
|
72
|
+
try {
|
|
73
|
+
result = target.schema['~standard'].validate(target.value);
|
|
74
|
+
} catch (cause) {
|
|
75
|
+
return createError(target, 'schemaThrew', undefined, cause);
|
|
76
|
+
}
|
|
77
|
+
if (isPromiseLike(result)) {
|
|
78
|
+
void Promise.resolve(result).catch(() => {});
|
|
79
|
+
return createError(target, 'asyncValidationUnsupported');
|
|
80
|
+
}
|
|
81
|
+
if (result.issues) {
|
|
82
|
+
return createError(target, 'invalid', result.issues);
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// Event schemas describe the payload, so `type` is removed before
|
|
88
|
+
// validation. A schema that reports an issue at `type` declares the key
|
|
89
|
+
// itself (e.g. one reused from a discriminated union), so it is checked
|
|
90
|
+
// against the complete event instead.
|
|
91
|
+
const checkEventTarget = (target, event) => {
|
|
92
|
+
const error = checkTarget({
|
|
93
|
+
...target,
|
|
94
|
+
value: getPayload(event)
|
|
95
|
+
});
|
|
96
|
+
return error?.issues?.some(isTypeIssue) ? checkTarget({
|
|
97
|
+
...target,
|
|
98
|
+
value: event
|
|
99
|
+
}) : error;
|
|
100
|
+
};
|
|
101
|
+
const checkEvent = (logic, event, eventOrigin) => {
|
|
102
|
+
const schemas = getSchemas(logic);
|
|
103
|
+
if (event.type.startsWith('xstate.') || event.type.startsWith('@xstate.')) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const eventSchemas = schemas?.events;
|
|
107
|
+
const internalEventSchemas = schemas?.internalEvents;
|
|
108
|
+
const schema = findEventSchema(internalEventSchemas, event.type) ?? findEventSchema(eventSchemas, event.type);
|
|
109
|
+
if (!eventSchemas && !internalEventSchemas) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
return checkEventTarget({
|
|
113
|
+
schema,
|
|
114
|
+
boundary: 'event',
|
|
115
|
+
logicId: getLogicId(logic),
|
|
116
|
+
eventType: event.type,
|
|
117
|
+
eventOrigin
|
|
118
|
+
}, event);
|
|
119
|
+
};
|
|
120
|
+
const checkEmitted = (logic, effects) => {
|
|
121
|
+
const schemas = getSchemas(logic);
|
|
122
|
+
if (!schemas?.emitted) {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
for (const effect of effects) {
|
|
126
|
+
if (effect.kind !== 'emit') {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const error = checkEventTarget({
|
|
130
|
+
schema: schemas.emitted[effect.event.type],
|
|
131
|
+
boundary: 'emitted',
|
|
132
|
+
logicId: getLogicId(logic),
|
|
133
|
+
eventType: effect.event.type
|
|
134
|
+
}, effect.event);
|
|
135
|
+
if (error) {
|
|
136
|
+
return error;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
};
|
|
141
|
+
const checkMachineResult = (machine, snapshot) => {
|
|
142
|
+
let error = checkTarget({
|
|
143
|
+
schema: machine.schemas?.context,
|
|
144
|
+
value: snapshot.context,
|
|
145
|
+
boundary: 'context',
|
|
146
|
+
logicId: machine.id
|
|
147
|
+
});
|
|
148
|
+
if (error) {
|
|
149
|
+
return error;
|
|
150
|
+
}
|
|
151
|
+
for (const stateNode of snapshot.nodes) {
|
|
152
|
+
// the root state node reuses the machine-level `schemas` object, which is
|
|
153
|
+
// already validated above and elsewhere; those are not state-local
|
|
154
|
+
if (stateNode === machine.root) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
error = checkTarget({
|
|
158
|
+
schema: stateNode.schemas?.context,
|
|
159
|
+
value: snapshot.context,
|
|
160
|
+
boundary: 'state.context',
|
|
161
|
+
logicId: machine.id,
|
|
162
|
+
stateNodeId: stateNode.id
|
|
163
|
+
});
|
|
164
|
+
if (error) {
|
|
165
|
+
return error;
|
|
166
|
+
}
|
|
167
|
+
if (stateNode.schemas?.input) {
|
|
168
|
+
error = checkTarget({
|
|
169
|
+
schema: stateNode.schemas.input,
|
|
170
|
+
value: snapshot._stateInputs[stateNode.id],
|
|
171
|
+
boundary: 'state.input',
|
|
172
|
+
logicId: machine.id,
|
|
173
|
+
stateNodeId: stateNode.id
|
|
174
|
+
});
|
|
175
|
+
if (error) {
|
|
176
|
+
return error;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
for (const childId of Object.keys(machine.schemas?.children ?? {})) {
|
|
181
|
+
const child = snapshot.children[childId];
|
|
182
|
+
if (child !== undefined) {
|
|
183
|
+
error = checkTarget({
|
|
184
|
+
schema: machine.schemas.children[childId],
|
|
185
|
+
value: child,
|
|
186
|
+
boundary: 'child',
|
|
187
|
+
logicId: machine.id,
|
|
188
|
+
childId
|
|
189
|
+
});
|
|
190
|
+
if (error) {
|
|
191
|
+
return error;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
for (const timer of snapshot.timers) {
|
|
196
|
+
if (timer.type === '@xstate.raise') {
|
|
197
|
+
error = checkEvent(machine, timer.event, 'raised');
|
|
198
|
+
if (error) {
|
|
199
|
+
return error;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return undefined;
|
|
204
|
+
};
|
|
205
|
+
return {
|
|
206
|
+
check(request) {
|
|
207
|
+
const {
|
|
208
|
+
logic
|
|
209
|
+
} = request;
|
|
210
|
+
const schemas = getSchemas(logic);
|
|
211
|
+
if (request.kind === 'input') {
|
|
212
|
+
return checkTarget({
|
|
213
|
+
schema: schemas?.input,
|
|
214
|
+
value: request.input,
|
|
215
|
+
boundary: 'input',
|
|
216
|
+
logicId: getLogicId(logic)
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
if (request.kind === 'event') {
|
|
220
|
+
return checkEvent(logic, request.event, request.eventOrigin);
|
|
221
|
+
}
|
|
222
|
+
const {
|
|
223
|
+
snapshot,
|
|
224
|
+
effects
|
|
225
|
+
} = request;
|
|
226
|
+
if (isStateMachine(logic)) {
|
|
227
|
+
const error = checkMachineResult(logic, snapshot);
|
|
228
|
+
if (error) {
|
|
229
|
+
return error;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (snapshot.status === 'done') {
|
|
233
|
+
const error = checkTarget({
|
|
234
|
+
schema: schemas?.output,
|
|
235
|
+
value: snapshot.output,
|
|
236
|
+
boundary: 'output',
|
|
237
|
+
logicId: getLogicId(logic)
|
|
238
|
+
});
|
|
239
|
+
if (error) {
|
|
240
|
+
return error;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return checkEmitted(logic, effects);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function createError(request, reason, issues, cause) {
|
|
248
|
+
return new ActorValidationError({
|
|
249
|
+
reason,
|
|
250
|
+
boundary: request.boundary,
|
|
251
|
+
...(request.logicId === undefined ? {} : {
|
|
252
|
+
logicId: request.logicId
|
|
253
|
+
}),
|
|
254
|
+
...(request.stateNodeId === undefined ? {} : {
|
|
255
|
+
stateNodeId: request.stateNodeId
|
|
256
|
+
}),
|
|
257
|
+
...(request.eventType === undefined ? {} : {
|
|
258
|
+
eventType: request.eventType
|
|
259
|
+
}),
|
|
260
|
+
...(request.eventOrigin === undefined ? {} : {
|
|
261
|
+
eventOrigin: request.eventOrigin
|
|
262
|
+
}),
|
|
263
|
+
...(request.childId === undefined ? {} : {
|
|
264
|
+
childId: request.childId
|
|
265
|
+
}),
|
|
266
|
+
...(issues === undefined ? {} : {
|
|
267
|
+
issues
|
|
268
|
+
}),
|
|
269
|
+
...(cause === undefined ? {} : {
|
|
270
|
+
cause
|
|
271
|
+
})
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function isStateMachine(logic) {
|
|
275
|
+
return 'root' in logic && 'schemas' in logic;
|
|
276
|
+
}
|
|
277
|
+
function getSchemas(logic) {
|
|
278
|
+
if (isStateMachine(logic)) {
|
|
279
|
+
return logic.schemas;
|
|
280
|
+
}
|
|
281
|
+
return logic.config?.schemas;
|
|
282
|
+
}
|
|
283
|
+
function findEventSchema(schemas, eventType) {
|
|
284
|
+
if (!schemas) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
if (Object.hasOwn(schemas, eventType)) {
|
|
288
|
+
return schemas[eventType];
|
|
289
|
+
}
|
|
290
|
+
const descriptor = Object.keys(schemas).find(key => createActor.matchesEventDescriptor(eventType, key));
|
|
291
|
+
return descriptor === undefined ? undefined : schemas[descriptor];
|
|
292
|
+
}
|
|
293
|
+
function getLogicId(logic) {
|
|
294
|
+
return 'id' in logic && typeof logic.id === 'string' ? logic.id : undefined;
|
|
295
|
+
}
|
|
296
|
+
function getPayload(event) {
|
|
297
|
+
const {
|
|
298
|
+
type: _,
|
|
299
|
+
...payload
|
|
300
|
+
} = event;
|
|
301
|
+
return payload;
|
|
302
|
+
}
|
|
303
|
+
function isTypeIssue(issue) {
|
|
304
|
+
const segment = issue.path?.[0];
|
|
305
|
+
return (typeof segment === 'object' ? segment.key : segment) === 'type';
|
|
306
|
+
}
|
|
307
|
+
function getMessage(options) {
|
|
308
|
+
const subject = options.eventType !== undefined ? ` "${options.eventType}"` : options.childId !== undefined ? ` "${options.childId}"` : '';
|
|
309
|
+
switch (options.reason) {
|
|
310
|
+
case 'unknownEvent':
|
|
311
|
+
return `Unknown event${subject}`;
|
|
312
|
+
case 'unknownEmitted':
|
|
313
|
+
return `Unknown emitted event${subject}`;
|
|
314
|
+
case 'asyncValidationUnsupported':
|
|
315
|
+
return `Async schema validation is unsupported for ${options.boundary}${subject}`;
|
|
316
|
+
case 'transformationUnsupported':
|
|
317
|
+
return `Schema transformations are unsupported for ${options.boundary}${subject}`;
|
|
318
|
+
case 'schemaThrew':
|
|
319
|
+
return `Schema threw while validating ${options.boundary}${subject}`;
|
|
320
|
+
case 'invalid':
|
|
321
|
+
return `Invalid ${options.boundary}${subject}`;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function isPromiseLike(value) {
|
|
325
|
+
return !!value && typeof value.then === 'function';
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
exports.ActorValidationError = ActorValidationError;
|
|
329
|
+
exports.isActorValidationError = isActorValidationError;
|
|
330
|
+
exports.standardSchemaValidator = standardSchemaValidator;
|