@typeonce/effect-machine 0.31.1 → 0.32.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/README.md +145 -140
- package/dist/Machine.d.ts +428 -254
- package/dist/Machine.d.ts.map +1 -1
- package/dist/Machine.js +91 -111
- package/dist/Machine.js.map +1 -1
- package/dist/internal/machine/atom.d.ts +3 -4
- package/dist/internal/machine/atom.d.ts.map +1 -1
- package/dist/internal/machine/atom.js +0 -2
- package/dist/internal/machine/atom.js.map +1 -1
- package/dist/internal/machine/childRegistry.d.ts +52 -0
- package/dist/internal/machine/childRegistry.d.ts.map +1 -0
- package/dist/internal/machine/childRegistry.js +74 -0
- package/dist/internal/machine/childRegistry.js.map +1 -0
- package/dist/internal/machine/cluster.d.ts +2 -3
- package/dist/internal/machine/cluster.d.ts.map +1 -1
- package/dist/internal/machine/cluster.js.map +1 -1
- package/dist/internal/machine/configuration.d.ts.map +1 -1
- package/dist/internal/machine/configuration.js +14 -4
- package/dist/internal/machine/configuration.js.map +1 -1
- package/dist/internal/machine/executionPlan.d.ts +1 -0
- package/dist/internal/machine/executionPlan.d.ts.map +1 -1
- package/dist/internal/machine/executionPlan.js +97 -53
- package/dist/internal/machine/executionPlan.js.map +1 -1
- package/dist/internal/machine/invocation.d.ts.map +1 -1
- package/dist/internal/machine/invocation.js +4 -2
- package/dist/internal/machine/invocation.js.map +1 -1
- package/dist/internal/machine/invocationDefinition.d.ts +35 -0
- package/dist/internal/machine/invocationDefinition.d.ts.map +1 -0
- package/dist/internal/machine/invocationDefinition.js +21 -0
- package/dist/internal/machine/invocationDefinition.js.map +1 -0
- package/dist/internal/machine/invocationEvent.d.ts +0 -2
- package/dist/internal/machine/invocationEvent.d.ts.map +1 -1
- package/dist/internal/machine/invocationEvent.js +0 -8
- package/dist/internal/machine/invocationEvent.js.map +1 -1
- package/dist/internal/machine/machine.d.ts +21 -43
- package/dist/internal/machine/machine.d.ts.map +1 -1
- package/dist/internal/machine/machine.js +98 -374
- package/dist/internal/machine/machine.js.map +1 -1
- package/dist/internal/machine/planner.d.ts +13 -19
- package/dist/internal/machine/planner.d.ts.map +1 -1
- package/dist/internal/machine/planner.js +71 -39
- package/dist/internal/machine/planner.js.map +1 -1
- package/dist/internal/machine/process.d.ts +6 -8
- package/dist/internal/machine/process.d.ts.map +1 -1
- package/dist/internal/machine/process.js +1 -0
- package/dist/internal/machine/process.js.map +1 -1
- package/dist/internal/machine/protocol.d.ts +2 -2
- package/dist/internal/machine/protocol.d.ts.map +1 -1
- package/dist/internal/machine/protocol.js +4 -18
- package/dist/internal/machine/protocol.js.map +1 -1
- package/dist/internal/machine/readiness.d.ts +1 -1
- package/dist/internal/machine/readiness.d.ts.map +1 -1
- package/dist/internal/machine/requirements.d.ts +4 -0
- package/dist/internal/machine/requirements.d.ts.map +1 -0
- package/dist/internal/machine/requirements.js +2 -0
- package/dist/internal/machine/requirements.js.map +1 -0
- package/dist/internal/machine/runtime.d.ts +4 -58
- package/dist/internal/machine/runtime.d.ts.map +1 -1
- package/dist/internal/machine/runtime.js +1 -69
- package/dist/internal/machine/runtime.js.map +1 -1
- package/dist/internal/machine/serialization.d.ts.map +1 -1
- package/dist/internal/machine/serialization.js +16 -0
- package/dist/internal/machine/serialization.js.map +1 -1
- package/dist/internal/machine/stateDefinition.d.ts +3 -1
- package/dist/internal/machine/stateDefinition.d.ts.map +1 -1
- package/dist/internal/machine/stateDefinition.js +36 -2
- package/dist/internal/machine/stateDefinition.js.map +1 -1
- package/dist/internal/machine/targetBuilder.d.ts +16 -0
- package/dist/internal/machine/targetBuilder.d.ts.map +1 -0
- package/dist/internal/machine/targetBuilder.js +333 -0
- package/dist/internal/machine/targetBuilder.js.map +1 -0
- package/dist/internal/machine/topology.js +3 -3
- package/dist/internal/machine/topology.js.map +1 -1
- package/dist/internal/machine/transition.d.ts +16 -0
- package/dist/internal/machine/transition.d.ts.map +1 -0
- package/dist/internal/machine/transition.js +2 -0
- package/dist/internal/machine/transition.js.map +1 -0
- package/dist/internal/testing/machine/finiteModel.d.ts.map +1 -1
- package/dist/internal/testing/machine/finiteModel.js +10 -12
- package/dist/internal/testing/machine/finiteModel.js.map +1 -1
- package/dist/internal/testing/machine/format.d.ts +7 -0
- package/dist/internal/testing/machine/format.d.ts.map +1 -0
- package/dist/internal/testing/machine/format.js +104 -0
- package/dist/internal/testing/machine/format.js.map +1 -0
- package/dist/internal/testing/machine/probe.d.ts +1 -1
- package/dist/internal/testing/machine/probe.d.ts.map +1 -1
- package/dist/internal/testing/machine/probe.js +1 -1
- package/dist/internal/testing/machine/probe.js.map +1 -1
- package/dist/internal/testing/machine/referenceModel.d.ts.map +1 -1
- package/dist/internal/testing/machine/referenceModel.js +15 -19
- package/dist/internal/testing/machine/referenceModel.js.map +1 -1
- package/dist/internal/testing/machine/trace.d.ts +1 -1
- package/dist/internal/testing/machine/trace.d.ts.map +1 -1
- package/dist/internal/testing/machine/trace.js +3 -3
- package/dist/internal/testing/machine/trace.js.map +1 -1
- package/dist/internal/testing/machine/value.d.ts +8 -0
- package/dist/internal/testing/machine/value.d.ts.map +1 -0
- package/dist/internal/testing/machine/value.js +82 -0
- package/dist/internal/testing/machine/value.js.map +1 -0
- package/dist/internal/testing/machine/verification.d.ts +2 -13
- package/dist/internal/testing/machine/verification.d.ts.map +1 -1
- package/dist/internal/testing/machine/verification.js +21 -113
- package/dist/internal/testing/machine/verification.js.map +1 -1
- package/dist/testing/MachineTest.d.ts +89 -104
- package/dist/testing/MachineTest.d.ts.map +1 -1
- package/dist/testing/MachineTest.js +70 -84
- package/dist/testing/MachineTest.js.map +1 -1
- package/dist/unstable/cluster/ClusterMachine.d.ts +10 -13
- package/dist/unstable/cluster/ClusterMachine.d.ts.map +1 -1
- package/dist/unstable/cluster/ClusterMachine.js +5 -8
- package/dist/unstable/cluster/ClusterMachine.js.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.d.ts +26 -61
- package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.js +17 -26
- package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
- package/docs/agent-guide.md +45 -45
- package/docs/effect-atom-react.md +35 -63
- package/docs/machine-review.md +7 -7
- package/docs/root-api.md +214 -0
- package/package.json +1 -1
- package/src/Machine.ts +778 -437
- package/src/internal/machine/atom.ts +3 -13
- package/src/internal/machine/childRegistry.ts +141 -0
- package/src/internal/machine/cluster.ts +5 -14
- package/src/internal/machine/configuration.ts +20 -4
- package/src/internal/machine/executionPlan.ts +109 -52
- package/src/internal/machine/invocation.ts +10 -6
- package/src/internal/machine/invocationDefinition.ts +52 -0
- package/src/internal/machine/invocationEvent.ts +0 -8
- package/src/internal/machine/machine.ts +154 -679
- package/src/internal/machine/planner.ts +82 -66
- package/src/internal/machine/process.ts +14 -21
- package/src/internal/machine/protocol.ts +9 -32
- package/src/internal/machine/readiness.ts +1 -0
- package/src/internal/machine/requirements.ts +11 -0
- package/src/internal/machine/runtime.ts +17 -186
- package/src/internal/machine/serialization.ts +22 -0
- package/src/internal/machine/stateDefinition.ts +36 -3
- package/src/internal/machine/targetBuilder.ts +525 -0
- package/src/internal/machine/topology.ts +3 -3
- package/src/internal/machine/transition.ts +26 -0
- package/src/internal/testing/machine/finiteModel.ts +22 -23
- package/src/internal/testing/machine/format.ts +120 -0
- package/src/internal/testing/machine/probe.ts +4 -4
- package/src/internal/testing/machine/referenceModel.ts +25 -17
- package/src/internal/testing/machine/trace.ts +4 -4
- package/src/internal/testing/machine/value.ts +77 -0
- package/src/internal/testing/machine/verification.ts +904 -1109
- package/src/testing/MachineTest.ts +103 -114
- package/src/unstable/cluster/ClusterMachine.ts +10 -20
- package/src/unstable/reactivity/AtomMachine.ts +42 -79
|
@@ -3,15 +3,18 @@ import * as Inspectable from "effect/Inspectable";
|
|
|
3
3
|
import * as Option from "effect/Option";
|
|
4
4
|
import { Prototype as PipeablePrototype } from "effect/Pipeable";
|
|
5
5
|
import { hasProperty } from "effect/Predicate";
|
|
6
|
+
import * as Schema from "effect/Schema";
|
|
6
7
|
import * as Activities from "./activities.js";
|
|
7
8
|
import * as Configuration from "./configuration.js";
|
|
9
|
+
import * as InvocationDefinition from "./invocationDefinition.js";
|
|
8
10
|
import * as internalPlanner from "./planner.js";
|
|
9
11
|
import * as internalProcess from "./process.js";
|
|
10
12
|
import * as Protocol from "./protocol.js";
|
|
11
13
|
import * as internalRuntime from "./runtime.js";
|
|
12
14
|
import * as Serialization from "./serialization.js";
|
|
13
15
|
import * as StateDefinition from "./stateDefinition.js";
|
|
14
|
-
import { ChildMachineLogicTypeId
|
|
16
|
+
import { ChildMachineLogicTypeId } from "./symbols.js";
|
|
17
|
+
import { getLocalTargetScope, getTargetBuilderNode, makeSnapshotBuilder, makeTargetBuilder, withFrom } from "./targetBuilder.js";
|
|
15
18
|
import * as Topology from "./topology.js";
|
|
16
19
|
export { ChildAlreadyExistsError, InfiniteTransitionError, MachineSchemaDecodeError, MachineSchemaEncodeError, ProcessLocalError, StartupError, StoppedError } from "./errors.js";
|
|
17
20
|
export { ChildMachineLogicTypeId, InitialEventTypeId, SnapshotBuilderStateTypeId } from "./symbols.js";
|
|
@@ -34,6 +37,7 @@ const Proto = {
|
|
|
34
37
|
const makeWithHandlers = (self, handlers) => {
|
|
35
38
|
const machine = Object.create(Proto);
|
|
36
39
|
machine.states = self.states;
|
|
40
|
+
machine.root = self.root;
|
|
37
41
|
machine.events = self.events;
|
|
38
42
|
machine.internalEvents = self.internalEvents;
|
|
39
43
|
machine.emittedEvents = self.emittedEvents;
|
|
@@ -71,10 +75,22 @@ const makeDirectTransitionDescriptor = (selection, resolve, options) => {
|
|
|
71
75
|
};
|
|
72
76
|
return resolve === undefined
|
|
73
77
|
? Object.freeze(shared)
|
|
74
|
-
: Object.freeze({ ...shared, resolve });
|
|
78
|
+
: Object.freeze({ ...shared, resolver: resolve });
|
|
79
|
+
};
|
|
80
|
+
const guardedSelection = (selection, predicate) => {
|
|
81
|
+
const wrap = (resolve, options) => makeDirectTransitionDescriptor(selection, (context, enqueue) => predicate(context) ? resolve(context, enqueue) : Topology.makeDeclined(), { ...transitionOptions(options), declinable: true });
|
|
82
|
+
return Object.freeze({
|
|
83
|
+
...wrap((context) => (selection.kind === "none" ? Topology.makeNoTarget() : constructSelectedTarget(context.target))),
|
|
84
|
+
from: (value) => wrap((context) => context.target.from(value(context))),
|
|
85
|
+
decoded: (value) => wrap((context) => context.target.decoded(value(context))),
|
|
86
|
+
resolve: wrap
|
|
87
|
+
});
|
|
75
88
|
};
|
|
76
89
|
const decorateTransitionSelection = (selection) => Object.freeze({
|
|
77
90
|
...selection,
|
|
91
|
+
guard: (predicate) => guardedSelection(selection, predicate),
|
|
92
|
+
from: (value) => makeDirectTransitionDescriptor(selection, (context) => context.target.from(value(context)), undefined),
|
|
93
|
+
decoded: (value) => makeDirectTransitionDescriptor(selection, (context) => context.target.decoded(value(context)), undefined),
|
|
78
94
|
resolve: (resolve, options) => makeDirectTransitionDescriptor(selection, resolve, options),
|
|
79
95
|
reenter: () => makeDirectTransitionDescriptor(selection, undefined, { reenter: true }),
|
|
80
96
|
updating: (owner) => {
|
|
@@ -89,11 +105,12 @@ const decorateTransitionSelection = (selection) => Object.freeze({
|
|
|
89
105
|
return decorateTransitionSelection(Topology.makeTargetSelection(selection.kind, selection.path, selection.scope, ownerSelection.path));
|
|
90
106
|
}
|
|
91
107
|
});
|
|
92
|
-
const decorateStateUpdateSelection = (selection) => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
const decorateStateUpdateSelection = (selection) => Object.freeze({
|
|
109
|
+
...selection,
|
|
110
|
+
from: (value) => makeDirectTransitionDescriptor(selection, (context) => context.owner.from(value(context)), undefined),
|
|
111
|
+
decoded: (value) => makeDirectTransitionDescriptor(selection, (context) => context.owner.decoded(value(context)), undefined),
|
|
112
|
+
resolve: (resolve, options) => makeDirectTransitionDescriptor(selection, resolve, options)
|
|
113
|
+
});
|
|
97
114
|
const noneTransitionSelection = decorateTransitionSelection(Topology.noneTargetSelection);
|
|
98
115
|
const makeInitialBuilderDescriptor = (selection, resolve) => Object.freeze({
|
|
99
116
|
[InitialBuilderDescriptorTypeId]: InitialBuilderDescriptorTypeId,
|
|
@@ -102,6 +119,8 @@ const makeInitialBuilderDescriptor = (selection, resolve) => Object.freeze({
|
|
|
102
119
|
});
|
|
103
120
|
const decorateInitialSelection = (selection) => Object.freeze({
|
|
104
121
|
...selection,
|
|
122
|
+
from: (value) => makeInitialBuilderDescriptor(selection, (context) => context.target.from(value(context))),
|
|
123
|
+
decoded: (value) => makeInitialBuilderDescriptor(selection, (context) => context.target.decoded(value(context))),
|
|
105
124
|
resolve: (resolve) => makeInitialBuilderDescriptor(selection, resolve)
|
|
106
125
|
});
|
|
107
126
|
const decorateInitialSelectorNode = (node) => {
|
|
@@ -125,6 +144,12 @@ const decorateInitialSelectorNode = (node) => {
|
|
|
125
144
|
};
|
|
126
145
|
const decorateTransitionSelectorNode = (node) => {
|
|
127
146
|
if (Topology.isTargetSelection(node)) {
|
|
147
|
+
if (node.kind === "state" && node.scope === "full" && hasProperty(node, "initial")) {
|
|
148
|
+
return Object.freeze({
|
|
149
|
+
...decorateTransitionSelection(node),
|
|
150
|
+
initial: decorateTransitionSelection(node.initial)
|
|
151
|
+
});
|
|
152
|
+
}
|
|
128
153
|
if (node.kind === "update")
|
|
129
154
|
return decorateStateUpdateSelection(node);
|
|
130
155
|
return node === Topology.noneTargetSelection ? noneTransitionSelection : decorateTransitionSelection(node);
|
|
@@ -179,7 +204,7 @@ const normalizeTransitionBuilder = (transition, stateNodes, path) => {
|
|
|
179
204
|
}
|
|
180
205
|
return {
|
|
181
206
|
target: () => descriptor.selection,
|
|
182
|
-
resolve: descriptor.
|
|
207
|
+
resolve: descriptor.resolver,
|
|
183
208
|
reenter: descriptor.reenter,
|
|
184
209
|
declinable: descriptor.declinable
|
|
185
210
|
};
|
|
@@ -215,7 +240,7 @@ const makeSelectionNode = (stateNodes, path, scope, source) => {
|
|
|
215
240
|
addSelectionChildren(method, stateNodes, path, scope, source);
|
|
216
241
|
}
|
|
217
242
|
if (scope === "branch" && source !== undefined && node.schema !== undefined &&
|
|
218
|
-
(source === path ||
|
|
243
|
+
(source === path || Configuration.isDescendantOf(source, path)) &&
|
|
219
244
|
getTargetBuilderNode(stateNodes, source).type !== "choice") {
|
|
220
245
|
Object.defineProperty(method, "update", {
|
|
221
246
|
value: makeStateUpdateSelection(path, "branch"),
|
|
@@ -223,6 +248,9 @@ const makeSelectionNode = (stateNodes, path, scope, source) => {
|
|
|
223
248
|
});
|
|
224
249
|
}
|
|
225
250
|
}
|
|
251
|
+
if (node.type === "atomic" && scope === "branch" && source === path && node.schema !== undefined) {
|
|
252
|
+
Object.defineProperty(method, "update", { value: makeStateUpdateSelection(path, "branch"), enumerable: true });
|
|
253
|
+
}
|
|
226
254
|
return method;
|
|
227
255
|
};
|
|
228
256
|
const makeHistorySelectionTree = (stateNodes, parent) => {
|
|
@@ -242,15 +270,12 @@ const makeHistorySelectionTree = (stateNodes, parent) => {
|
|
|
242
270
|
return builder;
|
|
243
271
|
};
|
|
244
272
|
const makeTargetSelector = (stateNodes, source) => {
|
|
245
|
-
const full = {}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
full[node.key] = makeSelectionNode(stateNodes, node.path, "full");
|
|
249
|
-
}
|
|
250
|
-
}
|
|
273
|
+
const full = Object.assign({}, makeSelectionValue("state", "", "full"), {
|
|
274
|
+
initial: makeSelectionValue("initial", "", "full")
|
|
275
|
+
});
|
|
251
276
|
const branch = {};
|
|
252
|
-
const root = getTargetBuilderNode(stateNodes,
|
|
253
|
-
branch
|
|
277
|
+
const root = getTargetBuilderNode(stateNodes, stateNodes.roots[0]);
|
|
278
|
+
addSelectionChildren(branch, stateNodes, root.path, "branch", source);
|
|
254
279
|
const local = {};
|
|
255
280
|
const localScope = getLocalTargetScope(stateNodes, source);
|
|
256
281
|
if (localScope !== undefined) {
|
|
@@ -265,10 +290,15 @@ const makeTargetSelector = (stateNodes, source) => {
|
|
|
265
290
|
}
|
|
266
291
|
return {
|
|
267
292
|
none: Topology.noneTargetSelection,
|
|
293
|
+
self: getTargetBuilderNode(stateNodes, source).schema === undefined ||
|
|
294
|
+
getTargetBuilderNode(stateNodes, source).type === "final"
|
|
295
|
+
? {}
|
|
296
|
+
: { update: makeStateUpdateSelection(source, "branch") },
|
|
297
|
+
root: makeSelectionNode(stateNodes, root.path, "branch", source),
|
|
268
298
|
local,
|
|
269
299
|
branch,
|
|
270
300
|
full,
|
|
271
|
-
history: makeHistorySelectionTree(stateNodes,
|
|
301
|
+
history: makeHistorySelectionTree(stateNodes, "")
|
|
272
302
|
};
|
|
273
303
|
};
|
|
274
304
|
const captureDefinitionBranch = (branch, selector, stateNodes, path, trigger) => {
|
|
@@ -327,6 +357,8 @@ const getSelectionBuilder = (target, selection, stateNodes, source) => {
|
|
|
327
357
|
let parts = selection.path.split(".");
|
|
328
358
|
if (selection.kind === "history") {
|
|
329
359
|
builder = target.history;
|
|
360
|
+
if (selection.path !== "")
|
|
361
|
+
parts.unshift("");
|
|
330
362
|
}
|
|
331
363
|
else if (selection.scope === "local") {
|
|
332
364
|
builder = target.local;
|
|
@@ -337,12 +369,14 @@ const getSelectionBuilder = (target, selection, stateNodes, source) => {
|
|
|
337
369
|
parts = [];
|
|
338
370
|
}
|
|
339
371
|
else {
|
|
340
|
-
parts = selection.path.slice(scope.length + 1).split(".");
|
|
372
|
+
parts = (scope === "" ? selection.path : selection.path.slice(scope.length + 1)).split(".");
|
|
341
373
|
}
|
|
342
374
|
}
|
|
343
375
|
}
|
|
344
376
|
else if (selection.scope === "branch") {
|
|
345
377
|
builder = target.branch;
|
|
378
|
+
if (selection.path !== "")
|
|
379
|
+
parts.unshift("");
|
|
346
380
|
}
|
|
347
381
|
else {
|
|
348
382
|
builder = target.full;
|
|
@@ -390,7 +424,7 @@ const validateResolvedSelection = (result, selection, stateNodes) => {
|
|
|
390
424
|
const acceptsDescendant = (selection.scope === "local" || selection.scope === "branch") &&
|
|
391
425
|
(selectedNode?.type === "compound" || selectedNode?.type === "parallel");
|
|
392
426
|
if (resultPath === undefined ||
|
|
393
|
-
(resultPath !== selection.path && !(acceptsDescendant &&
|
|
427
|
+
(resultPath !== selection.path && !(acceptsDescendant && Configuration.isDescendantOf(resultPath, selection.path)))) {
|
|
394
428
|
throw new Error(`Machine transition resolver selected "${selection.path}" but constructed "${resultPath ?? "<invalid>"}"`);
|
|
395
429
|
}
|
|
396
430
|
};
|
|
@@ -654,10 +688,10 @@ const captureInvokeDefinition = (invoke, stateNodes, path) => {
|
|
|
654
688
|
captured[key] = captureTransition(captured[key], stateNodes, path, key);
|
|
655
689
|
}
|
|
656
690
|
}
|
|
657
|
-
return captured;
|
|
691
|
+
return InvocationDefinition.capture(captured, path);
|
|
658
692
|
});
|
|
659
693
|
if (Array.isArray(authored))
|
|
660
|
-
return capturedDefinitions;
|
|
694
|
+
return Object.freeze(capturedDefinitions);
|
|
661
695
|
return capturedDefinitions[0];
|
|
662
696
|
};
|
|
663
697
|
const flattenHandlers = (handlers, stateNodes, states, prefix, config) => {
|
|
@@ -671,6 +705,12 @@ const flattenHandlers = (handlers, stateNodes, states, prefix, config) => {
|
|
|
671
705
|
throw new Error(`Machine expected state "${path}" handler to be an object`);
|
|
672
706
|
}
|
|
673
707
|
const { states: childConfig, ...stateConfig } = nodeConfig;
|
|
708
|
+
if (typeof stateConfig.history === "object" && stateConfig.history !== null) {
|
|
709
|
+
stateConfig.history = Object.freeze(Object.fromEntries(Object.entries(stateConfig.history).map(([key, entry]) => [
|
|
710
|
+
key,
|
|
711
|
+
typeof entry === "object" && entry !== null ? Object.freeze({ ...entry }) : entry
|
|
712
|
+
])));
|
|
713
|
+
}
|
|
674
714
|
const on = stateConfig.on;
|
|
675
715
|
if (typeof on === "object" && on !== null) {
|
|
676
716
|
const capturedOn = captureEventHandlers(on, stateNodes, path);
|
|
@@ -712,340 +752,11 @@ const flattenHandlers = (handlers, stateNodes, states, prefix, config) => {
|
|
|
712
752
|
};
|
|
713
753
|
const makeHandle = (self) => ((config) => {
|
|
714
754
|
const handlers = Object.create(null);
|
|
715
|
-
flattenHandlers(handlers, self.stateNodes, self.states, "", config);
|
|
755
|
+
flattenHandlers(handlers, self.stateNodes, self.states, "", { "": config });
|
|
716
756
|
return makeWithHandlers(self, handlers);
|
|
717
757
|
});
|
|
718
758
|
export const isMachine = (u) => hasProperty(u, TypeId) && u[TypeId] === TypeId;
|
|
719
759
|
export const isFinal = (machine, state) => internalPlanner.isFinal(machine, state);
|
|
720
|
-
const withFrom = (method, kind, valued) => {
|
|
721
|
-
const builder = {};
|
|
722
|
-
if (valued) {
|
|
723
|
-
Object.defineProperty(builder, "decoded", {
|
|
724
|
-
value: method,
|
|
725
|
-
enumerable: false
|
|
726
|
-
});
|
|
727
|
-
}
|
|
728
|
-
Object.defineProperty(builder, "from", {
|
|
729
|
-
value: (...args) => {
|
|
730
|
-
if (!valued) {
|
|
731
|
-
return method(undefined, ...args);
|
|
732
|
-
}
|
|
733
|
-
const omitted = args.length === 0 || (kind === "nested" && args.length === 1 && typeof args[0] === "function");
|
|
734
|
-
const input = omitted ? {} : args[0];
|
|
735
|
-
const rest = omitted ? args : args.slice(1);
|
|
736
|
-
return method(Topology.makeStateInput(input), ...rest);
|
|
737
|
-
},
|
|
738
|
-
enumerable: false
|
|
739
|
-
});
|
|
740
|
-
return builder;
|
|
741
|
-
};
|
|
742
|
-
const withInitial = (builder, path, valued, values) => {
|
|
743
|
-
const initial = withFrom((value) => Topology.makeInitialTarget(path, value, values), "leaf", valued);
|
|
744
|
-
Object.defineProperty(builder, "initial", {
|
|
745
|
-
value: initial,
|
|
746
|
-
enumerable: false
|
|
747
|
-
});
|
|
748
|
-
return builder;
|
|
749
|
-
};
|
|
750
|
-
const makeSnapshotBuilder = (states, options) => {
|
|
751
|
-
const builder = {};
|
|
752
|
-
for (const key of Object.keys(states)) {
|
|
753
|
-
const definition = states[key];
|
|
754
|
-
const pseudoType = definition.type;
|
|
755
|
-
if (pseudoType === "history") {
|
|
756
|
-
continue;
|
|
757
|
-
}
|
|
758
|
-
const path = options.prefix === "" ? key : `${options.prefix}.${key}`;
|
|
759
|
-
if (pseudoType === "choice") {
|
|
760
|
-
builder[key] = () => Topology.makeChoiceTarget(path, getParentPathRuntime(path));
|
|
761
|
-
continue;
|
|
762
|
-
}
|
|
763
|
-
const node = Topology.getStateNodeDefinition(path, definition);
|
|
764
|
-
const method = withFrom((value, selector) => makeSnapshotForNode(definition, key, value, selector, options), node.states === undefined ? "leaf" : "nested", node.schema !== undefined);
|
|
765
|
-
builder[key] = node.states === undefined || options.mode !== "full" || options.prefix !== ""
|
|
766
|
-
? method
|
|
767
|
-
: withInitial(method, path, node.schema !== undefined);
|
|
768
|
-
}
|
|
769
|
-
return builder;
|
|
770
|
-
};
|
|
771
|
-
const makeParallelSnapshotBuilder = (states, options, regions) => {
|
|
772
|
-
const builder = {};
|
|
773
|
-
Object.defineProperty(builder, SnapshotBuilderStateTypeId, {
|
|
774
|
-
value: regions,
|
|
775
|
-
enumerable: false
|
|
776
|
-
});
|
|
777
|
-
for (const key of Object.keys(states)) {
|
|
778
|
-
const definition = states[key];
|
|
779
|
-
const pseudoType = definition.type;
|
|
780
|
-
if (pseudoType === "history" || pseudoType === "choice") {
|
|
781
|
-
continue;
|
|
782
|
-
}
|
|
783
|
-
if (hasProperty(regions, key)) {
|
|
784
|
-
continue;
|
|
785
|
-
}
|
|
786
|
-
const path = options.prefix === "" ? key : `${options.prefix}.${key}`;
|
|
787
|
-
const node = Topology.getStateNodeDefinition(path, definition);
|
|
788
|
-
const method = withFrom((value, selector) => {
|
|
789
|
-
const nextRegions = {};
|
|
790
|
-
for (const regionKey of Object.keys(regions)) {
|
|
791
|
-
nextRegions[regionKey] = regions[regionKey];
|
|
792
|
-
}
|
|
793
|
-
nextRegions[key] = makeSnapshotForNode(definition, key, value, selector, options);
|
|
794
|
-
return makeParallelSnapshotBuilder(states, options, nextRegions);
|
|
795
|
-
}, node.states === undefined ? "leaf" : "nested", node.schema !== undefined);
|
|
796
|
-
builder[key] = method;
|
|
797
|
-
}
|
|
798
|
-
return builder;
|
|
799
|
-
};
|
|
800
|
-
const getParallelSnapshotBuilderRegions = (path, states, builder) => {
|
|
801
|
-
if (typeof builder !== "object" || builder === null || !hasProperty(builder, SnapshotBuilderStateTypeId)) {
|
|
802
|
-
throw new Error(`Machine expected parallel state "${path}" builder callback to return a builder`);
|
|
803
|
-
}
|
|
804
|
-
const regions = builder[SnapshotBuilderStateTypeId];
|
|
805
|
-
for (const key of Object.keys(states)) {
|
|
806
|
-
const pseudoType = states[key].type;
|
|
807
|
-
if (pseudoType === "history" || pseudoType === "choice") {
|
|
808
|
-
continue;
|
|
809
|
-
}
|
|
810
|
-
if (!hasProperty(regions, key)) {
|
|
811
|
-
throw new Error(`Machine expected parallel state "${path}" builder callback to provide region "${key}"`);
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
return regions;
|
|
815
|
-
};
|
|
816
|
-
const makeSnapshotForNode = (definition, key, value, selector, options) => {
|
|
817
|
-
const path = options.prefix === "" ? key : `${options.prefix}.${key}`;
|
|
818
|
-
const node = Topology.getStateNodeDefinition(path, definition);
|
|
819
|
-
const snapshot = {
|
|
820
|
-
path,
|
|
821
|
-
value
|
|
822
|
-
};
|
|
823
|
-
if (node.states === undefined) {
|
|
824
|
-
return snapshot;
|
|
825
|
-
}
|
|
826
|
-
if (selector === undefined) {
|
|
827
|
-
throw new Error(`Machine expected state "${path}" builder to provide active child states`);
|
|
828
|
-
}
|
|
829
|
-
if (node.type === "parallel") {
|
|
830
|
-
const builder = makeParallelSnapshotBuilder(node.states, { ...options, prefix: path }, {});
|
|
831
|
-
const selected = selector(builder);
|
|
832
|
-
snapshot.states = getParallelSnapshotBuilderRegions(path, node.states, selected);
|
|
833
|
-
return snapshot;
|
|
834
|
-
}
|
|
835
|
-
const childStates = options.mode === "initial" && node.initial !== undefined
|
|
836
|
-
? { [node.initial]: node.states[node.initial] }
|
|
837
|
-
: node.states;
|
|
838
|
-
const selected = selector(makeSnapshotBuilder(childStates, { ...options, prefix: path }));
|
|
839
|
-
snapshot.state = selected;
|
|
840
|
-
return snapshot;
|
|
841
|
-
};
|
|
842
|
-
const getTargetBuilderNode = (stateNodes, path) => {
|
|
843
|
-
const node = stateNodes.byPath.get(path);
|
|
844
|
-
if (node === undefined) {
|
|
845
|
-
throw new Error(`Machine expected state path "${path}" to exist`);
|
|
846
|
-
}
|
|
847
|
-
return node;
|
|
848
|
-
};
|
|
849
|
-
const getLocalTargetScope = (stateNodes, source) => {
|
|
850
|
-
let current = source;
|
|
851
|
-
while (current !== undefined) {
|
|
852
|
-
const node = stateNodes.byPath.get(current);
|
|
853
|
-
if (node === undefined) {
|
|
854
|
-
return undefined;
|
|
855
|
-
}
|
|
856
|
-
if (node.type === "compound") {
|
|
857
|
-
return node.path;
|
|
858
|
-
}
|
|
859
|
-
current = node.parent;
|
|
860
|
-
}
|
|
861
|
-
return undefined;
|
|
862
|
-
};
|
|
863
|
-
const hasTargetValues = (values) => values !== undefined && Object.keys(values).length > 0;
|
|
864
|
-
const makeTargetWithValues = (path, value, values) => hasTargetValues(values)
|
|
865
|
-
? Topology.makeTarget(path, value, { values: values })
|
|
866
|
-
: Topology.makeTarget(path, value);
|
|
867
|
-
const getTargetBuilderDefinition = (states, targetPath) => {
|
|
868
|
-
let children = states;
|
|
869
|
-
let path = "";
|
|
870
|
-
let definition;
|
|
871
|
-
for (const key of targetPath.split(".")) {
|
|
872
|
-
if (!hasProperty(children, key)) {
|
|
873
|
-
throw new Error(`Machine expected state path "${targetPath}" to exist`);
|
|
874
|
-
}
|
|
875
|
-
definition = children[key];
|
|
876
|
-
path = path === "" ? key : `${path}.${key}`;
|
|
877
|
-
const node = Topology.getStateNodeDefinition(path, definition);
|
|
878
|
-
children = node.states ?? {};
|
|
879
|
-
}
|
|
880
|
-
return definition;
|
|
881
|
-
};
|
|
882
|
-
const makeParallelTarget = (states, node, value, selector, values) => {
|
|
883
|
-
if (selector === undefined) {
|
|
884
|
-
throw new Error(`Machine expected parallel target "${node.path}" builder to provide every active region`);
|
|
885
|
-
}
|
|
886
|
-
const snapshot = makeSnapshotForNode(getTargetBuilderDefinition(states, node.path), node.key, value, selector, { mode: "full", prefix: node.parent ?? "" });
|
|
887
|
-
return Topology.makeTarget(node.path, value, {
|
|
888
|
-
snapshot: snapshot,
|
|
889
|
-
values: values
|
|
890
|
-
});
|
|
891
|
-
};
|
|
892
|
-
const extendTargetValues = (values, path, value) => {
|
|
893
|
-
const next = {};
|
|
894
|
-
if (values !== undefined) {
|
|
895
|
-
for (const key of Object.keys(values)) {
|
|
896
|
-
next[key] = values[key];
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
next[path] = value;
|
|
900
|
-
return next;
|
|
901
|
-
};
|
|
902
|
-
const makeLocalTargetChildBuilder = (states, stateNodes, parentPath, values, source) => {
|
|
903
|
-
const parent = getTargetBuilderNode(stateNodes, parentPath);
|
|
904
|
-
const builder = {};
|
|
905
|
-
for (const childPath of Array.from(stateNodes.byPath.values())
|
|
906
|
-
.filter((node) => node.parent === parent.path && node.type !== "history")
|
|
907
|
-
.map((node) => node.path)) {
|
|
908
|
-
const child = getTargetBuilderNode(stateNodes, childPath);
|
|
909
|
-
if (child.type === "choice") {
|
|
910
|
-
builder[child.key] = () => Topology.makeChoiceTarget(child.path, parent.path, values);
|
|
911
|
-
continue;
|
|
912
|
-
}
|
|
913
|
-
const method = withFrom((value, selector) => {
|
|
914
|
-
if (child.type === "atomic" || child.type === "final") {
|
|
915
|
-
return makeTargetWithValues(child.path, value, values);
|
|
916
|
-
}
|
|
917
|
-
if (child.type === "parallel") {
|
|
918
|
-
if (source !== child.path && !source.startsWith(`${child.path}.`)) {
|
|
919
|
-
return makeParallelTarget(states, child, value, selector, values);
|
|
920
|
-
}
|
|
921
|
-
if (selector === undefined) {
|
|
922
|
-
throw new Error(`Machine expected target "${child.path}" builder to provide an active child state`);
|
|
923
|
-
}
|
|
924
|
-
return selector(makeLocalTargetChildBuilder(states, stateNodes, child.path, child.schema === undefined ? values : extendTargetValues(values, child.path, value), source));
|
|
925
|
-
}
|
|
926
|
-
if (selector === undefined) {
|
|
927
|
-
throw new Error(`Machine expected target "${child.path}" builder to provide an active child state`);
|
|
928
|
-
}
|
|
929
|
-
return selector(makeLocalTargetChildBuilder(states, stateNodes, child.path, child.schema === undefined ? values : extendTargetValues(values, child.path, value), source));
|
|
930
|
-
}, child.type === "atomic" || child.type === "final" ? "leaf" : "nested", child.schema !== undefined);
|
|
931
|
-
builder[child.key] = child.type === "atomic" || child.type === "final"
|
|
932
|
-
? method
|
|
933
|
-
: withInitial(method, child.path, child.schema !== undefined, values);
|
|
934
|
-
}
|
|
935
|
-
return builder;
|
|
936
|
-
};
|
|
937
|
-
const makeLocalTargetBuilder = (states, stateNodes, source) => {
|
|
938
|
-
const scope = getLocalTargetScope(stateNodes, source);
|
|
939
|
-
if (scope === undefined) {
|
|
940
|
-
return {};
|
|
941
|
-
}
|
|
942
|
-
const builder = makeLocalTargetChildBuilder(states, stateNodes, scope, undefined, source);
|
|
943
|
-
const scopeNode = getTargetBuilderNode(stateNodes, scope);
|
|
944
|
-
if (scopeNode.schema !== undefined) {
|
|
945
|
-
builder.with = withFrom((value, selector) => {
|
|
946
|
-
if (selector === undefined) {
|
|
947
|
-
throw new Error(`Machine expected target "${scope}" builder to provide an active child state`);
|
|
948
|
-
}
|
|
949
|
-
return selector(makeLocalTargetChildBuilder(states, stateNodes, scope, { [scope]: value }, source));
|
|
950
|
-
}, "nested", true);
|
|
951
|
-
}
|
|
952
|
-
return builder;
|
|
953
|
-
};
|
|
954
|
-
const addBranchTargetChildren = (builder, states, stateNodes, parentPath, values, source) => {
|
|
955
|
-
const parent = getTargetBuilderNode(stateNodes, parentPath);
|
|
956
|
-
for (const childPath of Array.from(stateNodes.byPath.values())
|
|
957
|
-
.filter((node) => node.parent === parent.path && node.type !== "history")
|
|
958
|
-
.map((node) => node.path)) {
|
|
959
|
-
const child = getTargetBuilderNode(stateNodes, childPath);
|
|
960
|
-
if (child.type === "choice") {
|
|
961
|
-
builder[child.key] = () => Topology.makeChoiceTarget(child.path, parent.path, values);
|
|
962
|
-
continue;
|
|
963
|
-
}
|
|
964
|
-
builder[child.key] = makeBranchTargetNodeBuilder(states, stateNodes, child.path, values, source);
|
|
965
|
-
}
|
|
966
|
-
};
|
|
967
|
-
const makeBranchTargetNodeBuilder = (states, stateNodes, path, values, source) => {
|
|
968
|
-
const node = getTargetBuilderNode(stateNodes, path);
|
|
969
|
-
if (node.type === "atomic" || node.type === "final") {
|
|
970
|
-
return withFrom((value) => makeTargetWithValues(node.path, value, values), "leaf", node.schema !== undefined);
|
|
971
|
-
}
|
|
972
|
-
const builder = withFrom((value, selector) => {
|
|
973
|
-
if (node.type === "parallel") {
|
|
974
|
-
if (source !== node.path && !source.startsWith(`${node.path}.`)) {
|
|
975
|
-
return makeParallelTarget(states, node, value, selector, values);
|
|
976
|
-
}
|
|
977
|
-
if (selector === undefined) {
|
|
978
|
-
throw new Error(`Machine expected target "${node.path}" builder to provide an active child state`);
|
|
979
|
-
}
|
|
980
|
-
const nextBuilder = {};
|
|
981
|
-
addBranchTargetChildren(nextBuilder, states, stateNodes, node.path, node.schema === undefined ? values : extendTargetValues(values, node.path, value), source);
|
|
982
|
-
return selector(nextBuilder);
|
|
983
|
-
}
|
|
984
|
-
if (selector === undefined) {
|
|
985
|
-
throw new Error(`Machine expected target "${node.path}" builder to provide an active child state`);
|
|
986
|
-
}
|
|
987
|
-
const nextBuilder = {};
|
|
988
|
-
addBranchTargetChildren(nextBuilder, states, stateNodes, node.path, node.schema === undefined ? values : extendTargetValues(values, node.path, value), source);
|
|
989
|
-
return selector(nextBuilder);
|
|
990
|
-
}, "nested", node.schema !== undefined);
|
|
991
|
-
withInitial(builder, node.path, node.schema !== undefined, values);
|
|
992
|
-
if (node.type !== "parallel" || source === node.path || source.startsWith(`${node.path}.`)) {
|
|
993
|
-
addBranchTargetChildren(builder, states, stateNodes, node.path, values, source);
|
|
994
|
-
}
|
|
995
|
-
return builder;
|
|
996
|
-
};
|
|
997
|
-
const makeBranchTargetBuilder = (states, stateNodes, source) => {
|
|
998
|
-
const rootPath = source.split(".")[0];
|
|
999
|
-
const root = getTargetBuilderNode(stateNodes, rootPath);
|
|
1000
|
-
return {
|
|
1001
|
-
[root.key]: makeBranchTargetNodeBuilder(states, stateNodes, root.path, undefined, source)
|
|
1002
|
-
};
|
|
1003
|
-
};
|
|
1004
|
-
const makeHistoryTargetBuilder = (states, prefix) => {
|
|
1005
|
-
const builder = {};
|
|
1006
|
-
for (const key of Object.keys(states)) {
|
|
1007
|
-
const path = prefix === "" ? key : `${prefix}.${key}`;
|
|
1008
|
-
const definition = Topology.getStateNodeDefinition(path, states[key]);
|
|
1009
|
-
if (definition.type === "history") {
|
|
1010
|
-
const parent = getParentPathRuntime(path);
|
|
1011
|
-
builder[key] = () => Topology.makeHistoryTarget(path, parent);
|
|
1012
|
-
continue;
|
|
1013
|
-
}
|
|
1014
|
-
if (definition.states !== undefined) {
|
|
1015
|
-
builder[key] = makeHistoryTargetBuilder(definition.states, path);
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
return builder;
|
|
1019
|
-
};
|
|
1020
|
-
const getParentPathRuntime = (path) => {
|
|
1021
|
-
const separator = path.lastIndexOf(".");
|
|
1022
|
-
if (separator < 0) {
|
|
1023
|
-
throw new Error(`Machine expected history state "${path}" to have an active parent`);
|
|
1024
|
-
}
|
|
1025
|
-
return path.slice(0, separator);
|
|
1026
|
-
};
|
|
1027
|
-
const makeTargetBuilder = (states, stateNodes) => {
|
|
1028
|
-
const full = makeSnapshotBuilder(states, { mode: "full", prefix: "" });
|
|
1029
|
-
const history = makeHistoryTargetBuilder(states, "");
|
|
1030
|
-
return (source) => ({
|
|
1031
|
-
none: Topology.makeNoTarget,
|
|
1032
|
-
local: makeLocalTargetBuilder(states, stateNodes, source),
|
|
1033
|
-
branch: makeBranchTargetBuilder(states, stateNodes, source),
|
|
1034
|
-
full,
|
|
1035
|
-
history
|
|
1036
|
-
});
|
|
1037
|
-
};
|
|
1038
|
-
const makeInitialSelector = (stateNodes) => {
|
|
1039
|
-
const selector = {};
|
|
1040
|
-
for (const node of stateNodes.byPath.values()) {
|
|
1041
|
-
if (node.parent === undefined && node.type !== "history" && node.type !== "choice") {
|
|
1042
|
-
selector[node.key] = node.type === "atomic" || node.type === "final"
|
|
1043
|
-
? makeSelectionMethod("state", node.path, "initial")
|
|
1044
|
-
: Object.freeze({ initial: makeSelectionValue("initial", node.path, "initial") });
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
return Object.freeze(selector);
|
|
1048
|
-
};
|
|
1049
760
|
const getInitialSelectionBuilder = (initialBuilder, selection) => {
|
|
1050
761
|
const path = selection.path;
|
|
1051
762
|
if (path === undefined || path.includes(".")) {
|
|
@@ -1057,11 +768,12 @@ const getInitialSelectionBuilder = (initialBuilder, selection) => {
|
|
|
1057
768
|
}
|
|
1058
769
|
return builder;
|
|
1059
770
|
};
|
|
1060
|
-
const captureInitialBranch = (definition,
|
|
1061
|
-
if (typeof definition !== "function") {
|
|
771
|
+
const captureInitialBranch = (definition, initialBuilder, configuration) => {
|
|
772
|
+
if (definition !== undefined && typeof definition !== "function") {
|
|
1062
773
|
throw new Error("Machine initial definition must be a target-first callback");
|
|
1063
774
|
}
|
|
1064
|
-
const
|
|
775
|
+
const selector = decorateInitialSelection(makeSelectionValue(configuration ? "state" : "initial", "", "initial"));
|
|
776
|
+
const result = definition === undefined ? selector : definition(selector);
|
|
1065
777
|
let selection;
|
|
1066
778
|
let resolve;
|
|
1067
779
|
if (Topology.isTargetSelection(result)) {
|
|
@@ -1092,9 +804,12 @@ const validateInitialSelection = (result, selection) => {
|
|
|
1092
804
|
throw new Error(`Machine initial resolver selected "${selection.path}" but constructed "${resultPath}"`);
|
|
1093
805
|
}
|
|
1094
806
|
};
|
|
1095
|
-
const compileInitial = (definition, states, stateNodes) => {
|
|
1096
|
-
const
|
|
1097
|
-
const
|
|
807
|
+
const compileInitial = (definition, states, stateNodes, configuration = false) => {
|
|
808
|
+
const rootNode = getTargetBuilderNode(stateNodes, "");
|
|
809
|
+
const initialBuilder = configuration ?
|
|
810
|
+
makeSnapshotBuilder(states, { mode: "full", prefix: "" })
|
|
811
|
+
: { "": withFrom((value) => Topology.makeInitialTarget("", value), "leaf", rootNode.schema !== undefined) };
|
|
812
|
+
const branch = captureInitialBranch(definition, initialBuilder, configuration);
|
|
1098
813
|
return {
|
|
1099
814
|
initial: (input) => {
|
|
1100
815
|
const result = branch.resolve === undefined
|
|
@@ -1109,15 +824,13 @@ const compileInitial = (definition, states, stateNodes) => {
|
|
|
1109
824
|
})
|
|
1110
825
|
};
|
|
1111
826
|
};
|
|
1112
|
-
export const state = (
|
|
1113
|
-
StateDefinition.
|
|
1114
|
-
|
|
1115
|
-
});
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
const captured = StateDefinition.captureStateDefinitions(states);
|
|
827
|
+
export const state = (node) => {
|
|
828
|
+
const captured = StateDefinition.captureRoot(node);
|
|
829
|
+
const access = makeStateHelpers();
|
|
830
|
+
return Object.freeze({ ...access, "~effect/Machine/State": "~effect/Machine/State", node: captured });
|
|
831
|
+
};
|
|
832
|
+
const makeStateHelpers = () => {
|
|
1119
833
|
return {
|
|
1120
|
-
states: captured,
|
|
1121
834
|
path: ((path) => path),
|
|
1122
835
|
get: ((snapshot, path) => Topology.getSnapshotByPath(snapshot, path).pipe(Option.map((snapshot) => snapshot.value))),
|
|
1123
836
|
getWithParents: ((snapshot, path) => {
|
|
@@ -1127,31 +840,42 @@ export const states = ((states) => {
|
|
|
1127
840
|
getSnapshot: Topology.getSnapshotByPath,
|
|
1128
841
|
matches: ((snapshot, path) => Option.isSome(Topology.getSnapshotByPath(snapshot, path)))
|
|
1129
842
|
};
|
|
1130
|
-
}
|
|
1131
|
-
export const make = (
|
|
1132
|
-
|
|
843
|
+
};
|
|
844
|
+
export const make = (config) => {
|
|
845
|
+
const states = Object.freeze({ "": config.root.node });
|
|
1133
846
|
const self = Object.create(Proto);
|
|
1134
|
-
self.states =
|
|
847
|
+
self.states = states;
|
|
848
|
+
self.root = config.root;
|
|
1135
849
|
self.events = config.events;
|
|
1136
850
|
self.internalEvents = config.internalEvents ?? Protocol.makeEventProtocol("internal", []);
|
|
1137
851
|
self.emittedEvents = config.emittedEvents ?? Protocol.makeEventProtocol("emitted", []);
|
|
1138
852
|
self.parent = config.parent;
|
|
1139
853
|
self.input = config.input;
|
|
1140
854
|
self.id = config.id;
|
|
1141
|
-
self.stateNodes = Topology.compileStateNodes(
|
|
1142
|
-
const compiledInitial = compileInitial(config.initial,
|
|
855
|
+
self.stateNodes = Topology.compileStateNodes(states);
|
|
856
|
+
const compiledInitial = compileInitial(config.initialConfiguration ?? config.initial, states, self.stateNodes, config.initialConfiguration !== undefined);
|
|
1143
857
|
self.initial = compiledInitial.initial;
|
|
1144
858
|
self.initialDefinition = compiledInitial.definition;
|
|
1145
|
-
self.makeTargetBuilder = makeTargetBuilder(
|
|
859
|
+
self.makeTargetBuilder = makeTargetBuilder(states, self.stateNodes);
|
|
1146
860
|
self.handlers = Object.create(null);
|
|
1147
861
|
self.handle = makeHandle(self);
|
|
1148
862
|
Protocol.setProtocol(self);
|
|
1149
863
|
return self;
|
|
1150
|
-
}
|
|
864
|
+
};
|
|
1151
865
|
const flattenEventProtocolInputs = (kind, inputs) => inputs.flatMap((input) => Protocol.isEventProtocol(input, kind)
|
|
1152
866
|
? Protocol.eventProtocolSchemas(input)
|
|
1153
867
|
: [input]);
|
|
1154
868
|
export const events = (...inputs) => Protocol.makeEventProtocol("public", flattenEventProtocolInputs("public", inputs));
|
|
869
|
+
const eventFieldSchemas = (cases) => {
|
|
870
|
+
for (const [tag, fields] of Object.entries(cases)) {
|
|
871
|
+
if (Object.hasOwn(fields, "_tag"))
|
|
872
|
+
throw new Error(`Machine event "${tag}" fields cannot declare _tag`);
|
|
873
|
+
}
|
|
874
|
+
return Object.keys(cases).length === 0 ? [] : [Schema.TaggedUnion(cases)];
|
|
875
|
+
};
|
|
876
|
+
export const eventsFromFields = (cases) => Protocol.makeEventProtocol("public", eventFieldSchemas(cases));
|
|
877
|
+
export const internalEventsFromFields = (cases) => Protocol.makeEventProtocol("internal", eventFieldSchemas(cases));
|
|
878
|
+
export const emittedEventsFromFields = (cases) => Protocol.makeEventProtocol("emitted", eventFieldSchemas(cases));
|
|
1155
879
|
const makeParent = (mode, events) => {
|
|
1156
880
|
if (!Protocol.isEventProtocol(events, "public")) {
|
|
1157
881
|
throw new Error("Machine parent declarations require a protocol created with Machine.events");
|