@typeonce/effect-machine 0.2.0 → 0.4.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 +345 -42
- package/dist/Machine.d.ts +1273 -347
- package/dist/Machine.d.ts.map +1 -1
- package/dist/Machine.js +161 -426
- package/dist/Machine.js.map +1 -1
- package/dist/internal/machine/activities.d.ts +57 -0
- package/dist/internal/machine/activities.d.ts.map +1 -0
- package/dist/internal/machine/activities.js +49 -0
- package/dist/internal/machine/activities.js.map +1 -0
- package/dist/internal/machine/atom.d.ts +69 -0
- package/dist/internal/machine/atom.d.ts.map +1 -0
- package/dist/{AtomMachine.js → internal/machine/atom.js} +19 -94
- package/dist/internal/machine/atom.js.map +1 -0
- package/dist/internal/machine/cluster.d.ts +63 -0
- package/dist/internal/machine/cluster.d.ts.map +1 -0
- package/dist/{ClusterMachine.js → internal/machine/cluster.js} +15 -119
- package/dist/internal/machine/cluster.js.map +1 -0
- package/dist/internal/machine/command.d.ts +16 -0
- package/dist/internal/machine/command.d.ts.map +1 -0
- package/dist/internal/machine/command.js +45 -0
- package/dist/internal/machine/command.js.map +1 -0
- package/dist/internal/machine/commandRuntime.d.ts +13 -0
- package/dist/internal/machine/commandRuntime.d.ts.map +1 -0
- package/dist/internal/machine/commandRuntime.js +16 -0
- package/dist/internal/machine/commandRuntime.js.map +1 -0
- package/dist/internal/{machineModel.d.ts → machine/configuration.d.ts} +32 -38
- package/dist/internal/machine/configuration.d.ts.map +1 -0
- package/dist/internal/machine/configuration.js +965 -0
- package/dist/internal/machine/configuration.js.map +1 -0
- package/dist/internal/{machineErrors.d.ts → machine/errors.d.ts} +3 -3
- package/dist/internal/machine/errors.d.ts.map +1 -0
- package/dist/internal/{machineErrors.js → machine/errors.js} +1 -1
- package/dist/internal/machine/errors.js.map +1 -0
- package/dist/internal/machine/executionPlan.d.ts +49 -0
- package/dist/internal/machine/executionPlan.d.ts.map +1 -0
- package/dist/internal/machine/executionPlan.js +667 -0
- package/dist/internal/machine/executionPlan.js.map +1 -0
- package/dist/internal/machine/invocation.d.ts +23 -0
- package/dist/internal/machine/invocation.d.ts.map +1 -0
- package/dist/internal/machine/invocation.js +77 -0
- package/dist/internal/machine/invocation.js.map +1 -0
- package/dist/internal/machine/machine.d.ts +183 -0
- package/dist/internal/machine/machine.d.ts.map +1 -0
- package/dist/internal/machine/machine.js +552 -0
- package/dist/internal/machine/machine.js.map +1 -0
- package/dist/internal/machine/planner.d.ts +182 -0
- package/dist/internal/machine/planner.d.ts.map +1 -0
- package/dist/internal/machine/planner.js +1082 -0
- package/dist/internal/machine/planner.js.map +1 -0
- package/dist/internal/{machineProcess.d.ts → machine/process.d.ts} +10 -4
- package/dist/internal/machine/process.d.ts.map +1 -0
- package/dist/internal/machine/process.js +446 -0
- package/dist/internal/machine/process.js.map +1 -0
- package/dist/internal/machine/protocol.d.ts +34 -0
- package/dist/internal/machine/protocol.d.ts.map +1 -0
- package/dist/internal/machine/protocol.js +182 -0
- package/dist/internal/machine/protocol.js.map +1 -0
- package/dist/internal/machine/readiness.d.ts +4 -0
- package/dist/internal/machine/readiness.d.ts.map +1 -0
- package/dist/internal/machine/readiness.js +2 -0
- package/dist/internal/machine/readiness.js.map +1 -0
- package/dist/internal/{machineRuntime.d.ts → machine/runtime.d.ts} +104 -2
- package/dist/internal/machine/runtime.d.ts.map +1 -0
- package/dist/internal/machine/runtime.js +1381 -0
- package/dist/internal/machine/runtime.js.map +1 -0
- package/dist/internal/machine/serialization.d.ts +14 -0
- package/dist/internal/machine/serialization.d.ts.map +1 -0
- package/dist/internal/machine/serialization.js +338 -0
- package/dist/internal/machine/serialization.js.map +1 -0
- package/dist/internal/machine/stateDefinition.d.ts +15 -0
- package/dist/internal/machine/stateDefinition.d.ts.map +1 -0
- package/dist/internal/machine/stateDefinition.js +210 -0
- package/dist/internal/machine/stateDefinition.js.map +1 -0
- package/dist/internal/machine/symbols.d.ts +3 -0
- package/dist/internal/machine/symbols.d.ts.map +1 -0
- package/dist/internal/machine/symbols.js +3 -0
- package/dist/internal/machine/symbols.js.map +1 -0
- package/dist/internal/machine/topology.d.ts +98 -0
- package/dist/internal/machine/topology.d.ts.map +1 -0
- package/dist/internal/machine/topology.js +347 -0
- package/dist/internal/machine/topology.js.map +1 -0
- package/dist/internal/testing/machine/arbitrary.d.ts +36 -0
- package/dist/internal/testing/machine/arbitrary.d.ts.map +1 -0
- package/dist/internal/testing/machine/arbitrary.js +68 -0
- package/dist/internal/testing/machine/arbitrary.js.map +1 -0
- package/dist/internal/testing/machine/finiteModel.d.ts +322 -0
- package/dist/internal/testing/machine/finiteModel.d.ts.map +1 -0
- package/dist/internal/testing/machine/finiteModel.js +976 -0
- package/dist/internal/testing/machine/finiteModel.js.map +1 -0
- package/dist/internal/testing/machine/referenceModel.d.ts +203 -0
- package/dist/internal/testing/machine/referenceModel.d.ts.map +1 -0
- package/dist/internal/testing/machine/referenceModel.js +1012 -0
- package/dist/internal/testing/machine/referenceModel.js.map +1 -0
- package/dist/internal/testing/machine/runtime.d.ts +328 -0
- package/dist/internal/testing/machine/runtime.d.ts.map +1 -0
- package/dist/internal/testing/machine/runtime.js +437 -0
- package/dist/internal/testing/machine/runtime.js.map +1 -0
- package/dist/internal/testing/machine/verification.d.ts +33 -0
- package/dist/internal/testing/machine/verification.d.ts.map +1 -0
- package/dist/internal/testing/machine/verification.js +1446 -0
- package/dist/internal/testing/machine/verification.js.map +1 -0
- package/dist/testing/MachineTest.d.ts +606 -0
- package/dist/testing/MachineTest.d.ts.map +1 -0
- package/dist/testing/MachineTest.js +102 -0
- package/dist/testing/MachineTest.js.map +1 -0
- package/dist/testing/index.d.ts +7 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +7 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/{ClusterMachine.d.ts → unstable/cluster/ClusterMachine.d.ts} +22 -30
- package/dist/unstable/cluster/ClusterMachine.d.ts.map +1 -0
- package/dist/unstable/cluster/ClusterMachine.js +126 -0
- package/dist/unstable/cluster/ClusterMachine.js.map +1 -0
- package/dist/{cluster.js → unstable/cluster/index.d.ts} +1 -1
- package/dist/unstable/cluster/index.d.ts.map +1 -0
- package/dist/{cluster.d.ts → unstable/cluster/index.js} +1 -1
- package/dist/unstable/cluster/index.js.map +1 -0
- package/dist/{AtomMachine.d.ts → unstable/reactivity/AtomMachine.d.ts} +40 -23
- package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -0
- package/dist/unstable/reactivity/AtomMachine.js +113 -0
- package/dist/unstable/reactivity/AtomMachine.js.map +1 -0
- package/dist/{reactivity.js → unstable/reactivity/index.d.ts} +1 -1
- package/dist/unstable/reactivity/index.d.ts.map +1 -0
- package/dist/{reactivity.d.ts → unstable/reactivity/index.js} +1 -1
- package/dist/unstable/reactivity/index.js.map +1 -0
- package/docs/agent-guide.md +271 -38
- package/package.json +23 -13
- package/dist/AtomMachine.d.ts.map +0 -1
- package/dist/AtomMachine.js.map +0 -1
- package/dist/ClusterMachine.d.ts.map +0 -1
- package/dist/ClusterMachine.js.map +0 -1
- package/dist/cluster.d.ts.map +0 -1
- package/dist/cluster.js.map +0 -1
- package/dist/internal/machineErrors.d.ts.map +0 -1
- package/dist/internal/machineErrors.js.map +0 -1
- package/dist/internal/machineModel.d.ts.map +0 -1
- package/dist/internal/machineModel.js +0 -766
- package/dist/internal/machineModel.js.map +0 -1
- package/dist/internal/machinePlanner.d.ts +0 -74
- package/dist/internal/machinePlanner.d.ts.map +0 -1
- package/dist/internal/machinePlanner.js +0 -621
- package/dist/internal/machinePlanner.js.map +0 -1
- package/dist/internal/machineProcess.d.ts.map +0 -1
- package/dist/internal/machineProcess.js +0 -181
- package/dist/internal/machineProcess.js.map +0 -1
- package/dist/internal/machineRuntime.d.ts.map +0 -1
- package/dist/internal/machineRuntime.js +0 -365
- package/dist/internal/machineRuntime.js.map +0 -1
- package/dist/reactivity.d.ts.map +0 -1
- package/dist/reactivity.js.map +0 -1
|
@@ -0,0 +1,667 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal compiled machine execution plans.
|
|
3
|
+
*
|
|
4
|
+
* @since 4.0.0
|
|
5
|
+
*/
|
|
6
|
+
import { getTargetBuilder } from "./command.js";
|
|
7
|
+
import { compareDocumentOrder, completeConfigurationSync, getInitialEntryPaths, getPathToRoot, getRootPath, isActiveFinalConfiguration, isDescendantOf, normalizeConfigurationSync, normalizeTargetConfigurationSync, snapshotFromConfiguration, validateInitialConfiguration } from "./configuration.js";
|
|
8
|
+
import { InfiniteTransitionError } from "./errors.js";
|
|
9
|
+
import { broadenTransitionBoundary, getEntryPaths, getExitPaths, getLeastCommonAncestor, getTargetNodePath, InitialEvent, MaxMacrostepIterations, normalizeTransition, planConfiguration, removeConflictingTransitions, sortEntryPaths, sortEvaluatedTransitions, sortExitPaths, validateDeclaredTransitionTarget } from "./planner.js";
|
|
10
|
+
import { decodeEmitSync, decodeEventSync, decodeInputSync, decodeStateValueSync } from "./protocol.js";
|
|
11
|
+
import { isSnapshot, isTarget, TargetSnapshotTypeId } from "./topology.js";
|
|
12
|
+
const indexedStateConfigKeys = new Set([
|
|
13
|
+
"initial",
|
|
14
|
+
"invoke",
|
|
15
|
+
"on",
|
|
16
|
+
"output"
|
|
17
|
+
]);
|
|
18
|
+
// Fail closed so a newly introduced semantic field must explicitly opt into
|
|
19
|
+
// indexed execution instead of being accepted before the kernel supports it.
|
|
20
|
+
const supportsIndexedStateConfig = (config) => {
|
|
21
|
+
if (config === undefined) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
for (const key of Reflect.ownKeys(config)) {
|
|
25
|
+
if (!indexedStateConfigKeys.has(key)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
};
|
|
31
|
+
const compileIndexedExecutionDescriptor = (machine) => {
|
|
32
|
+
const nodes = [];
|
|
33
|
+
const leafPaths = [];
|
|
34
|
+
const finalPaths = [];
|
|
35
|
+
const transitionsByPath = new Map();
|
|
36
|
+
for (const node of machine.stateNodes.byPath.values()) {
|
|
37
|
+
nodes.push(node);
|
|
38
|
+
if (node.type === "choice" || node.type === "history") {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
if (node.type === "atomic" || node.type === "final") {
|
|
42
|
+
leafPaths.push(node.path);
|
|
43
|
+
}
|
|
44
|
+
if (node.type === "final") {
|
|
45
|
+
finalPaths.push(node.path);
|
|
46
|
+
}
|
|
47
|
+
const config = machine.handlers[node.path];
|
|
48
|
+
if (!supportsIndexedStateConfig(config)) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
if (config?.on === undefined) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const byEvent = new Map();
|
|
55
|
+
for (const tag of Reflect.ownKeys(config.on)) {
|
|
56
|
+
const transition = normalizeTransition(config.on[tag]);
|
|
57
|
+
if (transition !== undefined) {
|
|
58
|
+
byEvent.set(tag, transition);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (byEvent.size > 0) {
|
|
62
|
+
transitionsByPath.set(node.path, byEvent);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
leafPaths.sort((left, right) => compareDocumentOrder(machine, left, right));
|
|
66
|
+
finalPaths.sort((left, right) => compareDocumentOrder(machine, left, right));
|
|
67
|
+
nodes.sort((left, right) => left.order - right.order);
|
|
68
|
+
const indexByPath = new Map(nodes.map((node, index) => [node.path, index]));
|
|
69
|
+
const indexOf = (path) => {
|
|
70
|
+
const index = indexByPath.get(path);
|
|
71
|
+
if (index === undefined) {
|
|
72
|
+
throw new Error(`Machine expected compiled state path "${path}"`);
|
|
73
|
+
}
|
|
74
|
+
return index;
|
|
75
|
+
};
|
|
76
|
+
const leafIndices = leafPaths.map(indexOf);
|
|
77
|
+
const parentIndices = nodes.map((node) => node.parent === undefined ? -1 : indexOf(node.parent));
|
|
78
|
+
const childIndices = nodes.map((node) => node.children.map(indexOf));
|
|
79
|
+
const ancestorIndices = nodes.map((node) => getPathToRoot(machine, node.path).slice(0, -1).map(indexOf));
|
|
80
|
+
const transitionsByIndex = nodes.map((node) => transitionsByPath.get(node.path));
|
|
81
|
+
const dispatchByLeaf = new Map();
|
|
82
|
+
for (const leafIndex of leafIndices) {
|
|
83
|
+
const dispatch = new Map();
|
|
84
|
+
const candidates = [leafIndex, ...ancestorIndices[leafIndex].slice().reverse()];
|
|
85
|
+
for (const sourceIndex of candidates) {
|
|
86
|
+
for (const [tag, transition] of transitionsByIndex[sourceIndex] ?? []) {
|
|
87
|
+
if (!dispatch.has(tag))
|
|
88
|
+
dispatch.set(tag, { sourceIndex, transition });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
dispatchByLeaf.set(leafIndex, dispatch);
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
flat: nodes.every((node) => node.parent === undefined && (node.type === "atomic" || node.type === "final")),
|
|
95
|
+
nodes,
|
|
96
|
+
indexByPath,
|
|
97
|
+
parentIndices,
|
|
98
|
+
childIndices,
|
|
99
|
+
ancestorIndices,
|
|
100
|
+
rootIndices: nodes.flatMap((node, index) => node.parent === undefined ? [index] : []),
|
|
101
|
+
leafIndices,
|
|
102
|
+
finalIndices: finalPaths.map(indexOf),
|
|
103
|
+
dispatchByLeaf
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
const updateOwnedIndexedValue = (state, index, value) => {
|
|
107
|
+
state.values[index] = value;
|
|
108
|
+
};
|
|
109
|
+
const ownedIndexedStateFromActive = (descriptor, configuration) => {
|
|
110
|
+
const active = new Uint8Array(descriptor.nodes.length);
|
|
111
|
+
const values = new Array(descriptor.nodes.length);
|
|
112
|
+
const completed = new Uint8Array(descriptor.nodes.length);
|
|
113
|
+
const outputs = new Array(descriptor.nodes.length);
|
|
114
|
+
const completedOrder = [];
|
|
115
|
+
for (const path of configuration.active) {
|
|
116
|
+
const index = descriptor.indexByPath.get(path);
|
|
117
|
+
if (index === undefined)
|
|
118
|
+
throw new Error(`Machine expected indexed active path "${path}"`);
|
|
119
|
+
active[index] = 1;
|
|
120
|
+
values[index] = configuration.values.get(path);
|
|
121
|
+
}
|
|
122
|
+
for (const [path, output] of configuration.outputs) {
|
|
123
|
+
const index = descriptor.indexByPath.get(path);
|
|
124
|
+
if (index === undefined)
|
|
125
|
+
throw new Error(`Machine expected indexed completed path "${path}"`);
|
|
126
|
+
completed[index] = 1;
|
|
127
|
+
outputs[index] = output;
|
|
128
|
+
completedOrder.push(index);
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
active,
|
|
132
|
+
activeLeaves: descriptor.leafIndices.filter((index) => active[index] === 1),
|
|
133
|
+
values,
|
|
134
|
+
completed,
|
|
135
|
+
outputs,
|
|
136
|
+
completedOrder
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
const activeConfigurationFromIndexedState = (descriptor, configuration) => {
|
|
140
|
+
const active = new Set();
|
|
141
|
+
const values = new Map();
|
|
142
|
+
const outputs = new Map();
|
|
143
|
+
for (let index = 0; index < descriptor.nodes.length; index++) {
|
|
144
|
+
if (configuration.active[index] !== 1)
|
|
145
|
+
continue;
|
|
146
|
+
const path = descriptor.nodes[index].path;
|
|
147
|
+
active.add(path);
|
|
148
|
+
values.set(path, configuration.values[index]);
|
|
149
|
+
}
|
|
150
|
+
for (const index of configuration.completedOrder) {
|
|
151
|
+
if (configuration.completed[index] === 1) {
|
|
152
|
+
outputs.set(descriptor.nodes[index].path, configuration.outputs[index]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return { active, values, outputs, history: new Map() };
|
|
156
|
+
};
|
|
157
|
+
const snapshotFromIndexedStateStatePath = (descriptor, configuration, index) => {
|
|
158
|
+
const node = descriptor.nodes[index];
|
|
159
|
+
const snapshot = {
|
|
160
|
+
path: node.path,
|
|
161
|
+
value: configuration.values[index]
|
|
162
|
+
};
|
|
163
|
+
if (node.type === "compound") {
|
|
164
|
+
const childIndex = descriptor.childIndices[index].find((childIndex) => configuration.active[childIndex] === 1);
|
|
165
|
+
if (childIndex === undefined) {
|
|
166
|
+
throw new Error(`Machine expected indexed compound state "${node.path}" to have an active child`);
|
|
167
|
+
}
|
|
168
|
+
snapshot.state = snapshotFromIndexedStateStatePath(descriptor, configuration, childIndex);
|
|
169
|
+
}
|
|
170
|
+
else if (node.type === "parallel") {
|
|
171
|
+
const states = {};
|
|
172
|
+
for (const childIndex of descriptor.childIndices[index]) {
|
|
173
|
+
if (configuration.active[childIndex] !== 1) {
|
|
174
|
+
throw new Error(`Machine expected indexed parallel state "${node.path}" to have active region "${descriptor.nodes[childIndex].path}"`);
|
|
175
|
+
}
|
|
176
|
+
states[descriptor.nodes[childIndex].key] = snapshotFromIndexedStateStatePath(descriptor, configuration, childIndex);
|
|
177
|
+
}
|
|
178
|
+
snapshot.states = states;
|
|
179
|
+
}
|
|
180
|
+
return snapshot;
|
|
181
|
+
};
|
|
182
|
+
const snapshotFromIndexedState = (descriptor, configuration) => {
|
|
183
|
+
const rootIndex = descriptor.rootIndices.find((index) => configuration.active[index] === 1);
|
|
184
|
+
if (rootIndex === undefined)
|
|
185
|
+
throw new Error("Machine expected an active indexed root state");
|
|
186
|
+
const snapshot = snapshotFromIndexedStateStatePath(descriptor, configuration, rootIndex);
|
|
187
|
+
if (configuration.completedOrder.length > 0) {
|
|
188
|
+
;
|
|
189
|
+
snapshot.completed = configuration.completedOrder.map((index) => ({
|
|
190
|
+
path: descriptor.nodes[index].path,
|
|
191
|
+
output: configuration.outputs[index]
|
|
192
|
+
}));
|
|
193
|
+
}
|
|
194
|
+
return snapshot;
|
|
195
|
+
};
|
|
196
|
+
const makeIndexedTransitionContext = (machine, descriptor, configuration, sourceIndex, event) => {
|
|
197
|
+
const source = descriptor.nodes[sourceIndex];
|
|
198
|
+
const parentIndex = descriptor.parentIndices[sourceIndex];
|
|
199
|
+
const parents = {};
|
|
200
|
+
for (const ancestorIndex of descriptor.ancestorIndices[sourceIndex]) {
|
|
201
|
+
parents[descriptor.nodes[ancestorIndex].path] = configuration.values[ancestorIndex];
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
state: configuration.values[sourceIndex],
|
|
205
|
+
parent: parentIndex < 0 ? undefined : configuration.values[parentIndex],
|
|
206
|
+
parents,
|
|
207
|
+
event,
|
|
208
|
+
snapshot: snapshotFromIndexedState(descriptor, configuration),
|
|
209
|
+
target: getTargetBuilder(machine, source.path)
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
const emptyExecutionValues = Object.freeze([]);
|
|
213
|
+
const collectIndexedTransition = (machine, transition, context) => {
|
|
214
|
+
let commands;
|
|
215
|
+
let raisedEvents;
|
|
216
|
+
let emittedEvents;
|
|
217
|
+
const state = transition(context, {
|
|
218
|
+
raise: (event) => {
|
|
219
|
+
;
|
|
220
|
+
(raisedEvents ??= []).push(decodeEventSync(machine, event));
|
|
221
|
+
},
|
|
222
|
+
emit: (event) => {
|
|
223
|
+
;
|
|
224
|
+
(emittedEvents ??= []).push(decodeEmitSync(machine, event));
|
|
225
|
+
},
|
|
226
|
+
sendTo: (child, event) => {
|
|
227
|
+
;
|
|
228
|
+
(commands ??= []).push({ _tag: "SendTo", child: child, event });
|
|
229
|
+
},
|
|
230
|
+
stop: (child) => {
|
|
231
|
+
;
|
|
232
|
+
(commands ??= []).push({ _tag: "Stop", child: child });
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
return {
|
|
236
|
+
state,
|
|
237
|
+
commands: commands ?? emptyExecutionValues,
|
|
238
|
+
raisedEvents: raisedEvents ?? emptyExecutionValues,
|
|
239
|
+
emittedEvents: emittedEvents ?? emptyExecutionValues
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
const selectIndexedEventTransitions = (machine, descriptor, configuration, event) => {
|
|
243
|
+
const selected = [];
|
|
244
|
+
for (const leafIndex of configuration.activeLeaves) {
|
|
245
|
+
const dispatched = descriptor.dispatchByLeaf.get(leafIndex).get(event._tag);
|
|
246
|
+
if (dispatched !== undefined) {
|
|
247
|
+
const { sourceIndex, transition } = dispatched;
|
|
248
|
+
if (!selected.some((selection) => selection.sourceIndex === sourceIndex)) {
|
|
249
|
+
const sourcePath = descriptor.nodes[sourceIndex].path;
|
|
250
|
+
selected.push({
|
|
251
|
+
sourceIndex,
|
|
252
|
+
leafIndex,
|
|
253
|
+
sourcePath,
|
|
254
|
+
leafPath: descriptor.nodes[leafIndex].path,
|
|
255
|
+
trigger: { type: "event", event: event._tag },
|
|
256
|
+
transition,
|
|
257
|
+
context: makeIndexedTransitionContext(machine, descriptor, configuration, sourceIndex, event)
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return selected;
|
|
263
|
+
};
|
|
264
|
+
const hasSameIndexedActive = (left, right) => {
|
|
265
|
+
if (left.active === right.active)
|
|
266
|
+
return true;
|
|
267
|
+
for (let index = 0; index < left.active.length; index++) {
|
|
268
|
+
if (left.active[index] !== right.active[index])
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
return true;
|
|
272
|
+
};
|
|
273
|
+
const normalizeIndexedTargetStateSync = (machine, descriptor, current, target, activeLeafIndex) => {
|
|
274
|
+
const targetIndex = isTarget(target) ? descriptor.indexByPath.get(String(target.path)) : undefined;
|
|
275
|
+
if (targetIndex === activeLeafIndex && current.active[activeLeafIndex] === 1 && isTarget(target) &&
|
|
276
|
+
target[TargetSnapshotTypeId] === undefined && target.values === undefined && current.completedOrder.length === 0) {
|
|
277
|
+
const values = current.values.slice();
|
|
278
|
+
values[activeLeafIndex] = decodeStateValueSync(machine, descriptor.nodes[activeLeafIndex], target.value);
|
|
279
|
+
return { ...current, values };
|
|
280
|
+
}
|
|
281
|
+
return ownedIndexedStateFromActive(descriptor, normalizeTargetConfigurationSync(machine, activeConfigurationFromIndexedState(descriptor, current), target));
|
|
282
|
+
};
|
|
283
|
+
const collectIndexedEvaluatedTransition = (machine, descriptor, state, selection) => {
|
|
284
|
+
const transitionResult = collectIndexedTransition(machine, selection.transition.transition, selection.context);
|
|
285
|
+
const target = transitionResult.state;
|
|
286
|
+
validateDeclaredTransitionTarget(selection.sourcePath, selection.trigger, selection.transition.targets, target);
|
|
287
|
+
if (target !== undefined && !isTarget(target) && !isSnapshot(target)) {
|
|
288
|
+
throw new Error("Machine expected indexed transition target to be a snapshot or target builder result");
|
|
289
|
+
}
|
|
290
|
+
const next = target === undefined
|
|
291
|
+
? state
|
|
292
|
+
: normalizeIndexedTargetStateSync(machine, descriptor, state, target, selection.leafIndex);
|
|
293
|
+
const changed = selection.transition.reenter || !hasSameIndexedActive(state, next);
|
|
294
|
+
if (!changed) {
|
|
295
|
+
return {
|
|
296
|
+
selection,
|
|
297
|
+
unresolvedTarget: target,
|
|
298
|
+
target: target,
|
|
299
|
+
next,
|
|
300
|
+
commands: transitionResult.commands,
|
|
301
|
+
raisedEvents: transitionResult.raisedEvents,
|
|
302
|
+
emittedEvents: transitionResult.emittedEvents,
|
|
303
|
+
changed: false,
|
|
304
|
+
exitPaths: [],
|
|
305
|
+
entryPaths: [],
|
|
306
|
+
choiceTransitions: []
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
const targetPath = target === undefined ? undefined : getTargetNodePath(target);
|
|
310
|
+
const naturalBoundary = targetPath === undefined
|
|
311
|
+
? descriptor.nodes[selection.sourceIndex].parent
|
|
312
|
+
: getLeastCommonAncestor(machine, selection.leafPath, targetPath);
|
|
313
|
+
const reentryBoundary = descriptor.nodes[selection.sourceIndex].parent;
|
|
314
|
+
const boundary = selection.transition.reenter
|
|
315
|
+
? broadenTransitionBoundary(naturalBoundary, reentryBoundary)
|
|
316
|
+
: naturalBoundary;
|
|
317
|
+
return {
|
|
318
|
+
selection,
|
|
319
|
+
unresolvedTarget: target,
|
|
320
|
+
target: target,
|
|
321
|
+
next,
|
|
322
|
+
commands: transitionResult.commands,
|
|
323
|
+
raisedEvents: transitionResult.raisedEvents,
|
|
324
|
+
emittedEvents: transitionResult.emittedEvents,
|
|
325
|
+
changed: true,
|
|
326
|
+
exitPaths: getExitPaths(machine, activeConfigurationFromIndexedState(descriptor, state), boundary),
|
|
327
|
+
entryPaths: getEntryPaths(machine, activeConfigurationFromIndexedState(descriptor, next), boundary),
|
|
328
|
+
choiceTransitions: []
|
|
329
|
+
};
|
|
330
|
+
};
|
|
331
|
+
const indexedMicrostep = (machine, descriptor, state, event, selections) => {
|
|
332
|
+
if (selections.length === 1) {
|
|
333
|
+
const transition = collectIndexedEvaluatedTransition(machine, descriptor, state, selections[0]);
|
|
334
|
+
return {
|
|
335
|
+
next: transition.next,
|
|
336
|
+
event,
|
|
337
|
+
commands: transition.commands,
|
|
338
|
+
raisedEvents: transition.raisedEvents,
|
|
339
|
+
emittedEvents: transition.emittedEvents,
|
|
340
|
+
exitPaths: transition.exitPaths,
|
|
341
|
+
entryPaths: transition.entryPaths,
|
|
342
|
+
changed: transition.changed
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
const activeSelections = selections.filter((selection) => !selections.some((other) => other.sourceIndex !== selection.sourceIndex &&
|
|
346
|
+
isDescendantOf(other.sourcePath, selection.sourcePath)));
|
|
347
|
+
const evaluated = activeSelections.map((selection) => collectIndexedEvaluatedTransition(machine, descriptor, state, selection));
|
|
348
|
+
const transitions = sortEvaluatedTransitions(machine, removeConflictingTransitions(machine, evaluated));
|
|
349
|
+
let next = state;
|
|
350
|
+
if (transitions.length === 1) {
|
|
351
|
+
next = transitions[0].next;
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
const applicationOrder = [
|
|
355
|
+
...transitions.filter((transition) => !transition.changed),
|
|
356
|
+
...transitions.filter((transition) => transition.changed)
|
|
357
|
+
];
|
|
358
|
+
for (const transition of applicationOrder) {
|
|
359
|
+
if (transition.target !== undefined) {
|
|
360
|
+
next = normalizeIndexedTargetStateSync(machine, descriptor, next, transition.target, transition.selection.leafIndex);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const commands = transitions.flatMap((transition) => transition.commands);
|
|
365
|
+
const raisedEvents = transitions.flatMap((transition) => transition.raisedEvents);
|
|
366
|
+
const emittedEvents = transitions.flatMap((transition) => transition.emittedEvents);
|
|
367
|
+
const changed = transitions.some((transition) => transition.changed);
|
|
368
|
+
return {
|
|
369
|
+
next,
|
|
370
|
+
event,
|
|
371
|
+
commands,
|
|
372
|
+
raisedEvents,
|
|
373
|
+
emittedEvents,
|
|
374
|
+
exitPaths: changed ? sortExitPaths(machine, transitions.flatMap((transition) => transition.exitPaths)) : [],
|
|
375
|
+
entryPaths: changed ? sortEntryPaths(machine, transitions.flatMap((transition) => transition.entryPaths)) : [],
|
|
376
|
+
changed
|
|
377
|
+
};
|
|
378
|
+
};
|
|
379
|
+
const planIndexedFlatState = (machine, descriptor, configuration, decoded) => {
|
|
380
|
+
let current = configuration;
|
|
381
|
+
let event = decoded;
|
|
382
|
+
let commands;
|
|
383
|
+
let raisedEvents;
|
|
384
|
+
let emittedEvents;
|
|
385
|
+
let microsteps;
|
|
386
|
+
let raisedIndex = 0;
|
|
387
|
+
let iterations = 0;
|
|
388
|
+
while (true) {
|
|
389
|
+
iterations += 1;
|
|
390
|
+
if (iterations > MaxMacrostepIterations) {
|
|
391
|
+
throw new InfiniteTransitionError({
|
|
392
|
+
machineId: machine.id,
|
|
393
|
+
state: descriptor.nodes[current.activeLeaves[0]].path,
|
|
394
|
+
maxIterations: MaxMacrostepIterations
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
const sourceIndex = current.activeLeaves[0];
|
|
398
|
+
if (sourceIndex === undefined) {
|
|
399
|
+
throw new Error("Machine expected an active indexed root state");
|
|
400
|
+
}
|
|
401
|
+
if (descriptor.nodes[sourceIndex].type === "final") {
|
|
402
|
+
const completed = completeConfigurationSync(machine, activeConfigurationFromIndexedState(descriptor, current), event).configuration;
|
|
403
|
+
const root = getRootPath(machine, completed);
|
|
404
|
+
if (!completed.outputs.has(root)) {
|
|
405
|
+
throw new Error("Machine reached a terminal indexed configuration without a completed root output");
|
|
406
|
+
}
|
|
407
|
+
return {
|
|
408
|
+
next: ownedIndexedStateFromActive(descriptor, completed),
|
|
409
|
+
commands: commands ?? emptyExecutionValues,
|
|
410
|
+
emittedEvents: emittedEvents ?? emptyExecutionValues,
|
|
411
|
+
microsteps: microsteps ?? emptyExecutionValues,
|
|
412
|
+
done: true,
|
|
413
|
+
output: completed.outputs.get(root)
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
const sourcePath = descriptor.nodes[sourceIndex].path;
|
|
417
|
+
const transition = normalizeTransition(machine.handlers[sourcePath]?.on?.[event._tag]);
|
|
418
|
+
if (transition !== undefined) {
|
|
419
|
+
const transitionResult = collectIndexedTransition(machine, transition.transition, {
|
|
420
|
+
state: current.values[sourceIndex],
|
|
421
|
+
parent: undefined,
|
|
422
|
+
parents: {},
|
|
423
|
+
event,
|
|
424
|
+
snapshot: snapshotFromIndexedState(descriptor, current),
|
|
425
|
+
target: getTargetBuilder(machine, sourcePath)
|
|
426
|
+
});
|
|
427
|
+
const target = transitionResult.state;
|
|
428
|
+
validateDeclaredTransitionTarget(sourcePath, { type: "event", event: event._tag }, transition.targets, target);
|
|
429
|
+
if (target !== undefined && !isTarget(target) && !isSnapshot(target)) {
|
|
430
|
+
throw new Error("Machine expected indexed transition target to be a snapshot or target builder result");
|
|
431
|
+
}
|
|
432
|
+
let next = current;
|
|
433
|
+
if (target !== undefined) {
|
|
434
|
+
const targetIndex = descriptor.indexByPath.get(String(target.path));
|
|
435
|
+
const isSimpleTarget = isTarget(target)
|
|
436
|
+
? target[TargetSnapshotTypeId] === undefined && target.values === undefined
|
|
437
|
+
: !("state" in target) && !("states" in target) && !("completed" in target) && !("history" in target);
|
|
438
|
+
if (targetIndex === sourceIndex && isSimpleTarget && current.completedOrder.length === 0) {
|
|
439
|
+
updateOwnedIndexedValue(current, sourceIndex, decodeStateValueSync(machine, descriptor.nodes[sourceIndex], target.value));
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
next = normalizeIndexedTargetStateSync(machine, descriptor, current, target, sourceIndex);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const changed = transition.reenter || !hasSameIndexedActive(current, next);
|
|
446
|
+
const nextIndex = next.activeLeaves[0];
|
|
447
|
+
if (nextIndex === undefined) {
|
|
448
|
+
throw new Error("Machine expected an active indexed transition target");
|
|
449
|
+
}
|
|
450
|
+
const step = {
|
|
451
|
+
next,
|
|
452
|
+
event,
|
|
453
|
+
commands: transitionResult.commands,
|
|
454
|
+
raisedEvents: transitionResult.raisedEvents,
|
|
455
|
+
emittedEvents: transitionResult.emittedEvents,
|
|
456
|
+
exitPaths: changed ? [sourcePath] : emptyExecutionValues,
|
|
457
|
+
entryPaths: changed ? [descriptor.nodes[nextIndex].path] : emptyExecutionValues,
|
|
458
|
+
changed
|
|
459
|
+
};
|
|
460
|
+
current = next;
|
|
461
|
+
(microsteps ??= []).push(step);
|
|
462
|
+
if (transitionResult.commands.length > 0) {
|
|
463
|
+
;
|
|
464
|
+
(commands ??= []).push(...transitionResult.commands);
|
|
465
|
+
}
|
|
466
|
+
if (transitionResult.raisedEvents.length > 0) {
|
|
467
|
+
;
|
|
468
|
+
(raisedEvents ??= []).push(...transitionResult.raisedEvents);
|
|
469
|
+
}
|
|
470
|
+
if (transitionResult.emittedEvents.length > 0) {
|
|
471
|
+
;
|
|
472
|
+
(emittedEvents ??= []).push(...transitionResult.emittedEvents);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
if (descriptor.nodes[current.activeLeaves[0]].type === "final") {
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
const raised = raisedEvents?.[raisedIndex];
|
|
479
|
+
if (raised === undefined) {
|
|
480
|
+
return {
|
|
481
|
+
next: current,
|
|
482
|
+
commands: commands ?? emptyExecutionValues,
|
|
483
|
+
emittedEvents: emittedEvents ?? emptyExecutionValues,
|
|
484
|
+
microsteps: microsteps ?? emptyExecutionValues,
|
|
485
|
+
done: false,
|
|
486
|
+
output: undefined
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
raisedIndex += 1;
|
|
490
|
+
event = raised;
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
const planIndexedState = (machine, descriptor, configuration, input) => {
|
|
494
|
+
const decoded = decodeEventSync(machine, input);
|
|
495
|
+
if (descriptor.flat) {
|
|
496
|
+
return planIndexedFlatState(machine, descriptor, configuration, decoded);
|
|
497
|
+
}
|
|
498
|
+
if (descriptor.finalIndices.some((index) => configuration.active[index] === 1)) {
|
|
499
|
+
const active = activeConfigurationFromIndexedState(descriptor, configuration);
|
|
500
|
+
if (isActiveFinalConfiguration(machine, active)) {
|
|
501
|
+
const completed = completeConfigurationSync(machine, active, decoded).configuration;
|
|
502
|
+
const root = getRootPath(machine, completed);
|
|
503
|
+
if (!completed.outputs.has(root)) {
|
|
504
|
+
throw new Error("Machine reached a terminal indexed configuration without a completed root output");
|
|
505
|
+
}
|
|
506
|
+
return {
|
|
507
|
+
next: ownedIndexedStateFromActive(descriptor, completed),
|
|
508
|
+
commands: [],
|
|
509
|
+
emittedEvents: [],
|
|
510
|
+
microsteps: [],
|
|
511
|
+
done: true,
|
|
512
|
+
output: completed.outputs.get(root)
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
const selections = selectIndexedEventTransitions(machine, descriptor, configuration, decoded);
|
|
517
|
+
if (selections.length === 0) {
|
|
518
|
+
return {
|
|
519
|
+
next: configuration,
|
|
520
|
+
commands: [],
|
|
521
|
+
emittedEvents: [],
|
|
522
|
+
microsteps: [],
|
|
523
|
+
done: false,
|
|
524
|
+
output: undefined
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
const first = indexedMicrostep(machine, descriptor, configuration, decoded, selections);
|
|
528
|
+
let current = first.next;
|
|
529
|
+
let currentEvent = decoded;
|
|
530
|
+
const commands = [...first.commands];
|
|
531
|
+
const raisedEvents = [...first.raisedEvents];
|
|
532
|
+
const emittedEvents = [...first.emittedEvents];
|
|
533
|
+
const microsteps = [first];
|
|
534
|
+
let raisedIndex = 0;
|
|
535
|
+
let iterations = 0;
|
|
536
|
+
while (true) {
|
|
537
|
+
iterations += 1;
|
|
538
|
+
if (iterations > MaxMacrostepIterations) {
|
|
539
|
+
throw new InfiniteTransitionError({
|
|
540
|
+
machineId: machine.id,
|
|
541
|
+
state: descriptor.nodes[descriptor.leafIndices.find((index) => current.active[index] === 1)].path,
|
|
542
|
+
maxIterations: MaxMacrostepIterations
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
if (descriptor.finalIndices.some((index) => current.active[index] === 1)) {
|
|
546
|
+
const completed = completeConfigurationSync(machine, activeConfigurationFromIndexedState(descriptor, current), currentEvent).configuration;
|
|
547
|
+
current = ownedIndexedStateFromActive(descriptor, completed);
|
|
548
|
+
if (isActiveFinalConfiguration(machine, completed)) {
|
|
549
|
+
const root = getRootPath(machine, completed);
|
|
550
|
+
if (!completed.outputs.has(root)) {
|
|
551
|
+
throw new Error("Machine reached a terminal indexed configuration without a completed root output");
|
|
552
|
+
}
|
|
553
|
+
return {
|
|
554
|
+
next: current,
|
|
555
|
+
commands,
|
|
556
|
+
emittedEvents,
|
|
557
|
+
microsteps,
|
|
558
|
+
done: true,
|
|
559
|
+
output: completed.outputs.get(root)
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
const raised = raisedEvents[raisedIndex];
|
|
564
|
+
if (raised === undefined) {
|
|
565
|
+
return {
|
|
566
|
+
next: current,
|
|
567
|
+
commands,
|
|
568
|
+
emittedEvents,
|
|
569
|
+
microsteps,
|
|
570
|
+
done: false,
|
|
571
|
+
output: undefined
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
raisedIndex += 1;
|
|
575
|
+
currentEvent = raised;
|
|
576
|
+
const raisedSelections = selectIndexedEventTransitions(machine, descriptor, current, raised);
|
|
577
|
+
if (raisedSelections.length === 0)
|
|
578
|
+
continue;
|
|
579
|
+
const step = indexedMicrostep(machine, descriptor, current, raised, raisedSelections);
|
|
580
|
+
current = step.next;
|
|
581
|
+
commands.push(...step.commands);
|
|
582
|
+
raisedEvents.push(...step.raisedEvents);
|
|
583
|
+
emittedEvents.push(...step.emittedEvents);
|
|
584
|
+
microsteps.push(step);
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
const executionPlanCache = new WeakMap();
|
|
588
|
+
const makeActiveExecutionPlan = (machine) => ({
|
|
589
|
+
fromConfiguration: (configuration) => configuration,
|
|
590
|
+
toConfiguration: (state) => state,
|
|
591
|
+
snapshot: (state) => snapshotFromConfiguration(machine, state),
|
|
592
|
+
plan: (state, event) => planConfiguration(machine, state, event)
|
|
593
|
+
});
|
|
594
|
+
const makeIndexedExecutionPlan = (machine, indexed) => ({
|
|
595
|
+
fromConfiguration: (configuration) => ownedIndexedStateFromActive(indexed, configuration),
|
|
596
|
+
toConfiguration: (state) => activeConfigurationFromIndexedState(indexed, state),
|
|
597
|
+
snapshot: (state) => snapshotFromIndexedState(indexed, state),
|
|
598
|
+
plan: (state, event) => planIndexedState(machine, indexed, state, event),
|
|
599
|
+
initial: (args) => {
|
|
600
|
+
const inputArgs = machine.input === undefined
|
|
601
|
+
? args
|
|
602
|
+
: args.length === 0
|
|
603
|
+
? (decodeInputSync(machine, machine.input, undefined), args)
|
|
604
|
+
: [decodeInputSync(machine, machine.input, args[0])];
|
|
605
|
+
const initial = machine.initial(...inputArgs);
|
|
606
|
+
const active = normalizeConfigurationSync(machine, initial);
|
|
607
|
+
validateInitialConfiguration(machine, active);
|
|
608
|
+
const completed = completeConfigurationSync(machine, active, InitialEvent).configuration;
|
|
609
|
+
const configuration = ownedIndexedStateFromActive(indexed, completed);
|
|
610
|
+
const state = snapshotFromIndexedState(indexed, configuration);
|
|
611
|
+
const done = isActiveFinalConfiguration(machine, completed);
|
|
612
|
+
if (!done) {
|
|
613
|
+
return {
|
|
614
|
+
state,
|
|
615
|
+
configuration,
|
|
616
|
+
activeConfiguration: completed,
|
|
617
|
+
initialEntryPaths: getInitialEntryPaths(machine, completed),
|
|
618
|
+
done: false,
|
|
619
|
+
output: undefined
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
const root = getRootPath(machine, completed);
|
|
623
|
+
if (!completed.outputs.has(root)) {
|
|
624
|
+
throw new Error("Machine reached a terminal configuration without a completed root output");
|
|
625
|
+
}
|
|
626
|
+
return {
|
|
627
|
+
state,
|
|
628
|
+
configuration,
|
|
629
|
+
activeConfiguration: completed,
|
|
630
|
+
initialEntryPaths: getInitialEntryPaths(machine, completed),
|
|
631
|
+
done: true,
|
|
632
|
+
output: completed.outputs.get(root)
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
const selectExecutionPlan = (machine, strategy) => {
|
|
637
|
+
if (strategy === "generic") {
|
|
638
|
+
return { strategy, plan: makeActiveExecutionPlan(machine) };
|
|
639
|
+
}
|
|
640
|
+
const indexed = compileIndexedExecutionDescriptor(machine);
|
|
641
|
+
if (indexed === undefined) {
|
|
642
|
+
if (strategy === "auto") {
|
|
643
|
+
return { strategy: "generic", plan: makeActiveExecutionPlan(machine) };
|
|
644
|
+
}
|
|
645
|
+
throw new Error(`Machine cannot compile the requested ${strategy} execution plan`);
|
|
646
|
+
}
|
|
647
|
+
const selected = indexed.flat ? "indexed-flat" : "indexed-hierarchical";
|
|
648
|
+
if (strategy !== "auto" && strategy !== selected) {
|
|
649
|
+
throw new Error(`Machine compiled ${selected}, not the requested ${strategy} execution plan`);
|
|
650
|
+
}
|
|
651
|
+
return { strategy: selected, plan: makeIndexedExecutionPlan(machine, indexed) };
|
|
652
|
+
};
|
|
653
|
+
/** @internal Test-only uncached strategy selection. */
|
|
654
|
+
export const selectExecutionPlanForTesting = (machine, strategy) => selectExecutionPlan(machine, strategy);
|
|
655
|
+
export const compileExecutionPlan = (machine) => {
|
|
656
|
+
const cached = executionPlanCache.get(machine);
|
|
657
|
+
if (cached !== undefined) {
|
|
658
|
+
return cached;
|
|
659
|
+
}
|
|
660
|
+
const indexed = compileIndexedExecutionDescriptor(machine);
|
|
661
|
+
const compiled = indexed === undefined
|
|
662
|
+
? makeActiveExecutionPlan(machine)
|
|
663
|
+
: makeIndexedExecutionPlan(machine, indexed);
|
|
664
|
+
executionPlanCache.set(machine, compiled);
|
|
665
|
+
return compiled;
|
|
666
|
+
};
|
|
667
|
+
//# sourceMappingURL=executionPlan.js.map
|