@typeonce/effect-machine 0.31.2 → 0.33.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 +168 -162
- package/dist/Machine.d.ts +495 -284
- 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 +134 -403
- 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 +63 -35
- 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 +11 -13
- 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 +259 -0
- package/package.json +1 -1
- package/src/Machine.ts +1053 -538
- 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 +222 -716
- package/src/internal/machine/planner.ts +74 -62
- 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 +23 -24
- 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
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
} from "./configuration.js"
|
|
41
41
|
import { InfiniteTransitionError, MachineSchemaDecodeError, StartupError, StoppedError } from "./errors.js"
|
|
42
42
|
import { getStateInitializeValues, makeStateInitializeBuilder } from "./initialization.js"
|
|
43
|
+
import * as InvocationDefinition from "./invocationDefinition.js"
|
|
43
44
|
import * as InvocationEvent from "./invocationEvent.js"
|
|
44
45
|
import { decodeEventSync, decodeInputSync, decodeStateValueSync } from "./protocol.js"
|
|
45
46
|
import { InitialEventTypeId } from "./symbols.js"
|
|
@@ -56,9 +57,15 @@ import {
|
|
|
56
57
|
isStateUpdate,
|
|
57
58
|
isTarget,
|
|
58
59
|
makeChoiceTarget,
|
|
60
|
+
makeStateInput,
|
|
59
61
|
makeTarget,
|
|
60
62
|
TargetSnapshotTypeId
|
|
61
63
|
} from "./topology.js"
|
|
64
|
+
import type {
|
|
65
|
+
EventTransition,
|
|
66
|
+
TransitionEvaluator,
|
|
67
|
+
TransitionHandler as CapturedTransitionHandler
|
|
68
|
+
} from "./transition.js"
|
|
62
69
|
|
|
63
70
|
export type MicrostepPlan<State, Event, E, R> = {
|
|
64
71
|
readonly next: State
|
|
@@ -104,21 +111,12 @@ export type MacrostepPlan<State, Event, E, R, Output> =
|
|
|
104
111
|
}
|
|
105
112
|
)
|
|
106
113
|
|
|
107
|
-
export type TransitionHandler<States extends Machine.StateSchemas, E, R, Context> =
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
readonly result: Machine.HandlerResult<States, E, R> | Machine.Declined
|
|
114
|
-
readonly branchIndex: number
|
|
115
|
-
readonly branchKey: string | undefined
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
type TransitionEvaluator<States extends Machine.StateSchemas, E, R, Context> = (
|
|
119
|
-
context: Context,
|
|
120
|
-
enqueue: Enqueue<any, any>
|
|
121
|
-
) => TransitionEvaluation<States, E, R>
|
|
114
|
+
export type TransitionHandler<States extends Machine.StateSchemas, E, R, Context> = CapturedTransitionHandler<
|
|
115
|
+
States,
|
|
116
|
+
E,
|
|
117
|
+
R,
|
|
118
|
+
Context
|
|
119
|
+
>
|
|
122
120
|
|
|
123
121
|
type PlanningMachineReferences = {
|
|
124
122
|
readonly self: MachineTarget<any>
|
|
@@ -170,16 +168,6 @@ const resolveMachineReferences = (
|
|
|
170
168
|
return root
|
|
171
169
|
}
|
|
172
170
|
|
|
173
|
-
type EventTransition<States extends Machine.StateSchemas, E, R, Context> =
|
|
174
|
-
| TransitionHandler<States, E, R, Context>
|
|
175
|
-
| {
|
|
176
|
-
readonly reenter?: boolean
|
|
177
|
-
readonly declinable?: boolean
|
|
178
|
-
readonly targets?: ReadonlyArray<string>
|
|
179
|
-
readonly transition: TransitionHandler<States, E, R, Context>
|
|
180
|
-
readonly evaluate?: TransitionEvaluator<States, E, R, Context>
|
|
181
|
-
}
|
|
182
|
-
|
|
183
171
|
export type MicrostepTransition<States extends Machine.StateSchemas, E, R, Context> = {
|
|
184
172
|
readonly reenter: boolean
|
|
185
173
|
readonly declinable: boolean
|
|
@@ -344,7 +332,9 @@ const completeHistoryConfiguration = (
|
|
|
344
332
|
if (child.schema !== undefined) {
|
|
345
333
|
const initializer = machine.handlers[path]?.initialize
|
|
346
334
|
if (initializer === undefined) {
|
|
347
|
-
|
|
335
|
+
values.set(child.path, decodeStateValueSync(machine, child, makeStateInput({})))
|
|
336
|
+
changed = true
|
|
337
|
+
continue
|
|
348
338
|
}
|
|
349
339
|
const initialized = collectStateInitializer(machine, initializer, {
|
|
350
340
|
...resolveMachineReferences(machine, current),
|
|
@@ -374,9 +364,6 @@ const completeHistoryConfiguration = (
|
|
|
374
364
|
machineReferences: configuration.machineReferences
|
|
375
365
|
} as ActiveConfiguration
|
|
376
366
|
const initializer = valuedMissing.length === 0 ? undefined : machine.handlers[path]?.initialize
|
|
377
|
-
if (valuedMissing.length > 0 && initializer === undefined) {
|
|
378
|
-
throw new Error(`Machine shallow history requires an initial value implementation for state "${path}"`)
|
|
379
|
-
}
|
|
380
367
|
const initialized = initializer === undefined ? undefined : collectStateInitializer(machine, initializer, {
|
|
381
368
|
...resolveMachineReferences(machine, current),
|
|
382
369
|
state: current.values.get(path),
|
|
@@ -392,8 +379,11 @@ const completeHistoryConfiguration = (
|
|
|
392
379
|
const child = getNode(machine, childPath)
|
|
393
380
|
active.add(child.path)
|
|
394
381
|
if (child.schema !== undefined) {
|
|
382
|
+
if (initialized === undefined) {
|
|
383
|
+
values.set(child.path, decodeStateValueSync(machine, child, makeStateInput({})))
|
|
384
|
+
continue
|
|
385
|
+
}
|
|
395
386
|
if (
|
|
396
|
-
initialized === undefined ||
|
|
397
387
|
initializedValues === undefined || !Object.prototype.hasOwnProperty.call(initializedValues, child.key)
|
|
398
388
|
) {
|
|
399
389
|
throw new Error(`Machine parallel state initializer for "${path}" must return region "${child.key}"`)
|
|
@@ -468,6 +458,7 @@ function resolveHistoryTarget(
|
|
|
468
458
|
const completed = completeHistoryConfiguration(machine, restored, event)
|
|
469
459
|
const snapshot = snapshotFromConfigurationAtPath(machine, completed.configuration, target.parent)
|
|
470
460
|
const values = Object.fromEntries(completed.configuration.values)
|
|
461
|
+
if (target.parent !== "" && configuration.active.has("")) delete values[""]
|
|
471
462
|
return {
|
|
472
463
|
target: makeTarget(target.parent as any, snapshot.value as any, {
|
|
473
464
|
snapshot: snapshot as any,
|
|
@@ -487,7 +478,7 @@ function resolveHistoryTarget(
|
|
|
487
478
|
}
|
|
488
479
|
const collected = collectTransition(machine, fallback, {
|
|
489
480
|
event,
|
|
490
|
-
target: getTargetBuilder(machine, target.parent).full,
|
|
481
|
+
target: getTargetBuilder(machine, target.parent).full[""],
|
|
491
482
|
owner: target.parent
|
|
492
483
|
})
|
|
493
484
|
if (collected.state === undefined || isHistoryTarget(collected.state) || !isSnapshot(collected.state)) {
|
|
@@ -531,6 +522,7 @@ function resolveHistoryTarget(
|
|
|
531
522
|
}
|
|
532
523
|
const snapshot = snapshotFromConfigurationAtPath(machine, fallbackConfiguration, target.parent)
|
|
533
524
|
const values = Object.fromEntries(fallbackConfiguration.values)
|
|
525
|
+
if (target.parent !== "" && configuration.active.has("")) delete values[""]
|
|
534
526
|
return {
|
|
535
527
|
target: makeTarget(target.parent as any, snapshot.value as any, {
|
|
536
528
|
snapshot: snapshot as any,
|
|
@@ -765,7 +757,7 @@ const collectStateActions = <
|
|
|
765
757
|
) => {
|
|
766
758
|
const commands: Array<RuntimeCommand> = []
|
|
767
759
|
const raisedEvents: Array<Machine.EventOf<Events>> = []
|
|
768
|
-
const emittedEvents: Array<Machine.
|
|
760
|
+
const emittedEvents: Array<Machine.EmittedEventOf<Emits>> = []
|
|
769
761
|
for (const path of paths) {
|
|
770
762
|
const collected = collectStateAction<
|
|
771
763
|
Machine.StateActionContext<States, Events, Emits, Machine.StateIdentifier<States>>,
|
|
@@ -784,7 +776,7 @@ const collectStateActions = <
|
|
|
784
776
|
)
|
|
785
777
|
commands.push(...collected.commands)
|
|
786
778
|
raisedEvents.push(...collected.raisedEvents)
|
|
787
|
-
emittedEvents.push(...collected.emittedEvents as ReadonlyArray<Machine.
|
|
779
|
+
emittedEvents.push(...collected.emittedEvents as ReadonlyArray<Machine.EmittedEventOf<Emits>>)
|
|
788
780
|
}
|
|
789
781
|
return { commands, emittedEvents, raisedEvents }
|
|
790
782
|
}
|
|
@@ -1024,7 +1016,7 @@ const selectInvocationTransition = <
|
|
|
1024
1016
|
): ReadonlyArray<SelectedTransition<States, E, R, any>> => {
|
|
1025
1017
|
if (!configuration.active.has(event.path)) return []
|
|
1026
1018
|
const config = machine.handlers[event.path] as Machine.AnyStateConfig | undefined
|
|
1027
|
-
const invoke =
|
|
1019
|
+
const invoke = InvocationDefinition.definitions(config?.invoke).find((definition) => {
|
|
1028
1020
|
const id = "child" in definition ? definition.child?.id : definition.id
|
|
1029
1021
|
return String(id) === event.id
|
|
1030
1022
|
})
|
|
@@ -1096,7 +1088,7 @@ export const validateDeclaredTransitionTarget = (
|
|
|
1096
1088
|
const actual = typeof target === "object" && target !== null && "path" in target
|
|
1097
1089
|
? String(target.path)
|
|
1098
1090
|
: "<unknown>"
|
|
1099
|
-
if (!declaredTargets.some((path) => actual === path || actual.startsWith(`${path}.`))) {
|
|
1091
|
+
if (!declaredTargets.some((path) => actual === path || (path === "" || actual.startsWith(`${path}.`)))) {
|
|
1100
1092
|
const triggerLabel = trigger.type === "event" ? String(trigger.event) : trigger.type
|
|
1101
1093
|
throw new Error(
|
|
1102
1094
|
`Machine transition from "${sourcePath}" on "${triggerLabel}" returned target "${actual}" outside declared targets: ${
|
|
@@ -1386,10 +1378,9 @@ const collectEvaluatedTransition = <
|
|
|
1386
1378
|
? (() => {
|
|
1387
1379
|
const node = getNode(machine, stateUpdate.path)
|
|
1388
1380
|
if (
|
|
1389
|
-
!state.active.has(node.path) || node.schema === undefined
|
|
1390
|
-
(node.type !== "compound" && node.type !== "parallel")
|
|
1381
|
+
!state.active.has(node.path) || node.schema === undefined
|
|
1391
1382
|
) {
|
|
1392
|
-
throw new Error(`Machine state update owner "${node.path}" must be an active valued
|
|
1383
|
+
throw new Error(`Machine state update owner "${node.path}" must be an active valued state`)
|
|
1393
1384
|
}
|
|
1394
1385
|
return {
|
|
1395
1386
|
path: node.path,
|
|
@@ -1707,13 +1698,17 @@ export const planInitialSync = <
|
|
|
1707
1698
|
: args.length === 0
|
|
1708
1699
|
? (decodeInputSync(machine, machine.input, undefined), args)
|
|
1709
1700
|
: [decodeInputSync(machine, machine.input, args[0])] as [...Machine.InputArgs<Input>]
|
|
1710
|
-
const
|
|
1701
|
+
const initial = machine.initial(...inputArgs)
|
|
1711
1702
|
const emptyConfiguration: ActiveConfiguration = {
|
|
1712
1703
|
active: new Set(),
|
|
1713
1704
|
values: new Map(),
|
|
1714
1705
|
outputs: new Map(),
|
|
1715
1706
|
history: new Map()
|
|
1716
1707
|
}
|
|
1708
|
+
const rootResolution = isInitialTarget(initial)
|
|
1709
|
+
? resolveInitialTarget(machine, emptyConfiguration, initial, InitialEvent)
|
|
1710
|
+
: undefined
|
|
1711
|
+
const state = rootResolution?.target ?? initial
|
|
1717
1712
|
const initialChoice = choiceFromTarget(state)
|
|
1718
1713
|
const choiceResolution = initialChoice === undefined
|
|
1719
1714
|
? undefined
|
|
@@ -1729,9 +1724,11 @@ export const planInitialSync = <
|
|
|
1729
1724
|
const initialHistoryChoiceTransitions: Array<ResolvedChoiceTransition> = []
|
|
1730
1725
|
const resolvedInitialTargets: Array<unknown> = []
|
|
1731
1726
|
for (
|
|
1732
|
-
const target of choiceResolution
|
|
1727
|
+
const target of choiceResolution !== undefined
|
|
1728
|
+
? [choiceResolution.target, ...choiceResolution.additionalTargets]
|
|
1729
|
+
: rootResolution === undefined
|
|
1733
1730
|
? []
|
|
1734
|
-
: [
|
|
1731
|
+
: [rootResolution.target]
|
|
1735
1732
|
) {
|
|
1736
1733
|
if (!isHistoryTarget(target)) {
|
|
1737
1734
|
resolvedInitialTargets.push(target)
|
|
@@ -1744,7 +1741,7 @@ export const planInitialSync = <
|
|
|
1744
1741
|
initialHistoryEmittedEvents.push(...history.emittedEvents)
|
|
1745
1742
|
initialHistoryChoiceTransitions.push(...history.transitions)
|
|
1746
1743
|
}
|
|
1747
|
-
let resolvedConfiguration =
|
|
1744
|
+
let resolvedConfiguration = resolvedInitialTargets.length === 0
|
|
1748
1745
|
? normalizeConfigurationSync<States>(machine, state as Machine.Snapshot<States>)
|
|
1749
1746
|
: normalizeTargetConfigurationSync<States>(
|
|
1750
1747
|
machine,
|
|
@@ -1761,18 +1758,21 @@ export const planInitialSync = <
|
|
|
1761
1758
|
)
|
|
1762
1759
|
}
|
|
1763
1760
|
const configuration: ActiveConfiguration = resolvedConfiguration
|
|
1764
|
-
validateInitialConfiguration(machine, configuration)
|
|
1761
|
+
if (machine.initialDefinition.selection.kind === "initial") validateInitialConfiguration(machine, configuration)
|
|
1765
1762
|
const startingState = snapshotFromConfiguration<States>(machine, configuration)
|
|
1766
1763
|
const initialEntryPaths = getInitialEntryPaths(machine, configuration)
|
|
1767
1764
|
const commands = [
|
|
1765
|
+
...(rootResolution?.commands ?? []),
|
|
1768
1766
|
...(choiceResolution?.commands ?? []),
|
|
1769
1767
|
...initialHistoryActions
|
|
1770
1768
|
]
|
|
1771
1769
|
const raisedEvents = [
|
|
1770
|
+
...(rootResolution?.raisedEvents ?? []),
|
|
1772
1771
|
...(choiceResolution?.raisedEvents ?? []),
|
|
1773
1772
|
...initialHistoryRaisedEvents
|
|
1774
1773
|
]
|
|
1775
1774
|
const emittedEvents = [
|
|
1775
|
+
...(rootResolution?.emittedEvents ?? []),
|
|
1776
1776
|
...(choiceResolution?.emittedEvents ?? []),
|
|
1777
1777
|
...initialHistoryEmittedEvents
|
|
1778
1778
|
]
|
|
@@ -1790,21 +1790,27 @@ export const planInitialSync = <
|
|
|
1790
1790
|
[...entry.commands],
|
|
1791
1791
|
[...raisedEvents, ...entry.raisedEvents] as Array<Machine.EventOf<Events>>,
|
|
1792
1792
|
[...emittedEvents, ...entry.emittedEvents],
|
|
1793
|
-
choiceResolution === undefined
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1793
|
+
choiceResolution === undefined && (rootResolution?.transitions.length ?? 0) === 0 &&
|
|
1794
|
+
initialHistoryChoiceTransitions.length === 0 ?
|
|
1795
|
+
[] :
|
|
1796
|
+
[{
|
|
1797
|
+
next: configuration,
|
|
1798
|
+
event: InitialEvent,
|
|
1799
|
+
transitions: [
|
|
1800
|
+
...(rootResolution?.transitions ?? []),
|
|
1801
|
+
...(choiceResolution?.transitions ?? []),
|
|
1802
|
+
...initialHistoryChoiceTransitions
|
|
1803
|
+
],
|
|
1804
|
+
commands,
|
|
1805
|
+
raisedEvents: [
|
|
1806
|
+
...raisedEvents
|
|
1807
|
+
] as ReadonlyArray<Machine.EventOf<Events>>,
|
|
1808
|
+
emittedEvents,
|
|
1809
|
+
exitPaths: [],
|
|
1810
|
+
entryPaths: [],
|
|
1811
|
+
changed: false,
|
|
1812
|
+
stabilize: false
|
|
1813
|
+
}]
|
|
1808
1814
|
)
|
|
1809
1815
|
|
|
1810
1816
|
const planned = {
|
|
@@ -1815,7 +1821,7 @@ export const planInitialSync = <
|
|
|
1815
1821
|
...commands,
|
|
1816
1822
|
...settled.commands
|
|
1817
1823
|
],
|
|
1818
|
-
emittedEvents: settled.emittedEvents as ReadonlyArray<Machine.
|
|
1824
|
+
emittedEvents: settled.emittedEvents as ReadonlyArray<Machine.EmittedEventOf<Emits>>,
|
|
1819
1825
|
microsteps: settled.microsteps.map((step) => ({
|
|
1820
1826
|
next: snapshotFromConfiguration<States>(machine, step.next),
|
|
1821
1827
|
event: step.event,
|
|
@@ -2208,6 +2214,7 @@ const macrostepConfiguration = <
|
|
|
2208
2214
|
throw new Error("Machine reached a terminal configuration without a completed root output")
|
|
2209
2215
|
}
|
|
2210
2216
|
return {
|
|
2217
|
+
event: decodedEvent,
|
|
2211
2218
|
next: completed.configuration,
|
|
2212
2219
|
commands: [],
|
|
2213
2220
|
emittedEvents: [],
|
|
@@ -2226,6 +2233,7 @@ const macrostepConfiguration = <
|
|
|
2226
2233
|
)
|
|
2227
2234
|
if (selections.length === 0) {
|
|
2228
2235
|
return {
|
|
2236
|
+
event: decodedEvent,
|
|
2229
2237
|
next: configuration,
|
|
2230
2238
|
commands: [],
|
|
2231
2239
|
emittedEvents: [],
|
|
@@ -2244,7 +2252,10 @@ const macrostepConfiguration = <
|
|
|
2244
2252
|
const raisedEvents = [...step.raisedEvents]
|
|
2245
2253
|
const emittedEvents = [...step.emittedEvents]
|
|
2246
2254
|
const microsteps = [step]
|
|
2247
|
-
return
|
|
2255
|
+
return {
|
|
2256
|
+
...settle(machine, step.next, decodedEvent as any, commands, raisedEvents, emittedEvents, microsteps),
|
|
2257
|
+
event: decodedEvent
|
|
2258
|
+
}
|
|
2248
2259
|
}
|
|
2249
2260
|
|
|
2250
2261
|
const snapshotMacrostep = <
|
|
@@ -2255,9 +2266,10 @@ const snapshotMacrostep = <
|
|
|
2255
2266
|
Output
|
|
2256
2267
|
>(
|
|
2257
2268
|
machine: Machine.Any,
|
|
2258
|
-
settled: MacrostepPlan<ActiveConfiguration, Event, E, R, Output>
|
|
2259
|
-
): MacrostepPlan<Machine.Snapshot<States>, Event, E, R, Output> => {
|
|
2269
|
+
settled: MacrostepPlan<ActiveConfiguration, Event, E, R, Output> & { readonly event: unknown }
|
|
2270
|
+
): MacrostepPlan<Machine.Snapshot<States>, Event, E, R, Output> & { readonly event: unknown } => {
|
|
2260
2271
|
const planned = {
|
|
2272
|
+
event: settled.event,
|
|
2261
2273
|
next: snapshotFromConfiguration<States>(machine, settled.next),
|
|
2262
2274
|
commands: settled.commands,
|
|
2263
2275
|
emittedEvents: settled.emittedEvents,
|
|
@@ -16,19 +16,10 @@ import type { StoppedError } from "./errors.js"
|
|
|
16
16
|
import * as ExecutionPlan from "./executionPlan.js"
|
|
17
17
|
import * as Invocation from "./invocation.js"
|
|
18
18
|
import * as internalPlanner from "./planner.js"
|
|
19
|
+
import type { ExcludeCompatibleRuntime } from "./requirements.js"
|
|
19
20
|
import * as internalRuntime from "./runtime.js"
|
|
20
21
|
import * as Serialization from "./serialization.js"
|
|
21
22
|
|
|
22
|
-
type IsAny<A> = 0 extends (1 & A) ? true : false
|
|
23
|
-
|
|
24
|
-
type ExcludeCompatibleRuntime<Requirements, Events, Emits> = Requirements extends Runtime.Requirement<
|
|
25
|
-
infer RequiredEvents,
|
|
26
|
-
infer RequiredEmits
|
|
27
|
-
> ? IsAny<Requirements> extends true ? Requirements
|
|
28
|
-
: [RequiredEvents] extends [Events] ? [RequiredEmits] extends [Emits] ? never : Requirements
|
|
29
|
-
: Requirements
|
|
30
|
-
: Requirements
|
|
31
|
-
|
|
32
23
|
type ProcessEntry<States extends Machine.StateSchemas, Input extends Schema.Top> =
|
|
33
24
|
| {
|
|
34
25
|
readonly _tag: "Initial"
|
|
@@ -50,6 +41,7 @@ const runSequentialDiscard = <E, R>(
|
|
|
50
41
|
|
|
51
42
|
const acknowledgedPlan = (
|
|
52
43
|
planned: {
|
|
44
|
+
readonly event: unknown
|
|
53
45
|
readonly next: unknown
|
|
54
46
|
readonly commands: ReadonlyArray<unknown>
|
|
55
47
|
readonly emittedEvents: ReadonlyArray<unknown>
|
|
@@ -69,6 +61,7 @@ const acknowledgedPlan = (
|
|
|
69
61
|
},
|
|
70
62
|
snapshot: (state: unknown) => unknown
|
|
71
63
|
): unknown => ({
|
|
64
|
+
event: planned.event,
|
|
72
65
|
next: snapshot(planned.next),
|
|
73
66
|
commands: planned.commands,
|
|
74
67
|
emittedEvents: planned.emittedEvents,
|
|
@@ -397,7 +390,7 @@ const makeProcessLogic: <
|
|
|
397
390
|
ExcludeCompatibleRuntime<
|
|
398
391
|
Exclude<ExecutionServices<InitialR | R>, internalRuntime.MachineRuntime>,
|
|
399
392
|
Machine.EventOf<Events>,
|
|
400
|
-
Machine.
|
|
393
|
+
Machine.EmittedEventOf<Emits>
|
|
401
394
|
>,
|
|
402
395
|
Output,
|
|
403
396
|
| InitialE
|
|
@@ -469,7 +462,7 @@ const makeProcessLogic: <
|
|
|
469
462
|
? undefined
|
|
470
463
|
: CommandRuntime.runEmittedEvents(
|
|
471
464
|
planned.emittedEvents,
|
|
472
|
-
CommandRuntime.makeLiveRuntime<Machine.EventOf<Events>, Machine.
|
|
465
|
+
CommandRuntime.makeLiveRuntime<Machine.EventOf<Events>, Machine.EmittedEventOf<Emits>>(machine, scope)
|
|
473
466
|
)
|
|
474
467
|
const result = Effect.succeed({
|
|
475
468
|
state: planned.state,
|
|
@@ -531,7 +524,7 @@ const makeProcessLogic: <
|
|
|
531
524
|
// so the Effect scheduler remains responsible for cooperative yield.
|
|
532
525
|
let configuration: Configuration.ActiveConfiguration | undefined
|
|
533
526
|
let pendingMessage: Option.Option<internalRuntime.ProcessMessage<Machine.EventOf<Events>>> = Option.none()
|
|
534
|
-
let liveRuntime: Runtime<Machine.EventOf<Events>, Machine.
|
|
527
|
+
let liveRuntime: Runtime<Machine.EventOf<Events>, Machine.EmittedEventOf<Emits>> | undefined
|
|
535
528
|
while (terminal === undefined) {
|
|
536
529
|
const message = Option.isSome(pendingMessage) ? pendingMessage.value : yield* receiveMessage
|
|
537
530
|
pendingMessage = Option.none()
|
|
@@ -563,7 +556,7 @@ const makeProcessLogic: <
|
|
|
563
556
|
current = next
|
|
564
557
|
if (planned.emittedEvents.length > 0) {
|
|
565
558
|
yield* CommandRuntime.runEmittedEvents(
|
|
566
|
-
planned.emittedEvents as ReadonlyArray<Machine.
|
|
559
|
+
planned.emittedEvents as ReadonlyArray<Machine.EmittedEventOf<Emits>>,
|
|
567
560
|
liveRuntime ??= CommandRuntime.makeLiveRuntime(machine, context)
|
|
568
561
|
)
|
|
569
562
|
}
|
|
@@ -639,7 +632,7 @@ const makeProcessLogic: <
|
|
|
639
632
|
// worker can continue draining an already queued batch.
|
|
640
633
|
configuration = undefined
|
|
641
634
|
let pendingMessage: Option.Option<internalRuntime.ProcessMessage<Machine.EventOf<Events>>> = Option.none()
|
|
642
|
-
let liveRuntime: Runtime<Machine.EventOf<Events>, Machine.
|
|
635
|
+
let liveRuntime: Runtime<Machine.EventOf<Events>, Machine.EmittedEventOf<Emits>> | undefined
|
|
643
636
|
|
|
644
637
|
// Match the compact non-invoke loop while retaining state-scoped
|
|
645
638
|
// child lifecycle work at the same ordered Effect boundaries.
|
|
@@ -687,7 +680,7 @@ const makeProcessLogic: <
|
|
|
687
680
|
current = next
|
|
688
681
|
if (planned.emittedEvents.length > 0) {
|
|
689
682
|
yield* CommandRuntime.runEmittedEvents(
|
|
690
|
-
planned.emittedEvents as ReadonlyArray<Machine.
|
|
683
|
+
planned.emittedEvents as ReadonlyArray<Machine.EmittedEventOf<Emits>>,
|
|
691
684
|
liveRuntime ??= CommandRuntime.makeLiveRuntime(machine, context)
|
|
692
685
|
)
|
|
693
686
|
}
|
|
@@ -741,7 +734,7 @@ const makeProcessLogic: <
|
|
|
741
734
|
ExcludeCompatibleRuntime<
|
|
742
735
|
Exclude<ExecutionServices<InitialR | R>, internalRuntime.MachineRuntime>,
|
|
743
736
|
Machine.EventOf<Events>,
|
|
744
|
-
Machine.
|
|
737
|
+
Machine.EmittedEventOf<Emits>
|
|
745
738
|
>,
|
|
746
739
|
Output,
|
|
747
740
|
| InitialE
|
|
@@ -781,7 +774,7 @@ export const toProcessLogic: <
|
|
|
781
774
|
ExcludeCompatibleRuntime<
|
|
782
775
|
Exclude<ExecutionServices<InitialR | R>, internalRuntime.MachineRuntime>,
|
|
783
776
|
Machine.EventOf<Events>,
|
|
784
|
-
Machine.
|
|
777
|
+
Machine.EmittedEventOf<Emits>
|
|
785
778
|
>,
|
|
786
779
|
Output,
|
|
787
780
|
| InitialE
|
|
@@ -887,7 +880,7 @@ export const start: <
|
|
|
887
880
|
ExcludeCompatibleRuntime<
|
|
888
881
|
Exclude<ExecutionServices<InitialR | R>, internalRuntime.MachineRuntime>,
|
|
889
882
|
Machine.EventOf<Events>,
|
|
890
|
-
Machine.
|
|
883
|
+
Machine.EmittedEventOf<Emits>
|
|
891
884
|
>
|
|
892
885
|
> = (machine, ...args) =>
|
|
893
886
|
internalRuntime.startProcess(
|
|
@@ -931,7 +924,7 @@ export const prepare: <
|
|
|
931
924
|
ExcludeCompatibleRuntime<
|
|
932
925
|
Exclude<ExecutionServices<InitialR | R>, internalRuntime.MachineRuntime>,
|
|
933
926
|
Machine.EventOf<Events>,
|
|
934
|
-
Machine.
|
|
927
|
+
Machine.EmittedEventOf<Emits>
|
|
935
928
|
>
|
|
936
929
|
>
|
|
937
930
|
> = (machine, ...args) =>
|
|
@@ -966,7 +959,7 @@ export const resume: <
|
|
|
966
959
|
ExcludeCompatibleRuntime<
|
|
967
960
|
Exclude<ExecutionServices<R>, internalRuntime.MachineRuntime>,
|
|
968
961
|
Machine.EventOf<Events>,
|
|
969
|
-
Machine.
|
|
962
|
+
Machine.EmittedEventOf<Emits>
|
|
970
963
|
>
|
|
971
964
|
> = (machine, snapshot) =>
|
|
972
965
|
internalRuntime.startProcess(
|
|
@@ -24,9 +24,7 @@ interface MachineProtocolSchemas {
|
|
|
24
24
|
readonly event: Schema.Top
|
|
25
25
|
readonly emit: Schema.Top
|
|
26
26
|
readonly eventConstructors: ReadonlySet<object>
|
|
27
|
-
readonly trustedEvents: WeakSet<object>
|
|
28
27
|
readonly emissionConstructors: ReadonlySet<object>
|
|
29
|
-
readonly trustedEmissions: WeakSet<object>
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
interface EventProtocolDefinition {
|
|
@@ -171,9 +169,7 @@ export const setProtocol = (machine: Machine.Any): void => {
|
|
|
171
169
|
event: Schema.Union(events),
|
|
172
170
|
emit: Schema.Union(emittedEvents),
|
|
173
171
|
eventConstructors: collectEventConstructors(events),
|
|
174
|
-
|
|
175
|
-
emissionConstructors: collectEventConstructors(emittedEvents),
|
|
176
|
-
trustedEmissions: new WeakSet()
|
|
172
|
+
emissionConstructors: collectEventConstructors(emittedEvents)
|
|
177
173
|
})
|
|
178
174
|
}
|
|
179
175
|
|
|
@@ -419,11 +415,6 @@ const decodeEventConstruction = (
|
|
|
419
415
|
})
|
|
420
416
|
)
|
|
421
417
|
)
|
|
422
|
-
),
|
|
423
|
-
Effect.tap((event) =>
|
|
424
|
-
Effect.sync(() =>
|
|
425
|
-
(boundary === "event" ? protocol.trustedEvents : protocol.trustedEmissions).add(event as object)
|
|
426
|
-
)
|
|
427
418
|
)
|
|
428
419
|
)
|
|
429
420
|
}
|
|
@@ -453,13 +444,9 @@ const decodeEventConstructionSync = (
|
|
|
453
444
|
boundary,
|
|
454
445
|
event: String(construction._tag)
|
|
455
446
|
})
|
|
456
|
-
;(boundary === "event" ? protocol.trustedEvents : protocol.trustedEmissions).add(event as object)
|
|
457
447
|
return event
|
|
458
448
|
}
|
|
459
449
|
|
|
460
|
-
const isTrustedEvent = (protocol: MachineProtocolSchemas, event: unknown): boolean =>
|
|
461
|
-
typeof event === "object" && event !== null && protocol.trustedEvents.has(event)
|
|
462
|
-
|
|
463
450
|
export const decodeInput = <Input extends Schema.Top>(
|
|
464
451
|
machine: Machine.Any,
|
|
465
452
|
schema: Input,
|
|
@@ -478,10 +465,9 @@ export const decodeEvent = <const Events extends ReadonlyArray<Machine.TaggedSch
|
|
|
478
465
|
MachineSchemaDecodeError
|
|
479
466
|
>
|
|
480
467
|
}
|
|
481
|
-
if (isTrustedEvent(protocol, event)) {
|
|
482
|
-
return Effect.succeed(event as Machine.EventOf<Events>)
|
|
483
|
-
}
|
|
484
468
|
const eventName = getEventName(event)
|
|
469
|
+
// Decoded objects can escape to user code and be mutated. Validation is local
|
|
470
|
+
// to this delivery; object identity is never evidence of continued validity.
|
|
485
471
|
return decodeBoundary<Machine.EventOf<Events>>(
|
|
486
472
|
machine,
|
|
487
473
|
protocol.event,
|
|
@@ -498,9 +484,6 @@ export const decodeEventSync = <const Events extends ReadonlyArray<Machine.Tagge
|
|
|
498
484
|
if (isEventConstruction(event)) {
|
|
499
485
|
return decodeEventConstructionSync(machine, protocol, event, "event") as Machine.EventOf<Events>
|
|
500
486
|
}
|
|
501
|
-
if (isTrustedEvent(protocol, event)) {
|
|
502
|
-
return event as Machine.EventOf<Events>
|
|
503
|
-
}
|
|
504
487
|
const eventName = getEventName(event)
|
|
505
488
|
return decodeBoundarySync<Machine.EventOf<Events>>(
|
|
506
489
|
machine,
|
|
@@ -513,19 +496,16 @@ export const decodeEventSync = <const Events extends ReadonlyArray<Machine.Tagge
|
|
|
513
496
|
export const decodeEmit = <const Emits extends ReadonlyArray<Machine.TaggedSchema>>(
|
|
514
497
|
machine: Machine.Any,
|
|
515
498
|
event: unknown
|
|
516
|
-
): Effect.Effect<Machine.
|
|
499
|
+
): Effect.Effect<Machine.EmittedEventOf<Emits>, MachineSchemaDecodeError> => {
|
|
517
500
|
const protocol = getProtocolSchemas(machine)
|
|
518
501
|
if (isEventConstruction(event)) {
|
|
519
502
|
return decodeEventConstruction(machine, protocol, event, "emission") as Effect.Effect<
|
|
520
|
-
Machine.
|
|
503
|
+
Machine.EmittedEventOf<Emits>,
|
|
521
504
|
MachineSchemaDecodeError
|
|
522
505
|
>
|
|
523
506
|
}
|
|
524
|
-
if (typeof event === "object" && event !== null && protocol.trustedEmissions.has(event)) {
|
|
525
|
-
return Effect.succeed(event as Machine.EmitOf<Emits>)
|
|
526
|
-
}
|
|
527
507
|
const eventName = getEventName(event)
|
|
528
|
-
return decodeBoundary<Machine.
|
|
508
|
+
return decodeBoundary<Machine.EmittedEventOf<Emits>>(
|
|
529
509
|
machine,
|
|
530
510
|
protocol.emit,
|
|
531
511
|
event,
|
|
@@ -536,16 +516,13 @@ export const decodeEmit = <const Emits extends ReadonlyArray<Machine.TaggedSchem
|
|
|
536
516
|
export const decodeEmitSync = <const Emits extends ReadonlyArray<Machine.TaggedSchema>>(
|
|
537
517
|
machine: Machine.Any,
|
|
538
518
|
event: unknown
|
|
539
|
-
): Machine.
|
|
519
|
+
): Machine.EmittedEventOf<Emits> => {
|
|
540
520
|
const protocol = getProtocolSchemas(machine)
|
|
541
521
|
if (isEventConstruction(event)) {
|
|
542
|
-
return decodeEventConstructionSync(machine, protocol, event, "emission") as Machine.
|
|
543
|
-
}
|
|
544
|
-
if (typeof event === "object" && event !== null && protocol.trustedEmissions.has(event)) {
|
|
545
|
-
return event as Machine.EmitOf<Emits>
|
|
522
|
+
return decodeEventConstructionSync(machine, protocol, event, "emission") as Machine.EmittedEventOf<Emits>
|
|
546
523
|
}
|
|
547
524
|
const eventName = getEventName(event)
|
|
548
|
-
return decodeBoundarySync<Machine.
|
|
525
|
+
return decodeBoundarySync<Machine.EmittedEventOf<Emits>>(
|
|
549
526
|
machine,
|
|
550
527
|
protocol.emit,
|
|
551
528
|
event,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Runtime } from "../../Machine.js"
|
|
2
|
+
|
|
3
|
+
export type IsAny<A> = 0 extends (1 & A) ? true : false
|
|
4
|
+
|
|
5
|
+
export type ExcludeCompatibleRuntime<Requirements, Events, Emits> = Requirements extends Runtime.Requirement<
|
|
6
|
+
infer RequiredEvents,
|
|
7
|
+
infer RequiredEmits
|
|
8
|
+
> ? IsAny<Requirements> extends true ? Requirements
|
|
9
|
+
: [RequiredEvents] extends [Events] ? [RequiredEmits] extends [Emits] ? never : Requirements
|
|
10
|
+
: Requirements
|
|
11
|
+
: Requirements
|