@systemfsoftware/xstate 0.0.0-bootstrap.0 → 6.0.0-beta.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/graph.mjs ADDED
@@ -0,0 +1,667 @@
1
+ import { t as createEmptyActor } from "./actors-LxMBvgxO.mjs";
2
+ import { g as XSTATE_INIT, h as defaultWarn, r as getAllOwnEvents } from "./utils-CXBxxp3Z.mjs";
3
+ // src/graph/actorScope.ts
4
+ function actorSystem(actor) {
5
+ return actor.system;
6
+ }
7
+ function createMockActorScope() {
8
+ const emptyActor = createEmptyActor();
9
+ return {
10
+ self: emptyActor,
11
+ logger: console.log,
12
+ warn: defaultWarn,
13
+ id: "",
14
+ sessionId: "mock-actor-scope",
15
+ defer: () => {},
16
+ system: actorSystem(emptyActor),
17
+ stopChild: () => {},
18
+ emit: () => {},
19
+ actionExecutor: () => {}
20
+ };
21
+ }
22
+ // src/graph/graph.ts
23
+ const isActorLogic = (value) => value !== void 0 && "transition" in value;
24
+ const logicFirstOrLast = (compute) => (first, second) => isActorLogic(first) ? compute(first, second) : (logic) => compute(logic, first);
25
+ /**
26
+ * Returns all state nodes of the given `node`.
27
+ *
28
+ * @public
29
+ * @param stateNode State node to recursively get child state nodes from
30
+ * @public
31
+ */
32
+ function getDescendantStateNodes(stateNode) {
33
+ const { states } = stateNode;
34
+ return Object.keys(states).reduce((accNodes, stateKey) => {
35
+ const childStateNode = states[stateKey];
36
+ if (childStateNode === void 0) return accNodes;
37
+ accNodes.push(childStateNode, ...getDescendantStateNodes(childStateNode));
38
+ return accNodes;
39
+ }, []);
40
+ }
41
+ function getChildren(stateNode) {
42
+ return Object.values(stateNode.states);
43
+ }
44
+ function isFilled(context) {
45
+ return context !== void 0 && Object.keys(context).length > 0;
46
+ }
47
+ function nonEmptyContext(context) {
48
+ return isFilled(context) ? context : void 0;
49
+ }
50
+ function snapshotFields(snapshot) {
51
+ const { value, context } = snapshot;
52
+ return {
53
+ value,
54
+ context: nonEmptyContext(context)
55
+ };
56
+ }
57
+ function toSerializedSnapshot(value) {
58
+ return value;
59
+ }
60
+ function toSerializedEvent(value) {
61
+ return value;
62
+ }
63
+ /** @public */
64
+ function serializeSnapshot(snapshot) {
65
+ return toSerializedSnapshot(JSON.stringify(snapshotFields(snapshot)));
66
+ }
67
+ function serializeEvent(event) {
68
+ return toSerializedEvent(JSON.stringify(event));
69
+ }
70
+ function ownLogicEvents(state) {
71
+ return getAllOwnEvents(state);
72
+ }
73
+ function defaultSerializeState(state) {
74
+ return JSON.stringify(state);
75
+ }
76
+ function optionFromState(options) {
77
+ return options?.fromState;
78
+ }
79
+ function optionStopWhen(options) {
80
+ return options?.toState;
81
+ }
82
+ function startState(logic, options) {
83
+ return options.fromState ?? logic.getInitialSnapshot(createMockActorScope(), options.input);
84
+ }
85
+ function createDefaultMachineOptions(machine, options = {}) {
86
+ return {
87
+ serializeState: serializeSnapshot,
88
+ serializeEvent,
89
+ events: ownLogicEvents,
90
+ fromState: startState(machine, options)
91
+ };
92
+ }
93
+ const memberOf = (value, key) => new Object(Reflect.get(value, key));
94
+ const memberIs = (value, key, kind) => typeof Reflect.get(value, key) === kind;
95
+ const machineMethods = [
96
+ "getStateNodeById",
97
+ "resolveState",
98
+ "getTransitionData"
99
+ ];
100
+ function isMachineLogic(logic) {
101
+ const root = memberOf(logic, "root");
102
+ return [
103
+ typeof logic === "object",
104
+ memberIs(logic, "root", "object"),
105
+ memberIs(root, "id", "string"),
106
+ memberIs(root, "states", "object"),
107
+ memberIs(memberOf(root, "transitions"), "values", "function"),
108
+ ...machineMethods.map((method) => memberIs(logic, method, "function"))
109
+ ].every(Boolean);
110
+ }
111
+ function transitionEventType(transition) {
112
+ return transition.eventType;
113
+ }
114
+ /** @public */
115
+ function toDirectedGraph(stateMachine) {
116
+ const stateNode = isMachineLogic(stateMachine) ? stateMachine.root : stateMachine;
117
+ const edges = [...stateNode.transitions.values()].flat().flatMap((t, transitionIndex) => {
118
+ const targets = t.target !== void 0 ? t.target : [stateNode];
119
+ const eventType = transitionEventType(t);
120
+ return targets.map((target, targetIndex) => {
121
+ const edge = {
122
+ id: `${stateNode.id}:${transitionIndex}:${targetIndex}`,
123
+ source: stateNode,
124
+ target,
125
+ transition: t,
126
+ label: {
127
+ text: eventType,
128
+ toJSON: () => ({ text: eventType })
129
+ },
130
+ toJSON: () => {
131
+ const { label } = edge;
132
+ return {
133
+ source: stateNode.id,
134
+ target: target.id,
135
+ label
136
+ };
137
+ }
138
+ };
139
+ return edge;
140
+ });
141
+ });
142
+ const graph = {
143
+ id: stateNode.id,
144
+ stateNode,
145
+ children: getChildren(stateNode).map(toDirectedGraph),
146
+ edges,
147
+ toJSON: () => {
148
+ const { id, children, edges: graphEdges } = graph;
149
+ return {
150
+ id,
151
+ children,
152
+ edges: graphEdges
153
+ };
154
+ }
155
+ };
156
+ return graph;
157
+ }
158
+ function resolveDefaultOptions(logic, traversalOptions) {
159
+ return isMachineLogic(logic) ? createDefaultMachineOptions(logic, traversalOptions) : void 0;
160
+ }
161
+ function resolveTraversalOptions({ logic, options: traversalOptions }) {
162
+ const resolvedDefaultOptions = resolveDefaultOptions(logic, traversalOptions);
163
+ const serializeState = defaultSerializeState;
164
+ const fromState = optionFromState(traversalOptions) ?? optionFromState(resolvedDefaultOptions);
165
+ return {
166
+ serializeState,
167
+ serializeEvent,
168
+ events: [],
169
+ filterEvents: void 0,
170
+ limit: Infinity,
171
+ toState: void 0,
172
+ stopWhen: optionStopWhen(traversalOptions),
173
+ ...resolvedDefaultOptions,
174
+ ...traversalOptions,
175
+ fromState
176
+ };
177
+ }
178
+ function requireFirstStep(path) {
179
+ const firstStep = path.steps[0];
180
+ if (firstStep === void 0) throw new Error(`Paths cannot be joined`);
181
+ return firstStep;
182
+ }
183
+ const joinPathsDataFirst = (headPath, tailPath) => {
184
+ if (requireFirstStep(tailPath).state !== headPath.state) throw new Error(`Paths cannot be joined`);
185
+ return {
186
+ state: tailPath.state,
187
+ steps: headPath.steps.concat(tailPath.steps.slice(1)),
188
+ weight: headPath.weight + tailPath.weight
189
+ };
190
+ };
191
+ function joinPaths(...args) {
192
+ if (args.length === 2) return joinPathsDataFirst(args[0], args[1]);
193
+ const [tailPath] = args;
194
+ return (headPath) => joinPathsDataFirst(headPath, tailPath);
195
+ }
196
+ // src/graph/adjacency.ts
197
+ const createNullDict$2 = () => {
198
+ const dict = {};
199
+ Object.setPrototypeOf(dict, null);
200
+ return dict;
201
+ };
202
+ function resolveTransitionSnapshot(result) {
203
+ return Array.isArray(result) ? result[0] : result;
204
+ }
205
+ const initialSnapshotOf$3 = (logic, input, actorScope) => logic.getInitialSnapshot(actorScope, input);
206
+ function actorScopeOf$1(scope) {
207
+ return scope;
208
+ }
209
+ const isVisited = (adj, serialized) => adj[serialized] !== void 0;
210
+ const stopsAt = (traversal, state) => {
211
+ const { stopWhen } = traversal.config;
212
+ return stopWhen === void 0 ? false : stopWhen(state);
213
+ };
214
+ const countIteration = (traversal) => {
215
+ const exceeded = traversal.iterations > traversal.config.limit;
216
+ traversal.iterations += 1;
217
+ if (exceeded) throw new Error("Traversal limit exceeded");
218
+ };
219
+ const registerQueued = (adj, queued, traversal) => {
220
+ countIteration(traversal);
221
+ const { nextState, event, prevState } = queued;
222
+ const serialized = toSerializedSnapshot(traversal.config.serializeState(nextState, event, prevState));
223
+ if (isVisited(adj, serialized)) return;
224
+ return storeValue(adj, serialized, nextState, traversal);
225
+ };
226
+ const storeValue = (adj, serialized, state, traversal) => {
227
+ const value = {
228
+ state,
229
+ transitions: createNullDict$2()
230
+ };
231
+ adj[serialized] = value;
232
+ return stopsAt(traversal, state) ? void 0 : value;
233
+ };
234
+ const eventsFor = (traversal, state) => {
235
+ const { events } = traversal.config;
236
+ return typeof events === "function" ? events(state) : events;
237
+ };
238
+ const passesFilter = (traversal, state, event) => {
239
+ const { filterEvents } = traversal.config;
240
+ return filterEvents === void 0 ? true : filterEvents(state, event);
241
+ };
242
+ const recordTransition = (value, queue, queued, event, traversal) => {
243
+ const nextState = resolveTransitionSnapshot(traversal.logic.transition(queued.nextState, event, actorScopeOf$1(traversal.actorScope)));
244
+ value.transitions[toSerializedEvent(traversal.config.serializeEvent(event))] = {
245
+ event,
246
+ state: nextState
247
+ };
248
+ queue.push({
249
+ nextState,
250
+ event,
251
+ prevState: queued.nextState
252
+ });
253
+ };
254
+ const enqueueTransitions = (value, queue, queued, traversal) => {
255
+ for (const event of eventsFor(traversal, queued.nextState)) enqueueFiltered(value, queue, queued, event, traversal);
256
+ };
257
+ const enqueueFiltered = (value, queue, queued, event, traversal) => {
258
+ if (passesFilter(traversal, queued.nextState, event)) recordTransition(value, queue, queued, event, traversal);
259
+ };
260
+ const expand = (adj, queue, queued, traversal) => {
261
+ const value = registerQueued(adj, queued, traversal);
262
+ if (value === void 0) return;
263
+ enqueueTransitions(value, queue, queued, traversal);
264
+ };
265
+ const expandLevel = (adj, level, traversal) => {
266
+ const nextLevel = [];
267
+ for (const queued of level) expand(adj, nextLevel, queued, traversal);
268
+ return nextLevel;
269
+ };
270
+ const drain = (adj, start, traversal) => {
271
+ let level = [start];
272
+ while (level.length !== 0) level = expandLevel(adj, level, traversal);
273
+ };
274
+ function computeAdjacencyMap(logic, options) {
275
+ "use strict";
276
+ const config = resolveTraversalOptions({
277
+ logic,
278
+ options
279
+ });
280
+ const actorScope = createMockActorScope();
281
+ const traversal = {
282
+ config,
283
+ logic,
284
+ actorScope,
285
+ iterations: 0
286
+ };
287
+ const fromState = config.fromState ?? initialSnapshotOf$3(logic, options.input, actorScope);
288
+ const adj = createNullDict$2();
289
+ drain(adj, {
290
+ nextState: fromState,
291
+ event: void 0,
292
+ prevState: void 0
293
+ }, traversal);
294
+ return adj;
295
+ }
296
+ function getAdjacencyMap(...args) {
297
+ if (args.length === 1) {
298
+ const [options] = args;
299
+ return (logic) => computeAdjacencyMap(logic, options);
300
+ }
301
+ return computeAdjacencyMap(args[0], args[1]);
302
+ }
303
+ /** @public */
304
+ function adjacencyMapToArray(adjMap) {
305
+ return Object.values({ ...adjMap }).flatMap((adjValue) => adjacencyRow(adjValue));
306
+ }
307
+ const adjacencyRow = (adjValue) => Object.values({ ...adjValue.transitions }).map((transition) => ({
308
+ state: adjValue.state,
309
+ event: transition.event,
310
+ nextState: transition.state
311
+ }));
312
+ // src/graph/alterPath.ts
313
+ const initStepOf = (state) => ({
314
+ state,
315
+ event: { type: XSTATE_INIT }
316
+ });
317
+ const previousStepOf = (steps, index) => steps[index - 1];
318
+ const eventForStep = (steps, index) => {
319
+ const previous = previousStepOf(steps, index);
320
+ return previous === void 0 ? { type: XSTATE_INIT } : previous.event;
321
+ };
322
+ const replaySteps = (path) => path.steps.flatMap((step, index) => [{
323
+ state: step.state,
324
+ event: eventForStep(path.steps, index)
325
+ }]);
326
+ const finalStepOf = (path) => {
327
+ const last = path.steps[path.steps.length - 1];
328
+ return last === void 0 ? void 0 : {
329
+ state: path.state,
330
+ event: last.event
331
+ };
332
+ };
333
+ const appendedSteps = (path) => {
334
+ const steps = replaySteps(path);
335
+ const finalStep = finalStepOf(path);
336
+ steps.push(finalStep === void 0 ? initStepOf(path.state) : finalStep);
337
+ return steps;
338
+ };
339
+ function alterPath(path) {
340
+ return {
341
+ ...path,
342
+ steps: appendedSteps(path)
343
+ };
344
+ }
345
+ // src/graph/pathFromEvents.ts
346
+ const inputOf$2 = (options) => options === void 0 ? void 0 : options.input;
347
+ const initialSnapshotOf$2 = (logic, input, actorScope) => logic.getInitialSnapshot(actorScope, input);
348
+ function actorScopeOf(scope) {
349
+ return scope;
350
+ }
351
+ const passesFilterEvents = (filterEvents, state, event) => filterEvents === void 0 ? true : filterEvents(state, event);
352
+ const matchesCandidate = (filterEvents, serializeEvent, state, candidate, eventSerial) => passesFilterEvents(filterEvents, state, candidate) && serializeEvent(candidate) === eventSerial;
353
+ const lastMatchingCandidate = (candidates, filterEvents, serializeEvent, state, eventSerial) => [...candidates].reverse().find((candidate) => matchesCandidate(filterEvents, serializeEvent, state, candidate, eventSerial));
354
+ const eventsFrom = (events, state) => typeof events === "function" ? events(state) : events;
355
+ const overrideEvents = (options, state) => options === void 0 ? void 0 : eventsFrom(options.events, state);
356
+ const replayEvent = (filterEvents, state, event) => passesFilterEvents(filterEvents, state, event) ? event : void 0;
357
+ const nextEventFor = (context, state, event, eventSerial) => {
358
+ const override = overrideEvents(context.options, state);
359
+ if (override !== void 0) return lastMatchingCandidate(override, context.config.filterEvents, context.config.serializeEvent, state, eventSerial);
360
+ return replayEvent(context.config.filterEvents, state, event);
361
+ };
362
+ const assertWithinLimit = (stepCount, limit) => {
363
+ if (stepCount >= limit) throw new Error("Traversal limit exceeded");
364
+ };
365
+ const stopsBefore = (stopWhen, state) => stopWhen === void 0 ? false : stopWhen(state);
366
+ const isReplayable = (nextEvent, stopWhen, state) => nextEvent !== void 0 && !stopsBefore(stopWhen, state);
367
+ const invalidTransition = (stateSerial, eventSerial) => /* @__PURE__ */ new Error(`Invalid transition from ${stateSerial} with ${eventSerial}`);
368
+ const assertReplayable = (nextEvent, stopWhen, state, stateSerial, eventSerial) => {
369
+ if (isReplayable(nextEvent, stopWhen, state)) return nextEvent;
370
+ throw invalidTransition(stateSerial, eventSerial);
371
+ };
372
+ const advanceState = (context, replay, nextEvent, event) => {
373
+ const result = context.logic.transition(replay.state, nextEvent, actorScopeOf(context.actorScope));
374
+ const nextState = Array.isArray(result) ? result[0] : result;
375
+ return {
376
+ state: nextState,
377
+ stateSerial: toSerializedSnapshot(context.config.serializeState(nextState, event, replay.state))
378
+ };
379
+ };
380
+ const replayOne = (context, replay, event) => {
381
+ assertWithinLimit(context.steps.length, context.config.limit);
382
+ const eventSerial = toSerializedEvent(context.config.serializeEvent(event));
383
+ const nextEvent = assertReplayable(nextEventFor(context, replay.state, event, eventSerial), context.config.stopWhen, replay.state, replay.stateSerial, eventSerial);
384
+ context.steps.push({
385
+ state: replay.state,
386
+ event
387
+ });
388
+ return advanceState(context, replay, nextEvent, event);
389
+ };
390
+ const initialReplay = (config, logic, options, actorScope) => {
391
+ const state = config.fromState ?? initialSnapshotOf$2(logic, inputOf$2(options), actorScope);
392
+ return {
393
+ state,
394
+ stateSerial: toSerializedSnapshot(config.serializeState(state, void 0, void 0))
395
+ };
396
+ };
397
+ const reachesTarget = (toState, state) => toState === void 0 ? true : toState(state);
398
+ const buildPaths = (context, replay) => {
399
+ if (!reachesTarget(context.config.toState, replay.state)) return [];
400
+ return [alterPath({
401
+ state: replay.state,
402
+ steps: context.steps,
403
+ weight: context.steps.length
404
+ })];
405
+ };
406
+ function computePathsFromEvents(logic, events, options) {
407
+ const config = resolveTraversalOptions({
408
+ logic,
409
+ options: {
410
+ events,
411
+ ...options
412
+ }
413
+ });
414
+ const actorScope = createMockActorScope();
415
+ const context = {
416
+ config,
417
+ options,
418
+ logic,
419
+ actorScope,
420
+ steps: []
421
+ };
422
+ let replay = initialReplay(config, logic, options, actorScope);
423
+ for (const event of events) replay = replayOne(context, replay, event);
424
+ return buildPaths(context, replay);
425
+ }
426
+ const isDataLastReplay = (args) => Array.isArray(args[0]);
427
+ function getPathsFromEvents(...args) {
428
+ return isDataLastReplay(args) ? (logic) => computePathsFromEvents(logic, args[0], args[1]) : computePathsFromEvents(args[0], args[1], args[2]);
429
+ }
430
+ // src/graph/shortestPaths.ts
431
+ const createNullDict$1 = () => {
432
+ const dict = {};
433
+ Object.setPrototypeOf(dict, null);
434
+ return dict;
435
+ };
436
+ const inputOf$1 = (options) => options === void 0 ? void 0 : options.input;
437
+ const initialSnapshotOf$1 = (logic, input, actorScope) => logic.getInitialSnapshot(actorScope, input);
438
+ const discover = (context, nextSerialized, entry) => {
439
+ if (!context.visited.has(nextSerialized)) context.unvisited.set(nextSerialized, entry);
440
+ };
441
+ const recordReach = (context, nextSerialized, weight, origin, snapshot, event) => {
442
+ const existing = context.weightMap.get(nextSerialized);
443
+ const entry = existing === void 0 ? {
444
+ weight,
445
+ snapshot,
446
+ origin,
447
+ event
448
+ } : {
449
+ ...existing,
450
+ snapshot
451
+ };
452
+ context.weightMap.set(nextSerialized, entry);
453
+ discover(context, nextSerialized, entry);
454
+ };
455
+ const relaxTransition = (context, fromSerialized, fromSnapshot, weight, transitions, serializedEvent) => {
456
+ const transition = transitions[serializedEvent];
457
+ if (transition === void 0) return;
458
+ const nextSerialized = toSerializedSnapshot(context.serializeState(transition.state, transition.event, fromSnapshot));
459
+ recordReach(context, nextSerialized, weight + 1, fromSerialized, transition.state, transition.event);
460
+ };
461
+ const relaxTransitions = (context, fromSerialized, fromSnapshot, weight, adjacencyValue) => {
462
+ for (const serializedEvent of Object.keys(adjacencyValue.transitions).map(toSerializedEvent)) relaxTransition(context, fromSerialized, fromSnapshot, weight, adjacencyValue.transitions, serializedEvent);
463
+ };
464
+ const relaxState = (context, fromSerialized, entry) => {
465
+ const adjacencyValue = context.adjacency[fromSerialized];
466
+ if (adjacencyValue === void 0) return;
467
+ relaxTransitions(context, fromSerialized, entry.snapshot, entry.weight, adjacencyValue);
468
+ context.visited.add(fromSerialized);
469
+ context.unvisited.delete(fromSerialized);
470
+ };
471
+ const runTraversal = (context) => {
472
+ for (const [fromSerialized, entry] of context.unvisited) relaxState(context, fromSerialized, entry);
473
+ };
474
+ const firstPlanPath = (statePlanMap, fromSerialized) => {
475
+ const plan = statePlanMap[fromSerialized];
476
+ return plan === void 0 ? void 0 : plan.paths[0];
477
+ };
478
+ const stepTo = (fromState, event) => event === void 0 ? [] : [{
479
+ state: fromState,
480
+ event
481
+ }];
482
+ const stepsToward = (statePlanMap, fromSerialized, event) => {
483
+ const path = firstPlanPath(statePlanMap, fromSerialized);
484
+ return path === void 0 ? [] : path.steps.concat(stepTo(path.state, event));
485
+ };
486
+ const predecessorSteps = (statePlanMap, entry) => {
487
+ const origin = entry.origin;
488
+ return origin === void 0 ? [] : stepsToward(statePlanMap, origin, entry.event);
489
+ };
490
+ const buildPath = (statePlanMap, entry, stateSerial) => {
491
+ const state = entry.snapshot;
492
+ const steps = predecessorSteps(statePlanMap, entry);
493
+ statePlanMap[stateSerial] = {
494
+ state,
495
+ paths: [{
496
+ state,
497
+ steps,
498
+ weight: entry.weight
499
+ }]
500
+ };
501
+ return {
502
+ state,
503
+ steps,
504
+ weight: entry.weight
505
+ };
506
+ };
507
+ const collectPaths = (weightMap) => {
508
+ const statePlanMap = createNullDict$1();
509
+ const paths = [];
510
+ weightMap.forEach((entry, stateSerial) => {
511
+ paths.push(buildPath(statePlanMap, entry, stateSerial));
512
+ });
513
+ return paths;
514
+ };
515
+ const applyTarget$1 = (paths, toState) => {
516
+ const target = toState;
517
+ if (target === void 0) return paths.map(alterPath);
518
+ return paths.filter((path) => target(path.state)).map(alterPath);
519
+ };
520
+ const seed$1 = (context, fromState) => {
521
+ const serialized = toSerializedSnapshot(context.serializeState(fromState, void 0, void 0));
522
+ const entry = {
523
+ weight: 0,
524
+ snapshot: fromState,
525
+ origin: void 0,
526
+ event: void 0
527
+ };
528
+ context.weightMap.set(serialized, entry);
529
+ context.unvisited.set(serialized, entry);
530
+ };
531
+ function computeShortestPaths(logic, options) {
532
+ const resolvedOptions = resolveTraversalOptions({
533
+ logic,
534
+ options
535
+ });
536
+ const fromState = resolvedOptions.fromState ?? initialSnapshotOf$1(logic, inputOf$1(options), createMockActorScope());
537
+ const context = {
538
+ adjacency: getAdjacencyMap(logic, {
539
+ ...resolvedOptions,
540
+ fromState
541
+ }),
542
+ serializeState: resolvedOptions.serializeState,
543
+ weightMap: /* @__PURE__ */ new Map(),
544
+ visited: /* @__PURE__ */ new Set(),
545
+ unvisited: /* @__PURE__ */ new Map()
546
+ };
547
+ seed$1(context, fromState);
548
+ runTraversal(context);
549
+ return applyTarget$1(collectPaths(context.weightMap), resolvedOptions.toState);
550
+ }
551
+ function getShortestPaths(...args) {
552
+ const [first, second] = args;
553
+ return logicFirstOrLast(computeShortestPaths)(first, second);
554
+ }
555
+ // src/graph/simplePaths.ts
556
+ const createNullDict = () => {
557
+ const dict = {};
558
+ Object.setPrototypeOf(dict, null);
559
+ return dict;
560
+ };
561
+ const inputOf = (options) => options === void 0 ? void 0 : options.input;
562
+ const initialSnapshotOf = (logic, input, actorScope) => logic.getInitialSnapshot(actorScope, input);
563
+ const boxFor = (context, serialized, snapshot) => {
564
+ const existing = context.stateMap.get(serialized);
565
+ const box = existing === void 0 ? { snapshot } : existing;
566
+ box.snapshot = snapshot;
567
+ context.stateMap.set(serialized, box);
568
+ return box;
569
+ };
570
+ const createPlan = (pathMap, serialized, state) => {
571
+ const plan = {
572
+ state,
573
+ paths: []
574
+ };
575
+ pathMap[serialized] = plan;
576
+ return plan;
577
+ };
578
+ const planAt = (pathMap, serialized, state) => {
579
+ const existing = pathMap[serialized];
580
+ return existing === void 0 ? createPlan(pathMap, serialized, state) : existing;
581
+ };
582
+ const recordPath = (context, toSerialized, fromState) => {
583
+ planAt(context.pathMap, toSerialized, fromState).paths.push({
584
+ state: fromState,
585
+ weight: context.steps.length,
586
+ steps: [...context.steps]
587
+ });
588
+ };
589
+ function expandInto(context, box, toSerialized, serializedEvent, event, nextSerialized, nextBox) {
590
+ context.visitCtx.edges.add(serializedEvent);
591
+ context.steps.push({
592
+ state: box.snapshot,
593
+ event
594
+ });
595
+ visit(context, nextSerialized, nextBox, toSerialized);
596
+ }
597
+ const descendInto = (context, box, toSerialized, serializedEvent, transition) => {
598
+ const nextSerialized = toSerializedSnapshot(context.serializeState(transition.state, transition.event, box.snapshot));
599
+ const nextBox = boxFor(context, nextSerialized, transition.state);
600
+ if (!context.visitCtx.vertices.has(nextSerialized)) expandInto(context, box, toSerialized, serializedEvent, transition.event, nextSerialized, nextBox);
601
+ };
602
+ const descendTransition = (context, box, toSerialized, transitions, serializedEvent) => {
603
+ const transition = transitions[serializedEvent];
604
+ if (transition === void 0) return;
605
+ descendInto(context, box, toSerialized, serializedEvent, transition);
606
+ };
607
+ const descendTransitions = (context, box, toSerialized, adjacencyValue) => {
608
+ for (const serializedEvent of Object.keys(adjacencyValue.transitions).map(toSerializedEvent)) descendTransition(context, box, toSerialized, adjacencyValue.transitions, serializedEvent);
609
+ };
610
+ const descend = (context, fromSerialized, box, toSerialized) => {
611
+ const adjacencyValue = context.adjacency[fromSerialized];
612
+ if (adjacencyValue === void 0) return;
613
+ descendTransitions(context, box, toSerialized, adjacencyValue);
614
+ };
615
+ function visit(context, fromSerialized, box, toSerialized) {
616
+ context.visitCtx.vertices.add(fromSerialized);
617
+ if (fromSerialized === toSerialized) recordPath(context, toSerialized, box.snapshot);
618
+ else descend(context, fromSerialized, box, toSerialized);
619
+ context.steps.pop();
620
+ context.visitCtx.vertices.delete(fromSerialized);
621
+ }
622
+ const seed = (context, fromState) => {
623
+ const serialized = toSerializedSnapshot(context.serializeState(fromState, void 0));
624
+ return {
625
+ serialized,
626
+ box: boxFor(context, serialized, fromState)
627
+ };
628
+ };
629
+ const visitEachStart = (context, fromSerialized, box) => {
630
+ for (const nextSerialized of Object.keys(context.adjacency).map(toSerializedSnapshot)) visit(context, fromSerialized, box, nextSerialized);
631
+ };
632
+ const applyTarget = (paths, toState) => {
633
+ const target = toState;
634
+ if (target === void 0) return paths.map(alterPath);
635
+ return paths.filter((path) => target(path.state)).map(alterPath);
636
+ };
637
+ function computeSimplePaths(logic, options) {
638
+ const resolvedOptions = resolveTraversalOptions({
639
+ logic,
640
+ options
641
+ });
642
+ const actorScope = createMockActorScope();
643
+ const fromState = resolvedOptions.fromState ?? initialSnapshotOf(logic, inputOf(options), actorScope);
644
+ const context = {
645
+ adjacency: getAdjacencyMap(logic, {
646
+ ...resolvedOptions,
647
+ fromState
648
+ }),
649
+ serializeState: resolvedOptions.serializeState,
650
+ stateMap: /* @__PURE__ */ new Map(),
651
+ visitCtx: {
652
+ vertices: /* @__PURE__ */ new Set(),
653
+ edges: /* @__PURE__ */ new Set()
654
+ },
655
+ steps: [],
656
+ pathMap: createNullDict()
657
+ };
658
+ const { serialized: fromSerialized, box } = seed(context, fromState);
659
+ visitEachStart(context, fromSerialized, box);
660
+ const simplePaths = Object.values(context.pathMap).flatMap((plan) => plan.paths);
661
+ return applyTarget(simplePaths, resolvedOptions.toState);
662
+ }
663
+ function getSimplePaths(...args) {
664
+ const [first, second] = args;
665
+ return logicFirstOrLast(computeSimplePaths)(first, second);
666
+ }
667
+ export { adjacencyMapToArray, getAdjacencyMap, getDescendantStateNodes, getPathsFromEvents, getShortestPaths, getSimplePaths, joinPaths, serializeSnapshot, toDirectedGraph };