likec4 1.59.4 → 1.60.0
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/__app__/codegen/react.mjs +6 -6
- package/__app__/codegen/webcomponent.mjs +147 -69
- package/__app__/src/aichat/index.mjs +10 -5
- package/__app__/src/chunks/AIChat.mjs +1134 -693
- package/__app__/src/chunks/LikeC4Styles.mjs +3995 -1779
- package/__app__/src/chunks/ProjectsOverview.mjs +624 -334
- package/__app__/src/chunks/es.mjs +515 -335
- package/__app__/src/chunks/hooks.mjs +578 -369
- package/__app__/src/chunks/libs/@floating-ui.mjs +2720 -1966
- package/__app__/src/chunks/libs/@mantine.mjs +13920 -10057
- package/__app__/src/chunks/libs/@tanstack-ai.mjs +2266 -1146
- package/__app__/src/chunks/libs/@tanstack.mjs +3152 -1926
- package/__app__/src/chunks/libs/@xstate/react.mjs +2924 -1468
- package/__app__/src/chunks/libs/@xyflow/react.mjs +6627 -4067
- package/__app__/src/chunks/libs/bezier-js.mjs +1312 -726
- package/__app__/src/chunks/libs/d3.mjs +3219 -1505
- package/__app__/src/chunks/libs/fast-equals.mjs +434 -210
- package/__app__/src/chunks/libs/framer.mjs +9251 -3846
- package/__app__/src/chunks/libs/nanostores.mjs +174 -0
- package/__app__/src/chunks/libs/zod.mjs +4591 -2363
- package/__app__/src/chunks/rolldown-runtime.mjs +39 -23
- package/__app__/src/chunks/styled-system.mjs +2279 -1951
- package/__app__/src/fonts.css +112 -1
- package/__app__/src/main.mjs +40817 -21840
- package/__app__/src/style.css +18488 -1
- package/config/schema.json +122 -97
- package/dist/app/render-view-client.css +1 -1
- package/dist/app/render-view-client.js +508 -334
- package/dist/chunks/enableServer.mjs +1 -1
- package/dist/chunks/filenames.mjs +11 -9
- package/dist/chunks/generate-likec4.mjs +5 -0
- package/dist/chunks/index.d.mts +243 -183
- package/dist/chunks/index2.d.mts +2865 -1977
- package/dist/chunks/libs/@chevrotain/gast.mjs +27 -1
- package/dist/chunks/libs/@chevrotain/regexp-to-ast.mjs +81 -9
- package/dist/chunks/libs/@chevrotain/types.d.mts +4 -1
- package/dist/chunks/libs/@logtape/logtape.mjs +5 -4
- package/dist/chunks/libs/@lume/kiwi.mjs +1 -1
- package/dist/chunks/libs/@ts-graphviz/core.mjs +1 -1
- package/dist/chunks/libs/birpc.mjs +1 -1
- package/dist/chunks/libs/chevrotain-allstar.mjs +2 -2
- package/dist/chunks/libs/chevrotain.mjs +87 -35
- package/dist/chunks/libs/eventemitter3.mjs +1 -1
- package/dist/chunks/libs/json5.mjs +4 -4
- package/dist/chunks/libs/langium.d.mts +9038 -6193
- package/dist/chunks/libs/langium.mjs +16 -24
- package/dist/chunks/libs/merge-error-cause.mjs +1 -1
- package/dist/chunks/libs/p-limit.mjs +1 -0
- package/dist/chunks/libs/p-queue.mjs +1 -1
- package/dist/chunks/libs/package-manager-detector.mjs +1 -1
- package/dist/chunks/libs/pako.mjs +1 -1
- package/dist/chunks/libs/pretty-ms.mjs +1 -1
- package/dist/chunks/libs/remeda.mjs +1 -1
- package/dist/chunks/libs/ufo.mjs +1 -1
- package/dist/chunks/libs/unstorage.mjs +1 -1
- package/dist/chunks/libs/which.mjs +1 -1
- package/dist/chunks/node.mjs +59 -58
- package/dist/chunks/rolldown-runtime.mjs +1 -1
- package/dist/chunks/sequence-view.mjs +1 -1
- package/dist/chunks/vite-plugin.mjs +45 -45
- package/dist/cli/index.mjs +207 -1315
- package/dist/config/index.d.mts +2 -2
- package/dist/generators/likec4.d.mts +6578 -0
- package/dist/generators/likec4.mjs +1 -0
- package/dist/model/index.d.mts +4 -1
- package/dist/vite-plugin/index.d.mts +4 -1
- package/dist/vite-plugin/index.mjs +1 -1
- package/dist/vite-plugin/internal/chunks/rolldown-runtime.mjs +9 -0
- package/dist/vite-plugin/internal/index.d.mts +6 -5
- package/dist/vite-plugin/internal/index.mjs +83 -30
- package/generators/likec4/package.json +4 -0
- package/package.json +113 -106
- package/react/index.d.mts +8500 -26659
- package/react/index.mjs +534 -63936
- package/react/rolldown-runtime-DnkiqaRY.js +1 -0
- package/skills/likec4-dsl/SKILL.md +428 -0
- package/skills/likec4-dsl/evals/evals-public.json +202 -0
- package/skills/likec4-dsl/evals/grading-spec.json +589 -0
- package/skills/likec4-dsl/references/bridge-leanix-drawio.md +42 -0
- package/skills/likec4-dsl/references/cli.md +139 -0
- package/skills/likec4-dsl/references/configuration.md +266 -0
- package/skills/likec4-dsl/references/deployment.md +160 -0
- package/skills/likec4-dsl/references/dynamic-views.md +455 -0
- package/skills/likec4-dsl/references/examples.md +370 -0
- package/skills/likec4-dsl/references/identifier-validity.md +90 -0
- package/skills/likec4-dsl/references/include-predicates-wildcards.md +179 -0
- package/skills/likec4-dsl/references/model.md +151 -0
- package/skills/likec4-dsl/references/predicates.md +123 -0
- package/skills/likec4-dsl/references/relationships-bidirectional.md +176 -0
- package/skills/likec4-dsl/references/specification.md +75 -0
- package/skills/likec4-dsl/references/style-tokens-colors.md +150 -0
- package/skills/likec4-dsl/references/troubleshooting.md +96 -0
- package/skills/likec4-dsl/references/views.md +329 -0
- package/dist/chunks/libs/picomatch.mjs +0 -1
- package/dist/chunks/libs/zod.d.mts +0 -3840
- package/dist/chunks/libs/zod.mjs +0 -65
|
@@ -1,523 +1,838 @@
|
|
|
1
|
-
import { i as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
//#region ../../node_modules/.pnpm/use-isomorphic-layout-effect@1.2.1_@types+react@19.
|
|
5
|
-
var
|
|
1
|
+
import { i as __name } from "../../rolldown-runtime.mjs";
|
|
2
|
+
import { f as useSyncExternalStoreWithSelector } from "../@tanstack.mjs";
|
|
3
|
+
import { useCallback, useEffect, useLayoutEffect, useState } from "react";
|
|
4
|
+
//#region ../../node_modules/.pnpm/use-isomorphic-layout-effect@1.2.1_@types+react@19.3.0_react@19.3.0/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.js
|
|
5
|
+
var index = typeof document !== "undefined" ? useLayoutEffect : function noop() {};
|
|
6
6
|
//#endregion
|
|
7
|
-
//#region ../../node_modules/.pnpm/xstate@5.
|
|
7
|
+
//#region ../../node_modules/.pnpm/xstate@5.33.2/node_modules/xstate/dist/xstate-dev.esm.js
|
|
8
8
|
function getGlobal() {
|
|
9
|
-
if (typeof globalThis
|
|
10
|
-
if (typeof self
|
|
11
|
-
if (typeof window
|
|
12
|
-
if (typeof global
|
|
9
|
+
if (typeof globalThis !== "undefined") return globalThis;
|
|
10
|
+
if (typeof self !== "undefined") return self;
|
|
11
|
+
if (typeof window !== "undefined") return window;
|
|
12
|
+
if (typeof global !== "undefined") return global;
|
|
13
13
|
}
|
|
14
14
|
function getDevTools() {
|
|
15
|
-
|
|
16
|
-
if (
|
|
15
|
+
const w = getGlobal();
|
|
16
|
+
if (w.__xstate__) return w.__xstate__;
|
|
17
17
|
}
|
|
18
|
-
var devToolsAdapter = (
|
|
19
|
-
if (typeof window
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
var devToolsAdapter = (service) => {
|
|
19
|
+
if (typeof window === "undefined") return;
|
|
20
|
+
const devTools = getDevTools();
|
|
21
|
+
if (devTools) devTools.register(service);
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region ../../node_modules/.pnpm/xstate@5.33.2/node_modules/xstate/dist/raise-97446fd4.esm.js
|
|
25
|
+
var Mailbox = class {
|
|
26
|
+
constructor(_process) {
|
|
27
|
+
this._process = _process;
|
|
28
|
+
this._active = false;
|
|
29
|
+
this._current = null;
|
|
30
|
+
this._last = null;
|
|
25
31
|
}
|
|
26
32
|
start() {
|
|
27
|
-
this._active =
|
|
33
|
+
this._active = true;
|
|
34
|
+
this.flush();
|
|
28
35
|
}
|
|
29
36
|
clear() {
|
|
30
|
-
|
|
37
|
+
if (this._current) {
|
|
38
|
+
this._current.next = null;
|
|
39
|
+
this._last = this._current;
|
|
40
|
+
}
|
|
31
41
|
}
|
|
32
|
-
enqueue(
|
|
33
|
-
|
|
34
|
-
value:
|
|
42
|
+
enqueue(event) {
|
|
43
|
+
const enqueued = {
|
|
44
|
+
value: event,
|
|
35
45
|
next: null
|
|
36
46
|
};
|
|
37
47
|
if (this._current) {
|
|
38
|
-
this._last.next =
|
|
48
|
+
this._last.next = enqueued;
|
|
49
|
+
this._last = enqueued;
|
|
39
50
|
return;
|
|
40
51
|
}
|
|
41
|
-
this._current =
|
|
52
|
+
this._current = enqueued;
|
|
53
|
+
this._last = enqueued;
|
|
54
|
+
if (this._active) this.flush();
|
|
42
55
|
}
|
|
43
56
|
flush() {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this._process(
|
|
57
|
+
while (this._current) {
|
|
58
|
+
const consumed = this._current;
|
|
59
|
+
this._process(consumed.value);
|
|
60
|
+
this._current = consumed.next;
|
|
47
61
|
}
|
|
48
62
|
this._last = null;
|
|
49
63
|
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
64
|
+
};
|
|
65
|
+
var TARGETLESS_KEY = "";
|
|
66
|
+
var STATE_IDENTIFIER = "#";
|
|
67
|
+
var WILDCARD = "*";
|
|
68
|
+
var XSTATE_INIT = "xstate.init";
|
|
69
|
+
var XSTATE_STOP = "xstate.stop";
|
|
70
|
+
/**
|
|
71
|
+
* Returns an event that represents an implicit event that is sent after the
|
|
72
|
+
* specified `delay`.
|
|
73
|
+
*
|
|
74
|
+
* @param delayRef The delay in milliseconds
|
|
75
|
+
* @param id The state node ID where this event is handled
|
|
76
|
+
*/
|
|
77
|
+
function createAfterEvent(delayRef, id) {
|
|
78
|
+
return { type: `xstate.after.${delayRef}.${id}` };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Returns an event that represents that a final state node has been reached in
|
|
82
|
+
* the parent state node.
|
|
83
|
+
*
|
|
84
|
+
* @param id The final state node's parent state node `id`
|
|
85
|
+
* @param output The data to pass into the event
|
|
86
|
+
*/
|
|
87
|
+
function createDoneStateEvent(id, output) {
|
|
55
88
|
return {
|
|
56
|
-
type: `xstate.done.state.${
|
|
57
|
-
output
|
|
89
|
+
type: `xstate.done.state.${id}`,
|
|
90
|
+
output
|
|
58
91
|
};
|
|
59
92
|
}
|
|
60
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Returns an event that represents that an invoked service has terminated.
|
|
95
|
+
*
|
|
96
|
+
* An invoked service is terminated when it has reached a top-level final state
|
|
97
|
+
* node, but not when it is canceled.
|
|
98
|
+
*
|
|
99
|
+
* @param invokeId The invoked service ID
|
|
100
|
+
* @param output The data to pass into the event
|
|
101
|
+
*/
|
|
102
|
+
function createDoneActorEvent(invokeId, output) {
|
|
61
103
|
return {
|
|
62
|
-
type: `xstate.done.actor.${
|
|
63
|
-
output
|
|
64
|
-
actorId:
|
|
104
|
+
type: `xstate.done.actor.${invokeId}`,
|
|
105
|
+
output,
|
|
106
|
+
actorId: invokeId
|
|
65
107
|
};
|
|
66
108
|
}
|
|
67
|
-
function createErrorActorEvent(
|
|
109
|
+
function createErrorActorEvent(id, error) {
|
|
68
110
|
return {
|
|
69
|
-
type: `xstate.error.actor.${
|
|
70
|
-
error
|
|
71
|
-
actorId:
|
|
111
|
+
type: `xstate.error.actor.${id}`,
|
|
112
|
+
error,
|
|
113
|
+
actorId: id
|
|
72
114
|
};
|
|
73
115
|
}
|
|
74
|
-
function createInitEvent(
|
|
116
|
+
function createInitEvent(input) {
|
|
75
117
|
return {
|
|
76
|
-
type:
|
|
77
|
-
input
|
|
118
|
+
type: XSTATE_INIT,
|
|
119
|
+
input
|
|
78
120
|
};
|
|
79
121
|
}
|
|
80
|
-
|
|
122
|
+
/**
|
|
123
|
+
* This function makes sure that unhandled errors are thrown in a separate
|
|
124
|
+
* macrotask. It allows those errors to be detected by global error handlers and
|
|
125
|
+
* reported to bug tracking services without interrupting our own stack of
|
|
126
|
+
* execution.
|
|
127
|
+
*
|
|
128
|
+
* @param err Error to be thrown
|
|
129
|
+
*/
|
|
130
|
+
function reportUnhandledError(err) {
|
|
81
131
|
setTimeout(() => {
|
|
82
|
-
throw
|
|
132
|
+
throw err;
|
|
83
133
|
});
|
|
84
134
|
}
|
|
85
|
-
var
|
|
86
|
-
function matchesState(
|
|
87
|
-
|
|
88
|
-
|
|
135
|
+
var symbolObservable = (() => typeof Symbol === "function" && Symbol.observable || "@@observable")();
|
|
136
|
+
function matchesState(parentStateId, childStateId) {
|
|
137
|
+
const parentStateValue = toStateValue(parentStateId);
|
|
138
|
+
const childStateValue = toStateValue(childStateId);
|
|
139
|
+
if (typeof childStateValue === "string") {
|
|
140
|
+
if (typeof parentStateValue === "string") return childStateValue === parentStateValue;
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
if (typeof parentStateValue === "string") return parentStateValue in childStateValue;
|
|
144
|
+
return Object.keys(parentStateValue).every((key) => {
|
|
145
|
+
if (!(key in childStateValue)) return false;
|
|
146
|
+
return matchesState(parentStateValue[key], childStateValue[key]);
|
|
147
|
+
});
|
|
89
148
|
}
|
|
90
|
-
function toStatePath(
|
|
91
|
-
if (isArray(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
149
|
+
function toStatePath(stateId) {
|
|
150
|
+
if (isArray(stateId)) return stateId;
|
|
151
|
+
const result = [];
|
|
152
|
+
let segment = "";
|
|
153
|
+
for (let i = 0; i < stateId.length; i++) {
|
|
154
|
+
switch (stateId.charCodeAt(i)) {
|
|
95
155
|
case 92:
|
|
96
|
-
|
|
156
|
+
segment += stateId[i + 1];
|
|
157
|
+
i++;
|
|
97
158
|
continue;
|
|
98
159
|
case 46:
|
|
99
|
-
|
|
160
|
+
result.push(segment);
|
|
161
|
+
segment = "";
|
|
100
162
|
continue;
|
|
101
163
|
}
|
|
102
|
-
|
|
164
|
+
segment += stateId[i];
|
|
103
165
|
}
|
|
104
|
-
|
|
166
|
+
result.push(segment);
|
|
167
|
+
return result;
|
|
105
168
|
}
|
|
106
|
-
function toStateValue(
|
|
107
|
-
|
|
169
|
+
function toStateValue(stateValue) {
|
|
170
|
+
if (isMachineSnapshot(stateValue)) return stateValue.value;
|
|
171
|
+
if (typeof stateValue !== "string") return stateValue;
|
|
172
|
+
return pathToStateValue(toStatePath(stateValue));
|
|
108
173
|
}
|
|
109
|
-
function pathToStateValue(
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
|
|
174
|
+
function pathToStateValue(statePath) {
|
|
175
|
+
if (statePath.length === 1) return statePath[0];
|
|
176
|
+
const value = {};
|
|
177
|
+
let marker = value;
|
|
178
|
+
for (let i = 0; i < statePath.length - 1; i++) if (i === statePath.length - 2) marker[statePath[i]] = statePath[i + 1];
|
|
113
179
|
else {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return
|
|
132
|
-
}
|
|
133
|
-
function
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
180
|
+
const previous = marker;
|
|
181
|
+
marker = {};
|
|
182
|
+
previous[statePath[i]] = marker;
|
|
183
|
+
}
|
|
184
|
+
return value;
|
|
185
|
+
}
|
|
186
|
+
function mapValues(collection, iteratee) {
|
|
187
|
+
const result = {};
|
|
188
|
+
const collectionKeys = Object.keys(collection);
|
|
189
|
+
for (let i = 0; i < collectionKeys.length; i++) {
|
|
190
|
+
const key = collectionKeys[i];
|
|
191
|
+
result[key] = iteratee(collection[key], key, collection, i);
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
function toArrayStrict(value) {
|
|
196
|
+
if (isArray(value)) return value;
|
|
197
|
+
return [value];
|
|
198
|
+
}
|
|
199
|
+
function toArray(value) {
|
|
200
|
+
if (value === void 0) return [];
|
|
201
|
+
return toArrayStrict(value);
|
|
202
|
+
}
|
|
203
|
+
function resolveOutput(mapper, context, event, self) {
|
|
204
|
+
if (typeof mapper === "function") return mapper({
|
|
205
|
+
context,
|
|
206
|
+
event,
|
|
207
|
+
self
|
|
208
|
+
});
|
|
209
|
+
return mapper;
|
|
139
210
|
}
|
|
140
|
-
function isArray(
|
|
141
|
-
return Array.isArray(
|
|
211
|
+
function isArray(value) {
|
|
212
|
+
return Array.isArray(value);
|
|
142
213
|
}
|
|
143
|
-
function isErrorActorEvent(
|
|
144
|
-
return
|
|
214
|
+
function isErrorActorEvent(event) {
|
|
215
|
+
return event.type.startsWith("xstate.error.actor");
|
|
145
216
|
}
|
|
146
|
-
function toTransitionConfigArray(
|
|
147
|
-
return toArrayStrict(
|
|
217
|
+
function toTransitionConfigArray(configLike) {
|
|
218
|
+
return toArrayStrict(configLike).map((transitionLike) => {
|
|
219
|
+
if (typeof transitionLike === "undefined" || typeof transitionLike === "string") return { target: transitionLike };
|
|
220
|
+
return transitionLike;
|
|
221
|
+
});
|
|
148
222
|
}
|
|
149
|
-
function normalizeTarget(
|
|
150
|
-
if (
|
|
223
|
+
function normalizeTarget(target) {
|
|
224
|
+
if (target === void 0 || target === TARGETLESS_KEY) return;
|
|
225
|
+
return toArray(target);
|
|
151
226
|
}
|
|
152
|
-
function toObserver(
|
|
153
|
-
|
|
227
|
+
function toObserver(nextHandler, errorHandler, completionHandler) {
|
|
228
|
+
const isObserver = typeof nextHandler === "object";
|
|
229
|
+
const self = isObserver ? nextHandler : void 0;
|
|
154
230
|
return {
|
|
155
|
-
next: (
|
|
156
|
-
error: (
|
|
157
|
-
complete: (
|
|
231
|
+
next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),
|
|
232
|
+
error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),
|
|
233
|
+
complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(self)
|
|
158
234
|
};
|
|
159
235
|
}
|
|
160
|
-
function createInvokeId(
|
|
161
|
-
return `${
|
|
162
|
-
}
|
|
163
|
-
function resolveReferencedActor(
|
|
164
|
-
|
|
165
|
-
if (!
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
236
|
+
function createInvokeId(stateNodeId, index) {
|
|
237
|
+
return `${index}.${stateNodeId}`;
|
|
238
|
+
}
|
|
239
|
+
function resolveReferencedActor(machine, src) {
|
|
240
|
+
const match = src.match(/^xstate\.invoke\.(\d+)\.(.*)/);
|
|
241
|
+
if (!match) return machine.implementations.actors[src];
|
|
242
|
+
const [, indexStr, nodeId] = match;
|
|
243
|
+
const invokeConfig = machine.getStateNodeById(nodeId).config.invoke;
|
|
244
|
+
return (Array.isArray(invokeConfig) ? invokeConfig[indexStr] : invokeConfig).src;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Checks if an event type matches an event descriptor, supporting wildcards.
|
|
248
|
+
* Event descriptors can be:
|
|
249
|
+
*
|
|
250
|
+
* - Exact matches: "event.type"
|
|
251
|
+
* - Wildcard: "*"
|
|
252
|
+
* - Partial matches: "event.*"
|
|
253
|
+
*
|
|
254
|
+
* @param eventType - The actual event type string
|
|
255
|
+
* @param descriptor - The event descriptor to match against
|
|
256
|
+
* @returns True if the event type matches the descriptor
|
|
257
|
+
*/
|
|
258
|
+
function matchesEventDescriptor(eventType, descriptor) {
|
|
259
|
+
if (descriptor === eventType) return true;
|
|
260
|
+
if (descriptor === WILDCARD) return true;
|
|
261
|
+
if (!descriptor.endsWith(".*")) return false;
|
|
262
|
+
const partialEventTokens = descriptor.split(".");
|
|
263
|
+
const eventTokens = eventType.split(".");
|
|
264
|
+
for (let tokenIndex = 0; tokenIndex < partialEventTokens.length; tokenIndex++) {
|
|
265
|
+
const partialEventToken = partialEventTokens[tokenIndex];
|
|
266
|
+
const eventToken = eventTokens[tokenIndex];
|
|
267
|
+
if (partialEventToken === "*") return tokenIndex === partialEventTokens.length - 1;
|
|
268
|
+
if (partialEventToken !== eventToken) return false;
|
|
269
|
+
}
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
function createScheduledEventId(actorRef, id) {
|
|
273
|
+
return `${actorRef.sessionId}.${id}`;
|
|
274
|
+
}
|
|
275
|
+
var idCounter = 0;
|
|
276
|
+
function createSystem(rootActor, options) {
|
|
277
|
+
const children = /* @__PURE__ */ new Map();
|
|
278
|
+
const keyedActors = /* @__PURE__ */ new Map();
|
|
279
|
+
const reverseKeyedActors = /* @__PURE__ */ new WeakMap();
|
|
280
|
+
const inspectionObservers = /* @__PURE__ */ new Set();
|
|
281
|
+
const timerMap = {};
|
|
282
|
+
const { clock, logger } = options;
|
|
283
|
+
const scheduler = {
|
|
284
|
+
schedule: (source, target, event, delay, id = Math.random().toString(36).slice(2)) => {
|
|
285
|
+
const scheduledEvent = {
|
|
286
|
+
source,
|
|
287
|
+
target,
|
|
288
|
+
event,
|
|
289
|
+
delay,
|
|
290
|
+
id,
|
|
193
291
|
startedAt: Date.now()
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
292
|
+
};
|
|
293
|
+
const scheduledEventId = createScheduledEventId(source, id);
|
|
294
|
+
system._snapshot._scheduledEvents[scheduledEventId] = scheduledEvent;
|
|
295
|
+
const timeout = clock.setTimeout(() => {
|
|
296
|
+
delete timerMap[scheduledEventId];
|
|
297
|
+
delete system._snapshot._scheduledEvents[scheduledEventId];
|
|
298
|
+
system._relay(source, target, event);
|
|
299
|
+
}, delay);
|
|
300
|
+
timerMap[scheduledEventId] = timeout;
|
|
200
301
|
},
|
|
201
|
-
cancel: (
|
|
202
|
-
|
|
203
|
-
|
|
302
|
+
cancel: (source, id) => {
|
|
303
|
+
const scheduledEventId = createScheduledEventId(source, id);
|
|
304
|
+
const timeout = timerMap[scheduledEventId];
|
|
305
|
+
delete timerMap[scheduledEventId];
|
|
306
|
+
delete system._snapshot._scheduledEvents[scheduledEventId];
|
|
307
|
+
if (timeout !== void 0) clock.clearTimeout(timeout);
|
|
204
308
|
},
|
|
205
|
-
cancelAll: (
|
|
206
|
-
for (
|
|
207
|
-
|
|
208
|
-
|
|
309
|
+
cancelAll: (actorRef) => {
|
|
310
|
+
for (const scheduledEventId in system._snapshot._scheduledEvents) {
|
|
311
|
+
const scheduledEvent = system._snapshot._scheduledEvents[scheduledEventId];
|
|
312
|
+
if (scheduledEvent.source === actorRef) scheduler.cancel(actorRef, scheduledEvent.id);
|
|
209
313
|
}
|
|
210
314
|
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
315
|
+
};
|
|
316
|
+
const sendInspectionEvent = (event) => {
|
|
317
|
+
if (!inspectionObservers.size) return;
|
|
318
|
+
const resolvedInspectionEvent = {
|
|
319
|
+
...event,
|
|
320
|
+
rootId: rootActor.sessionId
|
|
216
321
|
};
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
t !== void 0 && (r.delete(t), i.delete(e));
|
|
322
|
+
inspectionObservers.forEach((observer) => observer.next?.(resolvedInspectionEvent));
|
|
323
|
+
};
|
|
324
|
+
const system = {
|
|
325
|
+
_snapshot: { _scheduledEvents: (options?.snapshot && options.snapshot.scheduler) ?? {} },
|
|
326
|
+
_bookId: () => `x:${idCounter++}`,
|
|
327
|
+
_register: (sessionId, actorRef) => {
|
|
328
|
+
children.set(sessionId, actorRef);
|
|
329
|
+
return sessionId;
|
|
226
330
|
},
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
331
|
+
_unregister: (actorRef) => {
|
|
332
|
+
children.delete(actorRef.sessionId);
|
|
333
|
+
const systemId = reverseKeyedActors.get(actorRef);
|
|
334
|
+
if (systemId !== void 0) {
|
|
335
|
+
keyedActors.delete(systemId);
|
|
336
|
+
reverseKeyedActors.delete(actorRef);
|
|
337
|
+
}
|
|
233
338
|
},
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
339
|
+
get: (systemId) => {
|
|
340
|
+
return keyedActors.get(systemId);
|
|
341
|
+
},
|
|
342
|
+
getAll: () => {
|
|
343
|
+
return Object.fromEntries(keyedActors.entries());
|
|
344
|
+
},
|
|
345
|
+
_set: (systemId, actorRef) => {
|
|
346
|
+
const existing = keyedActors.get(systemId);
|
|
347
|
+
if (existing && existing !== actorRef) throw new Error(`Actor with system ID '${systemId}' already exists.`);
|
|
348
|
+
keyedActors.set(systemId, actorRef);
|
|
349
|
+
reverseKeyedActors.set(actorRef, systemId);
|
|
350
|
+
},
|
|
351
|
+
inspect: (observerOrFn) => {
|
|
352
|
+
const observer = toObserver(observerOrFn);
|
|
353
|
+
inspectionObservers.add(observer);
|
|
354
|
+
return { unsubscribe() {
|
|
355
|
+
inspectionObservers.delete(observer);
|
|
238
356
|
} };
|
|
239
357
|
},
|
|
240
358
|
_sendInspectionEvent: sendInspectionEvent,
|
|
241
|
-
_relay: (
|
|
242
|
-
|
|
359
|
+
_relay: (source, target, event) => {
|
|
360
|
+
system._sendInspectionEvent({
|
|
243
361
|
type: "@xstate.event",
|
|
244
|
-
sourceRef:
|
|
245
|
-
actorRef:
|
|
246
|
-
event
|
|
247
|
-
})
|
|
362
|
+
sourceRef: source,
|
|
363
|
+
actorRef: target,
|
|
364
|
+
event
|
|
365
|
+
});
|
|
366
|
+
target._send(event);
|
|
367
|
+
},
|
|
368
|
+
scheduler,
|
|
369
|
+
getSnapshot: () => {
|
|
370
|
+
return { _scheduledEvents: { ...system._snapshot._scheduledEvents } };
|
|
248
371
|
},
|
|
249
|
-
scheduler: l,
|
|
250
|
-
getSnapshot: () => ({ _scheduledEvents: { ...u._snapshot._scheduledEvents } }),
|
|
251
372
|
start: () => {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
for (
|
|
255
|
-
|
|
256
|
-
|
|
373
|
+
const scheduledEvents = system._snapshot._scheduledEvents;
|
|
374
|
+
system._snapshot._scheduledEvents = {};
|
|
375
|
+
for (const scheduledId in scheduledEvents) {
|
|
376
|
+
const { source, target, event, delay, id } = scheduledEvents[scheduledId];
|
|
377
|
+
scheduler.schedule(source, target, event, delay, id);
|
|
257
378
|
}
|
|
258
379
|
},
|
|
259
|
-
_clock:
|
|
260
|
-
_logger:
|
|
380
|
+
_clock: clock,
|
|
381
|
+
_logger: logger
|
|
261
382
|
};
|
|
262
|
-
return
|
|
263
|
-
}
|
|
264
|
-
var
|
|
265
|
-
|
|
266
|
-
|
|
383
|
+
return system;
|
|
384
|
+
}
|
|
385
|
+
var executingCustomAction = false;
|
|
386
|
+
var ProcessingStatus = /*#__PURE__*/ function(ProcessingStatus) {
|
|
387
|
+
ProcessingStatus[ProcessingStatus["NotStarted"] = 0] = "NotStarted";
|
|
388
|
+
ProcessingStatus[ProcessingStatus["Running"] = 1] = "Running";
|
|
389
|
+
ProcessingStatus[ProcessingStatus["Stopped"] = 2] = "Stopped";
|
|
390
|
+
return ProcessingStatus;
|
|
391
|
+
}({});
|
|
392
|
+
var defaultOptions = {
|
|
267
393
|
clock: {
|
|
268
|
-
setTimeout: (
|
|
269
|
-
|
|
394
|
+
setTimeout: (fn, ms) => {
|
|
395
|
+
return setTimeout(fn, ms);
|
|
396
|
+
},
|
|
397
|
+
clearTimeout: (id) => {
|
|
398
|
+
return clearTimeout(id);
|
|
399
|
+
}
|
|
270
400
|
},
|
|
271
401
|
logger: console.log.bind(console),
|
|
272
|
-
devTools:
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
402
|
+
devTools: false
|
|
403
|
+
};
|
|
404
|
+
/**
|
|
405
|
+
* An Actor is a running process that can receive events, send events and change
|
|
406
|
+
* its behavior based on the events it receives, which can cause effects outside
|
|
407
|
+
* of the actor. When you run a state machine, it becomes an actor.
|
|
408
|
+
*/
|
|
409
|
+
var Actor = class {
|
|
410
|
+
/**
|
|
411
|
+
* Creates a new actor instance for the given logic with the provided options,
|
|
412
|
+
* if any.
|
|
413
|
+
*
|
|
414
|
+
* @param logic The logic to create an actor from
|
|
415
|
+
* @param options Actor options
|
|
416
|
+
*/
|
|
417
|
+
constructor(logic, options) {
|
|
418
|
+
this.logic = logic;
|
|
419
|
+
/** The current internal state of the actor. */
|
|
420
|
+
this._snapshot = void 0;
|
|
421
|
+
/**
|
|
422
|
+
* The clock that is responsible for setting and clearing timeouts, such as
|
|
423
|
+
* delayed events and transitions.
|
|
424
|
+
*/
|
|
425
|
+
this.clock = void 0;
|
|
426
|
+
this.options = void 0;
|
|
427
|
+
/** The unique identifier for this actor relative to its parent. */
|
|
428
|
+
this.id = void 0;
|
|
429
|
+
this.mailbox = new Mailbox(this._process.bind(this));
|
|
430
|
+
this.observers = /* @__PURE__ */ new Set();
|
|
431
|
+
this.eventListeners = /* @__PURE__ */ new Map();
|
|
432
|
+
this.logger = void 0;
|
|
433
|
+
/** @internal */
|
|
434
|
+
this._processingStatus = ProcessingStatus.NotStarted;
|
|
435
|
+
this._parent = void 0;
|
|
436
|
+
/** @internal */
|
|
437
|
+
this._syncSnapshot = void 0;
|
|
438
|
+
this.ref = void 0;
|
|
439
|
+
this._actorScope = void 0;
|
|
440
|
+
this.systemId = void 0;
|
|
441
|
+
/** The globally unique process ID for this invocation. */
|
|
442
|
+
this.sessionId = void 0;
|
|
443
|
+
/** The system to which this actor belongs. */
|
|
444
|
+
this.system = void 0;
|
|
445
|
+
this._doneEvent = void 0;
|
|
446
|
+
this.src = void 0;
|
|
447
|
+
this._deferred = [];
|
|
448
|
+
const resolvedOptions = {
|
|
449
|
+
...defaultOptions,
|
|
450
|
+
...options
|
|
451
|
+
};
|
|
452
|
+
const { clock, logger, parent, syncSnapshot, id, systemId, inspect } = resolvedOptions;
|
|
453
|
+
this.system = parent ? parent.system : createSystem(this, {
|
|
454
|
+
clock,
|
|
455
|
+
logger
|
|
456
|
+
});
|
|
457
|
+
if (inspect && !parent) this.system.inspect(toObserver(inspect));
|
|
458
|
+
this.sessionId = this.system._bookId();
|
|
459
|
+
this.id = id ?? this.sessionId;
|
|
460
|
+
this.logger = options?.logger ?? this.system._logger;
|
|
461
|
+
this.clock = options?.clock ?? this.system._clock;
|
|
462
|
+
this._parent = parent;
|
|
463
|
+
this._syncSnapshot = syncSnapshot;
|
|
464
|
+
this.options = resolvedOptions;
|
|
465
|
+
this.src = resolvedOptions.src ?? logic;
|
|
466
|
+
this.ref = this;
|
|
467
|
+
this._actorScope = {
|
|
284
468
|
self: this,
|
|
285
469
|
id: this.id,
|
|
286
470
|
sessionId: this.sessionId,
|
|
287
471
|
logger: this.logger,
|
|
288
|
-
defer: (
|
|
289
|
-
this._deferred.push(
|
|
472
|
+
defer: (fn) => {
|
|
473
|
+
this._deferred.push(fn);
|
|
290
474
|
},
|
|
291
475
|
system: this.system,
|
|
292
|
-
stopChild: (
|
|
293
|
-
if (
|
|
294
|
-
|
|
476
|
+
stopChild: (child) => {
|
|
477
|
+
if (child._parent !== this) throw new Error(`Cannot stop child actor ${child.id} of ${this.id} because it is not a child`);
|
|
478
|
+
child._stop();
|
|
295
479
|
},
|
|
296
|
-
emit: (
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
480
|
+
emit: (emittedEvent) => {
|
|
481
|
+
const listeners = this.eventListeners.get(emittedEvent.type);
|
|
482
|
+
const wildcardListener = this.eventListeners.get("*");
|
|
483
|
+
if (!listeners && !wildcardListener) return;
|
|
484
|
+
const allListeners = [...listeners ? listeners.values() : [], ...wildcardListener ? wildcardListener.values() : []];
|
|
485
|
+
for (const handler of allListeners) try {
|
|
486
|
+
handler(emittedEvent);
|
|
487
|
+
} catch (err) {
|
|
488
|
+
reportUnhandledError(err);
|
|
304
489
|
}
|
|
305
490
|
},
|
|
306
|
-
actionExecutor: (
|
|
307
|
-
|
|
308
|
-
|
|
491
|
+
actionExecutor: (action) => {
|
|
492
|
+
const exec = () => {
|
|
493
|
+
this._actorScope.system._sendInspectionEvent({
|
|
309
494
|
type: "@xstate.action",
|
|
310
495
|
actorRef: this,
|
|
311
496
|
action: {
|
|
312
|
-
type:
|
|
313
|
-
params:
|
|
497
|
+
type: action.type,
|
|
498
|
+
params: action.params
|
|
314
499
|
}
|
|
315
|
-
})
|
|
316
|
-
|
|
500
|
+
});
|
|
501
|
+
if (!action.exec) return;
|
|
502
|
+
const saveExecutingCustomAction = executingCustomAction;
|
|
317
503
|
try {
|
|
318
|
-
|
|
504
|
+
executingCustomAction = true;
|
|
505
|
+
action.exec(action.info, action.params);
|
|
319
506
|
} finally {
|
|
320
|
-
|
|
507
|
+
executingCustomAction = saveExecutingCustomAction;
|
|
321
508
|
}
|
|
322
509
|
};
|
|
323
|
-
this._processingStatus ===
|
|
510
|
+
if (this._processingStatus === ProcessingStatus.Running) exec();
|
|
511
|
+
else this._deferred.push(exec);
|
|
324
512
|
}
|
|
325
|
-
}
|
|
513
|
+
};
|
|
514
|
+
this.send = this.send.bind(this);
|
|
515
|
+
this.system._sendInspectionEvent({
|
|
326
516
|
type: "@xstate.actor",
|
|
327
517
|
actorRef: this
|
|
328
|
-
})
|
|
518
|
+
});
|
|
519
|
+
if (systemId) {
|
|
520
|
+
this.systemId = systemId;
|
|
521
|
+
this.system._set(systemId, this);
|
|
522
|
+
}
|
|
523
|
+
this._initState(options?.snapshot ?? options?.state);
|
|
524
|
+
if (systemId && this._snapshot.status !== "active") this.system._unregister(this);
|
|
329
525
|
}
|
|
330
|
-
_initState(
|
|
526
|
+
_initState(persistedState) {
|
|
331
527
|
try {
|
|
332
|
-
this._snapshot =
|
|
333
|
-
} catch (
|
|
528
|
+
this._snapshot = persistedState ? this.logic.restoreSnapshot ? this.logic.restoreSnapshot(persistedState, this._actorScope) : persistedState : this.logic.getInitialSnapshot(this._actorScope, this.options?.input);
|
|
529
|
+
} catch (err) {
|
|
334
530
|
this._snapshot = {
|
|
335
531
|
status: "error",
|
|
336
532
|
output: void 0,
|
|
337
|
-
error:
|
|
533
|
+
error: err
|
|
338
534
|
};
|
|
339
535
|
}
|
|
340
536
|
}
|
|
341
|
-
update(
|
|
342
|
-
this._snapshot =
|
|
343
|
-
let
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
} catch (
|
|
347
|
-
this._deferred.length = 0
|
|
348
|
-
|
|
537
|
+
update(snapshot, event) {
|
|
538
|
+
this._snapshot = snapshot;
|
|
539
|
+
let deferredFn;
|
|
540
|
+
while (deferredFn = this._deferred.shift()) try {
|
|
541
|
+
deferredFn();
|
|
542
|
+
} catch (err) {
|
|
543
|
+
this._deferred.length = 0;
|
|
544
|
+
this._snapshot = {
|
|
545
|
+
...snapshot,
|
|
349
546
|
status: "error",
|
|
350
|
-
error:
|
|
547
|
+
error: err
|
|
351
548
|
};
|
|
352
549
|
}
|
|
353
550
|
switch (this._snapshot.status) {
|
|
354
551
|
case "active":
|
|
355
|
-
for (
|
|
356
|
-
|
|
357
|
-
} catch (
|
|
358
|
-
reportUnhandledError(
|
|
552
|
+
for (const observer of this.observers) try {
|
|
553
|
+
observer.next?.(snapshot);
|
|
554
|
+
} catch (err) {
|
|
555
|
+
reportUnhandledError(err);
|
|
359
556
|
}
|
|
360
557
|
break;
|
|
361
558
|
case "done":
|
|
362
|
-
for (
|
|
363
|
-
|
|
364
|
-
} catch (
|
|
365
|
-
reportUnhandledError(
|
|
559
|
+
for (const observer of this.observers) try {
|
|
560
|
+
observer.next?.(snapshot);
|
|
561
|
+
} catch (err) {
|
|
562
|
+
reportUnhandledError(err);
|
|
366
563
|
}
|
|
367
|
-
this._stopProcedure()
|
|
564
|
+
this._stopProcedure();
|
|
565
|
+
this._complete();
|
|
566
|
+
this._doneEvent = createDoneActorEvent(this.id, this._snapshot.output);
|
|
567
|
+
if (this._parent) this.system._relay(this, this._parent, this._doneEvent);
|
|
368
568
|
break;
|
|
369
569
|
case "error": this._error(this._snapshot.error);
|
|
370
570
|
}
|
|
371
571
|
this.system._sendInspectionEvent({
|
|
372
572
|
type: "@xstate.snapshot",
|
|
373
573
|
actorRef: this,
|
|
374
|
-
event
|
|
375
|
-
snapshot
|
|
574
|
+
event,
|
|
575
|
+
snapshot
|
|
376
576
|
});
|
|
377
577
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
578
|
+
/**
|
|
579
|
+
* Subscribe an observer to an actor’s snapshot values.
|
|
580
|
+
*
|
|
581
|
+
* @remarks
|
|
582
|
+
* The observer will receive the actor’s snapshot value when it is emitted.
|
|
583
|
+
* The observer can be:
|
|
584
|
+
*
|
|
585
|
+
* - A plain function that receives the latest snapshot, or
|
|
586
|
+
* - An observer object whose `.next(snapshot)` method receives the latest
|
|
587
|
+
* snapshot
|
|
588
|
+
*
|
|
589
|
+
* @example
|
|
590
|
+
*
|
|
591
|
+
* ```ts
|
|
592
|
+
* // Observer as a plain function
|
|
593
|
+
* const subscription = actor.subscribe((snapshot) => {
|
|
594
|
+
* console.log(snapshot);
|
|
595
|
+
* });
|
|
596
|
+
* ```
|
|
597
|
+
*
|
|
598
|
+
* @example
|
|
599
|
+
*
|
|
600
|
+
* ```ts
|
|
601
|
+
* // Observer as an object
|
|
602
|
+
* const subscription = actor.subscribe({
|
|
603
|
+
* next(snapshot) {
|
|
604
|
+
* console.log(snapshot);
|
|
605
|
+
* },
|
|
606
|
+
* error(err) {
|
|
607
|
+
* // ...
|
|
608
|
+
* },
|
|
609
|
+
* complete() {
|
|
610
|
+
* // ...
|
|
611
|
+
* }
|
|
612
|
+
* });
|
|
613
|
+
* ```
|
|
614
|
+
*
|
|
615
|
+
* The return value of `actor.subscribe(observer)` is a subscription object
|
|
616
|
+
* that has an `.unsubscribe()` method. You can call
|
|
617
|
+
* `subscription.unsubscribe()` to unsubscribe the observer:
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
*
|
|
621
|
+
* ```ts
|
|
622
|
+
* const subscription = actor.subscribe((snapshot) => {
|
|
623
|
+
* // ...
|
|
624
|
+
* });
|
|
625
|
+
*
|
|
626
|
+
* // Unsubscribe the observer
|
|
627
|
+
* subscription.unsubscribe();
|
|
628
|
+
* ```
|
|
629
|
+
*
|
|
630
|
+
* When the actor is stopped, all of its observers will automatically be
|
|
631
|
+
* unsubscribed.
|
|
632
|
+
*
|
|
633
|
+
* @param observer - Either a plain function that receives the latest
|
|
634
|
+
* snapshot, or an observer object whose `.next(snapshot)` method receives
|
|
635
|
+
* the latest snapshot
|
|
636
|
+
*/
|
|
637
|
+
subscribe(nextListenerOrObserver, errorListener, completeListener) {
|
|
638
|
+
const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
|
|
639
|
+
if (this._processingStatus !== ProcessingStatus.Stopped) this.observers.add(observer);
|
|
381
640
|
else switch (this._snapshot.status) {
|
|
382
641
|
case "done":
|
|
383
642
|
try {
|
|
384
|
-
|
|
385
|
-
} catch (
|
|
386
|
-
reportUnhandledError(
|
|
643
|
+
observer.complete?.();
|
|
644
|
+
} catch (err) {
|
|
645
|
+
reportUnhandledError(err);
|
|
387
646
|
}
|
|
388
647
|
break;
|
|
389
648
|
case "error": {
|
|
390
|
-
|
|
391
|
-
if (!
|
|
649
|
+
const err = this._snapshot.error;
|
|
650
|
+
if (!observer.error) reportUnhandledError(err);
|
|
392
651
|
else try {
|
|
393
|
-
|
|
394
|
-
} catch (
|
|
395
|
-
reportUnhandledError(
|
|
652
|
+
observer.error(err);
|
|
653
|
+
} catch (err) {
|
|
654
|
+
reportUnhandledError(err);
|
|
396
655
|
}
|
|
397
656
|
break;
|
|
398
657
|
}
|
|
399
658
|
}
|
|
400
659
|
return { unsubscribe: () => {
|
|
401
|
-
this.observers.delete(
|
|
660
|
+
this.observers.delete(observer);
|
|
402
661
|
} };
|
|
403
662
|
}
|
|
404
|
-
on(
|
|
405
|
-
let
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
663
|
+
on(type, handler) {
|
|
664
|
+
let listeners = this.eventListeners.get(type);
|
|
665
|
+
if (!listeners) {
|
|
666
|
+
listeners = /* @__PURE__ */ new Set();
|
|
667
|
+
this.eventListeners.set(type, listeners);
|
|
668
|
+
}
|
|
669
|
+
const wrappedHandler = handler.bind(void 0);
|
|
670
|
+
listeners.add(wrappedHandler);
|
|
671
|
+
return { unsubscribe: () => {
|
|
672
|
+
listeners.delete(wrappedHandler);
|
|
410
673
|
} };
|
|
411
674
|
}
|
|
412
|
-
select(
|
|
675
|
+
select(selector, equalityFn = Object.is) {
|
|
413
676
|
return {
|
|
414
|
-
subscribe: (
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
677
|
+
subscribe: (observerOrFn) => {
|
|
678
|
+
const observer = toObserver(observerOrFn);
|
|
679
|
+
let previousSelected = selector(this.getSnapshot());
|
|
680
|
+
return this.subscribe((snapshot) => {
|
|
681
|
+
const nextSelected = selector(snapshot);
|
|
682
|
+
if (!equalityFn(previousSelected, nextSelected)) {
|
|
683
|
+
previousSelected = nextSelected;
|
|
684
|
+
observer.next?.(nextSelected);
|
|
685
|
+
}
|
|
419
686
|
});
|
|
420
687
|
},
|
|
421
|
-
get: () =>
|
|
688
|
+
get: () => selector(this.getSnapshot())
|
|
422
689
|
};
|
|
423
690
|
}
|
|
691
|
+
/** Starts the Actor from the initial state */
|
|
424
692
|
start() {
|
|
425
|
-
if (this._processingStatus ===
|
|
426
|
-
this._syncSnapshot
|
|
427
|
-
next: (
|
|
428
|
-
|
|
693
|
+
if (this._processingStatus === ProcessingStatus.Running) return this;
|
|
694
|
+
if (this._syncSnapshot) this.subscribe({
|
|
695
|
+
next: (snapshot) => {
|
|
696
|
+
if (snapshot.status === "active") this.system._relay(this, this._parent, {
|
|
429
697
|
type: `xstate.snapshot.${this.id}`,
|
|
430
|
-
snapshot
|
|
698
|
+
snapshot
|
|
431
699
|
});
|
|
432
700
|
},
|
|
433
701
|
error: () => {}
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
|
|
702
|
+
});
|
|
703
|
+
this.system._register(this.sessionId, this);
|
|
704
|
+
if (this.systemId) this.system._set(this.systemId, this);
|
|
705
|
+
this._processingStatus = ProcessingStatus.Running;
|
|
706
|
+
const initEvent = createInitEvent(this.options.input);
|
|
707
|
+
this.system._sendInspectionEvent({
|
|
437
708
|
type: "@xstate.event",
|
|
438
709
|
sourceRef: this._parent,
|
|
439
710
|
actorRef: this,
|
|
440
|
-
event:
|
|
441
|
-
})
|
|
442
|
-
|
|
443
|
-
case "
|
|
711
|
+
event: initEvent
|
|
712
|
+
});
|
|
713
|
+
switch (this._snapshot.status) {
|
|
714
|
+
case "done":
|
|
715
|
+
this.update(this._snapshot, initEvent);
|
|
716
|
+
return this;
|
|
717
|
+
case "error":
|
|
718
|
+
this._error(this._snapshot.error);
|
|
719
|
+
return this;
|
|
444
720
|
}
|
|
445
|
-
if (this._parent
|
|
721
|
+
if (!this._parent) this.system.start();
|
|
722
|
+
if (this.logic.start) try {
|
|
446
723
|
this.logic.start(this._snapshot, this._actorScope);
|
|
447
|
-
} catch (
|
|
448
|
-
|
|
724
|
+
} catch (err) {
|
|
725
|
+
this._snapshot = {
|
|
449
726
|
...this._snapshot,
|
|
450
727
|
status: "error",
|
|
451
|
-
error:
|
|
452
|
-
}
|
|
728
|
+
error: err
|
|
729
|
+
};
|
|
730
|
+
this._error(err);
|
|
731
|
+
return this;
|
|
453
732
|
}
|
|
454
|
-
|
|
733
|
+
this.update(this._snapshot, initEvent);
|
|
734
|
+
if (this.options.devTools) this.attachDevTools();
|
|
735
|
+
this.mailbox.start();
|
|
736
|
+
return this;
|
|
455
737
|
}
|
|
456
|
-
_process(
|
|
457
|
-
let
|
|
738
|
+
_process(event) {
|
|
739
|
+
let nextState;
|
|
740
|
+
let caughtError;
|
|
458
741
|
try {
|
|
459
|
-
|
|
460
|
-
} catch (
|
|
461
|
-
|
|
742
|
+
nextState = this.logic.transition(this._snapshot, event, this._actorScope);
|
|
743
|
+
} catch (err) {
|
|
744
|
+
caughtError = { err };
|
|
462
745
|
}
|
|
463
|
-
if (
|
|
464
|
-
|
|
746
|
+
if (caughtError) {
|
|
747
|
+
const { err } = caughtError;
|
|
465
748
|
this._snapshot = {
|
|
466
749
|
...this._snapshot,
|
|
467
750
|
status: "error",
|
|
468
|
-
error:
|
|
469
|
-
}
|
|
751
|
+
error: err
|
|
752
|
+
};
|
|
753
|
+
this._error(err);
|
|
470
754
|
return;
|
|
471
755
|
}
|
|
472
|
-
this.update(
|
|
756
|
+
this.update(nextState, event);
|
|
757
|
+
if (event.type === "xstate.stop") {
|
|
758
|
+
this._stopProcedure();
|
|
759
|
+
this._complete();
|
|
760
|
+
}
|
|
473
761
|
}
|
|
474
762
|
_stop() {
|
|
475
|
-
|
|
763
|
+
if (this._processingStatus === ProcessingStatus.Stopped) return this;
|
|
764
|
+
this.mailbox.clear();
|
|
765
|
+
if (this._processingStatus === ProcessingStatus.NotStarted) {
|
|
766
|
+
this._processingStatus = ProcessingStatus.Stopped;
|
|
767
|
+
return this;
|
|
768
|
+
}
|
|
769
|
+
this.mailbox.enqueue({ type: XSTATE_STOP });
|
|
770
|
+
return this;
|
|
476
771
|
}
|
|
772
|
+
/** Stops the Actor and unsubscribe all listeners. */
|
|
477
773
|
stop() {
|
|
478
|
-
if (this._parent) throw Error("A non-root actor cannot be stopped directly.");
|
|
774
|
+
if (this._parent) throw new Error("A non-root actor cannot be stopped directly.");
|
|
479
775
|
return this._stop();
|
|
480
776
|
}
|
|
481
777
|
_complete() {
|
|
482
|
-
for (
|
|
483
|
-
|
|
484
|
-
} catch (
|
|
485
|
-
reportUnhandledError(
|
|
778
|
+
for (const observer of this.observers) try {
|
|
779
|
+
observer.complete?.();
|
|
780
|
+
} catch (err) {
|
|
781
|
+
reportUnhandledError(err);
|
|
486
782
|
}
|
|
487
|
-
this.observers.clear()
|
|
783
|
+
this.observers.clear();
|
|
784
|
+
this.eventListeners.clear();
|
|
488
785
|
}
|
|
489
|
-
_reportError(
|
|
786
|
+
_reportError(err) {
|
|
490
787
|
if (!this.observers.size) {
|
|
491
|
-
this._parent
|
|
788
|
+
if (!this._parent) reportUnhandledError(err);
|
|
789
|
+
this.eventListeners.clear();
|
|
492
790
|
return;
|
|
493
791
|
}
|
|
494
|
-
let
|
|
495
|
-
for (
|
|
496
|
-
|
|
497
|
-
|
|
792
|
+
let reportError = false;
|
|
793
|
+
for (const observer of this.observers) {
|
|
794
|
+
const errorListener = observer.error;
|
|
795
|
+
reportError ||= !errorListener;
|
|
498
796
|
try {
|
|
499
|
-
|
|
500
|
-
} catch (
|
|
501
|
-
reportUnhandledError(
|
|
797
|
+
errorListener?.(err);
|
|
798
|
+
} catch (err2) {
|
|
799
|
+
reportUnhandledError(err2);
|
|
502
800
|
}
|
|
503
801
|
}
|
|
504
|
-
this.observers.clear()
|
|
802
|
+
this.observers.clear();
|
|
803
|
+
this.eventListeners.clear();
|
|
804
|
+
if (reportError) reportUnhandledError(err);
|
|
505
805
|
}
|
|
506
|
-
_error(
|
|
507
|
-
this._stopProcedure()
|
|
806
|
+
_error(err) {
|
|
807
|
+
this._stopProcedure();
|
|
808
|
+
this._reportError(err);
|
|
809
|
+
if (this._parent) this.system._relay(this, this._parent, createErrorActorEvent(this.id, err));
|
|
508
810
|
}
|
|
509
811
|
_stopProcedure() {
|
|
510
|
-
|
|
812
|
+
if (this._processingStatus !== ProcessingStatus.Running) return this;
|
|
813
|
+
this.system.scheduler.cancelAll(this);
|
|
814
|
+
this.mailbox.clear();
|
|
815
|
+
this.mailbox = new Mailbox(this._process.bind(this));
|
|
816
|
+
this._processingStatus = ProcessingStatus.Stopped;
|
|
817
|
+
this.system._unregister(this);
|
|
818
|
+
return this;
|
|
511
819
|
}
|
|
512
|
-
|
|
513
|
-
|
|
820
|
+
/** @internal */
|
|
821
|
+
_send(event) {
|
|
822
|
+
if (this._processingStatus === ProcessingStatus.Stopped) return;
|
|
823
|
+
this.mailbox.enqueue(event);
|
|
514
824
|
}
|
|
515
|
-
|
|
516
|
-
|
|
825
|
+
/**
|
|
826
|
+
* Sends an event to the running Actor to trigger a transition.
|
|
827
|
+
*
|
|
828
|
+
* @param event The event to send
|
|
829
|
+
*/
|
|
830
|
+
send(event) {
|
|
831
|
+
this.system._relay(void 0, this, event);
|
|
517
832
|
}
|
|
518
833
|
attachDevTools() {
|
|
519
|
-
|
|
520
|
-
|
|
834
|
+
const { devTools } = this.options;
|
|
835
|
+
if (devTools) (typeof devTools === "function" ? devTools : devToolsAdapter)(this);
|
|
521
836
|
}
|
|
522
837
|
toJSON() {
|
|
523
838
|
return {
|
|
@@ -525,988 +840,1763 @@ var m = !1, h = /*#__PURE__*/ function(e) {
|
|
|
525
840
|
id: this.id
|
|
526
841
|
};
|
|
527
842
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
843
|
+
/**
|
|
844
|
+
* Obtain the internal state of the actor, which can be persisted.
|
|
845
|
+
*
|
|
846
|
+
* @remarks
|
|
847
|
+
* The internal state can be persisted from any actor, not only machines.
|
|
848
|
+
*
|
|
849
|
+
* Note that the persisted state is not the same as the snapshot from
|
|
850
|
+
* {@link Actor.getSnapshot}. Persisted state represents the internal state of
|
|
851
|
+
* the actor, while snapshots represent the actor's last emitted value.
|
|
852
|
+
*
|
|
853
|
+
* Can be restored with {@link ActorOptions.state}
|
|
854
|
+
* @see https://stately.ai/docs/persistence
|
|
855
|
+
*/
|
|
856
|
+
getPersistedSnapshot(options) {
|
|
857
|
+
return this.logic.getPersistedSnapshot(this._snapshot, options);
|
|
858
|
+
}
|
|
859
|
+
[symbolObservable]() {
|
|
532
860
|
return this;
|
|
533
861
|
}
|
|
862
|
+
/**
|
|
863
|
+
* Read an actor’s snapshot synchronously.
|
|
864
|
+
*
|
|
865
|
+
* @remarks
|
|
866
|
+
* The snapshot represent an actor's last emitted value.
|
|
867
|
+
*
|
|
868
|
+
* When an actor receives an event, its internal state may change. An actor
|
|
869
|
+
* may emit a snapshot when a state transition occurs.
|
|
870
|
+
*
|
|
871
|
+
* Note that some actors, such as callback actors generated with
|
|
872
|
+
* `fromCallback`, will not emit snapshots.
|
|
873
|
+
* @see {@link Actor.subscribe} to subscribe to an actor’s snapshot values.
|
|
874
|
+
* @see {@link Actor.getPersistedSnapshot} to persist the internal state of an actor (which is more than just a snapshot).
|
|
875
|
+
*/
|
|
534
876
|
getSnapshot() {
|
|
535
877
|
return this._snapshot;
|
|
536
878
|
}
|
|
537
879
|
};
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
880
|
+
/**
|
|
881
|
+
* Creates a new actor instance for the given actor logic with the provided
|
|
882
|
+
* options, if any.
|
|
883
|
+
*
|
|
884
|
+
* @remarks
|
|
885
|
+
* When you create an actor from actor logic via `createActor(logic)`, you
|
|
886
|
+
* implicitly create an actor system where the created actor is the root actor.
|
|
887
|
+
* Any actors spawned from this root actor and its descendants are part of that
|
|
888
|
+
* actor system.
|
|
889
|
+
* @example
|
|
890
|
+
*
|
|
891
|
+
* ```ts
|
|
892
|
+
* import { createActor } from 'xstate';
|
|
893
|
+
* import { someActorLogic } from './someActorLogic.ts';
|
|
894
|
+
*
|
|
895
|
+
* // Creating the actor, which implicitly creates an actor system with itself as the root actor
|
|
896
|
+
* const actor = createActor(someActorLogic);
|
|
897
|
+
*
|
|
898
|
+
* actor.subscribe((snapshot) => {
|
|
899
|
+
* console.log(snapshot);
|
|
900
|
+
* });
|
|
901
|
+
*
|
|
902
|
+
* // Actors must be started by calling `actor.start()`, which will also start the actor system.
|
|
903
|
+
* actor.start();
|
|
904
|
+
*
|
|
905
|
+
* // Actors can receive events
|
|
906
|
+
* actor.send({ type: 'someEvent' });
|
|
907
|
+
*
|
|
908
|
+
* // You can stop root actors by calling `actor.stop()`, which will also stop the actor system and all actors in that system.
|
|
909
|
+
* actor.stop();
|
|
910
|
+
* ```
|
|
911
|
+
*
|
|
912
|
+
* @param logic - The actor logic to create an actor from. For a state machine
|
|
913
|
+
* actor logic creator, see {@link createMachine}. Other actor logic creators
|
|
914
|
+
* include {@link fromCallback}, {@link fromEventObservable},
|
|
915
|
+
* {@link fromObservable}, {@link fromPromise}, and {@link fromTransition}.
|
|
916
|
+
* @param options - Actor options
|
|
917
|
+
*/
|
|
918
|
+
function createActor(logic, ...[options]) {
|
|
919
|
+
return new Actor(logic, options);
|
|
920
|
+
}
|
|
921
|
+
/**
|
|
922
|
+
* @deprecated Use `Actor` instead.
|
|
923
|
+
* @alias
|
|
924
|
+
*/
|
|
925
|
+
function resolveCancel(_, snapshot, actionArgs, actionParams, { sendId }) {
|
|
542
926
|
return [
|
|
543
|
-
|
|
544
|
-
{ sendId: typeof
|
|
927
|
+
snapshot,
|
|
928
|
+
{ sendId: typeof sendId === "function" ? sendId(actionArgs, actionParams) : sendId },
|
|
545
929
|
void 0
|
|
546
930
|
];
|
|
547
931
|
}
|
|
548
|
-
function executeCancel(
|
|
549
|
-
|
|
550
|
-
|
|
932
|
+
function executeCancel(actorScope, params) {
|
|
933
|
+
actorScope.defer(() => {
|
|
934
|
+
actorScope.system.scheduler.cancel(actorScope.self, params.sendId);
|
|
551
935
|
});
|
|
552
936
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
937
|
+
/**
|
|
938
|
+
* Cancels a delayed `sendTo(...)` action that is waiting to be executed. The
|
|
939
|
+
* canceled `sendTo(...)` action will not send its event or execute, unless the
|
|
940
|
+
* `delay` has already elapsed before `cancel(...)` is called.
|
|
941
|
+
*
|
|
942
|
+
* @example
|
|
943
|
+
*
|
|
944
|
+
* ```ts
|
|
945
|
+
* import { createMachine, sendTo, cancel } from 'xstate';
|
|
946
|
+
*
|
|
947
|
+
* const machine = createMachine({
|
|
948
|
+
* // ...
|
|
949
|
+
* on: {
|
|
950
|
+
* sendEvent: {
|
|
951
|
+
* actions: sendTo(
|
|
952
|
+
* 'some-actor',
|
|
953
|
+
* { type: 'someEvent' },
|
|
954
|
+
* {
|
|
955
|
+
* id: 'some-id',
|
|
956
|
+
* delay: 1000
|
|
957
|
+
* }
|
|
958
|
+
* )
|
|
959
|
+
* },
|
|
960
|
+
* cancelEvent: {
|
|
961
|
+
* actions: cancel('some-id')
|
|
962
|
+
* }
|
|
963
|
+
* }
|
|
964
|
+
* });
|
|
965
|
+
* ```
|
|
966
|
+
*
|
|
967
|
+
* @param sendId The `id` of the `sendTo(...)` action to cancel.
|
|
968
|
+
*/
|
|
969
|
+
function cancel(sendId) {
|
|
970
|
+
function cancel(_args, _params) {}
|
|
971
|
+
cancel.type = "xstate.cancel";
|
|
972
|
+
cancel.sendId = sendId;
|
|
973
|
+
cancel.resolve = resolveCancel;
|
|
974
|
+
cancel.execute = executeCancel;
|
|
975
|
+
return cancel;
|
|
976
|
+
}
|
|
977
|
+
function resolveSpawn(actorScope, snapshot, actionArgs, _actionParams, { id, systemId, src, input, syncSnapshot }) {
|
|
978
|
+
const logic = typeof src === "string" ? resolveReferencedActor(snapshot.machine, src) : src;
|
|
979
|
+
const resolvedId = typeof id === "function" ? id(actionArgs) : id;
|
|
980
|
+
let actorRef;
|
|
981
|
+
let resolvedInput = void 0;
|
|
982
|
+
if (logic) {
|
|
983
|
+
resolvedInput = typeof input === "function" ? input({
|
|
984
|
+
context: snapshot.context,
|
|
985
|
+
event: actionArgs.event,
|
|
986
|
+
self: actorScope.self
|
|
987
|
+
}) : input;
|
|
988
|
+
actorRef = createActor(logic, {
|
|
989
|
+
id: resolvedId,
|
|
990
|
+
src,
|
|
991
|
+
parent: actorScope.self,
|
|
992
|
+
syncSnapshot,
|
|
993
|
+
systemId,
|
|
994
|
+
input: resolvedInput
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
return [
|
|
998
|
+
cloneMachineSnapshot(snapshot, { children: {
|
|
999
|
+
...snapshot.children,
|
|
1000
|
+
[resolvedId]: actorRef
|
|
574
1001
|
} }),
|
|
575
1002
|
{
|
|
576
|
-
id
|
|
577
|
-
systemId
|
|
578
|
-
actorRef
|
|
579
|
-
src
|
|
580
|
-
input:
|
|
1003
|
+
id,
|
|
1004
|
+
systemId,
|
|
1005
|
+
actorRef,
|
|
1006
|
+
src,
|
|
1007
|
+
input: resolvedInput
|
|
581
1008
|
},
|
|
582
1009
|
void 0
|
|
583
1010
|
];
|
|
584
1011
|
}
|
|
585
|
-
function executeSpawn(
|
|
586
|
-
|
|
587
|
-
|
|
1012
|
+
function executeSpawn(actorScope, { actorRef }) {
|
|
1013
|
+
if (!actorRef) return;
|
|
1014
|
+
actorScope.defer(() => {
|
|
1015
|
+
if (actorRef._processingStatus === ProcessingStatus.Stopped) return;
|
|
1016
|
+
actorRef.start();
|
|
588
1017
|
});
|
|
589
1018
|
}
|
|
590
|
-
function spawnChild(...[
|
|
591
|
-
function spawnChild(
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
1019
|
+
function spawnChild(...[src, { id, systemId, input, syncSnapshot = false } = {}]) {
|
|
1020
|
+
function spawnChild(_args, _params) {}
|
|
1021
|
+
spawnChild.type = "xstate.spawnChild";
|
|
1022
|
+
spawnChild.id = id;
|
|
1023
|
+
spawnChild.systemId = systemId;
|
|
1024
|
+
spawnChild.src = src;
|
|
1025
|
+
spawnChild.input = input;
|
|
1026
|
+
spawnChild.syncSnapshot = syncSnapshot;
|
|
1027
|
+
spawnChild.resolve = resolveSpawn;
|
|
1028
|
+
spawnChild.execute = executeSpawn;
|
|
1029
|
+
return spawnChild;
|
|
1030
|
+
}
|
|
1031
|
+
function resolveStop(_, snapshot, args, actionParams, { actorRef }) {
|
|
1032
|
+
const actorRefOrString = typeof actorRef === "function" ? actorRef(args, actionParams) : actorRef;
|
|
1033
|
+
const resolvedActorRef = typeof actorRefOrString === "string" ? snapshot.children[actorRefOrString] : actorRefOrString;
|
|
1034
|
+
let children = snapshot.children;
|
|
1035
|
+
if (resolvedActorRef) {
|
|
1036
|
+
children = { ...children };
|
|
1037
|
+
delete children[resolvedActorRef.id];
|
|
1038
|
+
}
|
|
1039
|
+
return [
|
|
1040
|
+
cloneMachineSnapshot(snapshot, { children }),
|
|
1041
|
+
resolvedActorRef,
|
|
599
1042
|
void 0
|
|
600
1043
|
];
|
|
601
1044
|
}
|
|
602
|
-
function unregisterRecursively(
|
|
603
|
-
|
|
604
|
-
if (
|
|
605
|
-
|
|
606
|
-
}
|
|
607
|
-
function executeStop(e, t) {
|
|
608
|
-
if (t) {
|
|
609
|
-
if (unregisterRecursively(e, t), t._processingStatus !== h.Running) {
|
|
610
|
-
e.stopChild(t);
|
|
611
|
-
return;
|
|
612
|
-
}
|
|
613
|
-
e.defer(() => {
|
|
614
|
-
e.stopChild(t);
|
|
615
|
-
});
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
function stopChild(e) {
|
|
619
|
-
function stop(e, t) {}
|
|
620
|
-
return stop.type = "xstate.stopChild", stop.actorRef = e, stop.resolve = resolveStop, stop.execute = executeStop, stop;
|
|
621
|
-
}
|
|
622
|
-
function checkNot(e, { context: t, event: n }, { guards: r }) {
|
|
623
|
-
return !evaluateGuard(r[0], t, n, e);
|
|
624
|
-
}
|
|
625
|
-
function not(e) {
|
|
626
|
-
function not(e, t) {
|
|
627
|
-
return !1;
|
|
628
|
-
}
|
|
629
|
-
return not.check = checkNot, not.guards = [e], not;
|
|
630
|
-
}
|
|
631
|
-
function checkAnd(e, { context: t, event: n }, { guards: r }) {
|
|
632
|
-
return r.every((r) => evaluateGuard(r, t, n, e));
|
|
633
|
-
}
|
|
634
|
-
function and(e) {
|
|
635
|
-
function and(e, t) {
|
|
636
|
-
return !1;
|
|
637
|
-
}
|
|
638
|
-
return and.check = checkAnd, and.guards = e, and;
|
|
639
|
-
}
|
|
640
|
-
function checkOr(e, { context: t, event: n }, { guards: r }) {
|
|
641
|
-
return r.some((r) => evaluateGuard(r, t, n, e));
|
|
1045
|
+
function unregisterRecursively(actorScope, actorRef) {
|
|
1046
|
+
const snapshot = actorRef.getSnapshot();
|
|
1047
|
+
if (snapshot && "children" in snapshot) for (const child of Object.values(snapshot.children)) unregisterRecursively(actorScope, child);
|
|
1048
|
+
actorScope.system._unregister(actorRef);
|
|
642
1049
|
}
|
|
643
|
-
function
|
|
644
|
-
|
|
645
|
-
|
|
1050
|
+
function executeStop(actorScope, actorRef) {
|
|
1051
|
+
if (!actorRef) return;
|
|
1052
|
+
unregisterRecursively(actorScope, actorRef);
|
|
1053
|
+
if (actorRef._processingStatus !== ProcessingStatus.Running) {
|
|
1054
|
+
actorScope.stopChild(actorRef);
|
|
1055
|
+
return;
|
|
646
1056
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
let { machine: i } = r, a = typeof e == "function", o = a ? e : i.implementations.guards[typeof e == "string" ? e : e.type];
|
|
651
|
-
if (!a && !o) throw Error(`Guard '${typeof e == "string" ? e : e.type}' is not implemented.'.`);
|
|
652
|
-
if (typeof o != "function") return evaluateGuard(o, t, n, r);
|
|
653
|
-
let s = {
|
|
654
|
-
context: t,
|
|
655
|
-
event: n
|
|
656
|
-
}, c = a || typeof e == "string" ? void 0 : "params" in e ? typeof e.params == "function" ? e.params({
|
|
657
|
-
context: t,
|
|
658
|
-
event: n
|
|
659
|
-
}) : e.params : void 0;
|
|
660
|
-
return "check" in o ? o.check(r, s, o) : o(s, c);
|
|
661
|
-
}
|
|
662
|
-
function isAtomicStateNode(e) {
|
|
663
|
-
return e.type === "atomic" || e.type === "final";
|
|
664
|
-
}
|
|
665
|
-
function getChildren(e) {
|
|
666
|
-
return Object.values(e.states).filter((e) => e.type !== "history");
|
|
667
|
-
}
|
|
668
|
-
function getProperAncestors(e, t) {
|
|
669
|
-
let n = [];
|
|
670
|
-
if (t === e) return n;
|
|
671
|
-
let r = e.parent;
|
|
672
|
-
for (; r && r !== t;) n.push(r), r = r.parent;
|
|
673
|
-
return n;
|
|
1057
|
+
actorScope.defer(() => {
|
|
1058
|
+
actorScope.stopChild(actorRef);
|
|
1059
|
+
});
|
|
674
1060
|
}
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
1061
|
+
/**
|
|
1062
|
+
* Stops a child actor.
|
|
1063
|
+
*
|
|
1064
|
+
* @param actorRef The actor to stop.
|
|
1065
|
+
*/
|
|
1066
|
+
function stopChild(actorRef) {
|
|
1067
|
+
function stop(_args, _params) {}
|
|
1068
|
+
stop.type = "xstate.stopChild";
|
|
1069
|
+
stop.actorRef = actorRef;
|
|
1070
|
+
stop.resolve = resolveStop;
|
|
1071
|
+
stop.execute = executeStop;
|
|
1072
|
+
return stop;
|
|
1073
|
+
}
|
|
1074
|
+
function checkNot(snapshot, { context, event }, { guards }) {
|
|
1075
|
+
return !evaluateGuard(guards[0], context, event, snapshot);
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Higher-order guard that evaluates to `true` if the `guard` passed to it
|
|
1079
|
+
* evaluates to `false`.
|
|
1080
|
+
*
|
|
1081
|
+
* @category Guards
|
|
1082
|
+
* @example
|
|
1083
|
+
*
|
|
1084
|
+
* ```ts
|
|
1085
|
+
* import { setup, not } from 'xstate';
|
|
1086
|
+
*
|
|
1087
|
+
* const machine = setup({
|
|
1088
|
+
* guards: {
|
|
1089
|
+
* someNamedGuard: () => false
|
|
1090
|
+
* }
|
|
1091
|
+
* }).createMachine({
|
|
1092
|
+
* on: {
|
|
1093
|
+
* someEvent: {
|
|
1094
|
+
* guard: not('someNamedGuard'),
|
|
1095
|
+
* actions: () => {
|
|
1096
|
+
* // will be executed if guard in `not(...)`
|
|
1097
|
+
* // evaluates to `false`
|
|
1098
|
+
* }
|
|
1099
|
+
* }
|
|
1100
|
+
* }
|
|
1101
|
+
* });
|
|
1102
|
+
* ```
|
|
1103
|
+
*
|
|
1104
|
+
* @returns A guard
|
|
1105
|
+
*/
|
|
1106
|
+
function not(guard) {
|
|
1107
|
+
function not(_args, _params) {
|
|
1108
|
+
return false;
|
|
1109
|
+
}
|
|
1110
|
+
not.check = checkNot;
|
|
1111
|
+
not.guards = [guard];
|
|
1112
|
+
return not;
|
|
1113
|
+
}
|
|
1114
|
+
function checkAnd(snapshot, { context, event }, { guards }) {
|
|
1115
|
+
return guards.every((guard) => evaluateGuard(guard, context, event, snapshot));
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Higher-order guard that evaluates to `true` if all `guards` passed to it
|
|
1119
|
+
* evaluate to `true`.
|
|
1120
|
+
*
|
|
1121
|
+
* @category Guards
|
|
1122
|
+
* @example
|
|
1123
|
+
*
|
|
1124
|
+
* ```ts
|
|
1125
|
+
* import { setup, and } from 'xstate';
|
|
1126
|
+
*
|
|
1127
|
+
* const machine = setup({
|
|
1128
|
+
* guards: {
|
|
1129
|
+
* someNamedGuard: () => true
|
|
1130
|
+
* }
|
|
1131
|
+
* }).createMachine({
|
|
1132
|
+
* on: {
|
|
1133
|
+
* someEvent: {
|
|
1134
|
+
* guard: and([({ context }) => context.value > 0, 'someNamedGuard']),
|
|
1135
|
+
* actions: () => {
|
|
1136
|
+
* // will be executed if all guards in `and(...)`
|
|
1137
|
+
* // evaluate to true
|
|
1138
|
+
* }
|
|
1139
|
+
* }
|
|
1140
|
+
* }
|
|
1141
|
+
* });
|
|
1142
|
+
* ```
|
|
1143
|
+
*
|
|
1144
|
+
* @returns A guard action object
|
|
1145
|
+
*/
|
|
1146
|
+
function and(guards) {
|
|
1147
|
+
function and(_args, _params) {
|
|
1148
|
+
return false;
|
|
1149
|
+
}
|
|
1150
|
+
and.check = checkAnd;
|
|
1151
|
+
and.guards = guards;
|
|
1152
|
+
return and;
|
|
1153
|
+
}
|
|
1154
|
+
function checkOr(snapshot, { context, event }, { guards }) {
|
|
1155
|
+
return guards.some((guard) => evaluateGuard(guard, context, event, snapshot));
|
|
1156
|
+
}
|
|
1157
|
+
/**
|
|
1158
|
+
* Higher-order guard that evaluates to `true` if any of the `guards` passed to
|
|
1159
|
+
* it evaluate to `true`.
|
|
1160
|
+
*
|
|
1161
|
+
* @category Guards
|
|
1162
|
+
* @example
|
|
1163
|
+
*
|
|
1164
|
+
* ```ts
|
|
1165
|
+
* import { setup, or } from 'xstate';
|
|
1166
|
+
*
|
|
1167
|
+
* const machine = setup({
|
|
1168
|
+
* guards: {
|
|
1169
|
+
* someNamedGuard: () => true
|
|
1170
|
+
* }
|
|
1171
|
+
* }).createMachine({
|
|
1172
|
+
* on: {
|
|
1173
|
+
* someEvent: {
|
|
1174
|
+
* guard: or([({ context }) => context.value > 0, 'someNamedGuard']),
|
|
1175
|
+
* actions: () => {
|
|
1176
|
+
* // will be executed if any of the guards in `or(...)`
|
|
1177
|
+
* // evaluate to true
|
|
1178
|
+
* }
|
|
1179
|
+
* }
|
|
1180
|
+
* }
|
|
1181
|
+
* });
|
|
1182
|
+
* ```
|
|
1183
|
+
*
|
|
1184
|
+
* @returns A guard action object
|
|
1185
|
+
*/
|
|
1186
|
+
function or(guards) {
|
|
1187
|
+
function or(_args, _params) {
|
|
1188
|
+
return false;
|
|
1189
|
+
}
|
|
1190
|
+
or.check = checkOr;
|
|
1191
|
+
or.guards = guards;
|
|
1192
|
+
return or;
|
|
1193
|
+
}
|
|
1194
|
+
function evaluateGuard(guard, context, event, snapshot) {
|
|
1195
|
+
const { machine } = snapshot;
|
|
1196
|
+
const isInline = typeof guard === "function";
|
|
1197
|
+
const resolved = isInline ? guard : machine.implementations.guards[typeof guard === "string" ? guard : guard.type];
|
|
1198
|
+
if (!isInline && !resolved) throw new Error(`Guard '${typeof guard === "string" ? guard : guard.type}' is not implemented.'.`);
|
|
1199
|
+
if (typeof resolved !== "function") return evaluateGuard(resolved, context, event, snapshot);
|
|
1200
|
+
const guardArgs = {
|
|
1201
|
+
context,
|
|
1202
|
+
event
|
|
1203
|
+
};
|
|
1204
|
+
const guardParams = isInline || typeof guard === "string" ? void 0 : "params" in guard ? typeof guard.params === "function" ? guard.params({
|
|
1205
|
+
context,
|
|
1206
|
+
event
|
|
1207
|
+
}) : guard.params : void 0;
|
|
1208
|
+
if (!("check" in resolved)) return resolved(guardArgs, guardParams);
|
|
1209
|
+
return resolved.check(snapshot, guardArgs, resolved);
|
|
1210
|
+
}
|
|
1211
|
+
function isAtomicStateNode(stateNode) {
|
|
1212
|
+
return stateNode.type === "atomic" || stateNode.type === "final";
|
|
1213
|
+
}
|
|
1214
|
+
function getChildren(stateNode) {
|
|
1215
|
+
return Object.values(stateNode.states).filter((sn) => sn.type !== "history");
|
|
1216
|
+
}
|
|
1217
|
+
function getProperAncestors(stateNode, toStateNode) {
|
|
1218
|
+
const ancestors = [];
|
|
1219
|
+
if (toStateNode === stateNode) return ancestors;
|
|
1220
|
+
let m = stateNode.parent;
|
|
1221
|
+
while (m && m !== toStateNode) {
|
|
1222
|
+
ancestors.push(m);
|
|
1223
|
+
m = m.parent;
|
|
1224
|
+
}
|
|
1225
|
+
return ancestors;
|
|
1226
|
+
}
|
|
1227
|
+
function getAllStateNodes(stateNodes) {
|
|
1228
|
+
const nodeSet = new Set(stateNodes);
|
|
1229
|
+
const adjList = getAdjList(nodeSet);
|
|
1230
|
+
for (const s of nodeSet) if (s.type === "compound" && (!adjList.get(s) || !adjList.get(s).length)) getInitialStateNodesWithTheirAncestors(s).forEach((sn) => nodeSet.add(sn));
|
|
1231
|
+
else if (s.type === "parallel") for (const child of getChildren(s)) {
|
|
1232
|
+
if (child.type === "history") continue;
|
|
1233
|
+
if (!nodeSet.has(child)) {
|
|
1234
|
+
const initialStates = getInitialStateNodesWithTheirAncestors(child);
|
|
1235
|
+
for (const initialStateNode of initialStates) nodeSet.add(initialStateNode);
|
|
682
1236
|
}
|
|
683
1237
|
}
|
|
684
|
-
for (
|
|
685
|
-
let
|
|
686
|
-
|
|
1238
|
+
for (const s of nodeSet) {
|
|
1239
|
+
let m = s.parent;
|
|
1240
|
+
while (m) {
|
|
1241
|
+
nodeSet.add(m);
|
|
1242
|
+
m = m.parent;
|
|
1243
|
+
}
|
|
687
1244
|
}
|
|
688
|
-
return
|
|
1245
|
+
return nodeSet;
|
|
689
1246
|
}
|
|
690
|
-
function getValueFromAdj(
|
|
691
|
-
|
|
692
|
-
if (!
|
|
693
|
-
if (
|
|
694
|
-
|
|
695
|
-
if (
|
|
696
|
-
if (isAtomicStateNode(
|
|
1247
|
+
function getValueFromAdj(baseNode, adjList) {
|
|
1248
|
+
const childStateNodes = adjList.get(baseNode);
|
|
1249
|
+
if (!childStateNodes) return {};
|
|
1250
|
+
if (baseNode.type === "compound") {
|
|
1251
|
+
const childStateNode = childStateNodes[0];
|
|
1252
|
+
if (childStateNode) {
|
|
1253
|
+
if (isAtomicStateNode(childStateNode)) return childStateNode.key;
|
|
697
1254
|
} else return {};
|
|
698
1255
|
}
|
|
699
|
-
|
|
700
|
-
for (
|
|
701
|
-
return
|
|
702
|
-
}
|
|
703
|
-
function getAdjList(
|
|
704
|
-
|
|
705
|
-
for (
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
return
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
1256
|
+
const stateValue = {};
|
|
1257
|
+
for (const childStateNode of childStateNodes) stateValue[childStateNode.key] = getValueFromAdj(childStateNode, adjList);
|
|
1258
|
+
return stateValue;
|
|
1259
|
+
}
|
|
1260
|
+
function getAdjList(stateNodes) {
|
|
1261
|
+
const adjList = /* @__PURE__ */ new Map();
|
|
1262
|
+
for (const s of stateNodes) {
|
|
1263
|
+
if (!adjList.has(s)) adjList.set(s, []);
|
|
1264
|
+
if (s.parent) {
|
|
1265
|
+
if (!adjList.has(s.parent)) adjList.set(s.parent, []);
|
|
1266
|
+
adjList.get(s.parent).push(s);
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
return adjList;
|
|
1270
|
+
}
|
|
1271
|
+
function getStateValue(rootNode, stateNodes) {
|
|
1272
|
+
return getValueFromAdj(rootNode, getAdjList(getAllStateNodes(stateNodes)));
|
|
1273
|
+
}
|
|
1274
|
+
function isInFinalState(stateNodeSet, stateNode) {
|
|
1275
|
+
if (stateNode.type === "compound") return getChildren(stateNode).some((s) => s.type === "final" && stateNodeSet.has(s));
|
|
1276
|
+
if (stateNode.type === "parallel") return getChildren(stateNode).every((sn) => isInFinalState(stateNodeSet, sn));
|
|
1277
|
+
return stateNode.type === "final";
|
|
1278
|
+
}
|
|
1279
|
+
var isStateId = (str) => str[0] === STATE_IDENTIFIER;
|
|
1280
|
+
function getCandidates(stateNode, receivedEventType) {
|
|
1281
|
+
const exactMatch = stateNode.transitions.get(receivedEventType);
|
|
1282
|
+
const wildcardCandidates = [...stateNode.transitions.keys()].filter((eventDescriptor) => eventDescriptor !== receivedEventType && matchesEventDescriptor(receivedEventType, eventDescriptor)).sort((a, b) => b.length - a.length).flatMap((key) => stateNode.transitions.get(key));
|
|
1283
|
+
return exactMatch ? [...exactMatch, ...wildcardCandidates] : wildcardCandidates;
|
|
1284
|
+
}
|
|
1285
|
+
/** All delayed transitions from the config. */
|
|
1286
|
+
function getDelayedTransitions(stateNode) {
|
|
1287
|
+
const afterConfig = stateNode.config.after;
|
|
1288
|
+
if (!afterConfig) return [];
|
|
1289
|
+
const mutateEntryExit = (delay) => {
|
|
1290
|
+
const afterEvent = createAfterEvent(delay, stateNode.id);
|
|
1291
|
+
const eventType = afterEvent.type;
|
|
1292
|
+
stateNode.entry.push(raise(afterEvent, {
|
|
1293
|
+
id: eventType,
|
|
1294
|
+
delay
|
|
1295
|
+
}));
|
|
1296
|
+
stateNode.exit.push(cancel(eventType));
|
|
1297
|
+
return eventType;
|
|
728
1298
|
};
|
|
729
|
-
return Object.keys(
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
1299
|
+
return Object.keys(afterConfig).flatMap((delay) => {
|
|
1300
|
+
const configTransition = afterConfig[delay];
|
|
1301
|
+
const resolvedTransition = typeof configTransition === "string" ? { target: configTransition } : configTransition;
|
|
1302
|
+
const resolvedDelay = Number.isNaN(+delay) ? delay : +delay;
|
|
1303
|
+
const eventType = mutateEntryExit(resolvedDelay);
|
|
1304
|
+
return toArray(resolvedTransition).map((transition) => ({
|
|
1305
|
+
...transition,
|
|
1306
|
+
event: eventType,
|
|
1307
|
+
delay: resolvedDelay
|
|
735
1308
|
}));
|
|
736
|
-
}).map((
|
|
737
|
-
|
|
1309
|
+
}).map((delayedTransition) => {
|
|
1310
|
+
const { delay } = delayedTransition;
|
|
738
1311
|
return {
|
|
739
|
-
...formatTransition(
|
|
740
|
-
delay
|
|
1312
|
+
...formatTransition(stateNode, delayedTransition.event, delayedTransition),
|
|
1313
|
+
delay
|
|
741
1314
|
};
|
|
742
1315
|
});
|
|
743
1316
|
}
|
|
744
|
-
function formatTransition(
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
1317
|
+
function formatTransition(stateNode, descriptor, transitionConfig) {
|
|
1318
|
+
const normalizedTarget = normalizeTarget(transitionConfig.target);
|
|
1319
|
+
const reenter = transitionConfig.reenter ?? false;
|
|
1320
|
+
const target = resolveTarget(stateNode, normalizedTarget);
|
|
1321
|
+
const transition = {
|
|
1322
|
+
...transitionConfig,
|
|
1323
|
+
actions: toArray(transitionConfig.actions),
|
|
1324
|
+
guard: transitionConfig.guard,
|
|
1325
|
+
target,
|
|
1326
|
+
source: stateNode,
|
|
1327
|
+
reenter,
|
|
1328
|
+
eventType: descriptor,
|
|
753
1329
|
toJSON: () => ({
|
|
754
|
-
...
|
|
755
|
-
source: `#${
|
|
756
|
-
target:
|
|
1330
|
+
...transition,
|
|
1331
|
+
source: `#${stateNode.id}`,
|
|
1332
|
+
target: target ? target.map((t) => `#${t.id}`) : void 0
|
|
757
1333
|
})
|
|
758
1334
|
};
|
|
759
|
-
return
|
|
760
|
-
}
|
|
761
|
-
function formatTransitions(
|
|
762
|
-
|
|
763
|
-
if (
|
|
764
|
-
if (
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
}
|
|
768
|
-
if (
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
}
|
|
772
|
-
for (
|
|
773
|
-
if (
|
|
774
|
-
|
|
775
|
-
|
|
1335
|
+
return transition;
|
|
1336
|
+
}
|
|
1337
|
+
function formatTransitions(stateNode) {
|
|
1338
|
+
const transitions = /* @__PURE__ */ new Map();
|
|
1339
|
+
if (stateNode.config.on) for (const descriptor of Object.keys(stateNode.config.on)) {
|
|
1340
|
+
if (descriptor === "") throw new Error("Null events (\"\") cannot be specified as a transition key. Use `always: { ... }` instead.");
|
|
1341
|
+
const transitionsConfig = stateNode.config.on[descriptor];
|
|
1342
|
+
transitions.set(descriptor, toTransitionConfigArray(transitionsConfig).map((t) => formatTransition(stateNode, descriptor, t)));
|
|
1343
|
+
}
|
|
1344
|
+
if (stateNode.config.onDone) {
|
|
1345
|
+
const descriptor = `xstate.done.state.${stateNode.id}`;
|
|
1346
|
+
transitions.set(descriptor, toTransitionConfigArray(stateNode.config.onDone).map((t) => formatTransition(stateNode, descriptor, t)));
|
|
1347
|
+
}
|
|
1348
|
+
for (const invokeDef of stateNode.invoke) {
|
|
1349
|
+
if (invokeDef.onDone) {
|
|
1350
|
+
const descriptor = `xstate.done.actor.${invokeDef.id}`;
|
|
1351
|
+
transitions.set(descriptor, toTransitionConfigArray(invokeDef.onDone).map((t) => formatTransition(stateNode, descriptor, t)));
|
|
776
1352
|
}
|
|
777
|
-
if (
|
|
778
|
-
|
|
779
|
-
|
|
1353
|
+
if (invokeDef.onError) {
|
|
1354
|
+
const descriptor = `xstate.error.actor.${invokeDef.id}`;
|
|
1355
|
+
transitions.set(descriptor, toTransitionConfigArray(invokeDef.onError).map((t) => formatTransition(stateNode, descriptor, t)));
|
|
780
1356
|
}
|
|
781
|
-
if (
|
|
782
|
-
|
|
783
|
-
|
|
1357
|
+
if (invokeDef.onSnapshot) {
|
|
1358
|
+
const descriptor = `xstate.snapshot.${invokeDef.id}`;
|
|
1359
|
+
transitions.set(descriptor, toTransitionConfigArray(invokeDef.onSnapshot).map((t) => formatTransition(stateNode, descriptor, t)));
|
|
784
1360
|
}
|
|
785
1361
|
}
|
|
786
|
-
for (
|
|
787
|
-
let
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
1362
|
+
for (const delayedTransition of stateNode.after) {
|
|
1363
|
+
let existing = transitions.get(delayedTransition.eventType);
|
|
1364
|
+
if (!existing) {
|
|
1365
|
+
existing = [];
|
|
1366
|
+
transitions.set(delayedTransition.eventType, existing);
|
|
1367
|
+
}
|
|
1368
|
+
existing.push(delayedTransition);
|
|
1369
|
+
}
|
|
1370
|
+
return transitions;
|
|
1371
|
+
}
|
|
1372
|
+
/**
|
|
1373
|
+
* Collects route transitions from all descendants with explicit IDs. Called
|
|
1374
|
+
* once on the root node to avoid O(N²) repeated traversals.
|
|
1375
|
+
*/
|
|
1376
|
+
function formatRouteTransitions(rootStateNode) {
|
|
1377
|
+
const routeTransitions = [];
|
|
1378
|
+
const collectRoutes = (states) => {
|
|
1379
|
+
Object.values(states).forEach((sn) => {
|
|
1380
|
+
if (sn.config.route && sn.config.id) {
|
|
1381
|
+
const routeId = sn.config.id;
|
|
1382
|
+
const userGuard = sn.config.route.guard;
|
|
1383
|
+
const routeMatches = ({ event }) => event.to === `#${routeId}`;
|
|
1384
|
+
const transition = {
|
|
1385
|
+
...sn.config.route,
|
|
1386
|
+
guard: userGuard ? and([routeMatches, userGuard]) : routeMatches,
|
|
1387
|
+
target: `#${routeId}`
|
|
800
1388
|
};
|
|
801
|
-
|
|
1389
|
+
routeTransitions.push(formatTransition(rootStateNode, "xstate.route", transition));
|
|
802
1390
|
}
|
|
803
|
-
|
|
1391
|
+
if (sn.states) collectRoutes(sn.states);
|
|
804
1392
|
});
|
|
805
1393
|
};
|
|
806
|
-
collectRoutes(
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
1394
|
+
collectRoutes(rootStateNode.states);
|
|
1395
|
+
if (routeTransitions.length > 0) rootStateNode.transitions.set("xstate.route", routeTransitions);
|
|
1396
|
+
}
|
|
1397
|
+
function formatInitialTransition(stateNode, _target) {
|
|
1398
|
+
const resolvedTarget = typeof _target === "string" ? stateNode.states[_target] : _target ? stateNode.states[_target.target] : void 0;
|
|
1399
|
+
if (!resolvedTarget && _target) throw new Error(`Initial state node "${_target}" not found on parent state node #${stateNode.id}`);
|
|
1400
|
+
const transition = {
|
|
1401
|
+
source: stateNode,
|
|
1402
|
+
actions: !_target || typeof _target === "string" ? [] : toArray(_target.actions),
|
|
814
1403
|
eventType: null,
|
|
815
|
-
reenter:
|
|
816
|
-
target:
|
|
1404
|
+
reenter: false,
|
|
1405
|
+
target: resolvedTarget ? [resolvedTarget] : [],
|
|
1406
|
+
meta: typeof _target === "object" ? _target.meta : void 0,
|
|
1407
|
+
description: typeof _target === "object" ? _target.description : void 0,
|
|
817
1408
|
toJSON: () => ({
|
|
818
|
-
...
|
|
819
|
-
source: `#${
|
|
820
|
-
target:
|
|
1409
|
+
...transition,
|
|
1410
|
+
source: `#${stateNode.id}`,
|
|
1411
|
+
target: resolvedTarget ? [`#${resolvedTarget.id}`] : []
|
|
821
1412
|
})
|
|
822
1413
|
};
|
|
823
|
-
return
|
|
824
|
-
}
|
|
825
|
-
function resolveTarget(
|
|
826
|
-
if (
|
|
827
|
-
|
|
828
|
-
if (
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
1414
|
+
return transition;
|
|
1415
|
+
}
|
|
1416
|
+
function resolveTarget(stateNode, targets) {
|
|
1417
|
+
if (targets === void 0) return;
|
|
1418
|
+
return targets.map((target) => {
|
|
1419
|
+
if (typeof target !== "string") return target;
|
|
1420
|
+
if (isStateId(target)) return stateNode.machine.getStateNodeById(target);
|
|
1421
|
+
const isInternalTarget = target[0] === ".";
|
|
1422
|
+
if (isInternalTarget && !stateNode.parent) return getStateNodeByPath(stateNode, target.slice(1));
|
|
1423
|
+
const resolvedTarget = isInternalTarget ? stateNode.key + target : target;
|
|
1424
|
+
if (stateNode.parent) try {
|
|
1425
|
+
return getStateNodeByPath(stateNode.parent, resolvedTarget);
|
|
1426
|
+
} catch (err) {
|
|
1427
|
+
throw new Error(`Invalid transition definition for state node '${stateNode.id}':\n${err.message}`);
|
|
836
1428
|
}
|
|
837
|
-
throw Error(`Invalid target: "${
|
|
1429
|
+
else throw new Error(`Invalid target: "${target}" is not a valid target from the root node. Did you mean ".${target}"?`);
|
|
838
1430
|
});
|
|
839
1431
|
}
|
|
840
|
-
function resolveHistoryDefaultTransition(
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
if (
|
|
871
|
-
|
|
1432
|
+
function resolveHistoryDefaultTransition(stateNode) {
|
|
1433
|
+
const normalizedTarget = normalizeTarget(stateNode.config.target);
|
|
1434
|
+
if (!normalizedTarget) {
|
|
1435
|
+
if (stateNode.parent.type === "parallel") return { target: [stateNode.parent] };
|
|
1436
|
+
return stateNode.parent.initial;
|
|
1437
|
+
}
|
|
1438
|
+
return { target: normalizedTarget.map((t) => typeof t === "string" ? getStateNodeByPath(stateNode.parent, t) : t) };
|
|
1439
|
+
}
|
|
1440
|
+
function isHistoryNode(stateNode) {
|
|
1441
|
+
return stateNode.type === "history";
|
|
1442
|
+
}
|
|
1443
|
+
function getInitialStateNodesWithTheirAncestors(stateNode) {
|
|
1444
|
+
const states = getInitialStateNodes(stateNode);
|
|
1445
|
+
for (const initialState of states) for (const ancestor of getProperAncestors(initialState, stateNode)) states.add(ancestor);
|
|
1446
|
+
return states;
|
|
1447
|
+
}
|
|
1448
|
+
function getInitialStateNodes(stateNode) {
|
|
1449
|
+
const set = /* @__PURE__ */ new Set();
|
|
1450
|
+
function iter(descStateNode) {
|
|
1451
|
+
if (set.has(descStateNode)) return;
|
|
1452
|
+
set.add(descStateNode);
|
|
1453
|
+
if (descStateNode.type === "compound") iter(descStateNode.initial.target[0]);
|
|
1454
|
+
else if (descStateNode.type === "parallel") for (const child of getChildren(descStateNode)) iter(child);
|
|
1455
|
+
}
|
|
1456
|
+
iter(stateNode);
|
|
1457
|
+
return set;
|
|
1458
|
+
}
|
|
1459
|
+
/** Returns the child state node from its relative `stateKey`, or throws. */
|
|
1460
|
+
function getStateNode(stateNode, stateKey) {
|
|
1461
|
+
if (isStateId(stateKey)) return stateNode.machine.getStateNodeById(stateKey);
|
|
1462
|
+
if (!stateNode.states) throw new Error(`Unable to retrieve child state '${stateKey}' from '${stateNode.id}'; no child states exist.`);
|
|
1463
|
+
const result = stateNode.states[stateKey];
|
|
1464
|
+
if (!result) throw new Error(`Child state '${stateKey}' does not exist on '${stateNode.id}'`);
|
|
1465
|
+
return result;
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
* Returns the relative state node from the given `statePath`, or throws.
|
|
1469
|
+
*
|
|
1470
|
+
* @param statePath The string or string array relative path to the state node.
|
|
1471
|
+
*/
|
|
1472
|
+
function getStateNodeByPath(stateNode, statePath) {
|
|
1473
|
+
if (typeof statePath === "string" && isStateId(statePath)) try {
|
|
1474
|
+
return stateNode.machine.getStateNodeById(statePath);
|
|
872
1475
|
} catch {}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
if (!
|
|
891
|
-
|
|
892
|
-
|
|
1476
|
+
const arrayStatePath = toStatePath(statePath).slice();
|
|
1477
|
+
let currentStateNode = stateNode;
|
|
1478
|
+
while (arrayStatePath.length) {
|
|
1479
|
+
const key = arrayStatePath.shift();
|
|
1480
|
+
if (!key.length) break;
|
|
1481
|
+
currentStateNode = getStateNode(currentStateNode, key);
|
|
1482
|
+
}
|
|
1483
|
+
return currentStateNode;
|
|
1484
|
+
}
|
|
1485
|
+
/**
|
|
1486
|
+
* Returns the state nodes represented by the current state value.
|
|
1487
|
+
*
|
|
1488
|
+
* @param stateValue The state value or State instance
|
|
1489
|
+
*/
|
|
1490
|
+
function getStateNodes(stateNode, stateValue) {
|
|
1491
|
+
if (typeof stateValue === "string") {
|
|
1492
|
+
const childStateNode = stateNode.states[stateValue];
|
|
1493
|
+
if (!childStateNode) throw new Error(`State '${stateValue}' does not exist on '${stateNode.id}'`);
|
|
1494
|
+
return [stateNode, childStateNode];
|
|
1495
|
+
}
|
|
1496
|
+
const childStateKeys = Object.keys(stateValue);
|
|
1497
|
+
const childStateNodes = childStateKeys.map((subStateKey) => getStateNode(stateNode, subStateKey)).filter(Boolean);
|
|
1498
|
+
return [stateNode.machine.root, stateNode].concat(childStateNodes, childStateKeys.reduce((allSubStateNodes, subStateKey) => {
|
|
1499
|
+
const subStateNode = getStateNode(stateNode, subStateKey);
|
|
1500
|
+
if (!subStateNode) return allSubStateNodes;
|
|
1501
|
+
const subStateNodes = getStateNodes(subStateNode, stateValue[subStateKey]);
|
|
1502
|
+
return allSubStateNodes.concat(subStateNodes);
|
|
893
1503
|
}, []));
|
|
894
1504
|
}
|
|
895
|
-
function transitionAtomicNode(
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
return
|
|
929
|
-
}
|
|
930
|
-
function
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1505
|
+
function transitionAtomicNode(stateNode, stateValue, snapshot, event) {
|
|
1506
|
+
const next = getStateNode(stateNode, stateValue).next(snapshot, event);
|
|
1507
|
+
if (!next || !next.length) return stateNode.next(snapshot, event);
|
|
1508
|
+
return next;
|
|
1509
|
+
}
|
|
1510
|
+
function transitionCompoundNode(stateNode, stateValue, snapshot, event) {
|
|
1511
|
+
const subStateKeys = Object.keys(stateValue);
|
|
1512
|
+
const next = transitionNode(getStateNode(stateNode, subStateKeys[0]), stateValue[subStateKeys[0]], snapshot, event);
|
|
1513
|
+
if (!next || !next.length) return stateNode.next(snapshot, event);
|
|
1514
|
+
return next;
|
|
1515
|
+
}
|
|
1516
|
+
function transitionParallelNode(stateNode, stateValue, snapshot, event) {
|
|
1517
|
+
const allInnerTransitions = [];
|
|
1518
|
+
for (const subStateKey of Object.keys(stateValue)) {
|
|
1519
|
+
const subStateValue = stateValue[subStateKey];
|
|
1520
|
+
if (!subStateValue) continue;
|
|
1521
|
+
const innerTransitions = transitionNode(getStateNode(stateNode, subStateKey), subStateValue, snapshot, event);
|
|
1522
|
+
if (innerTransitions) allInnerTransitions.push(...innerTransitions);
|
|
1523
|
+
}
|
|
1524
|
+
if (!allInnerTransitions.length) return stateNode.next(snapshot, event);
|
|
1525
|
+
return allInnerTransitions;
|
|
1526
|
+
}
|
|
1527
|
+
function transitionNode(stateNode, stateValue, snapshot, event) {
|
|
1528
|
+
if (typeof stateValue === "string") return transitionAtomicNode(stateNode, stateValue, snapshot, event);
|
|
1529
|
+
if (Object.keys(stateValue).length === 1) return transitionCompoundNode(stateNode, stateValue, snapshot, event);
|
|
1530
|
+
return transitionParallelNode(stateNode, stateValue, snapshot, event);
|
|
1531
|
+
}
|
|
1532
|
+
function getHistoryNodes(stateNode) {
|
|
1533
|
+
return Object.keys(stateNode.states).map((key) => stateNode.states[key]).filter((sn) => sn.type === "history");
|
|
1534
|
+
}
|
|
1535
|
+
function isDescendant(childStateNode, parentStateNode) {
|
|
1536
|
+
let marker = childStateNode;
|
|
1537
|
+
while (marker.parent && marker.parent !== parentStateNode) marker = marker.parent;
|
|
1538
|
+
return marker.parent === parentStateNode;
|
|
1539
|
+
}
|
|
1540
|
+
function hasIntersection(s1, s2) {
|
|
1541
|
+
const set1 = new Set(s1);
|
|
1542
|
+
const set2 = new Set(s2);
|
|
1543
|
+
for (const item of set1) if (set2.has(item)) return true;
|
|
1544
|
+
for (const item of set2) if (set1.has(item)) return true;
|
|
1545
|
+
return false;
|
|
1546
|
+
}
|
|
1547
|
+
function removeConflictingTransitions(enabledTransitions, stateNodeSet, historyValue) {
|
|
1548
|
+
const filteredTransitions = /* @__PURE__ */ new Set();
|
|
1549
|
+
for (const t1 of enabledTransitions) {
|
|
1550
|
+
let t1Preempted = false;
|
|
1551
|
+
const transitionsToRemove = /* @__PURE__ */ new Set();
|
|
1552
|
+
for (const t2 of filteredTransitions) if (hasIntersection(computeExitSet([t1], stateNodeSet, historyValue), computeExitSet([t2], stateNodeSet, historyValue))) {
|
|
1553
|
+
if (isDescendant(t1.source, t2.source)) transitionsToRemove.add(t2);
|
|
936
1554
|
else {
|
|
937
|
-
|
|
1555
|
+
t1Preempted = true;
|
|
938
1556
|
break;
|
|
939
1557
|
}
|
|
940
1558
|
}
|
|
941
|
-
if (!
|
|
942
|
-
for (
|
|
943
|
-
|
|
1559
|
+
if (!t1Preempted) {
|
|
1560
|
+
for (const t3 of transitionsToRemove) filteredTransitions.delete(t3);
|
|
1561
|
+
filteredTransitions.add(t1);
|
|
944
1562
|
}
|
|
945
1563
|
}
|
|
946
|
-
return Array.from(
|
|
947
|
-
}
|
|
948
|
-
function findLeastCommonAncestor(
|
|
949
|
-
|
|
950
|
-
for (
|
|
951
|
-
}
|
|
952
|
-
function getEffectiveTargetStates(
|
|
953
|
-
if (!
|
|
954
|
-
|
|
955
|
-
for (
|
|
956
|
-
if (
|
|
957
|
-
else for (
|
|
958
|
-
} else
|
|
959
|
-
return [...
|
|
960
|
-
}
|
|
961
|
-
function getTransitionDomain(
|
|
962
|
-
|
|
963
|
-
if (!
|
|
964
|
-
if (!
|
|
965
|
-
|
|
966
|
-
if (
|
|
967
|
-
if (
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
return
|
|
982
|
-
|
|
983
|
-
|
|
1564
|
+
return Array.from(filteredTransitions);
|
|
1565
|
+
}
|
|
1566
|
+
function findLeastCommonAncestor(stateNodes) {
|
|
1567
|
+
const [head, ...tail] = stateNodes;
|
|
1568
|
+
for (const ancestor of getProperAncestors(head, void 0)) if (tail.every((sn) => isDescendant(sn, ancestor))) return ancestor;
|
|
1569
|
+
}
|
|
1570
|
+
function getEffectiveTargetStates(transition, historyValue) {
|
|
1571
|
+
if (!transition.target) return [];
|
|
1572
|
+
const targets = /* @__PURE__ */ new Set();
|
|
1573
|
+
for (const targetNode of transition.target) if (isHistoryNode(targetNode)) {
|
|
1574
|
+
if (historyValue[targetNode.id]) for (const node of historyValue[targetNode.id]) targets.add(node);
|
|
1575
|
+
else for (const node of getEffectiveTargetStates(resolveHistoryDefaultTransition(targetNode), historyValue)) targets.add(node);
|
|
1576
|
+
} else targets.add(targetNode);
|
|
1577
|
+
return [...targets];
|
|
1578
|
+
}
|
|
1579
|
+
function getTransitionDomain(transition, historyValue) {
|
|
1580
|
+
const targetStates = getEffectiveTargetStates(transition, historyValue);
|
|
1581
|
+
if (!targetStates) return;
|
|
1582
|
+
if (!transition.reenter && targetStates.every((target) => target === transition.source || isDescendant(target, transition.source))) return transition.source;
|
|
1583
|
+
const lca = findLeastCommonAncestor(targetStates.concat(transition.source));
|
|
1584
|
+
if (lca) return lca;
|
|
1585
|
+
if (transition.reenter) return;
|
|
1586
|
+
return transition.source.machine.root;
|
|
1587
|
+
}
|
|
1588
|
+
function computeExitSet(transitions, stateNodeSet, historyValue) {
|
|
1589
|
+
const statesToExit = /* @__PURE__ */ new Set();
|
|
1590
|
+
for (const t of transitions) if (t.target?.length) {
|
|
1591
|
+
const domain = getTransitionDomain(t, historyValue);
|
|
1592
|
+
if (t.reenter && t.source === domain) statesToExit.add(domain);
|
|
1593
|
+
for (const stateNode of stateNodeSet) if (isDescendant(stateNode, domain)) statesToExit.add(stateNode);
|
|
1594
|
+
}
|
|
1595
|
+
return [...statesToExit];
|
|
1596
|
+
}
|
|
1597
|
+
function areStateNodeCollectionsEqual(prevStateNodes, nextStateNodeSet) {
|
|
1598
|
+
if (prevStateNodes.length !== nextStateNodeSet.size) return false;
|
|
1599
|
+
for (const node of prevStateNodes) if (!nextStateNodeSet.has(node)) return false;
|
|
1600
|
+
return true;
|
|
1601
|
+
}
|
|
1602
|
+
function initialMicrostep(root, preInitialState, actorScope, initEvent, internalQueue) {
|
|
984
1603
|
return microstep([{
|
|
985
|
-
target: [...getInitialStateNodes(
|
|
986
|
-
source:
|
|
987
|
-
reenter:
|
|
1604
|
+
target: [...getInitialStateNodes(root)],
|
|
1605
|
+
source: root,
|
|
1606
|
+
reenter: true,
|
|
988
1607
|
actions: [],
|
|
989
1608
|
eventType: null,
|
|
990
1609
|
toJSON: null
|
|
991
|
-
}],
|
|
992
|
-
}
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1610
|
+
}], preInitialState, actorScope, initEvent, true, internalQueue);
|
|
1611
|
+
}
|
|
1612
|
+
/** https://www.w3.org/TR/scxml/#microstepProcedure */
|
|
1613
|
+
function microstep(transitions, currentSnapshot, actorScope, event, isInitial, internalQueue) {
|
|
1614
|
+
const actions = [];
|
|
1615
|
+
if (!transitions.length) return [currentSnapshot, actions];
|
|
1616
|
+
const originalExecutor = actorScope.actionExecutor;
|
|
1617
|
+
actorScope.actionExecutor = (action) => {
|
|
1618
|
+
actions.push(action);
|
|
1619
|
+
originalExecutor(action);
|
|
999
1620
|
};
|
|
1000
1621
|
try {
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1622
|
+
const mutStateNodeSet = new Set(currentSnapshot._nodes);
|
|
1623
|
+
let historyValue = currentSnapshot.historyValue;
|
|
1624
|
+
const filteredTransitions = removeConflictingTransitions(transitions, mutStateNodeSet, historyValue);
|
|
1625
|
+
let nextState = currentSnapshot;
|
|
1626
|
+
if (!isInitial) [nextState, historyValue] = exitStates(nextState, event, actorScope, filteredTransitions, mutStateNodeSet, historyValue, internalQueue, actorScope.actionExecutor);
|
|
1627
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, filteredTransitions.flatMap((t) => t.actions), internalQueue, void 0);
|
|
1628
|
+
nextState = enterStates(nextState, event, actorScope, filteredTransitions, mutStateNodeSet, internalQueue, historyValue, isInitial);
|
|
1629
|
+
const nextStateNodes = [...mutStateNodeSet];
|
|
1630
|
+
if (nextState.status === "done") nextState = resolveActionsAndContext(nextState, event, actorScope, nextStateNodes.sort((a, b) => b.order - a.order).flatMap((state) => state.exit), internalQueue, void 0);
|
|
1005
1631
|
try {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1632
|
+
if (historyValue === currentSnapshot.historyValue && areStateNodeCollectionsEqual(currentSnapshot._nodes, mutStateNodeSet)) return [nextState, actions];
|
|
1633
|
+
return [cloneMachineSnapshot(nextState, {
|
|
1634
|
+
_nodes: nextStateNodes,
|
|
1635
|
+
historyValue
|
|
1636
|
+
}), actions];
|
|
1010
1637
|
} catch (e) {
|
|
1011
1638
|
throw e;
|
|
1012
1639
|
}
|
|
1013
1640
|
} finally {
|
|
1014
|
-
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
function getMachineOutput(
|
|
1018
|
-
if (
|
|
1019
|
-
|
|
1020
|
-
return resolveOutput(
|
|
1021
|
-
}
|
|
1022
|
-
function enterStates(
|
|
1023
|
-
let
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1641
|
+
actorScope.actionExecutor = originalExecutor;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
function getMachineOutput(snapshot, event, actorScope, rootNode, rootCompletionNode) {
|
|
1645
|
+
if (rootNode.output === void 0) return;
|
|
1646
|
+
const doneStateEvent = createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output !== void 0 && rootCompletionNode.parent ? resolveOutput(rootCompletionNode.output, snapshot.context, event, actorScope.self) : void 0);
|
|
1647
|
+
return resolveOutput(rootNode.output, snapshot.context, doneStateEvent, actorScope.self);
|
|
1648
|
+
}
|
|
1649
|
+
function enterStates(currentSnapshot, event, actorScope, filteredTransitions, mutStateNodeSet, internalQueue, historyValue, isInitial) {
|
|
1650
|
+
let nextSnapshot = currentSnapshot;
|
|
1651
|
+
const statesToEnter = /* @__PURE__ */ new Set();
|
|
1652
|
+
const statesForDefaultEntry = /* @__PURE__ */ new Set();
|
|
1653
|
+
computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1654
|
+
if (isInitial) statesForDefaultEntry.add(currentSnapshot.machine.root);
|
|
1655
|
+
const completedNodes = /* @__PURE__ */ new Set();
|
|
1656
|
+
for (const stateNodeToEnter of [...statesToEnter].sort((a, b) => a.order - b.order)) {
|
|
1657
|
+
mutStateNodeSet.add(stateNodeToEnter);
|
|
1658
|
+
const actions = [];
|
|
1659
|
+
actions.push(...stateNodeToEnter.entry);
|
|
1660
|
+
for (const invokeDef of stateNodeToEnter.invoke) actions.push(spawnChild(invokeDef.src, {
|
|
1661
|
+
...invokeDef,
|
|
1662
|
+
syncSnapshot: !!invokeDef.onSnapshot
|
|
1033
1663
|
}));
|
|
1034
|
-
if (
|
|
1035
|
-
|
|
1036
|
-
|
|
1664
|
+
if (statesForDefaultEntry.has(stateNodeToEnter)) {
|
|
1665
|
+
const initialActions = stateNodeToEnter.initial.actions;
|
|
1666
|
+
actions.push(...initialActions);
|
|
1037
1667
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1668
|
+
nextSnapshot = resolveActionsAndContext(nextSnapshot, event, actorScope, actions, internalQueue, stateNodeToEnter.invoke.map((invokeDef) => invokeDef.id));
|
|
1669
|
+
if (stateNodeToEnter.type === "final") {
|
|
1670
|
+
const parent = stateNodeToEnter.parent;
|
|
1671
|
+
let ancestorMarker = parent?.type === "parallel" ? parent : parent?.parent;
|
|
1672
|
+
let rootCompletionNode = ancestorMarker || stateNodeToEnter;
|
|
1673
|
+
if (parent?.type === "compound") internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output !== void 0 ? resolveOutput(stateNodeToEnter.output, nextSnapshot.context, event, actorScope.self) : void 0));
|
|
1674
|
+
while (ancestorMarker?.type === "parallel" && !completedNodes.has(ancestorMarker) && isInFinalState(mutStateNodeSet, ancestorMarker)) {
|
|
1675
|
+
completedNodes.add(ancestorMarker);
|
|
1676
|
+
internalQueue.push(createDoneStateEvent(ancestorMarker.id));
|
|
1677
|
+
rootCompletionNode = ancestorMarker;
|
|
1678
|
+
ancestorMarker = ancestorMarker.parent;
|
|
1679
|
+
}
|
|
1680
|
+
if (ancestorMarker) continue;
|
|
1681
|
+
nextSnapshot = cloneMachineSnapshot(nextSnapshot, {
|
|
1043
1682
|
status: "done",
|
|
1044
|
-
output: getMachineOutput(
|
|
1683
|
+
output: getMachineOutput(nextSnapshot, event, actorScope, nextSnapshot.machine.root, rootCompletionNode)
|
|
1045
1684
|
});
|
|
1046
1685
|
}
|
|
1047
1686
|
}
|
|
1048
|
-
return
|
|
1687
|
+
return nextSnapshot;
|
|
1049
1688
|
}
|
|
1050
|
-
function computeEntrySet(
|
|
1051
|
-
for (
|
|
1052
|
-
|
|
1053
|
-
for (
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1689
|
+
function computeEntrySet(transitions, historyValue, statesForDefaultEntry, statesToEnter) {
|
|
1690
|
+
for (const t of transitions) {
|
|
1691
|
+
const domain = getTransitionDomain(t, historyValue);
|
|
1692
|
+
for (const s of t.target || []) {
|
|
1693
|
+
if (!isHistoryNode(s) && (t.source !== s || t.source !== domain || t.reenter)) {
|
|
1694
|
+
statesToEnter.add(s);
|
|
1695
|
+
statesForDefaultEntry.add(s);
|
|
1696
|
+
}
|
|
1697
|
+
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1698
|
+
}
|
|
1699
|
+
const targetStates = getEffectiveTargetStates(t, historyValue);
|
|
1700
|
+
for (const s of targetStates) {
|
|
1701
|
+
const ancestors = getProperAncestors(s, domain);
|
|
1702
|
+
if (domain?.type === "parallel") ancestors.push(domain);
|
|
1703
|
+
addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, !t.source.parent && t.reenter ? void 0 : domain);
|
|
1058
1704
|
}
|
|
1059
1705
|
}
|
|
1060
1706
|
}
|
|
1061
|
-
function addDescendantStatesToEnter(
|
|
1062
|
-
if (isHistoryNode(
|
|
1063
|
-
if (
|
|
1064
|
-
|
|
1065
|
-
for (
|
|
1066
|
-
|
|
1707
|
+
function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEntry, statesToEnter) {
|
|
1708
|
+
if (isHistoryNode(stateNode)) {
|
|
1709
|
+
if (historyValue[stateNode.id]) {
|
|
1710
|
+
const historyStateNodes = historyValue[stateNode.id];
|
|
1711
|
+
for (const s of historyStateNodes) {
|
|
1712
|
+
statesToEnter.add(s);
|
|
1713
|
+
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1714
|
+
}
|
|
1715
|
+
for (const s of historyStateNodes) addProperAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1067
1716
|
} else {
|
|
1068
|
-
|
|
1069
|
-
for (
|
|
1070
|
-
|
|
1717
|
+
const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
|
|
1718
|
+
for (const s of historyDefaultTransition.target) {
|
|
1719
|
+
statesToEnter.add(s);
|
|
1720
|
+
if (historyDefaultTransition === stateNode.parent?.initial) statesForDefaultEntry.add(stateNode.parent);
|
|
1721
|
+
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1722
|
+
}
|
|
1723
|
+
for (const s of historyDefaultTransition.target) addProperAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1724
|
+
}
|
|
1725
|
+
} else if (stateNode.type === "compound") {
|
|
1726
|
+
const [initialState] = stateNode.initial.target;
|
|
1727
|
+
if (!isHistoryNode(initialState)) {
|
|
1728
|
+
statesToEnter.add(initialState);
|
|
1729
|
+
statesForDefaultEntry.add(initialState);
|
|
1730
|
+
}
|
|
1731
|
+
addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1732
|
+
addProperAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1733
|
+
} else if (stateNode.type === "parallel") {
|
|
1734
|
+
for (const child of getChildren(stateNode).filter((sn) => !isHistoryNode(sn))) if (![...statesToEnter].some((s) => isDescendant(s, child))) {
|
|
1735
|
+
if (!isHistoryNode(child)) {
|
|
1736
|
+
statesToEnter.add(child);
|
|
1737
|
+
statesForDefaultEntry.add(child);
|
|
1738
|
+
}
|
|
1739
|
+
addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1071
1740
|
}
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
function addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, reentrancyDomain) {
|
|
1744
|
+
for (const anc of ancestors) {
|
|
1745
|
+
if (!reentrancyDomain || isDescendant(anc, reentrancyDomain)) statesToEnter.add(anc);
|
|
1746
|
+
if (anc.type === "parallel") {
|
|
1747
|
+
for (const child of getChildren(anc).filter((sn) => !isHistoryNode(sn))) if (![...statesToEnter].some((s) => isDescendant(s, child))) {
|
|
1748
|
+
statesToEnter.add(child);
|
|
1749
|
+
addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
function addProperAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
|
|
1755
|
+
addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, getProperAncestors(stateNode, toStateNode));
|
|
1756
|
+
}
|
|
1757
|
+
function exitStates(currentSnapshot, event, actorScope, transitions, mutStateNodeSet, historyValue, internalQueue, _actionExecutor) {
|
|
1758
|
+
let nextSnapshot = currentSnapshot;
|
|
1759
|
+
const statesToExit = computeExitSet(transitions, mutStateNodeSet, historyValue);
|
|
1760
|
+
statesToExit.sort((a, b) => b.order - a.order);
|
|
1761
|
+
let changedHistory;
|
|
1762
|
+
for (const exitStateNode of statesToExit) for (const historyNode of getHistoryNodes(exitStateNode)) {
|
|
1763
|
+
let predicate;
|
|
1764
|
+
if (historyNode.history === "deep") predicate = (sn) => isAtomicStateNode(sn) && isDescendant(sn, exitStateNode);
|
|
1765
|
+
else predicate = (sn) => {
|
|
1766
|
+
return sn.parent === exitStateNode;
|
|
1767
|
+
};
|
|
1768
|
+
changedHistory ??= { ...historyValue };
|
|
1769
|
+
changedHistory[historyNode.id] = Array.from(mutStateNodeSet).filter(predicate);
|
|
1770
|
+
}
|
|
1771
|
+
for (const s of statesToExit) {
|
|
1772
|
+
nextSnapshot = resolveActionsAndContext(nextSnapshot, event, actorScope, [...s.exit, ...s.invoke.map((def) => stopChild(def.id))], internalQueue, void 0);
|
|
1773
|
+
mutStateNodeSet.delete(s);
|
|
1774
|
+
}
|
|
1775
|
+
return [nextSnapshot, changedHistory || historyValue];
|
|
1776
|
+
}
|
|
1777
|
+
function getAction(machine, actionType) {
|
|
1778
|
+
return machine.implementations.actions[actionType];
|
|
1779
|
+
}
|
|
1780
|
+
function resolveAndExecuteActionsWithContext(currentSnapshot, event, actorScope, actions, extra, retries) {
|
|
1781
|
+
const { machine } = currentSnapshot;
|
|
1782
|
+
let intermediateSnapshot = currentSnapshot;
|
|
1783
|
+
for (const action of actions) {
|
|
1784
|
+
const isInline = typeof action === "function";
|
|
1785
|
+
const resolvedAction = isInline ? action : getAction(machine, typeof action === "string" ? action : action.type);
|
|
1786
|
+
const actionArgs = {
|
|
1787
|
+
context: intermediateSnapshot.context,
|
|
1788
|
+
event,
|
|
1789
|
+
self: actorScope.self,
|
|
1790
|
+
system: actorScope.system
|
|
1791
|
+
};
|
|
1792
|
+
const actionParams = isInline || typeof action === "string" ? void 0 : "params" in action ? typeof action.params === "function" ? action.params({
|
|
1793
|
+
context: intermediateSnapshot.context,
|
|
1794
|
+
event
|
|
1795
|
+
}) : action.params : void 0;
|
|
1796
|
+
if (!resolvedAction || !("resolve" in resolvedAction)) {
|
|
1797
|
+
actorScope.actionExecutor({
|
|
1798
|
+
type: typeof action === "string" ? action : typeof action === "object" ? action.type : action.name || "(anonymous)",
|
|
1799
|
+
info: actionArgs,
|
|
1800
|
+
params: actionParams,
|
|
1801
|
+
exec: resolvedAction
|
|
1115
1802
|
});
|
|
1116
1803
|
continue;
|
|
1117
1804
|
}
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1805
|
+
const builtinAction = resolvedAction;
|
|
1806
|
+
const [nextState, params, actions] = builtinAction.resolve(actorScope, intermediateSnapshot, actionArgs, actionParams, resolvedAction, extra);
|
|
1807
|
+
intermediateSnapshot = nextState;
|
|
1808
|
+
if ("retryResolve" in builtinAction) retries?.push([builtinAction, params]);
|
|
1809
|
+
if ("execute" in builtinAction) actorScope.actionExecutor({
|
|
1810
|
+
type: builtinAction.type,
|
|
1811
|
+
info: actionArgs,
|
|
1812
|
+
params,
|
|
1813
|
+
exec: builtinAction.execute.bind(null, actorScope, params)
|
|
1814
|
+
});
|
|
1815
|
+
if (actions) intermediateSnapshot = resolveAndExecuteActionsWithContext(intermediateSnapshot, event, actorScope, actions, extra, retries);
|
|
1816
|
+
}
|
|
1817
|
+
return intermediateSnapshot;
|
|
1818
|
+
}
|
|
1819
|
+
function resolveActionsAndContext(currentSnapshot, event, actorScope, actions, internalQueue, deferredActorIds) {
|
|
1820
|
+
const retries = deferredActorIds ? [] : void 0;
|
|
1821
|
+
const nextState = resolveAndExecuteActionsWithContext(currentSnapshot, event, actorScope, actions, {
|
|
1822
|
+
internalQueue,
|
|
1823
|
+
deferredActorIds
|
|
1824
|
+
}, retries);
|
|
1825
|
+
retries?.forEach(([builtinAction, params]) => {
|
|
1826
|
+
builtinAction.retryResolve(actorScope, nextState, params);
|
|
1827
|
+
});
|
|
1828
|
+
return nextState;
|
|
1829
|
+
}
|
|
1830
|
+
function macrostep(snapshot, event, actorScope, internalQueue) {
|
|
1831
|
+
let nextSnapshot = snapshot;
|
|
1832
|
+
const microsteps = [];
|
|
1833
|
+
function addMicrostep(step, event, transitions) {
|
|
1834
|
+
actorScope.system._sendInspectionEvent({
|
|
1141
1835
|
type: "@xstate.microstep",
|
|
1142
|
-
actorRef:
|
|
1143
|
-
event
|
|
1144
|
-
snapshot:
|
|
1145
|
-
_transitions:
|
|
1146
|
-
})
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
if (s && !c.length) return i = cloneMachineSnapshot(e, {
|
|
1156
|
-
status: "error",
|
|
1157
|
-
error: t.error
|
|
1158
|
-
}), addMicrostep([i, []], t, []), {
|
|
1159
|
-
snapshot: i,
|
|
1160
|
-
microsteps: a
|
|
1836
|
+
actorRef: actorScope.self,
|
|
1837
|
+
event,
|
|
1838
|
+
snapshot: step[0],
|
|
1839
|
+
_transitions: transitions
|
|
1840
|
+
});
|
|
1841
|
+
microsteps.push(step);
|
|
1842
|
+
}
|
|
1843
|
+
if (event.type === "xstate.stop") {
|
|
1844
|
+
nextSnapshot = cloneMachineSnapshot(stopChildren(nextSnapshot, event, actorScope), { status: "stopped" });
|
|
1845
|
+
addMicrostep([nextSnapshot, []], event, []);
|
|
1846
|
+
return {
|
|
1847
|
+
snapshot: nextSnapshot,
|
|
1848
|
+
microsteps
|
|
1161
1849
|
};
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1850
|
+
}
|
|
1851
|
+
let nextEvent = event;
|
|
1852
|
+
if (nextEvent.type !== XSTATE_INIT) {
|
|
1853
|
+
const currentEvent = nextEvent;
|
|
1854
|
+
const isErr = isErrorActorEvent(currentEvent);
|
|
1855
|
+
const transitions = selectTransitions(currentEvent, nextSnapshot);
|
|
1856
|
+
if (isErr && !transitions.length) {
|
|
1857
|
+
nextSnapshot = cloneMachineSnapshot(snapshot, {
|
|
1858
|
+
status: "error",
|
|
1859
|
+
error: currentEvent.error
|
|
1860
|
+
});
|
|
1861
|
+
addMicrostep([nextSnapshot, []], currentEvent, []);
|
|
1862
|
+
return {
|
|
1863
|
+
snapshot: nextSnapshot,
|
|
1864
|
+
microsteps
|
|
1865
|
+
};
|
|
1866
|
+
}
|
|
1867
|
+
const step = microstep(transitions, snapshot, actorScope, nextEvent, false, internalQueue);
|
|
1868
|
+
nextSnapshot = step[0];
|
|
1869
|
+
addMicrostep(step, currentEvent, transitions);
|
|
1870
|
+
}
|
|
1871
|
+
let shouldSelectEventlessTransitions = true;
|
|
1872
|
+
const maxIterations = snapshot.machine.options?.maxIterations ?? Infinity;
|
|
1873
|
+
let iterationCount = 0;
|
|
1874
|
+
while (nextSnapshot.status === "active") {
|
|
1875
|
+
iterationCount++;
|
|
1876
|
+
if (iterationCount > maxIterations) throw new Error(`Infinite loop detected: the machine has processed more than ${maxIterations} microsteps without reaching a stable state. This usually happens when there's a cycle of transitions (e.g., eventless transitions or raised events causing state A -> B -> C -> A).`);
|
|
1877
|
+
let enabledTransitions = shouldSelectEventlessTransitions ? selectEventlessTransitions(nextSnapshot, nextEvent) : [];
|
|
1878
|
+
const previousState = enabledTransitions.length ? nextSnapshot : void 0;
|
|
1879
|
+
if (!enabledTransitions.length) {
|
|
1880
|
+
if (!internalQueue.length) break;
|
|
1881
|
+
nextEvent = internalQueue.shift();
|
|
1882
|
+
enabledTransitions = selectTransitions(nextEvent, nextSnapshot);
|
|
1172
1883
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1884
|
+
const step = microstep(enabledTransitions, nextSnapshot, actorScope, nextEvent, false, internalQueue);
|
|
1885
|
+
nextSnapshot = step[0];
|
|
1886
|
+
shouldSelectEventlessTransitions = nextSnapshot !== previousState;
|
|
1887
|
+
addMicrostep(step, nextEvent, enabledTransitions);
|
|
1175
1888
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1889
|
+
if (nextSnapshot.status !== "active") stopChildren(nextSnapshot, nextEvent, actorScope);
|
|
1890
|
+
return {
|
|
1891
|
+
snapshot: nextSnapshot,
|
|
1892
|
+
microsteps
|
|
1179
1893
|
};
|
|
1180
1894
|
}
|
|
1181
|
-
function stopChildren(
|
|
1182
|
-
return resolveActionsAndContext(
|
|
1895
|
+
function stopChildren(nextState, event, actorScope) {
|
|
1896
|
+
return resolveActionsAndContext(nextState, event, actorScope, Object.values(nextState.children).map((child) => stopChild(child)), [], void 0);
|
|
1183
1897
|
}
|
|
1184
|
-
function selectTransitions(
|
|
1185
|
-
return
|
|
1898
|
+
function selectTransitions(event, nextState) {
|
|
1899
|
+
return nextState.machine.getTransitionData(nextState, event);
|
|
1186
1900
|
}
|
|
1187
|
-
function selectEventlessTransitions(
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1901
|
+
function selectEventlessTransitions(nextState, event) {
|
|
1902
|
+
const enabledTransitionSet = /* @__PURE__ */ new Set();
|
|
1903
|
+
const atomicStates = nextState._nodes.filter(isAtomicStateNode);
|
|
1904
|
+
for (const stateNode of atomicStates) loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, void 0))) {
|
|
1905
|
+
if (!s.always) continue;
|
|
1906
|
+
for (const transition of s.always) if (transition.guard === void 0 || evaluateGuard(transition.guard, nextState.context, event, nextState)) {
|
|
1907
|
+
enabledTransitionSet.add(transition);
|
|
1192
1908
|
break loop;
|
|
1193
1909
|
}
|
|
1194
1910
|
}
|
|
1195
|
-
return removeConflictingTransitions(Array.from(
|
|
1911
|
+
return removeConflictingTransitions(Array.from(enabledTransitionSet), new Set(nextState._nodes), nextState.historyValue);
|
|
1196
1912
|
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1913
|
+
/**
|
|
1914
|
+
* Resolves a partial state value with its full representation in the state
|
|
1915
|
+
* node's machine.
|
|
1916
|
+
*
|
|
1917
|
+
* @param stateValue The partial state value to resolve.
|
|
1918
|
+
*/
|
|
1919
|
+
function resolveStateValue(rootNode, stateValue) {
|
|
1920
|
+
return getStateValue(rootNode, [...getAllStateNodes(getStateNodes(rootNode, stateValue))]);
|
|
1199
1921
|
}
|
|
1200
|
-
function isMachineSnapshot(
|
|
1201
|
-
return !!
|
|
1922
|
+
function isMachineSnapshot(value) {
|
|
1923
|
+
return !!value && typeof value === "object" && "machine" in value && "value" in value;
|
|
1202
1924
|
}
|
|
1203
|
-
var
|
|
1204
|
-
return matchesState(
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1925
|
+
var machineSnapshotMatches = function matches(testValue) {
|
|
1926
|
+
return matchesState(testValue, this.value);
|
|
1927
|
+
};
|
|
1928
|
+
var machineSnapshotHasTag = function hasTag(tag) {
|
|
1929
|
+
return this.tags.has(tag);
|
|
1930
|
+
};
|
|
1931
|
+
var machineSnapshotCan = function can(event) {
|
|
1932
|
+
const transitionData = this.machine.getTransitionData(this, event);
|
|
1933
|
+
return !!transitionData?.length && transitionData.some((t) => t.target !== void 0 || t.actions.length);
|
|
1934
|
+
};
|
|
1935
|
+
var machineSnapshotToJSON = function toJSON() {
|
|
1936
|
+
const { _nodes: nodes, tags, machine, getMeta, toJSON, can, hasTag, matches, ...jsonValues } = this;
|
|
1212
1937
|
return {
|
|
1213
|
-
...
|
|
1214
|
-
tags: Array.from(
|
|
1938
|
+
...jsonValues,
|
|
1939
|
+
tags: Array.from(tags)
|
|
1215
1940
|
};
|
|
1216
|
-
}, x = function getMeta() {
|
|
1217
|
-
return this._nodes.reduce((e, t) => (t.meta !== void 0 && (e[t.id] = t.meta), e), {});
|
|
1218
1941
|
};
|
|
1219
|
-
function
|
|
1942
|
+
var machineSnapshotGetMeta = function getMeta() {
|
|
1943
|
+
return this._nodes.reduce((acc, stateNode) => {
|
|
1944
|
+
if (stateNode.meta !== void 0) acc[stateNode.id] = stateNode.meta;
|
|
1945
|
+
return acc;
|
|
1946
|
+
}, {});
|
|
1947
|
+
};
|
|
1948
|
+
function createMachineSnapshot(config, machine) {
|
|
1220
1949
|
return {
|
|
1221
|
-
status:
|
|
1222
|
-
output:
|
|
1223
|
-
error:
|
|
1224
|
-
machine
|
|
1225
|
-
context:
|
|
1226
|
-
_nodes:
|
|
1227
|
-
value: getStateValue(
|
|
1228
|
-
tags: new Set(
|
|
1229
|
-
children:
|
|
1230
|
-
historyValue:
|
|
1231
|
-
matches:
|
|
1232
|
-
hasTag:
|
|
1233
|
-
can:
|
|
1234
|
-
getMeta:
|
|
1235
|
-
toJSON:
|
|
1950
|
+
status: config.status,
|
|
1951
|
+
output: config.output,
|
|
1952
|
+
error: config.error,
|
|
1953
|
+
machine,
|
|
1954
|
+
context: config.context,
|
|
1955
|
+
_nodes: config._nodes,
|
|
1956
|
+
value: getStateValue(machine.root, config._nodes),
|
|
1957
|
+
tags: new Set(config._nodes.flatMap((sn) => sn.tags)),
|
|
1958
|
+
children: config.children,
|
|
1959
|
+
historyValue: config.historyValue || {},
|
|
1960
|
+
matches: machineSnapshotMatches,
|
|
1961
|
+
hasTag: machineSnapshotHasTag,
|
|
1962
|
+
can: machineSnapshotCan,
|
|
1963
|
+
getMeta: machineSnapshotGetMeta,
|
|
1964
|
+
toJSON: machineSnapshotToJSON
|
|
1236
1965
|
};
|
|
1237
1966
|
}
|
|
1238
|
-
function cloneMachineSnapshot(
|
|
1967
|
+
function cloneMachineSnapshot(snapshot, config = {}) {
|
|
1239
1968
|
return createMachineSnapshot({
|
|
1240
|
-
...
|
|
1241
|
-
...
|
|
1242
|
-
},
|
|
1243
|
-
}
|
|
1244
|
-
function serializeHistoryValue(
|
|
1245
|
-
if (typeof
|
|
1246
|
-
|
|
1247
|
-
for (
|
|
1248
|
-
|
|
1249
|
-
Array.isArray(
|
|
1250
|
-
}
|
|
1251
|
-
return
|
|
1252
|
-
}
|
|
1253
|
-
function getPersistedSnapshot(
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1969
|
+
...snapshot,
|
|
1970
|
+
...config
|
|
1971
|
+
}, snapshot.machine);
|
|
1972
|
+
}
|
|
1973
|
+
function serializeHistoryValue(historyValue) {
|
|
1974
|
+
if (typeof historyValue !== "object" || historyValue === null) return {};
|
|
1975
|
+
const result = {};
|
|
1976
|
+
for (const key in historyValue) {
|
|
1977
|
+
const value = historyValue[key];
|
|
1978
|
+
if (Array.isArray(value)) result[key] = value.map((item) => ({ id: item.id }));
|
|
1979
|
+
}
|
|
1980
|
+
return result;
|
|
1981
|
+
}
|
|
1982
|
+
function getPersistedSnapshot(snapshot, options) {
|
|
1983
|
+
const { _nodes: nodes, tags, machine, children, context, can, hasTag, matches, getMeta, toJSON, ...jsonValues } = snapshot;
|
|
1984
|
+
const childrenJson = {};
|
|
1985
|
+
for (const id in children) {
|
|
1986
|
+
const child = children[id];
|
|
1987
|
+
childrenJson[id] = {
|
|
1988
|
+
snapshot: child.getPersistedSnapshot(options),
|
|
1989
|
+
src: child.src,
|
|
1990
|
+
systemId: child.systemId,
|
|
1991
|
+
syncSnapshot: child._syncSnapshot
|
|
1262
1992
|
};
|
|
1263
1993
|
}
|
|
1264
1994
|
return {
|
|
1265
|
-
...
|
|
1266
|
-
context: persistContext(
|
|
1267
|
-
children:
|
|
1268
|
-
historyValue: serializeHistoryValue(
|
|
1995
|
+
...jsonValues,
|
|
1996
|
+
context: persistContext(context),
|
|
1997
|
+
children: childrenJson,
|
|
1998
|
+
historyValue: serializeHistoryValue(jsonValues.historyValue)
|
|
1269
1999
|
};
|
|
1270
2000
|
}
|
|
1271
|
-
function persistContext(
|
|
1272
|
-
let
|
|
1273
|
-
for (
|
|
1274
|
-
|
|
1275
|
-
if (
|
|
1276
|
-
if ("sessionId" in
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
2001
|
+
function persistContext(contextPart) {
|
|
2002
|
+
let copy;
|
|
2003
|
+
for (const key in contextPart) {
|
|
2004
|
+
const value = contextPart[key];
|
|
2005
|
+
if (value && typeof value === "object") {
|
|
2006
|
+
if ("sessionId" in value && "send" in value && "ref" in value) {
|
|
2007
|
+
copy ??= Array.isArray(contextPart) ? contextPart.slice() : { ...contextPart };
|
|
2008
|
+
copy[key] = {
|
|
2009
|
+
xstate$$type: 1,
|
|
2010
|
+
id: value.id
|
|
2011
|
+
};
|
|
2012
|
+
} else {
|
|
2013
|
+
const result = persistContext(value);
|
|
2014
|
+
if (result !== value) {
|
|
2015
|
+
copy ??= Array.isArray(contextPart) ? contextPart.slice() : { ...contextPart };
|
|
2016
|
+
copy[key] = result;
|
|
2017
|
+
}
|
|
1283
2018
|
}
|
|
1284
2019
|
}
|
|
1285
2020
|
}
|
|
1286
|
-
return
|
|
1287
|
-
}
|
|
1288
|
-
function resolveRaise(
|
|
1289
|
-
|
|
1290
|
-
if (typeof
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
2021
|
+
return copy ?? contextPart;
|
|
2022
|
+
}
|
|
2023
|
+
function resolveRaise(_, snapshot, args, actionParams, { event: eventOrExpr, id, delay }, { internalQueue }) {
|
|
2024
|
+
const delaysMap = snapshot.machine.implementations.delays;
|
|
2025
|
+
if (typeof eventOrExpr === "string") throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
|
|
2026
|
+
const resolvedEvent = typeof eventOrExpr === "function" ? eventOrExpr(args, actionParams) : eventOrExpr;
|
|
2027
|
+
let resolvedDelay;
|
|
2028
|
+
if (typeof delay === "string") {
|
|
2029
|
+
const configDelay = delaysMap && delaysMap[delay];
|
|
2030
|
+
resolvedDelay = typeof configDelay === "function" ? configDelay(args, actionParams) : configDelay;
|
|
2031
|
+
} else resolvedDelay = typeof delay === "function" ? delay(args, actionParams) : delay;
|
|
2032
|
+
if (typeof resolvedDelay !== "number") internalQueue.push(resolvedEvent);
|
|
2033
|
+
return [
|
|
2034
|
+
snapshot,
|
|
1298
2035
|
{
|
|
1299
|
-
event:
|
|
1300
|
-
id
|
|
1301
|
-
delay:
|
|
2036
|
+
event: resolvedEvent,
|
|
2037
|
+
id,
|
|
2038
|
+
delay: resolvedDelay
|
|
1302
2039
|
},
|
|
1303
2040
|
void 0
|
|
1304
2041
|
];
|
|
1305
2042
|
}
|
|
1306
|
-
function executeRaise(
|
|
1307
|
-
|
|
1308
|
-
if (typeof
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
2043
|
+
function executeRaise(actorScope, params) {
|
|
2044
|
+
const { event, delay, id } = params;
|
|
2045
|
+
if (typeof delay === "number") {
|
|
2046
|
+
actorScope.defer(() => {
|
|
2047
|
+
const self = actorScope.self;
|
|
2048
|
+
actorScope.system.scheduler.schedule(self, self, event, delay, id);
|
|
1312
2049
|
});
|
|
1313
2050
|
return;
|
|
1314
2051
|
}
|
|
1315
2052
|
}
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
2053
|
+
/**
|
|
2054
|
+
* Raises an event. This places the event in the internal event queue, so that
|
|
2055
|
+
* the event is immediately consumed by the machine in the current step.
|
|
2056
|
+
*
|
|
2057
|
+
* @param eventType The event to raise.
|
|
2058
|
+
*/
|
|
2059
|
+
function raise(eventOrExpr, options) {
|
|
2060
|
+
function raise(_args, _params) {}
|
|
2061
|
+
raise.type = "xstate.raise";
|
|
2062
|
+
raise.event = eventOrExpr;
|
|
2063
|
+
raise.id = options?.id;
|
|
2064
|
+
raise.delay = options?.delay;
|
|
2065
|
+
raise.resolve = resolveRaise;
|
|
2066
|
+
raise.execute = executeRaise;
|
|
2067
|
+
return raise;
|
|
2068
|
+
}
|
|
2069
|
+
var instanceStates = /* #__PURE__ */ new WeakMap();
|
|
2070
|
+
/**
|
|
2071
|
+
* Represents an actor created by `fromCallback`.
|
|
2072
|
+
*
|
|
2073
|
+
* The type of `self` within the actor's logic.
|
|
2074
|
+
*
|
|
2075
|
+
* @example
|
|
2076
|
+
*
|
|
2077
|
+
* ```ts
|
|
2078
|
+
* import { fromCallback, createActor } from 'xstate';
|
|
2079
|
+
*
|
|
2080
|
+
* // The events the actor receives.
|
|
2081
|
+
* type Event = { type: 'someEvent' };
|
|
2082
|
+
* // The actor's input.
|
|
2083
|
+
* type Input = { name: string };
|
|
2084
|
+
*
|
|
2085
|
+
* // Actor logic that logs whenever it receives an event of type `someEvent`.
|
|
2086
|
+
* const logic = fromCallback<Event, Input>(({ self, input, receive }) => {
|
|
2087
|
+
* self;
|
|
2088
|
+
* // ^? CallbackActorRef<Event, Input>
|
|
2089
|
+
*
|
|
2090
|
+
* receive((event) => {
|
|
2091
|
+
* if (event.type === 'someEvent') {
|
|
2092
|
+
* console.log(`${input.name}: received "someEvent" event`);
|
|
2093
|
+
* // logs 'myActor: received "someEvent" event'
|
|
2094
|
+
* }
|
|
2095
|
+
* });
|
|
2096
|
+
* });
|
|
2097
|
+
*
|
|
2098
|
+
* const actor = createActor(logic, { input: { name: 'myActor' } });
|
|
2099
|
+
* // ^? CallbackActorRef<Event, Input>
|
|
2100
|
+
* ```
|
|
2101
|
+
*
|
|
2102
|
+
* @see {@link fromCallback}
|
|
2103
|
+
*/
|
|
2104
|
+
/**
|
|
2105
|
+
* An actor logic creator which returns callback logic as defined by a callback
|
|
2106
|
+
* function.
|
|
2107
|
+
*
|
|
2108
|
+
* @remarks
|
|
2109
|
+
* Useful for subscription-based or other free-form logic that can send events
|
|
2110
|
+
* back to the parent actor.
|
|
2111
|
+
*
|
|
2112
|
+
* Actors created from callback logic (“callback actors”) can:
|
|
2113
|
+
*
|
|
2114
|
+
* - Receive events via the `receive` function
|
|
2115
|
+
* - Send events to the parent actor via the `sendBack` function
|
|
2116
|
+
*
|
|
2117
|
+
* Callback actors are a bit different from other actors in that they:
|
|
2118
|
+
*
|
|
2119
|
+
* - Do not work with `onDone`
|
|
2120
|
+
* - Do not produce a snapshot using `.getSnapshot()`
|
|
2121
|
+
* - Do not emit values when used with `.subscribe()`
|
|
2122
|
+
* - Can not be stopped with `.stop()`
|
|
2123
|
+
*
|
|
2124
|
+
* @example
|
|
2125
|
+
*
|
|
2126
|
+
* ```typescript
|
|
2127
|
+
* const callbackLogic = fromCallback(({ sendBack, receive }) => {
|
|
2128
|
+
* let lockStatus = 'unlocked';
|
|
2129
|
+
*
|
|
2130
|
+
* const handler = (event) => {
|
|
2131
|
+
* if (lockStatus === 'locked') {
|
|
2132
|
+
* return;
|
|
2133
|
+
* }
|
|
2134
|
+
* sendBack(event);
|
|
2135
|
+
* };
|
|
2136
|
+
*
|
|
2137
|
+
* receive((event) => {
|
|
2138
|
+
* if (event.type === 'lock') {
|
|
2139
|
+
* lockStatus = 'locked';
|
|
2140
|
+
* } else if (event.type === 'unlock') {
|
|
2141
|
+
* lockStatus = 'unlocked';
|
|
2142
|
+
* }
|
|
2143
|
+
* });
|
|
2144
|
+
*
|
|
2145
|
+
* document.body.addEventListener('click', handler);
|
|
2146
|
+
*
|
|
2147
|
+
* return () => {
|
|
2148
|
+
* document.body.removeEventListener('click', handler);
|
|
2149
|
+
* };
|
|
2150
|
+
* });
|
|
2151
|
+
* ```
|
|
2152
|
+
*
|
|
2153
|
+
* @param callback - The callback function used to describe the callback logic
|
|
2154
|
+
* The callback function is passed an object with the following properties:
|
|
2155
|
+
*
|
|
2156
|
+
* - `receive` - A function that can send events back to the parent actor; the
|
|
2157
|
+
* listener is then called whenever events are received by the callback
|
|
2158
|
+
* actor
|
|
2159
|
+
* - `sendBack` - A function that can send events back to the parent actor
|
|
2160
|
+
* - `input` - Data that was provided to the callback actor
|
|
2161
|
+
* - `self` - The parent actor of the callback actor
|
|
2162
|
+
* - `system` - The actor system to which the callback actor belongs The callback
|
|
2163
|
+
* function can (optionally) return a cleanup function, which is called
|
|
2164
|
+
* when the actor is stopped.
|
|
2165
|
+
*
|
|
2166
|
+
* @returns Callback logic
|
|
2167
|
+
* @see {@link CallbackLogicFunction} for more information about the callback function and its object argument
|
|
2168
|
+
* @see {@link https://stately.ai/docs/input | Input docs} for more information about how input is passed
|
|
2169
|
+
*/
|
|
2170
|
+
function fromCallback(callback) {
|
|
1322
2171
|
return {
|
|
1323
|
-
config:
|
|
1324
|
-
start: (
|
|
1325
|
-
|
|
2172
|
+
config: callback,
|
|
2173
|
+
start: (state, actorScope) => {
|
|
2174
|
+
const { self, system, emit } = actorScope;
|
|
2175
|
+
const callbackState = {
|
|
1326
2176
|
receivers: void 0,
|
|
1327
2177
|
dispose: void 0
|
|
1328
2178
|
};
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
2179
|
+
instanceStates.set(self, callbackState);
|
|
2180
|
+
callbackState.dispose = callback({
|
|
2181
|
+
input: state.input,
|
|
2182
|
+
system,
|
|
2183
|
+
self,
|
|
2184
|
+
sendBack: (event) => {
|
|
2185
|
+
if (self.getSnapshot().status === "stopped") return;
|
|
2186
|
+
if (self._parent) system._relay(self, self._parent, event);
|
|
1335
2187
|
},
|
|
1336
|
-
receive: (
|
|
1337
|
-
|
|
2188
|
+
receive: (listener) => {
|
|
2189
|
+
callbackState.receivers ??= /* @__PURE__ */ new Set();
|
|
2190
|
+
callbackState.receivers.add(listener);
|
|
1338
2191
|
},
|
|
1339
|
-
emit
|
|
2192
|
+
emit
|
|
1340
2193
|
});
|
|
1341
2194
|
},
|
|
1342
|
-
transition: (
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
2195
|
+
transition: (state, event, actorScope) => {
|
|
2196
|
+
const callbackState = instanceStates.get(actorScope.self);
|
|
2197
|
+
if (event.type === "xstate.stop") {
|
|
2198
|
+
state = {
|
|
2199
|
+
...state,
|
|
2200
|
+
status: "stopped",
|
|
2201
|
+
error: void 0
|
|
2202
|
+
};
|
|
2203
|
+
instanceStates.delete(actorScope.self);
|
|
2204
|
+
callbackState.receivers?.clear();
|
|
2205
|
+
callbackState.dispose?.();
|
|
2206
|
+
return state;
|
|
2207
|
+
}
|
|
2208
|
+
callbackState.receivers?.forEach((receiver) => receiver(event));
|
|
2209
|
+
return state;
|
|
1349
2210
|
},
|
|
1350
|
-
getInitialSnapshot: (
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
2211
|
+
getInitialSnapshot: (_, input) => {
|
|
2212
|
+
return {
|
|
2213
|
+
status: "active",
|
|
2214
|
+
output: void 0,
|
|
2215
|
+
error: void 0,
|
|
2216
|
+
input
|
|
2217
|
+
};
|
|
2218
|
+
},
|
|
2219
|
+
getPersistedSnapshot: (snapshot) => snapshot,
|
|
2220
|
+
restoreSnapshot: (snapshot) => snapshot
|
|
1358
2221
|
};
|
|
1359
2222
|
}
|
|
1360
|
-
var
|
|
1361
|
-
|
|
2223
|
+
var XSTATE_PROMISE_RESOLVE = "xstate.promise.resolve";
|
|
2224
|
+
var XSTATE_PROMISE_REJECT = "xstate.promise.reject";
|
|
2225
|
+
/**
|
|
2226
|
+
* Represents an actor created by `fromPromise`.
|
|
2227
|
+
*
|
|
2228
|
+
* The type of `self` within the actor's logic.
|
|
2229
|
+
*
|
|
2230
|
+
* @example
|
|
2231
|
+
*
|
|
2232
|
+
* ```ts
|
|
2233
|
+
* import { fromPromise, createActor } from 'xstate';
|
|
2234
|
+
*
|
|
2235
|
+
* // The actor's resolved output
|
|
2236
|
+
* type Output = string;
|
|
2237
|
+
* // The actor's input.
|
|
2238
|
+
* type Input = { message: string };
|
|
2239
|
+
*
|
|
2240
|
+
* // Actor logic that fetches the url of an image of a cat saying `input.message`.
|
|
2241
|
+
* const logic = fromPromise<Output, Input>(async ({ input, self }) => {
|
|
2242
|
+
* self;
|
|
2243
|
+
* // ^? PromiseActorRef<Output, Input>
|
|
2244
|
+
*
|
|
2245
|
+
* const data = await fetch(
|
|
2246
|
+
* `https://cataas.com/cat/says/${input.message}`
|
|
2247
|
+
* );
|
|
2248
|
+
* const url = await data.json();
|
|
2249
|
+
* return url;
|
|
2250
|
+
* });
|
|
2251
|
+
*
|
|
2252
|
+
* const actor = createActor(logic, { input: { message: 'hello world' } });
|
|
2253
|
+
* // ^? PromiseActorRef<Output, Input>
|
|
2254
|
+
* ```
|
|
2255
|
+
*
|
|
2256
|
+
* @see {@link fromPromise}
|
|
2257
|
+
*/
|
|
2258
|
+
var controllerMap = /* @__PURE__ */ new WeakMap();
|
|
2259
|
+
/**
|
|
2260
|
+
* An actor logic creator which returns promise logic as defined by an async
|
|
2261
|
+
* process that resolves or rejects after some time.
|
|
2262
|
+
*
|
|
2263
|
+
* Actors created from promise actor logic (“promise actors”) can:
|
|
2264
|
+
*
|
|
2265
|
+
* - Emit the resolved value of the promise
|
|
2266
|
+
* - Output the resolved value of the promise
|
|
2267
|
+
*
|
|
2268
|
+
* Sending events to promise actors will have no effect.
|
|
2269
|
+
*
|
|
2270
|
+
* @example
|
|
2271
|
+
*
|
|
2272
|
+
* ```ts
|
|
2273
|
+
* const promiseLogic = fromPromise(async () => {
|
|
2274
|
+
* const result = await fetch('https://example.com/...').then((data) =>
|
|
2275
|
+
* data.json()
|
|
2276
|
+
* );
|
|
2277
|
+
*
|
|
2278
|
+
* return result;
|
|
2279
|
+
* });
|
|
2280
|
+
*
|
|
2281
|
+
* const promiseActor = createActor(promiseLogic);
|
|
2282
|
+
* promiseActor.subscribe((snapshot) => {
|
|
2283
|
+
* console.log(snapshot);
|
|
2284
|
+
* });
|
|
2285
|
+
* promiseActor.start();
|
|
2286
|
+
* // => {
|
|
2287
|
+
* // output: undefined,
|
|
2288
|
+
* // status: 'active'
|
|
2289
|
+
* // ...
|
|
2290
|
+
* // }
|
|
2291
|
+
*
|
|
2292
|
+
* // After promise resolves
|
|
2293
|
+
* // => {
|
|
2294
|
+
* // output: { ... },
|
|
2295
|
+
* // status: 'done',
|
|
2296
|
+
* // ...
|
|
2297
|
+
* // }
|
|
2298
|
+
* ```
|
|
2299
|
+
*
|
|
2300
|
+
* @param promiseCreator A function which returns a Promise, and accepts an
|
|
2301
|
+
* object with the following properties:
|
|
2302
|
+
*
|
|
2303
|
+
* - `input` - Data that was provided to the promise actor
|
|
2304
|
+
* - `self` - The parent actor of the promise actor
|
|
2305
|
+
* - `system` - The actor system to which the promise actor belongs
|
|
2306
|
+
*
|
|
2307
|
+
* @see {@link https://stately.ai/docs/input | Input docs} for more information about how input is passed
|
|
2308
|
+
*/
|
|
2309
|
+
function fromPromise(promiseCreator) {
|
|
1362
2310
|
return {
|
|
1363
|
-
config:
|
|
1364
|
-
transition: (
|
|
1365
|
-
if (
|
|
1366
|
-
switch (
|
|
1367
|
-
case
|
|
1368
|
-
|
|
2311
|
+
config: promiseCreator,
|
|
2312
|
+
transition: (state, event, scope) => {
|
|
2313
|
+
if (state.status !== "active") return state;
|
|
2314
|
+
switch (event.type) {
|
|
2315
|
+
case XSTATE_PROMISE_RESOLVE: {
|
|
2316
|
+
const resolvedValue = event.data;
|
|
1369
2317
|
return {
|
|
1370
|
-
...
|
|
2318
|
+
...state,
|
|
1371
2319
|
status: "done",
|
|
1372
|
-
output:
|
|
2320
|
+
output: resolvedValue,
|
|
1373
2321
|
input: void 0
|
|
1374
2322
|
};
|
|
1375
2323
|
}
|
|
1376
|
-
case
|
|
1377
|
-
...
|
|
2324
|
+
case XSTATE_PROMISE_REJECT: return {
|
|
2325
|
+
...state,
|
|
1378
2326
|
status: "error",
|
|
1379
|
-
error:
|
|
2327
|
+
error: event.data,
|
|
1380
2328
|
input: void 0
|
|
1381
2329
|
};
|
|
1382
|
-
case
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
2330
|
+
case XSTATE_STOP:
|
|
2331
|
+
controllerMap.get(scope.self)?.abort();
|
|
2332
|
+
controllerMap.delete(scope.self);
|
|
2333
|
+
return {
|
|
2334
|
+
...state,
|
|
2335
|
+
status: "stopped",
|
|
2336
|
+
input: void 0
|
|
2337
|
+
};
|
|
2338
|
+
default: return state;
|
|
1388
2339
|
}
|
|
1389
2340
|
},
|
|
1390
|
-
start: (
|
|
1391
|
-
if (
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
2341
|
+
start: (state, { self, system, emit }) => {
|
|
2342
|
+
if (state.status !== "active") return;
|
|
2343
|
+
const controller = new AbortController();
|
|
2344
|
+
controllerMap.set(self, controller);
|
|
2345
|
+
Promise.resolve(promiseCreator({
|
|
2346
|
+
input: state.input,
|
|
2347
|
+
system,
|
|
2348
|
+
self,
|
|
2349
|
+
signal: controller.signal,
|
|
2350
|
+
emit
|
|
2351
|
+
})).then((response) => {
|
|
2352
|
+
if (self.getSnapshot().status !== "active") return;
|
|
2353
|
+
controllerMap.delete(self);
|
|
2354
|
+
system._relay(self, self, {
|
|
2355
|
+
type: XSTATE_PROMISE_RESOLVE,
|
|
2356
|
+
data: response
|
|
2357
|
+
});
|
|
2358
|
+
}, (errorData) => {
|
|
2359
|
+
if (self.getSnapshot().status !== "active") return;
|
|
2360
|
+
controllerMap.delete(self);
|
|
2361
|
+
system._relay(self, self, {
|
|
2362
|
+
type: XSTATE_PROMISE_REJECT,
|
|
2363
|
+
data: errorData
|
|
2364
|
+
});
|
|
1409
2365
|
});
|
|
1410
2366
|
},
|
|
1411
|
-
getInitialSnapshot: (
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
2367
|
+
getInitialSnapshot: (_, input) => {
|
|
2368
|
+
return {
|
|
2369
|
+
status: "active",
|
|
2370
|
+
output: void 0,
|
|
2371
|
+
error: void 0,
|
|
2372
|
+
input
|
|
2373
|
+
};
|
|
2374
|
+
},
|
|
2375
|
+
getPersistedSnapshot: (snapshot) => snapshot,
|
|
2376
|
+
restoreSnapshot: (snapshot) => snapshot
|
|
1419
2377
|
};
|
|
1420
2378
|
}
|
|
1421
2379
|
//#endregion
|
|
1422
|
-
//#region ../../node_modules/.pnpm/xstate@5.
|
|
1423
|
-
function createSpawner(
|
|
1424
|
-
|
|
1425
|
-
if (typeof
|
|
1426
|
-
|
|
1427
|
-
if (!
|
|
1428
|
-
|
|
1429
|
-
id:
|
|
1430
|
-
parent:
|
|
1431
|
-
syncSnapshot:
|
|
1432
|
-
input: typeof
|
|
1433
|
-
context
|
|
1434
|
-
event
|
|
1435
|
-
self:
|
|
1436
|
-
}) :
|
|
1437
|
-
src
|
|
1438
|
-
systemId:
|
|
2380
|
+
//#region ../../node_modules/.pnpm/xstate@5.33.2/node_modules/xstate/dist/assign-b4b1f28f.esm.js
|
|
2381
|
+
function createSpawner(actorScope, { machine, context }, event, spawnedChildren) {
|
|
2382
|
+
const spawn = (src, options) => {
|
|
2383
|
+
if (typeof src === "string") {
|
|
2384
|
+
const logic = resolveReferencedActor(machine, src);
|
|
2385
|
+
if (!logic) throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
|
|
2386
|
+
const actorRef = createActor(logic, {
|
|
2387
|
+
id: options?.id,
|
|
2388
|
+
parent: actorScope.self,
|
|
2389
|
+
syncSnapshot: options?.syncSnapshot,
|
|
2390
|
+
input: typeof options?.input === "function" ? options.input({
|
|
2391
|
+
context,
|
|
2392
|
+
event,
|
|
2393
|
+
self: actorScope.self
|
|
2394
|
+
}) : options?.input,
|
|
2395
|
+
src,
|
|
2396
|
+
systemId: options?.systemId
|
|
1439
2397
|
});
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
return createActor(
|
|
1443
|
-
id:
|
|
1444
|
-
parent:
|
|
1445
|
-
syncSnapshot:
|
|
1446
|
-
input:
|
|
1447
|
-
src
|
|
1448
|
-
systemId:
|
|
2398
|
+
spawnedChildren[actorRef.id] = actorRef;
|
|
2399
|
+
return actorRef;
|
|
2400
|
+
} else return createActor(src, {
|
|
2401
|
+
id: options?.id,
|
|
2402
|
+
parent: actorScope.self,
|
|
2403
|
+
syncSnapshot: options?.syncSnapshot,
|
|
2404
|
+
input: options?.input,
|
|
2405
|
+
src,
|
|
2406
|
+
systemId: options?.systemId
|
|
1449
2407
|
});
|
|
1450
2408
|
};
|
|
1451
|
-
return (
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
2409
|
+
return (src, options) => {
|
|
2410
|
+
const actorRef = spawn(src, options);
|
|
2411
|
+
spawnedChildren[actorRef.id] = actorRef;
|
|
2412
|
+
actorScope.defer(() => {
|
|
2413
|
+
if (actorRef._processingStatus === ProcessingStatus.Stopped) return;
|
|
2414
|
+
actorRef.start();
|
|
2415
|
+
});
|
|
2416
|
+
return actorRef;
|
|
1456
2417
|
};
|
|
1457
2418
|
}
|
|
1458
|
-
function resolveAssign(
|
|
1459
|
-
if (!
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
2419
|
+
function resolveAssign(actorScope, snapshot, actionArgs, actionParams, { assignment }) {
|
|
2420
|
+
if (!snapshot.context) throw new Error("Cannot assign to undefined `context`. Ensure that `context` is defined in the machine config.");
|
|
2421
|
+
const spawnedChildren = {};
|
|
2422
|
+
const assignArgs = {
|
|
2423
|
+
context: snapshot.context,
|
|
2424
|
+
event: actionArgs.event,
|
|
2425
|
+
spawn: createSpawner(actorScope, snapshot, actionArgs.event, spawnedChildren),
|
|
2426
|
+
self: actorScope.self,
|
|
2427
|
+
system: actorScope.system
|
|
2428
|
+
};
|
|
2429
|
+
let partialUpdate = {};
|
|
2430
|
+
if (typeof assignment === "function") partialUpdate = assignment(assignArgs, actionParams);
|
|
2431
|
+
else for (const key of Object.keys(assignment)) {
|
|
2432
|
+
const propAssignment = assignment[key];
|
|
2433
|
+
partialUpdate[key] = typeof propAssignment === "function" ? propAssignment(assignArgs, actionParams) : propAssignment;
|
|
1471
2434
|
}
|
|
1472
2435
|
return [
|
|
1473
|
-
cloneMachineSnapshot(
|
|
1474
|
-
context: Object.assign({},
|
|
1475
|
-
children: Object.keys(
|
|
1476
|
-
...
|
|
1477
|
-
...
|
|
1478
|
-
} :
|
|
2436
|
+
cloneMachineSnapshot(snapshot, {
|
|
2437
|
+
context: Object.assign({}, snapshot.context, partialUpdate),
|
|
2438
|
+
children: Object.keys(spawnedChildren).length ? {
|
|
2439
|
+
...snapshot.children,
|
|
2440
|
+
...spawnedChildren
|
|
2441
|
+
} : snapshot.children
|
|
1479
2442
|
}),
|
|
1480
2443
|
void 0,
|
|
1481
2444
|
void 0
|
|
1482
2445
|
];
|
|
1483
2446
|
}
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
2447
|
+
/**
|
|
2448
|
+
* Updates the current context of the machine.
|
|
2449
|
+
*
|
|
2450
|
+
* @example
|
|
2451
|
+
*
|
|
2452
|
+
* ```ts
|
|
2453
|
+
* import { createMachine, assign } from 'xstate';
|
|
2454
|
+
*
|
|
2455
|
+
* const countMachine = createMachine({
|
|
2456
|
+
* context: {
|
|
2457
|
+
* count: 0,
|
|
2458
|
+
* message: ''
|
|
2459
|
+
* },
|
|
2460
|
+
* on: {
|
|
2461
|
+
* inc: {
|
|
2462
|
+
* actions: assign({
|
|
2463
|
+
* count: ({ context }) => context.count + 1
|
|
2464
|
+
* })
|
|
2465
|
+
* },
|
|
2466
|
+
* updateMessage: {
|
|
2467
|
+
* actions: assign(({ context, event }) => {
|
|
2468
|
+
* return {
|
|
2469
|
+
* message: event.message.trim()
|
|
2470
|
+
* };
|
|
2471
|
+
* })
|
|
2472
|
+
* }
|
|
2473
|
+
* }
|
|
2474
|
+
* });
|
|
2475
|
+
* ```
|
|
2476
|
+
*
|
|
2477
|
+
* @param assignment An object that represents the partial context to update, or
|
|
2478
|
+
* a function that returns an object that represents the partial context to
|
|
2479
|
+
* update.
|
|
2480
|
+
*/
|
|
2481
|
+
function assign(assignment) {
|
|
2482
|
+
function assign(_args, _params) {}
|
|
2483
|
+
assign.type = "xstate.assign";
|
|
2484
|
+
assign.assignment = assignment;
|
|
2485
|
+
assign.resolve = resolveAssign;
|
|
2486
|
+
return assign;
|
|
1487
2487
|
}
|
|
1488
2488
|
//#endregion
|
|
1489
|
-
//#region ../../node_modules/.pnpm/xstate@5.
|
|
1490
|
-
var
|
|
1491
|
-
function memo$1(
|
|
1492
|
-
let
|
|
1493
|
-
|
|
1494
|
-
}
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
2489
|
+
//#region ../../node_modules/.pnpm/xstate@5.33.2/node_modules/xstate/dist/StateMachine-521e1f66.esm.js
|
|
2490
|
+
var cache = /* @__PURE__ */ new WeakMap();
|
|
2491
|
+
function memo$1(object, key, fn) {
|
|
2492
|
+
let memoizedData = cache.get(object);
|
|
2493
|
+
if (!memoizedData) {
|
|
2494
|
+
memoizedData = { [key]: fn() };
|
|
2495
|
+
cache.set(object, memoizedData);
|
|
2496
|
+
} else if (!(key in memoizedData)) memoizedData[key] = fn();
|
|
2497
|
+
return memoizedData[key];
|
|
2498
|
+
}
|
|
2499
|
+
__name(memo$1, "memo");
|
|
2500
|
+
var EMPTY_OBJECT = {};
|
|
2501
|
+
var toSerializableAction = (action) => {
|
|
2502
|
+
if (typeof action === "string") return { type: action };
|
|
2503
|
+
if (typeof action === "function") {
|
|
2504
|
+
if ("resolve" in action) return { type: action.type };
|
|
2505
|
+
return { type: action.name };
|
|
2506
|
+
}
|
|
2507
|
+
return action;
|
|
2508
|
+
};
|
|
2509
|
+
var StateNode = class StateNode {
|
|
2510
|
+
constructor(config, options) {
|
|
2511
|
+
this.config = config;
|
|
2512
|
+
/**
|
|
2513
|
+
* The relative key of the state node, which represents its location in the
|
|
2514
|
+
* overall state value.
|
|
2515
|
+
*/
|
|
2516
|
+
this.key = void 0;
|
|
2517
|
+
/** The unique ID of the state node. */
|
|
2518
|
+
this.id = void 0;
|
|
2519
|
+
/**
|
|
2520
|
+
* The type of this state node:
|
|
2521
|
+
*
|
|
2522
|
+
* - `'atomic'` - no child state nodes
|
|
2523
|
+
* - `'compound'` - nested child state nodes (XOR)
|
|
2524
|
+
* - `'parallel'` - orthogonal nested child state nodes (AND)
|
|
2525
|
+
* - `'history'` - history state node
|
|
2526
|
+
* - `'final'` - final state node
|
|
2527
|
+
*/
|
|
2528
|
+
this.type = void 0;
|
|
2529
|
+
/** The string path from the root machine node to this node. */
|
|
2530
|
+
this.path = void 0;
|
|
2531
|
+
/** The child state nodes. */
|
|
2532
|
+
this.states = void 0;
|
|
2533
|
+
/**
|
|
2534
|
+
* The type of history on this state node. Can be:
|
|
2535
|
+
*
|
|
2536
|
+
* - `'shallow'` - recalls only top-level historical state value
|
|
2537
|
+
* - `'deep'` - recalls historical state value at all levels
|
|
2538
|
+
*/
|
|
2539
|
+
this.history = void 0;
|
|
2540
|
+
/** The action(s) to be executed upon entering the state node. */
|
|
2541
|
+
this.entry = void 0;
|
|
2542
|
+
/** The action(s) to be executed upon exiting the state node. */
|
|
2543
|
+
this.exit = void 0;
|
|
2544
|
+
/** The parent state node. */
|
|
2545
|
+
this.parent = void 0;
|
|
2546
|
+
/** The root machine node. */
|
|
2547
|
+
this.machine = void 0;
|
|
2548
|
+
/**
|
|
2549
|
+
* The meta data associated with this state node, which will be returned in
|
|
2550
|
+
* State instances.
|
|
2551
|
+
*/
|
|
2552
|
+
this.meta = void 0;
|
|
2553
|
+
/**
|
|
2554
|
+
* The output data sent with the "xstate.done.state._id_" event if this is a
|
|
2555
|
+
* final state node.
|
|
2556
|
+
*/
|
|
2557
|
+
this.output = void 0;
|
|
2558
|
+
/**
|
|
2559
|
+
* The order this state node appears. Corresponds to the implicit document
|
|
2560
|
+
* order.
|
|
2561
|
+
*/
|
|
2562
|
+
this.order = -1;
|
|
2563
|
+
this.description = void 0;
|
|
2564
|
+
this.tags = [];
|
|
2565
|
+
this.transitions = void 0;
|
|
2566
|
+
this.always = void 0;
|
|
2567
|
+
this.parent = options._parent;
|
|
2568
|
+
this.key = options._key;
|
|
2569
|
+
this.machine = options._machine;
|
|
2570
|
+
this.path = this.parent ? this.parent.path.concat(this.key) : [];
|
|
2571
|
+
this.id = this.config.id || [this.machine.id, ...this.path].join(".");
|
|
2572
|
+
this.type = this.config.type || (this.config.states && Object.keys(this.config.states).length ? "compound" : this.config.history ? "history" : "atomic");
|
|
2573
|
+
this.description = this.config.description;
|
|
2574
|
+
this.order = this.machine.idMap.size;
|
|
2575
|
+
this.machine.idMap.set(this.id, this);
|
|
2576
|
+
this.states = this.config.states ? mapValues(this.config.states, (stateConfig, key) => {
|
|
2577
|
+
return new StateNode(stateConfig, {
|
|
2578
|
+
_parent: this,
|
|
2579
|
+
_key: key,
|
|
2580
|
+
_machine: this.machine
|
|
2581
|
+
});
|
|
2582
|
+
}) : EMPTY_OBJECT;
|
|
2583
|
+
if (this.type === "compound" && !this.config.initial) throw new Error(`No initial state specified for compound state node "#${this.id}". Try adding { initial: "${Object.keys(this.states)[0]}" } to the state config.`);
|
|
2584
|
+
this.history = this.config.history === true ? "shallow" : this.config.history || false;
|
|
2585
|
+
this.entry = toArray(this.config.entry).slice();
|
|
2586
|
+
this.exit = toArray(this.config.exit).slice();
|
|
2587
|
+
this.meta = this.config.meta;
|
|
2588
|
+
this.output = this.type === "final" || !this.parent ? this.config.output : void 0;
|
|
2589
|
+
this.tags = toArray(config.tags).slice();
|
|
2590
|
+
}
|
|
2591
|
+
/** @internal */
|
|
1505
2592
|
_initialize() {
|
|
1506
|
-
this.transitions = formatTransitions(this)
|
|
1507
|
-
|
|
2593
|
+
this.transitions = formatTransitions(this);
|
|
2594
|
+
if (this.config.always) this.always = toTransitionConfigArray(this.config.always).map((t) => formatTransition(this, "", t));
|
|
2595
|
+
Object.keys(this.states).forEach((key) => {
|
|
2596
|
+
this.states[key]._initialize();
|
|
1508
2597
|
});
|
|
1509
2598
|
}
|
|
2599
|
+
/** The well-structured state node definition. */
|
|
1510
2600
|
get definition() {
|
|
1511
2601
|
return {
|
|
1512
2602
|
id: this.id,
|
|
@@ -1518,20 +2608,24 @@ var D = {}, toSerializableAction = (e) => typeof e == "string" ? { type: e } : t
|
|
|
1518
2608
|
source: this,
|
|
1519
2609
|
actions: this.initial.actions.map(toSerializableAction),
|
|
1520
2610
|
eventType: null,
|
|
1521
|
-
reenter:
|
|
2611
|
+
reenter: false,
|
|
2612
|
+
meta: this.initial.meta,
|
|
2613
|
+
description: this.initial.description,
|
|
1522
2614
|
toJSON: () => ({
|
|
1523
|
-
target: this.initial.target.map((
|
|
2615
|
+
target: this.initial.target.map((t) => `#${t.id}`),
|
|
1524
2616
|
source: `#${this.id}`,
|
|
1525
2617
|
actions: this.initial.actions.map(toSerializableAction),
|
|
1526
|
-
eventType: null
|
|
2618
|
+
eventType: null,
|
|
2619
|
+
meta: this.initial.meta,
|
|
2620
|
+
description: this.initial.description
|
|
1527
2621
|
})
|
|
1528
2622
|
} : void 0,
|
|
1529
2623
|
history: this.history,
|
|
1530
|
-
states: mapValues(this.states, (
|
|
2624
|
+
states: mapValues(this.states, (state) => state.definition),
|
|
1531
2625
|
on: this.on,
|
|
1532
|
-
transitions: [...this.transitions.values()].flat().map((
|
|
1533
|
-
...
|
|
1534
|
-
actions:
|
|
2626
|
+
transitions: [...this.transitions.values()].flat().map((t) => ({
|
|
2627
|
+
...t,
|
|
2628
|
+
actions: t.actions.map(toSerializableAction)
|
|
1535
2629
|
})),
|
|
1536
2630
|
entry: this.entry.map(toSerializableAction),
|
|
1537
2631
|
exit: this.exit.map(toSerializableAction),
|
|
@@ -1543,31 +2637,42 @@ var D = {}, toSerializableAction = (e) => typeof e == "string" ? { type: e } : t
|
|
|
1543
2637
|
tags: this.tags
|
|
1544
2638
|
};
|
|
1545
2639
|
}
|
|
2640
|
+
/** @internal */
|
|
1546
2641
|
toJSON() {
|
|
1547
2642
|
return this.definition;
|
|
1548
2643
|
}
|
|
2644
|
+
/** The logic invoked as actors by this state node. */
|
|
1549
2645
|
get invoke() {
|
|
1550
|
-
return memo$1(this, "invoke", () => toArray(this.config.invoke).map((
|
|
1551
|
-
|
|
2646
|
+
return memo$1(this, "invoke", () => toArray(this.config.invoke).map((invokeConfig, i) => {
|
|
2647
|
+
const { src, systemId } = invokeConfig;
|
|
2648
|
+
const resolvedId = invokeConfig.id ?? createInvokeId(this.id, i);
|
|
2649
|
+
const sourceName = typeof src === "string" ? src : `xstate.invoke.${createInvokeId(this.id, i)}`;
|
|
1552
2650
|
return {
|
|
1553
|
-
...
|
|
1554
|
-
src:
|
|
1555
|
-
id:
|
|
1556
|
-
systemId
|
|
2651
|
+
...invokeConfig,
|
|
2652
|
+
src: sourceName,
|
|
2653
|
+
id: resolvedId,
|
|
2654
|
+
systemId,
|
|
1557
2655
|
toJSON() {
|
|
1558
|
-
|
|
2656
|
+
const { onDone, onError, ...invokeDefValues } = invokeConfig;
|
|
1559
2657
|
return {
|
|
1560
|
-
...
|
|
2658
|
+
...invokeDefValues,
|
|
1561
2659
|
type: "xstate.invoke",
|
|
1562
|
-
src:
|
|
1563
|
-
id:
|
|
2660
|
+
src: sourceName,
|
|
2661
|
+
id: resolvedId
|
|
1564
2662
|
};
|
|
1565
2663
|
}
|
|
1566
2664
|
};
|
|
1567
2665
|
}));
|
|
1568
2666
|
}
|
|
2667
|
+
/** The mapping of events to transitions. */
|
|
1569
2668
|
get on() {
|
|
1570
|
-
return memo$1(this, "on", () =>
|
|
2669
|
+
return memo$1(this, "on", () => {
|
|
2670
|
+
return [...this.transitions].flatMap(([descriptor, t]) => t.map((t) => [descriptor, t])).reduce((map, [descriptor, transition]) => {
|
|
2671
|
+
map[descriptor] = map[descriptor] || [];
|
|
2672
|
+
map[descriptor].push(transition);
|
|
2673
|
+
return map;
|
|
2674
|
+
}, {});
|
|
2675
|
+
});
|
|
1571
2676
|
}
|
|
1572
2677
|
get after() {
|
|
1573
2678
|
return memo$1(this, "delayedTransitions", () => getDelayedTransitions(this));
|
|
@@ -1575,138 +2680,224 @@ var D = {}, toSerializableAction = (e) => typeof e == "string" ? { type: e } : t
|
|
|
1575
2680
|
get initial() {
|
|
1576
2681
|
return memo$1(this, "initial", () => formatInitialTransition(this, this.config.initial));
|
|
1577
2682
|
}
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
2683
|
+
/** @internal */
|
|
2684
|
+
next(snapshot, event) {
|
|
2685
|
+
const eventType = event.type;
|
|
2686
|
+
const actions = [];
|
|
2687
|
+
let selectedTransition;
|
|
2688
|
+
const candidates = memo$1(this, `candidates-${eventType}`, () => getCandidates(this, eventType));
|
|
2689
|
+
for (const candidate of candidates) {
|
|
2690
|
+
const { guard } = candidate;
|
|
2691
|
+
const resolvedContext = snapshot.context;
|
|
2692
|
+
let guardPassed = false;
|
|
1582
2693
|
try {
|
|
1583
|
-
|
|
1584
|
-
} catch (
|
|
1585
|
-
|
|
1586
|
-
throw Error(`Unable to evaluate guard ${
|
|
2694
|
+
guardPassed = !guard || evaluateGuard(guard, resolvedContext, event, snapshot);
|
|
2695
|
+
} catch (err) {
|
|
2696
|
+
const guardType = typeof guard === "string" ? guard : typeof guard === "object" ? guard.type : void 0;
|
|
2697
|
+
throw new Error(`Unable to evaluate guard ${guardType ? `'${guardType}' ` : ""}in transition for event '${eventType}' in state node '${this.id}':\n${err.message}`);
|
|
1587
2698
|
}
|
|
1588
|
-
if (
|
|
1589
|
-
|
|
2699
|
+
if (guardPassed) {
|
|
2700
|
+
actions.push(...candidate.actions);
|
|
2701
|
+
selectedTransition = candidate;
|
|
1590
2702
|
break;
|
|
1591
2703
|
}
|
|
1592
2704
|
}
|
|
1593
|
-
return
|
|
2705
|
+
return selectedTransition ? [selectedTransition] : void 0;
|
|
1594
2706
|
}
|
|
2707
|
+
/** All the event types accepted by this state node and its descendants. */
|
|
1595
2708
|
get events() {
|
|
1596
2709
|
return memo$1(this, "events", () => {
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
2710
|
+
const { states } = this;
|
|
2711
|
+
const events = new Set(this.ownEvents);
|
|
2712
|
+
if (states) for (const stateId of Object.keys(states)) {
|
|
2713
|
+
const state = states[stateId];
|
|
2714
|
+
if (state.states) for (const event of state.events) events.add(`${event}`);
|
|
1601
2715
|
}
|
|
1602
|
-
return Array.from(
|
|
2716
|
+
return Array.from(events);
|
|
1603
2717
|
});
|
|
1604
2718
|
}
|
|
2719
|
+
/**
|
|
2720
|
+
* All the events that have transitions directly from this state node.
|
|
2721
|
+
*
|
|
2722
|
+
* Excludes any inert events.
|
|
2723
|
+
*/
|
|
1605
2724
|
get ownEvents() {
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
2725
|
+
const keys = Object.keys(Object.fromEntries(this.transitions));
|
|
2726
|
+
const events = new Set(keys.filter((descriptor) => {
|
|
2727
|
+
return this.transitions.get(descriptor).some((transition) => !(!transition.target && !transition.actions.length && !transition.reenter));
|
|
2728
|
+
}));
|
|
2729
|
+
return Array.from(events);
|
|
2730
|
+
}
|
|
2731
|
+
};
|
|
2732
|
+
var StateMachine = class StateMachine {
|
|
2733
|
+
constructor(config, implementations) {
|
|
2734
|
+
this.config = config;
|
|
2735
|
+
/** The machine's own version. */
|
|
2736
|
+
this.version = void 0;
|
|
2737
|
+
this.schemas = void 0;
|
|
2738
|
+
this.implementations = void 0;
|
|
2739
|
+
/** Runtime options for machine execution. */
|
|
2740
|
+
this.options = void 0;
|
|
2741
|
+
/** @internal */
|
|
2742
|
+
this.__xstatenode = true;
|
|
2743
|
+
/** @internal */
|
|
2744
|
+
this.idMap = /* @__PURE__ */ new Map();
|
|
2745
|
+
this.root = void 0;
|
|
2746
|
+
this.id = void 0;
|
|
2747
|
+
this.states = void 0;
|
|
2748
|
+
this.events = void 0;
|
|
2749
|
+
this.id = config.id || "(machine)";
|
|
2750
|
+
this.implementations = {
|
|
2751
|
+
actors: implementations?.actors ?? {},
|
|
2752
|
+
actions: implementations?.actions ?? {},
|
|
2753
|
+
delays: implementations?.delays ?? {},
|
|
2754
|
+
guards: implementations?.guards ?? {}
|
|
2755
|
+
};
|
|
2756
|
+
this.version = this.config.version;
|
|
2757
|
+
this.schemas = this.config.schemas;
|
|
2758
|
+
this.options = {
|
|
1617
2759
|
maxIterations: Infinity,
|
|
1618
2760
|
...this.config.options
|
|
1619
|
-
}
|
|
2761
|
+
};
|
|
2762
|
+
this.transition = this.transition.bind(this);
|
|
2763
|
+
this.getInitialSnapshot = this.getInitialSnapshot.bind(this);
|
|
2764
|
+
this.getPersistedSnapshot = this.getPersistedSnapshot.bind(this);
|
|
2765
|
+
this.restoreSnapshot = this.restoreSnapshot.bind(this);
|
|
2766
|
+
this.start = this.start.bind(this);
|
|
2767
|
+
this.root = new StateNode(config, {
|
|
1620
2768
|
_key: this.id,
|
|
1621
2769
|
_machine: this
|
|
1622
|
-
})
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
2770
|
+
});
|
|
2771
|
+
this.root._initialize();
|
|
2772
|
+
formatRouteTransitions(this.root);
|
|
2773
|
+
this.states = this.root.states;
|
|
2774
|
+
this.events = this.root.events;
|
|
2775
|
+
}
|
|
2776
|
+
/**
|
|
2777
|
+
* Clones this state machine with the provided implementations.
|
|
2778
|
+
*
|
|
2779
|
+
* @param implementations Options (`actions`, `guards`, `actors`, `delays`) to
|
|
2780
|
+
* recursively merge with the existing options.
|
|
2781
|
+
* @returns A new `StateMachine` instance with the provided implementations.
|
|
2782
|
+
*/
|
|
2783
|
+
provide(implementations) {
|
|
2784
|
+
const { actions, guards, actors, delays } = this.implementations;
|
|
1626
2785
|
return new StateMachine(this.config, {
|
|
1627
2786
|
actions: {
|
|
1628
|
-
...
|
|
1629
|
-
...
|
|
2787
|
+
...actions,
|
|
2788
|
+
...implementations.actions
|
|
1630
2789
|
},
|
|
1631
2790
|
guards: {
|
|
1632
|
-
...
|
|
1633
|
-
...
|
|
2791
|
+
...guards,
|
|
2792
|
+
...implementations.guards
|
|
1634
2793
|
},
|
|
1635
2794
|
actors: {
|
|
1636
|
-
...
|
|
1637
|
-
...
|
|
2795
|
+
...actors,
|
|
2796
|
+
...implementations.actors
|
|
1638
2797
|
},
|
|
1639
2798
|
delays: {
|
|
1640
|
-
...
|
|
1641
|
-
...
|
|
2799
|
+
...delays,
|
|
2800
|
+
...implementations.delays
|
|
1642
2801
|
}
|
|
1643
2802
|
});
|
|
1644
2803
|
}
|
|
1645
|
-
resolveState(
|
|
1646
|
-
|
|
2804
|
+
resolveState(config) {
|
|
2805
|
+
const resolvedStateValue = resolveStateValue(this.root, config.value);
|
|
2806
|
+
const nodeSet = getAllStateNodes(getStateNodes(this.root, resolvedStateValue));
|
|
1647
2807
|
return createMachineSnapshot({
|
|
1648
|
-
_nodes: [...
|
|
1649
|
-
context:
|
|
2808
|
+
_nodes: [...nodeSet],
|
|
2809
|
+
context: config.context || {},
|
|
1650
2810
|
children: {},
|
|
1651
|
-
status: isInFinalState(
|
|
1652
|
-
output:
|
|
1653
|
-
error:
|
|
1654
|
-
historyValue:
|
|
2811
|
+
status: isInFinalState(nodeSet, this.root) ? "done" : config.status || "active",
|
|
2812
|
+
output: config.output,
|
|
2813
|
+
error: config.error,
|
|
2814
|
+
historyValue: config.historyValue
|
|
1655
2815
|
}, this);
|
|
1656
2816
|
}
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
2817
|
+
/**
|
|
2818
|
+
* Determines the next snapshot given the current `snapshot` and received
|
|
2819
|
+
* `event`. Calculates a full macrostep from all microsteps.
|
|
2820
|
+
*
|
|
2821
|
+
* @param snapshot The current snapshot
|
|
2822
|
+
* @param event The received event
|
|
2823
|
+
*/
|
|
2824
|
+
transition(snapshot, event, actorScope) {
|
|
2825
|
+
return macrostep(snapshot, event, actorScope, []).snapshot;
|
|
2826
|
+
}
|
|
2827
|
+
/**
|
|
2828
|
+
* Determines the next state given the current `state` and `event`. Calculates
|
|
2829
|
+
* a microstep.
|
|
2830
|
+
*
|
|
2831
|
+
* @param state The current state
|
|
2832
|
+
* @param event The received event
|
|
2833
|
+
*/
|
|
2834
|
+
microstep(snapshot, event, actorScope) {
|
|
2835
|
+
return macrostep(snapshot, event, actorScope, []).microsteps.map(([s]) => s);
|
|
2836
|
+
}
|
|
2837
|
+
getTransitionData(snapshot, event) {
|
|
2838
|
+
return transitionNode(this.root, snapshot.value, snapshot, event) || [];
|
|
2839
|
+
}
|
|
2840
|
+
/**
|
|
2841
|
+
* The initial state _before_ evaluating any microsteps. This "pre-initial"
|
|
2842
|
+
* state is provided to initial actions executed in the initial state.
|
|
2843
|
+
*
|
|
2844
|
+
* @internal
|
|
2845
|
+
*/
|
|
2846
|
+
_getPreInitialState(actorScope, initEvent, internalQueue) {
|
|
2847
|
+
const { context } = this.config;
|
|
2848
|
+
const preInitial = createMachineSnapshot({
|
|
2849
|
+
context: typeof context !== "function" && context ? context : {},
|
|
1669
2850
|
_nodes: [this.root],
|
|
1670
2851
|
children: {},
|
|
1671
2852
|
status: "active"
|
|
1672
2853
|
}, this);
|
|
1673
|
-
if (typeof
|
|
1674
|
-
|
|
1675
|
-
spawn
|
|
1676
|
-
input:
|
|
1677
|
-
self
|
|
2854
|
+
if (typeof context === "function") {
|
|
2855
|
+
const assignment = ({ spawn, event, self }) => context({
|
|
2856
|
+
spawn,
|
|
2857
|
+
input: event.input,
|
|
2858
|
+
self
|
|
1678
2859
|
});
|
|
1679
|
-
return resolveActionsAndContext(
|
|
2860
|
+
return resolveActionsAndContext(preInitial, initEvent, actorScope, [assign(assignment)], internalQueue, void 0);
|
|
1680
2861
|
}
|
|
1681
|
-
return
|
|
1682
|
-
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
2862
|
+
return preInitial;
|
|
2863
|
+
}
|
|
2864
|
+
/**
|
|
2865
|
+
* Returns the initial `State` instance, with reference to `self` as an
|
|
2866
|
+
* `ActorRef`.
|
|
2867
|
+
*/
|
|
2868
|
+
getInitialSnapshot(actorScope, input) {
|
|
2869
|
+
const initEvent = createInitEvent(input);
|
|
2870
|
+
const internalQueue = [];
|
|
2871
|
+
let snapshot = createMachineSnapshot({
|
|
2872
|
+
context: typeof this.config.context !== "function" && this.config.context ? this.config.context : {},
|
|
1686
2873
|
_nodes: [this.root],
|
|
1687
2874
|
children: {},
|
|
1688
2875
|
status: "active"
|
|
1689
2876
|
}, this);
|
|
1690
2877
|
try {
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
2878
|
+
snapshot = this._getPreInitialState(actorScope, initEvent, internalQueue);
|
|
2879
|
+
const [nextState] = initialMicrostep(this.root, snapshot, actorScope, initEvent, internalQueue);
|
|
2880
|
+
const { snapshot: macroState } = macrostep(nextState, initEvent, actorScope, internalQueue);
|
|
2881
|
+
return macroState;
|
|
2882
|
+
} catch (error) {
|
|
2883
|
+
return cloneMachineSnapshot(snapshot, {
|
|
1696
2884
|
status: "error",
|
|
1697
|
-
error
|
|
2885
|
+
error
|
|
1698
2886
|
});
|
|
1699
2887
|
}
|
|
1700
2888
|
}
|
|
1701
|
-
start(
|
|
1702
|
-
Object.values(
|
|
1703
|
-
|
|
2889
|
+
start(snapshot) {
|
|
2890
|
+
Object.values(snapshot.children).forEach((child) => {
|
|
2891
|
+
if (child.getSnapshot().status === "active") child.start();
|
|
1704
2892
|
});
|
|
1705
2893
|
}
|
|
1706
|
-
getStateNodeById(
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
2894
|
+
getStateNodeById(stateId) {
|
|
2895
|
+
const fullPath = toStatePath(stateId);
|
|
2896
|
+
const relativePath = fullPath.slice(1);
|
|
2897
|
+
const resolvedStateId = isStateId(fullPath[0]) ? fullPath[0].slice(1) : fullPath[0];
|
|
2898
|
+
const stateNode = this.idMap.get(resolvedStateId);
|
|
2899
|
+
if (!stateNode) throw new Error(`Child state node '#${resolvedStateId}' does not exist on machine '${this.id}'`);
|
|
2900
|
+
return getStateNodeByPath(stateNode, relativePath);
|
|
1710
2901
|
}
|
|
1711
2902
|
get definition() {
|
|
1712
2903
|
return this.root.definition;
|
|
@@ -1714,199 +2905,452 @@ var D = {}, toSerializableAction = (e) => typeof e == "string" ? { type: e } : t
|
|
|
1714
2905
|
toJSON() {
|
|
1715
2906
|
return this.definition;
|
|
1716
2907
|
}
|
|
1717
|
-
getPersistedSnapshot(
|
|
1718
|
-
return getPersistedSnapshot(
|
|
1719
|
-
}
|
|
1720
|
-
restoreSnapshot(
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
2908
|
+
getPersistedSnapshot(snapshot, options) {
|
|
2909
|
+
return getPersistedSnapshot(snapshot, options);
|
|
2910
|
+
}
|
|
2911
|
+
restoreSnapshot(snapshot, _actorScope) {
|
|
2912
|
+
const children = {};
|
|
2913
|
+
const snapshotChildren = snapshot.children;
|
|
2914
|
+
Object.keys(snapshotChildren).forEach((actorId) => {
|
|
2915
|
+
const actorData = snapshotChildren[actorId];
|
|
2916
|
+
const childState = actorData.snapshot;
|
|
2917
|
+
const src = actorData.src;
|
|
2918
|
+
const logic = typeof src === "string" ? resolveReferencedActor(this, src) : src;
|
|
2919
|
+
if (!logic) return;
|
|
2920
|
+
const actorRef = createActor(logic, {
|
|
2921
|
+
id: actorId,
|
|
2922
|
+
parent: _actorScope.self,
|
|
2923
|
+
syncSnapshot: actorData.syncSnapshot,
|
|
2924
|
+
snapshot: childState,
|
|
2925
|
+
src,
|
|
2926
|
+
systemId: actorData.systemId
|
|
1732
2927
|
});
|
|
1733
|
-
|
|
2928
|
+
children[actorId] = actorRef;
|
|
1734
2929
|
});
|
|
1735
|
-
function resolveHistoryReferencedState(
|
|
1736
|
-
if (
|
|
2930
|
+
function resolveHistoryReferencedState(root, referenced) {
|
|
2931
|
+
if (referenced instanceof StateNode) return referenced;
|
|
1737
2932
|
try {
|
|
1738
|
-
return
|
|
2933
|
+
return root.machine.getStateNodeById(referenced.id);
|
|
1739
2934
|
} catch {}
|
|
1740
2935
|
}
|
|
1741
|
-
function reviveHistoryValue(
|
|
1742
|
-
if (!
|
|
1743
|
-
|
|
1744
|
-
for (
|
|
1745
|
-
|
|
1746
|
-
for (
|
|
1747
|
-
|
|
1748
|
-
|
|
2936
|
+
function reviveHistoryValue(root, historyValue) {
|
|
2937
|
+
if (!historyValue || typeof historyValue !== "object") return {};
|
|
2938
|
+
const revived = {};
|
|
2939
|
+
for (const key in historyValue) {
|
|
2940
|
+
const arr = historyValue[key];
|
|
2941
|
+
for (const item of arr) {
|
|
2942
|
+
const resolved = resolveHistoryReferencedState(root, item);
|
|
2943
|
+
if (!resolved) continue;
|
|
2944
|
+
revived[key] ??= [];
|
|
2945
|
+
revived[key].push(resolved);
|
|
1749
2946
|
}
|
|
1750
2947
|
}
|
|
1751
|
-
return
|
|
2948
|
+
return revived;
|
|
1752
2949
|
}
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
2950
|
+
const revivedHistoryValue = reviveHistoryValue(this.root, snapshot.historyValue);
|
|
2951
|
+
const restoredSnapshot = createMachineSnapshot({
|
|
2952
|
+
...snapshot,
|
|
2953
|
+
children,
|
|
2954
|
+
_nodes: Array.from(getAllStateNodes(getStateNodes(this.root, snapshot.value))),
|
|
2955
|
+
historyValue: revivedHistoryValue
|
|
2956
|
+
}, this);
|
|
2957
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2958
|
+
function reviveContext(contextPart, children) {
|
|
2959
|
+
if (seen.has(contextPart)) return;
|
|
2960
|
+
seen.add(contextPart);
|
|
2961
|
+
for (const key in contextPart) {
|
|
2962
|
+
const value = contextPart[key];
|
|
2963
|
+
if (value && typeof value === "object") {
|
|
2964
|
+
if ("xstate$$type" in value && value.xstate$$type === 1) {
|
|
2965
|
+
contextPart[key] = children[value.id];
|
|
2966
|
+
continue;
|
|
1770
2967
|
}
|
|
2968
|
+
reviveContext(value, children);
|
|
1771
2969
|
}
|
|
1772
2970
|
}
|
|
1773
2971
|
}
|
|
1774
|
-
|
|
2972
|
+
reviveContext(restoredSnapshot.context, children);
|
|
2973
|
+
return restoredSnapshot;
|
|
1775
2974
|
}
|
|
1776
2975
|
};
|
|
1777
2976
|
//#endregion
|
|
1778
|
-
//#region ../../node_modules/.pnpm/xstate@5.
|
|
1779
|
-
function resolveEmit(
|
|
2977
|
+
//#region ../../node_modules/.pnpm/xstate@5.33.2/node_modules/xstate/dist/log-ddf17a4a.esm.js
|
|
2978
|
+
function resolveEmit(_, snapshot, args, actionParams, { event: eventOrExpr }) {
|
|
1780
2979
|
return [
|
|
1781
|
-
|
|
1782
|
-
{ event: typeof
|
|
2980
|
+
snapshot,
|
|
2981
|
+
{ event: typeof eventOrExpr === "function" ? eventOrExpr(args, actionParams) : eventOrExpr },
|
|
1783
2982
|
void 0
|
|
1784
2983
|
];
|
|
1785
2984
|
}
|
|
1786
|
-
function executeEmit(
|
|
1787
|
-
|
|
1788
|
-
}
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
2985
|
+
function executeEmit(actorScope, { event }) {
|
|
2986
|
+
actorScope.defer(() => actorScope.emit(event));
|
|
2987
|
+
}
|
|
2988
|
+
/**
|
|
2989
|
+
* Emits an event to event handlers registered on the actor via `actor.on(event,
|
|
2990
|
+
* handler)`.
|
|
2991
|
+
*
|
|
2992
|
+
* @example
|
|
2993
|
+
*
|
|
2994
|
+
* ```ts
|
|
2995
|
+
* import { emit } from 'xstate';
|
|
2996
|
+
*
|
|
2997
|
+
* const machine = createMachine({
|
|
2998
|
+
* // ...
|
|
2999
|
+
* on: {
|
|
3000
|
+
* something: {
|
|
3001
|
+
* actions: emit({
|
|
3002
|
+
* type: 'emitted',
|
|
3003
|
+
* some: 'data'
|
|
3004
|
+
* })
|
|
3005
|
+
* }
|
|
3006
|
+
* }
|
|
3007
|
+
* // ...
|
|
3008
|
+
* });
|
|
3009
|
+
*
|
|
3010
|
+
* const actor = createActor(machine).start();
|
|
3011
|
+
*
|
|
3012
|
+
* actor.on('emitted', (event) => {
|
|
3013
|
+
* console.log(event);
|
|
3014
|
+
* });
|
|
3015
|
+
*
|
|
3016
|
+
* actor.send({ type: 'something' });
|
|
3017
|
+
* // logs:
|
|
3018
|
+
* // {
|
|
3019
|
+
* // type: 'emitted',
|
|
3020
|
+
* // some: 'data'
|
|
3021
|
+
* // }
|
|
3022
|
+
* ```
|
|
3023
|
+
*/
|
|
3024
|
+
function emit(eventOrExpr) {
|
|
3025
|
+
function emit(_args, _params) {}
|
|
3026
|
+
emit.type = "xstate.emit";
|
|
3027
|
+
emit.event = eventOrExpr;
|
|
3028
|
+
emit.resolve = resolveEmit;
|
|
3029
|
+
emit.execute = executeEmit;
|
|
3030
|
+
return emit;
|
|
3031
|
+
}
|
|
3032
|
+
/**
|
|
3033
|
+
* @remarks
|
|
3034
|
+
* `T | unknown` reduces to `unknown` and that can be problematic when it comes
|
|
3035
|
+
* to contextual typing. It especially is a problem when the union has a
|
|
3036
|
+
* function member, like here:
|
|
3037
|
+
*
|
|
3038
|
+
* ```ts
|
|
3039
|
+
* declare function test(
|
|
3040
|
+
* cbOrVal: ((arg: number) => unknown) | unknown
|
|
3041
|
+
* ): void;
|
|
3042
|
+
* test((arg) => {}); // oops, implicit any
|
|
3043
|
+
* ```
|
|
3044
|
+
*
|
|
3045
|
+
* This type can be used to avoid this problem. This union represents the same
|
|
3046
|
+
* value space as `unknown`.
|
|
3047
|
+
*/
|
|
3048
|
+
/** @deprecated Use the built-in `NoInfer` type instead */
|
|
3049
|
+
/** The full definition of an event, with a string `type`. */
|
|
3050
|
+
/**
|
|
3051
|
+
* The string or object representing the state value relative to the parent
|
|
3052
|
+
* state node.
|
|
3053
|
+
*
|
|
3054
|
+
* @remarks
|
|
3055
|
+
* - For a child atomic state node, this is a string, e.g., `"pending"`.
|
|
3056
|
+
* - For complex state nodes, this is an object, e.g., `{ success:
|
|
3057
|
+
* "someChildState" }`.
|
|
3058
|
+
*/
|
|
3059
|
+
/** @deprecated Use `AnyMachineSnapshot` instead */
|
|
3060
|
+
/** @ignore */
|
|
3061
|
+
/**
|
|
3062
|
+
* Runtime options for state machine execution.
|
|
3063
|
+
*
|
|
3064
|
+
* @example
|
|
3065
|
+
*
|
|
3066
|
+
* ```ts
|
|
3067
|
+
* const machine = createMachine({
|
|
3068
|
+
* // ... machine config
|
|
3069
|
+
* options: {
|
|
3070
|
+
* maxIterations: 5000
|
|
3071
|
+
* // other runtime options can be added here
|
|
3072
|
+
* }
|
|
3073
|
+
* });
|
|
3074
|
+
* ```
|
|
3075
|
+
*/
|
|
3076
|
+
/** Maps history state IDs to recalled nodes, preserving TContext and TEvent with arbitrary metadata. */
|
|
3077
|
+
/** Transitions with known context and event types and arbitrary metadata. */
|
|
3078
|
+
var SpecialTargets = /*#__PURE__*/ function(SpecialTargets) {
|
|
3079
|
+
SpecialTargets["Parent"] = "#_parent";
|
|
3080
|
+
SpecialTargets["Internal"] = "#_internal";
|
|
3081
|
+
return SpecialTargets;
|
|
1795
3082
|
}({});
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
3083
|
+
/** @deprecated Use `AnyActor` instead. */
|
|
3084
|
+
/** @deprecated Use `Actor<T>` instead. */
|
|
3085
|
+
/**
|
|
3086
|
+
* Represents logic which can be used by an actor.
|
|
3087
|
+
*
|
|
3088
|
+
* @template TSnapshot - The type of the snapshot.
|
|
3089
|
+
* @template TEvent - The type of the event object.
|
|
3090
|
+
* @template TInput - The type of the input.
|
|
3091
|
+
* @template TSystem - The type of the actor system.
|
|
3092
|
+
*/
|
|
3093
|
+
/** @deprecated */
|
|
3094
|
+
function resolveSendTo(actorScope, snapshot, args, actionParams, { to, event: eventOrExpr, id, delay }, extra) {
|
|
3095
|
+
const delaysMap = snapshot.machine.implementations.delays;
|
|
3096
|
+
if (typeof eventOrExpr === "string") throw new Error(`Only event objects may be used with sendTo; use sendTo({ type: "${eventOrExpr}" }) instead`);
|
|
3097
|
+
const resolvedEvent = typeof eventOrExpr === "function" ? eventOrExpr(args, actionParams) : eventOrExpr;
|
|
3098
|
+
let resolvedDelay;
|
|
3099
|
+
if (typeof delay === "string") {
|
|
3100
|
+
const configDelay = delaysMap && delaysMap[delay];
|
|
3101
|
+
resolvedDelay = typeof configDelay === "function" ? configDelay(args, actionParams) : configDelay;
|
|
3102
|
+
} else resolvedDelay = typeof delay === "function" ? delay(args, actionParams) : delay;
|
|
3103
|
+
const resolvedTarget = typeof to === "function" ? to(args, actionParams) : to;
|
|
3104
|
+
let targetActorRef;
|
|
3105
|
+
if (typeof resolvedTarget === "string") {
|
|
3106
|
+
if (resolvedTarget === SpecialTargets.Parent) targetActorRef = actorScope.self._parent;
|
|
3107
|
+
else if (resolvedTarget === SpecialTargets.Internal) targetActorRef = actorScope.self;
|
|
3108
|
+
else if (resolvedTarget.startsWith("#_")) targetActorRef = snapshot.children[resolvedTarget.slice(2)];
|
|
3109
|
+
else targetActorRef = extra.deferredActorIds?.includes(resolvedTarget) ? resolvedTarget : snapshot.children[resolvedTarget];
|
|
3110
|
+
if (!targetActorRef) throw new Error(`Unable to send event to actor '${resolvedTarget}' from machine '${snapshot.machine.id}'.`);
|
|
3111
|
+
} else targetActorRef = resolvedTarget || actorScope.self;
|
|
1808
3112
|
return [
|
|
1809
|
-
|
|
3113
|
+
snapshot,
|
|
1810
3114
|
{
|
|
1811
|
-
to:
|
|
1812
|
-
targetId: typeof
|
|
1813
|
-
event:
|
|
1814
|
-
id
|
|
1815
|
-
delay:
|
|
3115
|
+
to: targetActorRef,
|
|
3116
|
+
targetId: typeof resolvedTarget === "string" ? resolvedTarget : void 0,
|
|
3117
|
+
event: resolvedEvent,
|
|
3118
|
+
id,
|
|
3119
|
+
delay: resolvedDelay
|
|
1816
3120
|
},
|
|
1817
3121
|
void 0
|
|
1818
3122
|
];
|
|
1819
3123
|
}
|
|
1820
|
-
function retryResolveSendTo(
|
|
1821
|
-
typeof
|
|
3124
|
+
function retryResolveSendTo(_, snapshot, params) {
|
|
3125
|
+
if (typeof params.to === "string") params.to = snapshot.children[params.to];
|
|
1822
3126
|
}
|
|
1823
|
-
function executeSendTo(
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
if (typeof
|
|
1827
|
-
|
|
3127
|
+
function executeSendTo(actorScope, params) {
|
|
3128
|
+
actorScope.defer(() => {
|
|
3129
|
+
const { to, event, delay, id } = params;
|
|
3130
|
+
if (typeof delay === "number") {
|
|
3131
|
+
actorScope.system.scheduler.schedule(actorScope.self, to, event, delay, id);
|
|
1828
3132
|
return;
|
|
1829
3133
|
}
|
|
1830
|
-
|
|
3134
|
+
actorScope.system._relay(actorScope.self, to, event.type === "xstate.error" ? createErrorActorEvent(actorScope.self.id, event.data) : event);
|
|
1831
3135
|
});
|
|
1832
3136
|
}
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
3137
|
+
/**
|
|
3138
|
+
* Sends an event to an actor.
|
|
3139
|
+
*
|
|
3140
|
+
* @param actor The `ActorRef` to send the event to.
|
|
3141
|
+
* @param event The event to send, or an expression that evaluates to the event
|
|
3142
|
+
* to send
|
|
3143
|
+
* @param options Send action options
|
|
3144
|
+
*
|
|
3145
|
+
* - `id` - The unique send event identifier (used with `cancel()`).
|
|
3146
|
+
* - `delay` - The number of milliseconds to delay the sending of the event.
|
|
3147
|
+
*/
|
|
3148
|
+
function sendTo(to, eventOrExpr, options) {
|
|
3149
|
+
function sendTo(_args, _params) {}
|
|
3150
|
+
sendTo.type = "xstate.sendTo";
|
|
3151
|
+
sendTo.to = to;
|
|
3152
|
+
sendTo.event = eventOrExpr;
|
|
3153
|
+
sendTo.id = options?.id;
|
|
3154
|
+
sendTo.delay = options?.delay;
|
|
3155
|
+
sendTo.resolve = resolveSendTo;
|
|
3156
|
+
sendTo.retryResolve = retryResolveSendTo;
|
|
3157
|
+
sendTo.execute = executeSendTo;
|
|
3158
|
+
return sendTo;
|
|
3159
|
+
}
|
|
3160
|
+
/**
|
|
3161
|
+
* Sends an event to this machine's parent.
|
|
3162
|
+
*
|
|
3163
|
+
* @param event The event to send to the parent machine.
|
|
3164
|
+
* @param options Options to pass into the send event.
|
|
3165
|
+
*/
|
|
3166
|
+
function sendParent(event, options) {
|
|
3167
|
+
return sendTo(SpecialTargets.Parent, event, options);
|
|
3168
|
+
}
|
|
3169
|
+
function resolveEnqueueActions(actorScope, snapshot, args, actionParams, { collect }) {
|
|
3170
|
+
const actions = [];
|
|
3171
|
+
const enqueue = function enqueue(action) {
|
|
3172
|
+
actions.push(action);
|
|
3173
|
+
};
|
|
3174
|
+
enqueue.assign = (...args) => {
|
|
3175
|
+
actions.push(assign(...args));
|
|
3176
|
+
};
|
|
3177
|
+
enqueue.cancel = (...args) => {
|
|
3178
|
+
actions.push(cancel(...args));
|
|
3179
|
+
};
|
|
3180
|
+
enqueue.raise = (...args) => {
|
|
3181
|
+
actions.push(raise(...args));
|
|
3182
|
+
};
|
|
3183
|
+
enqueue.sendTo = (...args) => {
|
|
3184
|
+
actions.push(sendTo(...args));
|
|
3185
|
+
};
|
|
3186
|
+
enqueue.sendParent = (...args) => {
|
|
3187
|
+
actions.push(sendParent(...args));
|
|
1843
3188
|
};
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
},
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
enqueue: o,
|
|
1864
|
-
check: (e) => evaluateGuard(e, t.context, n.event, t),
|
|
1865
|
-
self: e.self,
|
|
1866
|
-
system: e.system
|
|
1867
|
-
}, r), [
|
|
1868
|
-
t,
|
|
3189
|
+
enqueue.spawnChild = (...args) => {
|
|
3190
|
+
actions.push(spawnChild(...args));
|
|
3191
|
+
};
|
|
3192
|
+
enqueue.stopChild = (...args) => {
|
|
3193
|
+
actions.push(stopChild(...args));
|
|
3194
|
+
};
|
|
3195
|
+
enqueue.emit = (...args) => {
|
|
3196
|
+
actions.push(emit(...args));
|
|
3197
|
+
};
|
|
3198
|
+
collect({
|
|
3199
|
+
context: args.context,
|
|
3200
|
+
event: args.event,
|
|
3201
|
+
enqueue,
|
|
3202
|
+
check: (guard) => evaluateGuard(guard, snapshot.context, args.event, snapshot),
|
|
3203
|
+
self: actorScope.self,
|
|
3204
|
+
system: actorScope.system
|
|
3205
|
+
}, actionParams);
|
|
3206
|
+
return [
|
|
3207
|
+
snapshot,
|
|
1869
3208
|
void 0,
|
|
1870
|
-
|
|
3209
|
+
actions
|
|
1871
3210
|
];
|
|
1872
3211
|
}
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
3212
|
+
/**
|
|
3213
|
+
* Creates an action object that will execute actions that are queued by the
|
|
3214
|
+
* `enqueue(action)` function.
|
|
3215
|
+
*
|
|
3216
|
+
* @example
|
|
3217
|
+
*
|
|
3218
|
+
* ```ts
|
|
3219
|
+
* import { createMachine, enqueueActions } from 'xstate';
|
|
3220
|
+
*
|
|
3221
|
+
* const machine = createMachine({
|
|
3222
|
+
* entry: enqueueActions(({ enqueue, check }) => {
|
|
3223
|
+
* enqueue.assign({ count: 0 });
|
|
3224
|
+
*
|
|
3225
|
+
* if (check('someGuard')) {
|
|
3226
|
+
* enqueue.assign({ count: 1 });
|
|
3227
|
+
* }
|
|
3228
|
+
*
|
|
3229
|
+
* enqueue('someAction');
|
|
3230
|
+
* })
|
|
3231
|
+
* });
|
|
3232
|
+
* ```
|
|
3233
|
+
*/
|
|
3234
|
+
function enqueueActions(collect) {
|
|
3235
|
+
function enqueueActions(_args, _params) {}
|
|
3236
|
+
enqueueActions.type = "xstate.enqueueActions";
|
|
3237
|
+
enqueueActions.collect = collect;
|
|
3238
|
+
enqueueActions.resolve = resolveEnqueueActions;
|
|
3239
|
+
return enqueueActions;
|
|
3240
|
+
}
|
|
3241
|
+
function resolveLog(_, snapshot, actionArgs, actionParams, { value, label }) {
|
|
1878
3242
|
return [
|
|
1879
|
-
|
|
3243
|
+
snapshot,
|
|
1880
3244
|
{
|
|
1881
|
-
value: typeof
|
|
1882
|
-
label
|
|
3245
|
+
value: typeof value === "function" ? value(actionArgs, actionParams) : value,
|
|
3246
|
+
label
|
|
1883
3247
|
},
|
|
1884
3248
|
void 0
|
|
1885
3249
|
];
|
|
1886
3250
|
}
|
|
1887
|
-
function executeLog({ logger
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
3251
|
+
function executeLog({ logger }, { value, label }) {
|
|
3252
|
+
if (label) logger(label, value);
|
|
3253
|
+
else logger(value);
|
|
3254
|
+
}
|
|
3255
|
+
/**
|
|
3256
|
+
* @param expr The expression function to evaluate which will be logged. Takes
|
|
3257
|
+
* in 2 arguments:
|
|
3258
|
+
*
|
|
3259
|
+
* - `ctx` - the current state context
|
|
3260
|
+
* - `event` - the event that caused this action to be executed.
|
|
3261
|
+
*
|
|
3262
|
+
* @param label The label to give to the logged expression.
|
|
3263
|
+
*/
|
|
3264
|
+
function log(value = ({ context, event }) => ({
|
|
3265
|
+
context,
|
|
3266
|
+
event
|
|
3267
|
+
}), label) {
|
|
3268
|
+
function log(_args, _params) {}
|
|
3269
|
+
log.type = "xstate.log";
|
|
3270
|
+
log.value = value;
|
|
3271
|
+
log.label = label;
|
|
3272
|
+
log.resolve = resolveLog;
|
|
3273
|
+
log.execute = executeLog;
|
|
3274
|
+
return log;
|
|
1896
3275
|
}
|
|
1897
3276
|
//#endregion
|
|
1898
|
-
//#region ../../node_modules/.pnpm/xstate@5.
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
3277
|
+
//#region ../../node_modules/.pnpm/xstate@5.33.2/node_modules/xstate/dist/xstate.esm.js
|
|
3278
|
+
/**
|
|
3279
|
+
* Asserts that the given event object is of the specified type or types. Throws
|
|
3280
|
+
* an error if the event object is not of the specified types.
|
|
3281
|
+
*
|
|
3282
|
+
* @example
|
|
3283
|
+
*
|
|
3284
|
+
* ```ts
|
|
3285
|
+
* // ...
|
|
3286
|
+
* entry: ({ event }) => {
|
|
3287
|
+
* assertEvent(event, 'doNothing');
|
|
3288
|
+
* // event is { type: 'doNothing' }
|
|
3289
|
+
* },
|
|
3290
|
+
* // ...
|
|
3291
|
+
* exit: ({ event }) => {
|
|
3292
|
+
* assertEvent(event, 'greet');
|
|
3293
|
+
* // event is { type: 'greet'; message: string }
|
|
3294
|
+
*
|
|
3295
|
+
* assertEvent(event, ['greet', 'notify']);
|
|
3296
|
+
* // event is { type: 'greet'; message: string }
|
|
3297
|
+
* // or { type: 'notify'; message: string; level: 'info' | 'error' }
|
|
3298
|
+
* },
|
|
3299
|
+
* ```
|
|
3300
|
+
*/
|
|
3301
|
+
function assertEvent(event, type) {
|
|
3302
|
+
const types = toArray(type);
|
|
3303
|
+
if (!types.some((descriptor) => matchesEventDescriptor(event.type, descriptor))) {
|
|
3304
|
+
const typesText = types.length === 1 ? `type matching "${types[0]}"` : `one of types matching "${types.join("\", \"")}"`;
|
|
3305
|
+
throw new Error(`Expected event ${JSON.stringify(event)} to have ${typesText}`);
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
/**
|
|
3309
|
+
* Creates a state machine (statechart) with the given configuration.
|
|
3310
|
+
*
|
|
3311
|
+
* The state machine represents the pure logic of a state machine actor.
|
|
3312
|
+
*
|
|
3313
|
+
* @example
|
|
3314
|
+
*
|
|
3315
|
+
* ```ts
|
|
3316
|
+
* import { createMachine } from 'xstate';
|
|
3317
|
+
*
|
|
3318
|
+
* const lightMachine = createMachine({
|
|
3319
|
+
* id: 'light',
|
|
3320
|
+
* initial: 'green',
|
|
3321
|
+
* states: {
|
|
3322
|
+
* green: {
|
|
3323
|
+
* on: {
|
|
3324
|
+
* TIMER: { target: 'yellow' }
|
|
3325
|
+
* }
|
|
3326
|
+
* },
|
|
3327
|
+
* yellow: {
|
|
3328
|
+
* on: {
|
|
3329
|
+
* TIMER: { target: 'red' }
|
|
3330
|
+
* }
|
|
3331
|
+
* },
|
|
3332
|
+
* red: {
|
|
3333
|
+
* on: {
|
|
3334
|
+
* TIMER: { target: 'green' }
|
|
3335
|
+
* }
|
|
3336
|
+
* }
|
|
3337
|
+
* }
|
|
3338
|
+
* });
|
|
3339
|
+
*
|
|
3340
|
+
* const lightActor = createActor(lightMachine);
|
|
3341
|
+
* lightActor.start();
|
|
3342
|
+
*
|
|
3343
|
+
* lightActor.send({ type: 'TIMER' });
|
|
3344
|
+
* ```
|
|
3345
|
+
*
|
|
3346
|
+
* @param config The state machine configuration.
|
|
3347
|
+
* @param options DEPRECATED: use `setup({ ... })` or `machine.provide({ ... })`
|
|
3348
|
+
* to provide machine implementations instead.
|
|
3349
|
+
*/
|
|
3350
|
+
function createMachine(config, implementations) {
|
|
3351
|
+
return new StateMachine(config, implementations);
|
|
3352
|
+
}
|
|
3353
|
+
function setup({ schemas, actors, actions, guards, delays }) {
|
|
1910
3354
|
return {
|
|
1911
3355
|
assign,
|
|
1912
3356
|
sendTo,
|
|
@@ -1917,99 +3361,111 @@ function setup({ schemas: e, actors: t, actions: n, guards: r, delays: i }) {
|
|
|
1917
3361
|
enqueueActions,
|
|
1918
3362
|
emit,
|
|
1919
3363
|
spawnChild,
|
|
1920
|
-
createStateConfig: (
|
|
1921
|
-
createAction: (
|
|
1922
|
-
createMachine: (
|
|
1923
|
-
...
|
|
1924
|
-
schemas
|
|
3364
|
+
createStateConfig: (config) => config,
|
|
3365
|
+
createAction: (fn) => fn,
|
|
3366
|
+
createMachine: (config) => createMachine({
|
|
3367
|
+
...config,
|
|
3368
|
+
schemas
|
|
1925
3369
|
}, {
|
|
1926
|
-
actors
|
|
1927
|
-
actions
|
|
1928
|
-
guards
|
|
1929
|
-
delays
|
|
3370
|
+
actors,
|
|
3371
|
+
actions,
|
|
3372
|
+
guards,
|
|
3373
|
+
delays
|
|
1930
3374
|
}),
|
|
1931
|
-
extend: (
|
|
1932
|
-
schemas
|
|
1933
|
-
actors
|
|
3375
|
+
extend: (extended) => setup({
|
|
3376
|
+
schemas,
|
|
3377
|
+
actors,
|
|
1934
3378
|
actions: {
|
|
1935
|
-
...
|
|
1936
|
-
...
|
|
3379
|
+
...actions,
|
|
3380
|
+
...extended.actions
|
|
1937
3381
|
},
|
|
1938
3382
|
guards: {
|
|
1939
|
-
...
|
|
1940
|
-
...
|
|
3383
|
+
...guards,
|
|
3384
|
+
...extended.guards
|
|
1941
3385
|
},
|
|
1942
3386
|
delays: {
|
|
1943
|
-
...
|
|
1944
|
-
...
|
|
3387
|
+
...delays,
|
|
3388
|
+
...extended.delays
|
|
1945
3389
|
}
|
|
1946
3390
|
})
|
|
1947
3391
|
};
|
|
1948
3392
|
}
|
|
1949
3393
|
//#endregion
|
|
1950
|
-
//#region ../../node_modules/.pnpm/@xstate+react@6.1.0_@types+react@19.
|
|
1951
|
-
var forEachActor = (
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
forEachActor(
|
|
3394
|
+
//#region ../../node_modules/.pnpm/@xstate+react@6.1.0_@types+react@19.3.0_react@19.3.0_xstate@5.33.2/node_modules/@xstate/react/dist/xstate-react.esm.js
|
|
3395
|
+
var forEachActor = (actorRef, callback) => {
|
|
3396
|
+
callback(actorRef);
|
|
3397
|
+
const children = actorRef.getSnapshot().children;
|
|
3398
|
+
if (children) Object.values(children).forEach((child) => {
|
|
3399
|
+
forEachActor(child, callback);
|
|
1956
3400
|
});
|
|
1957
3401
|
};
|
|
1958
|
-
function stopRootWithRehydration(
|
|
1959
|
-
|
|
1960
|
-
forEachActor(
|
|
1961
|
-
|
|
3402
|
+
function stopRootWithRehydration(actorRef) {
|
|
3403
|
+
const persistedSnapshots = [];
|
|
3404
|
+
forEachActor(actorRef, (ref) => {
|
|
3405
|
+
persistedSnapshots.push([ref, ref.getSnapshot()]);
|
|
3406
|
+
ref.observers = /* @__PURE__ */ new Set();
|
|
1962
3407
|
});
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
3408
|
+
const systemSnapshot = actorRef.system.getSnapshot?.();
|
|
3409
|
+
actorRef.stop();
|
|
3410
|
+
actorRef.system._snapshot = systemSnapshot;
|
|
3411
|
+
persistedSnapshots.forEach(([ref, snapshot]) => {
|
|
3412
|
+
ref._processingStatus = 0;
|
|
3413
|
+
ref._snapshot = snapshot;
|
|
1966
3414
|
});
|
|
1967
3415
|
}
|
|
1968
|
-
function useIdleActorRef(
|
|
1969
|
-
let [[
|
|
1970
|
-
|
|
1971
|
-
return [
|
|
3416
|
+
function useIdleActorRef(logic, ...[options]) {
|
|
3417
|
+
let [[currentConfig, actorRef], setCurrent] = useState(() => {
|
|
3418
|
+
const actorRef = createActor(logic, options);
|
|
3419
|
+
return [logic.config, actorRef];
|
|
1972
3420
|
});
|
|
1973
|
-
if (
|
|
1974
|
-
|
|
1975
|
-
...
|
|
1976
|
-
snapshot:
|
|
3421
|
+
if (logic.config !== currentConfig) {
|
|
3422
|
+
const newActorRef = createActor(logic, {
|
|
3423
|
+
...options,
|
|
3424
|
+
snapshot: actorRef.getPersistedSnapshot({ __unsafeAllowInlineActors: true })
|
|
1977
3425
|
});
|
|
1978
|
-
|
|
3426
|
+
setCurrent([logic.config, newActorRef]);
|
|
3427
|
+
actorRef = newActorRef;
|
|
1979
3428
|
}
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
})
|
|
3429
|
+
index(() => {
|
|
3430
|
+
actorRef.logic.implementations = logic.implementations;
|
|
3431
|
+
});
|
|
3432
|
+
return actorRef;
|
|
1983
3433
|
}
|
|
1984
|
-
function useActorRef(
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
if (!
|
|
1988
|
-
|
|
3434
|
+
function useActorRef(machine, ...[options, observerOrListener]) {
|
|
3435
|
+
const actorRef = useIdleActorRef(machine, options);
|
|
3436
|
+
useEffect(() => {
|
|
3437
|
+
if (!observerOrListener) return;
|
|
3438
|
+
const sub = actorRef.subscribe(toObserver(observerOrListener));
|
|
3439
|
+
return () => {
|
|
3440
|
+
sub.unsubscribe();
|
|
3441
|
+
};
|
|
3442
|
+
}, [observerOrListener]);
|
|
3443
|
+
useEffect(() => {
|
|
3444
|
+
actorRef.start();
|
|
1989
3445
|
return () => {
|
|
1990
|
-
|
|
3446
|
+
stopRootWithRehydration(actorRef);
|
|
1991
3447
|
};
|
|
1992
|
-
}, [
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
error: t
|
|
3448
|
+
}, [actorRef]);
|
|
3449
|
+
return actorRef;
|
|
3450
|
+
}
|
|
3451
|
+
function defaultCompare(a, b) {
|
|
3452
|
+
return a === b;
|
|
3453
|
+
}
|
|
3454
|
+
function useSelector(actor, selector, compare = defaultCompare) {
|
|
3455
|
+
const subscribe = useCallback((handleStoreChange) => {
|
|
3456
|
+
if (!actor) return () => {};
|
|
3457
|
+
const { unsubscribe } = actor.subscribe({
|
|
3458
|
+
next: handleStoreChange,
|
|
3459
|
+
error: handleStoreChange
|
|
2005
3460
|
});
|
|
2006
|
-
return
|
|
2007
|
-
}, [
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
3461
|
+
return unsubscribe;
|
|
3462
|
+
}, [actor]);
|
|
3463
|
+
const boundGetSnapshot = useCallback(() => {
|
|
3464
|
+
const snapshot = actor?.getSnapshot();
|
|
3465
|
+
if (snapshot && "status" in snapshot && snapshot.status === "error") throw snapshot.error;
|
|
3466
|
+
return snapshot;
|
|
3467
|
+
}, [actor]);
|
|
3468
|
+
return useSyncExternalStoreWithSelector(subscribe, boundGetSnapshot, boundGetSnapshot, selector, compare);
|
|
2013
3469
|
}
|
|
2014
3470
|
//#endregion
|
|
2015
3471
|
export { spawnChild as _, emit as a, sendTo as c, fromPromise as d, and as f, raise as g, or as h, setup as i, assign as l, not as m, useSelector as n, enqueueActions as o, cancel as p, assertEvent as r, log as s, useActorRef as t, fromCallback as u, stopChild as v };
|