@typeonce/effect-machine 0.9.0 → 0.10.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 +128 -28
- package/dist/Machine.d.ts +334 -238
- package/dist/Machine.d.ts.map +1 -1
- package/dist/Machine.js +45 -76
- package/dist/Machine.js.map +1 -1
- package/dist/internal/machine/atom.d.ts +6 -2
- package/dist/internal/machine/atom.d.ts.map +1 -1
- package/dist/internal/machine/atom.js +5 -0
- package/dist/internal/machine/atom.js.map +1 -1
- package/dist/internal/machine/cluster.d.ts.map +1 -1
- package/dist/internal/machine/cluster.js +2 -1
- package/dist/internal/machine/cluster.js.map +1 -1
- package/dist/internal/machine/command.js +2 -2
- package/dist/internal/machine/command.js.map +1 -1
- package/dist/internal/machine/commandRuntime.d.ts.map +1 -1
- package/dist/internal/machine/commandRuntime.js +6 -3
- package/dist/internal/machine/commandRuntime.js.map +1 -1
- package/dist/internal/machine/configuration.d.ts +8 -1
- package/dist/internal/machine/configuration.d.ts.map +1 -1
- package/dist/internal/machine/configuration.js +9 -4
- package/dist/internal/machine/configuration.js.map +1 -1
- package/dist/internal/machine/errors.d.ts +1 -1
- package/dist/internal/machine/errors.d.ts.map +1 -1
- package/dist/internal/machine/executionPlan.d.ts +3 -3
- package/dist/internal/machine/executionPlan.d.ts.map +1 -1
- package/dist/internal/machine/executionPlan.js +50 -25
- 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 +3 -2
- package/dist/internal/machine/invocation.js.map +1 -1
- package/dist/internal/machine/machine.d.ts +14 -19
- package/dist/internal/machine/machine.d.ts.map +1 -1
- package/dist/internal/machine/machine.js +12 -10
- package/dist/internal/machine/machine.js.map +1 -1
- package/dist/internal/machine/planner.d.ts +2 -1
- package/dist/internal/machine/planner.d.ts.map +1 -1
- package/dist/internal/machine/planner.js +61 -24
- package/dist/internal/machine/planner.js.map +1 -1
- package/dist/internal/machine/process.d.ts.map +1 -1
- package/dist/internal/machine/process.js +8 -8
- package/dist/internal/machine/process.js.map +1 -1
- package/dist/internal/machine/protocol.d.ts +7 -13
- package/dist/internal/machine/protocol.d.ts.map +1 -1
- package/dist/internal/machine/protocol.js +128 -50
- package/dist/internal/machine/protocol.js.map +1 -1
- package/dist/internal/machine/runtime.d.ts +8 -2
- package/dist/internal/machine/runtime.d.ts.map +1 -1
- package/dist/internal/machine/runtime.js +86 -8
- package/dist/internal/machine/runtime.js.map +1 -1
- package/dist/internal/machine/topology.d.ts +7 -0
- package/dist/internal/machine/topology.d.ts.map +1 -1
- package/dist/internal/machine/topology.js +6 -0
- package/dist/internal/machine/topology.js.map +1 -1
- package/dist/internal/testing/machine/finiteModel.js +1 -1
- package/dist/internal/testing/machine/finiteModel.js.map +1 -1
- package/dist/internal/testing/machine/runtime.d.ts.map +1 -1
- package/dist/internal/testing/machine/runtime.js +2 -1
- package/dist/internal/testing/machine/runtime.js.map +1 -1
- package/dist/internal/testing/machine/verification.d.ts.map +1 -1
- package/dist/internal/testing/machine/verification.js +5 -3
- package/dist/internal/testing/machine/verification.js.map +1 -1
- package/dist/testing/MachineTest.d.ts +7 -7
- package/dist/testing/MachineTest.js +7 -7
- package/dist/unstable/cluster/ClusterMachine.d.ts +1 -1
- package/dist/unstable/cluster/ClusterMachine.js +1 -1
- package/dist/unstable/reactivity/AtomMachine.d.ts +25 -8
- package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.js +18 -3
- package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
- package/docs/agent-guide.md +143 -48
- package/package.json +1 -1
- package/src/Machine.ts +559 -307
- package/src/internal/machine/atom.ts +35 -10
- package/src/internal/machine/cluster.ts +2 -1
- package/src/internal/machine/command.ts +2 -2
- package/src/internal/machine/commandRuntime.ts +9 -4
- package/src/internal/machine/configuration.ts +23 -5
- package/src/internal/machine/errors.ts +1 -1
- package/src/internal/machine/executionPlan.ts +74 -29
- package/src/internal/machine/invocation.ts +3 -2
- package/src/internal/machine/machine.ts +68 -49
- package/src/internal/machine/planner.ts +68 -24
- package/src/internal/machine/process.ts +18 -8
- package/src/internal/machine/protocol.ts +207 -68
- package/src/internal/machine/runtime.ts +135 -9
- package/src/internal/machine/topology.ts +15 -0
- package/src/internal/testing/machine/finiteModel.ts +1 -1
- package/src/internal/testing/machine/runtime.ts +2 -1
- package/src/internal/testing/machine/verification.ts +5 -3
- package/src/testing/MachineTest.ts +7 -7
- package/src/unstable/cluster/ClusterMachine.ts +1 -1
- package/src/unstable/reactivity/AtomMachine.ts +42 -10
|
@@ -72,9 +72,9 @@ type MachineStartError<InitialE, E, InitialR, R, RuntimeError = never> =
|
|
|
72
72
|
| Machine.StoppedError
|
|
73
73
|
| RuntimeError
|
|
74
74
|
|
|
75
|
-
const runMachineAtomEffect = <State, Event, Error, Output, StartError, Requirements>(
|
|
75
|
+
const runMachineAtomEffect = <State, Event, Error, Output, Emitted, StartError, Requirements>(
|
|
76
76
|
get: Atom.AtomContext,
|
|
77
|
-
start: Effect.Effect<Machine.MachineRef<State, Event, Error, Output>, StartError, Requirements>
|
|
77
|
+
start: Effect.Effect<Machine.MachineRef<State, Event, Error, Output, Emitted>, StartError, Requirements>
|
|
78
78
|
): Effect.Effect<never, StartError, Requirements> =>
|
|
79
79
|
Effect.scoped(
|
|
80
80
|
Effect.acquireRelease(start, (ref) => ref.stop).pipe(
|
|
@@ -96,7 +96,8 @@ const startMachineAtomEffect = <
|
|
|
96
96
|
FinalStates extends Machine.Machine.StateIdentifier<States> = never,
|
|
97
97
|
Output = never,
|
|
98
98
|
OutputStates extends Machine.Machine.StateIdentifier<States> = never,
|
|
99
|
-
InputEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = Events
|
|
99
|
+
InputEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = Events,
|
|
100
|
+
ParentEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = readonly []
|
|
100
101
|
>(
|
|
101
102
|
get: Atom.AtomContext,
|
|
102
103
|
machine:
|
|
@@ -113,7 +114,8 @@ const startMachineAtomEffect = <
|
|
|
113
114
|
Output,
|
|
114
115
|
Emits,
|
|
115
116
|
OutputStates,
|
|
116
|
-
InputEvents
|
|
117
|
+
InputEvents,
|
|
118
|
+
ParentEvents
|
|
117
119
|
>
|
|
118
120
|
& EnsureExecutable<States, UnhandledStates, OutputStates>,
|
|
119
121
|
args: [...Machine.Machine.InputArgs<Input>]
|
|
@@ -122,11 +124,12 @@ const startMachineAtomEffect = <
|
|
|
122
124
|
Machine.Machine.Snapshot<States>,
|
|
123
125
|
Machine.Machine.EventInputOf<InputEvents>,
|
|
124
126
|
MachineRuntimeError<E, R>,
|
|
125
|
-
Output
|
|
127
|
+
Output,
|
|
128
|
+
Machine.Machine.EmittedEventOf<Emits>
|
|
126
129
|
>,
|
|
127
130
|
MachineStartError<InitialE, E, InitialR, R>,
|
|
128
131
|
MachineRequirements<InitialR, R, Machine.Machine.EventOf<Events>, Machine.Machine.EmitOf<Emits>>
|
|
129
|
-
> => runMachineAtomEffect(get, internalMachine.start(machine, ...args))
|
|
132
|
+
> => runMachineAtomEffect(get, internalMachine.start(machine as any, ...args) as any)
|
|
130
133
|
|
|
131
134
|
const resumeMachineAtomEffect = (
|
|
132
135
|
get: Atom.AtomContext,
|
|
@@ -137,6 +140,24 @@ const resumeMachineAtomEffect = (
|
|
|
137
140
|
type RefState<Ref> = Ref extends Machine.MachineRef<infer State, any, any, any> ? State : never
|
|
138
141
|
type RefError<Ref> = Ref extends Machine.MachineRef<any, any, infer Error, any> ? Error : never
|
|
139
142
|
type RefOutput<Ref> = Ref extends Machine.MachineRef<any, any, any, infer Output> ? Output : never
|
|
143
|
+
type RefEmitted<Ref> = Ref extends Machine.MachineRef<any, any, any, any, infer Emitted> ? Emitted : never
|
|
144
|
+
|
|
145
|
+
export const emissions = <State, Event, Error, Output, StartError, Emitted>(
|
|
146
|
+
self: MachineAtom<State, Event, Error, Output, StartError, Emitted>
|
|
147
|
+
): Stream.Stream<Emitted, StartError, AtomRegistry.AtomRegistry> =>
|
|
148
|
+
Atom.toStreamResult(self.ref).pipe(Stream.flatMap((ref) => ref.emissions))
|
|
149
|
+
|
|
150
|
+
export const childEmissions = <Child extends Machine.ChildMachine.Any, StartError>(
|
|
151
|
+
self: ChildMachineAtom<Child, StartError>
|
|
152
|
+
): Stream.Stream<RefEmitted<Machine.ChildMachine.Ref<Child>>, StartError, AtomRegistry.AtomRegistry> =>
|
|
153
|
+
Atom.toStreamResult(self.ref).pipe(
|
|
154
|
+
Stream.flatMap(
|
|
155
|
+
Option.match({
|
|
156
|
+
onNone: () => Stream.empty,
|
|
157
|
+
onSome: (ref) => ref.emissions
|
|
158
|
+
})
|
|
159
|
+
)
|
|
160
|
+
)
|
|
140
161
|
|
|
141
162
|
const makeRuntimeResultAtom = <State, Error, Output, StartError>(
|
|
142
163
|
snapshot: Atom.Atom<AsyncResult.AsyncResult<Machine.RuntimeSnapshot<State, Error, Output>, StartError>>
|
|
@@ -588,7 +609,8 @@ type ResumedMachineAtomOf<M extends Machine.Machine.Any, RuntimeError> = Machine
|
|
|
588
609
|
Machine.Machine.EventInput<Machine.Machine.InputEvent<M>>,
|
|
589
610
|
MachineRuntimeError<Machine.Machine.Error<M>, Machine.Machine.Services<M>>,
|
|
590
611
|
Machine.Machine.Output<M>,
|
|
591
|
-
Machine.MachineSchemaDecodeError | RuntimeError
|
|
612
|
+
Machine.MachineSchemaDecodeError | RuntimeError,
|
|
613
|
+
Machine.Machine.EmittedEvent<M>
|
|
592
614
|
>
|
|
593
615
|
|
|
594
616
|
export const make: {
|
|
@@ -605,7 +627,8 @@ export const make: {
|
|
|
605
627
|
FinalStates extends Machine.Machine.StateIdentifier<States> = never,
|
|
606
628
|
Output = never,
|
|
607
629
|
OutputStates extends Machine.Machine.StateIdentifier<States> = never,
|
|
608
|
-
InputEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = Events
|
|
630
|
+
InputEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = Events,
|
|
631
|
+
ParentEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = readonly []
|
|
609
632
|
>(
|
|
610
633
|
machine:
|
|
611
634
|
& Machine.Machine<
|
|
@@ -621,7 +644,8 @@ export const make: {
|
|
|
621
644
|
Output,
|
|
622
645
|
Emits,
|
|
623
646
|
OutputStates,
|
|
624
|
-
InputEvents
|
|
647
|
+
InputEvents,
|
|
648
|
+
ParentEvents
|
|
625
649
|
>
|
|
626
650
|
& EnsureNoExternalRequirements<
|
|
627
651
|
MachineRequirements<
|
|
@@ -638,7 +662,8 @@ export const make: {
|
|
|
638
662
|
Machine.Machine.EventInputOf<InputEvents>,
|
|
639
663
|
MachineRuntimeError<E, R>,
|
|
640
664
|
Output,
|
|
641
|
-
MachineStartError<InitialE, E, InitialR, R
|
|
665
|
+
MachineStartError<InitialE, E, InitialR, R>,
|
|
666
|
+
Machine.Machine.EmittedEventOf<Emits>
|
|
642
667
|
>
|
|
643
668
|
} = ((machine: Machine.Machine.Any, ...args: ReadonlyArray<unknown>) => {
|
|
644
669
|
const ref = Atom.make((get) => startMachineAtomEffect(get, machine as any, args as []))
|
|
@@ -14,6 +14,7 @@ import { Rpc } from "effect/unstable/rpc"
|
|
|
14
14
|
import type * as Machine from "../../Machine.js"
|
|
15
15
|
import type { Checkpoint, ClusterMachine, LoadResult } from "../../unstable/cluster/ClusterMachine.js"
|
|
16
16
|
import * as internalMachine from "./machine.js"
|
|
17
|
+
import * as Protocol from "./protocol.js"
|
|
17
18
|
import type { EnsureExecutable } from "./readiness.js"
|
|
18
19
|
|
|
19
20
|
type EntityAddress = EntityAddress.EntityAddress
|
|
@@ -248,7 +249,7 @@ export const make = <
|
|
|
248
249
|
OutputStates,
|
|
249
250
|
InputEvents
|
|
250
251
|
>
|
|
251
|
-
const eventSchema = Schema.Union(machine
|
|
252
|
+
const eventSchema = Schema.Union(Protocol.inputEventSchemas(machine) as MachineEvents<M>)
|
|
252
253
|
const rpc = Rpc.make("send", {
|
|
253
254
|
payload: eventSchema,
|
|
254
255
|
success: SendResult
|
|
@@ -47,8 +47,8 @@ export const makeCollector = <Event>(machine: Machine.Any): Collected<Event> =>
|
|
|
47
47
|
emit: (event) => {
|
|
48
48
|
emittedEvents.push(decodeEmitSync(machine, event))
|
|
49
49
|
},
|
|
50
|
-
sendTo: (
|
|
51
|
-
commands.push({ _tag: "SendTo",
|
|
50
|
+
sendTo: (target: unknown, event: unknown) => {
|
|
51
|
+
commands.push({ _tag: "SendTo", target: target as any, event })
|
|
52
52
|
},
|
|
53
53
|
stop: (child: unknown) => {
|
|
54
54
|
commands.push({ _tag: "Stop", child: child as any })
|
|
@@ -10,6 +10,9 @@ import type { RuntimeCommand } from "./command.js"
|
|
|
10
10
|
import { decodeEmit, decodeEvent } from "./protocol.js"
|
|
11
11
|
import type { ProcessScope } from "./runtime.js"
|
|
12
12
|
|
|
13
|
+
const isActorRef = (target: unknown): target is { readonly send: (event: unknown) => Effect.Effect<void, unknown> } =>
|
|
14
|
+
typeof target === "object" && target !== null && "send" in target && typeof target.send === "function"
|
|
15
|
+
|
|
13
16
|
export const makeLiveRuntime = <Events, Emits>(
|
|
14
17
|
machine: Machine.Any,
|
|
15
18
|
scope: ProcessScope<Events>
|
|
@@ -18,9 +21,9 @@ export const makeLiveRuntime = <Events, Emits>(
|
|
|
18
21
|
decodeEvent(machine, event).pipe(
|
|
19
22
|
Effect.flatMap((event) => scope.self.send(event as Events))
|
|
20
23
|
),
|
|
21
|
-
|
|
24
|
+
emit: (event) =>
|
|
22
25
|
decodeEmit(machine, event).pipe(
|
|
23
|
-
Effect.flatMap((event) => scope.
|
|
26
|
+
Effect.flatMap((event) => scope.emit(event))
|
|
24
27
|
)
|
|
25
28
|
})
|
|
26
29
|
|
|
@@ -30,7 +33,9 @@ export const runCommands = <Event>(
|
|
|
30
33
|
) =>
|
|
31
34
|
Effect.forEach(commands, (command) =>
|
|
32
35
|
command._tag === "SendTo"
|
|
33
|
-
?
|
|
36
|
+
? isActorRef(command.target)
|
|
37
|
+
? command.target.send(command.event)
|
|
38
|
+
: scope.sendTo(command.target as never, command.event)
|
|
34
39
|
: scope.stopChild(command.child as never), { discard: true })
|
|
35
40
|
|
|
36
41
|
export const runEmittedEvents = <Events, Emits>(
|
|
@@ -38,6 +43,6 @@ export const runEmittedEvents = <Events, Emits>(
|
|
|
38
43
|
runtime: Runtime<Events, Emits>
|
|
39
44
|
) =>
|
|
40
45
|
Effect.all(
|
|
41
|
-
Array.from(events, (event) => runtime.
|
|
46
|
+
Array.from(events, (event) => runtime.emit(event)),
|
|
42
47
|
{ discard: true }
|
|
43
48
|
)
|
|
@@ -8,7 +8,7 @@ import * as Cause from "effect/Cause"
|
|
|
8
8
|
import * as Effect from "effect/Effect"
|
|
9
9
|
import * as Option from "effect/Option"
|
|
10
10
|
import { hasProperty } from "effect/Predicate"
|
|
11
|
-
import type { Machine } from "../../Machine.js"
|
|
11
|
+
import type { ActorRef, Machine } from "../../Machine.js"
|
|
12
12
|
import { MachineSchemaDecodeError } from "./errors.js"
|
|
13
13
|
import {
|
|
14
14
|
decodeBoundary,
|
|
@@ -252,8 +252,26 @@ export interface ActiveConfiguration {
|
|
|
252
252
|
readonly values: ReadonlyMap<string, unknown>
|
|
253
253
|
readonly outputs: ReadonlyMap<string, unknown>
|
|
254
254
|
readonly history: ReadonlyMap<string, HistoryRecord>
|
|
255
|
+
readonly actorScope?: PlanningActorScope
|
|
255
256
|
}
|
|
256
257
|
|
|
258
|
+
export interface PlanningActorScope {
|
|
259
|
+
readonly self: ActorRef<any>
|
|
260
|
+
readonly parent: ActorRef<any> | undefined
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export const withActorScope = (
|
|
264
|
+
configuration: ActiveConfiguration,
|
|
265
|
+
actorScope: PlanningActorScope
|
|
266
|
+
): ActiveConfiguration => ({
|
|
267
|
+
...configuration,
|
|
268
|
+
actorScope: { self: actorScope.self, parent: actorScope.parent }
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
export const getActorScope = (
|
|
272
|
+
configuration: ActiveConfiguration
|
|
273
|
+
): PlanningActorScope | undefined => configuration.actorScope
|
|
274
|
+
|
|
257
275
|
export interface FinalCompletion {
|
|
258
276
|
readonly path: string
|
|
259
277
|
readonly output: unknown
|
|
@@ -1178,8 +1196,8 @@ export const resolveFinalOutputEffect: <
|
|
|
1178
1196
|
const node = getNode(machine, path)
|
|
1179
1197
|
const output = getStateConfigByPath(machine, path)?.output?.({
|
|
1180
1198
|
state: configuration.values.get(path),
|
|
1181
|
-
|
|
1182
|
-
|
|
1199
|
+
containingState: getParentValue(machine, configuration, path),
|
|
1200
|
+
ancestors: getParentValues(machine, configuration, path),
|
|
1183
1201
|
event,
|
|
1184
1202
|
outputs
|
|
1185
1203
|
} as any)
|
|
@@ -1331,8 +1349,8 @@ const resolveFinalOutputSync = <const Events extends ReadonlyArray<Machine.Tagge
|
|
|
1331
1349
|
const node = getNode(machine, path)
|
|
1332
1350
|
const output = getStateConfigByPath(machine, path)?.output?.({
|
|
1333
1351
|
state: configuration.values.get(path),
|
|
1334
|
-
|
|
1335
|
-
|
|
1352
|
+
containingState: getParentValue(machine, configuration, path),
|
|
1353
|
+
ancestors: getParentValues(machine, configuration, path),
|
|
1336
1354
|
event,
|
|
1337
1355
|
outputs
|
|
1338
1356
|
} as any)
|
|
@@ -25,7 +25,7 @@ export class MachineSchemaEncodeError extends Data.TaggedError("MachineSchemaEnc
|
|
|
25
25
|
*/
|
|
26
26
|
export class MachineSchemaDecodeError extends Data.TaggedError("MachineSchemaDecodeError")<{
|
|
27
27
|
readonly machineId: string | undefined
|
|
28
|
-
readonly boundary: "input" | "event" | "
|
|
28
|
+
readonly boundary: "input" | "event" | "emission" | "state" | "output" | "history" | "configuration"
|
|
29
29
|
readonly state?: string
|
|
30
30
|
readonly event?: string
|
|
31
31
|
readonly cause: Schema.SchemaError | Cause.Cause<unknown>
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* @since 0.4.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import * as Effect from "effect/Effect"
|
|
8
|
+
import type { ActorRef, Machine } from "../../Machine.js"
|
|
8
9
|
import { getTargetBuilder, type RuntimeCommand } from "./command.js"
|
|
9
10
|
import {
|
|
10
11
|
type ActiveConfiguration,
|
|
@@ -17,10 +18,12 @@ import {
|
|
|
17
18
|
isDescendantOf,
|
|
18
19
|
normalizeConfigurationSync,
|
|
19
20
|
normalizeTargetConfigurationSync,
|
|
21
|
+
type PlanningActorScope,
|
|
20
22
|
snapshotFromConfiguration,
|
|
21
|
-
validateInitialConfiguration
|
|
23
|
+
validateInitialConfiguration,
|
|
24
|
+
withActorScope
|
|
22
25
|
} from "./configuration.js"
|
|
23
|
-
import { InfiniteTransitionError } from "./errors.js"
|
|
26
|
+
import { InfiniteTransitionError, StoppedError } from "./errors.js"
|
|
24
27
|
import * as InvocationEvent from "./invocationEvent.js"
|
|
25
28
|
import {
|
|
26
29
|
broadenTransitionBoundary,
|
|
@@ -43,7 +46,7 @@ import {
|
|
|
43
46
|
validateDeclaredTransitionTarget
|
|
44
47
|
} from "./planner.js"
|
|
45
48
|
import { decodeEmitSync, decodeEventSync, decodeInputSync, decodeStateValueSync } from "./protocol.js"
|
|
46
|
-
import { isSnapshot, isTarget, TargetSnapshotTypeId } from "./topology.js"
|
|
49
|
+
import { isNoTarget, isSnapshot, isTarget, TargetSnapshotTypeId } from "./topology.js"
|
|
47
50
|
|
|
48
51
|
interface IndexedExecutionDescriptor {
|
|
49
52
|
readonly flat: boolean
|
|
@@ -64,6 +67,29 @@ interface IndexedExecutionDescriptor {
|
|
|
64
67
|
>
|
|
65
68
|
}
|
|
66
69
|
|
|
70
|
+
const planningActorScopes = new WeakMap<Machine.Any, PlanningActorScope>()
|
|
71
|
+
|
|
72
|
+
const getPlanningActorScope = (machine: Machine.Any): PlanningActorScope => {
|
|
73
|
+
const cached = planningActorScopes.get(machine)
|
|
74
|
+
if (cached !== undefined) return cached
|
|
75
|
+
const self: ActorRef<unknown> = {
|
|
76
|
+
id: machine.id ?? "Machine",
|
|
77
|
+
sessionId: "Machine.plan",
|
|
78
|
+
send: () => Effect.fail(new StoppedError())
|
|
79
|
+
}
|
|
80
|
+
const scope = { self, parent: undefined }
|
|
81
|
+
planningActorScopes.set(machine, scope)
|
|
82
|
+
return scope
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const getActorContext = (
|
|
86
|
+
machine: Machine.Any,
|
|
87
|
+
actorScope: PlanningActorScope | undefined
|
|
88
|
+
): PlanningActorScope =>
|
|
89
|
+
actorScope === undefined
|
|
90
|
+
? getPlanningActorScope(machine)
|
|
91
|
+
: { self: actorScope.self, parent: actorScope.parent }
|
|
92
|
+
|
|
67
93
|
const indexedStateConfigKeys: ReadonlySet<PropertyKey> = new Set([
|
|
68
94
|
"initial",
|
|
69
95
|
"invoke",
|
|
@@ -336,18 +362,20 @@ const makeIndexedTransitionContext = (
|
|
|
336
362
|
descriptor: IndexedExecutionDescriptor,
|
|
337
363
|
configuration: OwnedIndexedState,
|
|
338
364
|
sourceIndex: number,
|
|
339
|
-
event: any
|
|
365
|
+
event: any,
|
|
366
|
+
actorScope?: PlanningActorScope
|
|
340
367
|
): any => {
|
|
341
368
|
const source = descriptor.nodes[sourceIndex]!
|
|
342
369
|
const parentIndex = descriptor.parentIndices[sourceIndex]!
|
|
343
|
-
const
|
|
370
|
+
const ancestors: Record<string, unknown> = {}
|
|
344
371
|
for (const ancestorIndex of descriptor.ancestorIndices[sourceIndex]!) {
|
|
345
|
-
|
|
372
|
+
ancestors[descriptor.nodes[ancestorIndex]!.path] = configuration.values[ancestorIndex]
|
|
346
373
|
}
|
|
347
374
|
return {
|
|
375
|
+
...getActorContext(machine, actorScope),
|
|
348
376
|
state: configuration.values[sourceIndex],
|
|
349
|
-
|
|
350
|
-
|
|
377
|
+
containingState: parentIndex < 0 ? undefined : configuration.values[parentIndex],
|
|
378
|
+
ancestors,
|
|
351
379
|
event,
|
|
352
380
|
snapshot: snapshotFromIndexedState(descriptor, configuration),
|
|
353
381
|
target: getTargetBuilder(machine, source.path)
|
|
@@ -399,7 +427,7 @@ const collectIndexedTransition = (
|
|
|
399
427
|
let commands: Array<RuntimeCommand> | undefined
|
|
400
428
|
let raisedEvents: Array<any> | undefined
|
|
401
429
|
let emittedEvents: Array<unknown> | undefined
|
|
402
|
-
const
|
|
430
|
+
const result = transition(context, {
|
|
403
431
|
raise: (event: unknown) => {
|
|
404
432
|
;(raisedEvents ??= []).push(decodeEventSync(machine, event))
|
|
405
433
|
},
|
|
@@ -407,14 +435,14 @@ const collectIndexedTransition = (
|
|
|
407
435
|
;(emittedEvents ??= []).push(decodeEmitSync(machine, event))
|
|
408
436
|
},
|
|
409
437
|
sendTo: (child: unknown, event: unknown) => {
|
|
410
|
-
;(commands ??= []).push({ _tag: "SendTo",
|
|
438
|
+
;(commands ??= []).push({ _tag: "SendTo", target: child as any, event })
|
|
411
439
|
},
|
|
412
440
|
stop: (child: unknown) => {
|
|
413
441
|
;(commands ??= []).push({ _tag: "Stop", child: child as any })
|
|
414
442
|
}
|
|
415
443
|
})
|
|
416
444
|
return {
|
|
417
|
-
state,
|
|
445
|
+
state: isNoTarget(result) ? undefined : result,
|
|
418
446
|
commands: commands ?? emptyExecutionValues,
|
|
419
447
|
raisedEvents: raisedEvents ?? emptyExecutionValues,
|
|
420
448
|
emittedEvents: emittedEvents ?? emptyExecutionValues
|
|
@@ -425,7 +453,8 @@ const selectIndexedEventTransitions = (
|
|
|
425
453
|
machine: Machine.Any,
|
|
426
454
|
descriptor: IndexedExecutionDescriptor,
|
|
427
455
|
configuration: OwnedIndexedState,
|
|
428
|
-
event: any
|
|
456
|
+
event: any,
|
|
457
|
+
actorScope?: PlanningActorScope
|
|
429
458
|
): ReadonlyArray<IndexedSelectedTransition> => {
|
|
430
459
|
const selected: Array<IndexedSelectedTransition> = []
|
|
431
460
|
for (const leafIndex of configuration.activeLeaves) {
|
|
@@ -446,7 +475,8 @@ const selectIndexedEventTransitions = (
|
|
|
446
475
|
descriptor,
|
|
447
476
|
configuration,
|
|
448
477
|
sourceIndex,
|
|
449
|
-
event
|
|
478
|
+
event,
|
|
479
|
+
actorScope
|
|
450
480
|
)
|
|
451
481
|
})
|
|
452
482
|
}
|
|
@@ -629,7 +659,8 @@ const planIndexedFlatState = (
|
|
|
629
659
|
descriptor: IndexedExecutionDescriptor,
|
|
630
660
|
configuration: OwnedIndexedState,
|
|
631
661
|
decoded: { readonly _tag: PropertyKey },
|
|
632
|
-
retainMicrosteps: boolean
|
|
662
|
+
retainMicrosteps: boolean,
|
|
663
|
+
actorScope?: PlanningActorScope
|
|
633
664
|
): ExecutionMacrostep<OwnedIndexedState> => {
|
|
634
665
|
let current = configuration
|
|
635
666
|
let event: any = decoded
|
|
@@ -681,9 +712,10 @@ const planIndexedFlatState = (
|
|
|
681
712
|
machine,
|
|
682
713
|
transition.transition,
|
|
683
714
|
{
|
|
715
|
+
...getActorContext(machine, actorScope),
|
|
684
716
|
state: current.values[sourceIndex],
|
|
685
|
-
|
|
686
|
-
|
|
717
|
+
containingState: undefined,
|
|
718
|
+
ancestors: {},
|
|
687
719
|
event,
|
|
688
720
|
snapshot: snapshotFromIndexedState(descriptor, current),
|
|
689
721
|
target: getTargetBuilder(machine, sourcePath)
|
|
@@ -774,7 +806,8 @@ const planIndexedState = (
|
|
|
774
806
|
descriptor: IndexedExecutionDescriptor,
|
|
775
807
|
configuration: OwnedIndexedState,
|
|
776
808
|
input: unknown,
|
|
777
|
-
retainMicrosteps: boolean
|
|
809
|
+
retainMicrosteps: boolean,
|
|
810
|
+
actorScope?: PlanningActorScope
|
|
778
811
|
): ExecutionMacrostep<OwnedIndexedState> => {
|
|
779
812
|
if (InvocationEvent.isInvocationEvent(input)) {
|
|
780
813
|
// Invocation lifecycle transitions retain the generic planner as their
|
|
@@ -783,7 +816,9 @@ const planIndexedState = (
|
|
|
783
816
|
// the representation boundary.
|
|
784
817
|
const planned = planConfiguration(
|
|
785
818
|
machine as any,
|
|
786
|
-
|
|
819
|
+
actorScope === undefined
|
|
820
|
+
? activeConfigurationFromIndexedState(descriptor, configuration)
|
|
821
|
+
: withActorScope(activeConfigurationFromIndexedState(descriptor, configuration), actorScope),
|
|
787
822
|
input
|
|
788
823
|
)
|
|
789
824
|
return {
|
|
@@ -806,7 +841,7 @@ const planIndexedState = (
|
|
|
806
841
|
}
|
|
807
842
|
const decoded = decodeEventSync(machine, input)
|
|
808
843
|
if (descriptor.flat) {
|
|
809
|
-
return planIndexedFlatState(machine, descriptor, configuration, decoded, retainMicrosteps)
|
|
844
|
+
return planIndexedFlatState(machine, descriptor, configuration, decoded, retainMicrosteps, actorScope)
|
|
810
845
|
}
|
|
811
846
|
if (descriptor.finalIndices.some((index) => configuration.active[index] === 1)) {
|
|
812
847
|
const active = activeConfigurationFromIndexedState(descriptor, configuration)
|
|
@@ -827,7 +862,7 @@ const planIndexedState = (
|
|
|
827
862
|
}
|
|
828
863
|
}
|
|
829
864
|
|
|
830
|
-
const selections = selectIndexedEventTransitions(machine, descriptor, configuration, decoded)
|
|
865
|
+
const selections = selectIndexedEventTransitions(machine, descriptor, configuration, decoded, actorScope)
|
|
831
866
|
if (selections.length === 0) {
|
|
832
867
|
return {
|
|
833
868
|
next: configuration,
|
|
@@ -895,7 +930,7 @@ const planIndexedState = (
|
|
|
895
930
|
}
|
|
896
931
|
raisedIndex += 1
|
|
897
932
|
currentEvent = raised
|
|
898
|
-
const raisedSelections = selectIndexedEventTransitions(machine, descriptor, current, raised)
|
|
933
|
+
const raisedSelections = selectIndexedEventTransitions(machine, descriptor, current, raised, actorScope)
|
|
899
934
|
if (raisedSelections.length === 0) continue
|
|
900
935
|
const step = indexedMicrostep(machine, descriptor, current, raised, raisedSelections)
|
|
901
936
|
current = step.next
|
|
@@ -913,10 +948,12 @@ export interface CompiledExecutionPlan {
|
|
|
913
948
|
readonly plan: (
|
|
914
949
|
state: unknown,
|
|
915
950
|
event: unknown,
|
|
916
|
-
retainMicrosteps?: boolean
|
|
951
|
+
retainMicrosteps?: boolean,
|
|
952
|
+
actorScope?: PlanningActorScope
|
|
917
953
|
) => ExecutionMacrostep
|
|
918
954
|
readonly initial?: (
|
|
919
|
-
args: ReadonlyArray<unknown
|
|
955
|
+
args: ReadonlyArray<unknown>,
|
|
956
|
+
actorScope?: PlanningActorScope
|
|
920
957
|
) => {
|
|
921
958
|
readonly state: Machine.Snapshot<any>
|
|
922
959
|
readonly configuration: unknown
|
|
@@ -933,7 +970,14 @@ const makeActiveExecutionPlan = (machine: Machine.Any): CompiledExecutionPlan =>
|
|
|
933
970
|
fromConfiguration: (configuration) => configuration,
|
|
934
971
|
toConfiguration: (state) => state as ActiveConfiguration,
|
|
935
972
|
snapshot: (state) => snapshotFromConfiguration(machine, state as ActiveConfiguration),
|
|
936
|
-
plan: (state, event
|
|
973
|
+
plan: (state, event, _retainMicrosteps, actorScope) =>
|
|
974
|
+
planConfiguration(
|
|
975
|
+
machine as any,
|
|
976
|
+
actorScope === undefined
|
|
977
|
+
? state as ActiveConfiguration
|
|
978
|
+
: withActorScope(state as ActiveConfiguration, actorScope),
|
|
979
|
+
event as any
|
|
980
|
+
)
|
|
937
981
|
})
|
|
938
982
|
|
|
939
983
|
const makeIndexedExecutionPlan = (
|
|
@@ -943,16 +987,17 @@ const makeIndexedExecutionPlan = (
|
|
|
943
987
|
fromConfiguration: (configuration) => ownedIndexedStateFromActive(indexed, configuration),
|
|
944
988
|
toConfiguration: (state) => activeConfigurationFromIndexedState(indexed, state as OwnedIndexedState),
|
|
945
989
|
snapshot: (state) => snapshotFromIndexedState(indexed, state as OwnedIndexedState),
|
|
946
|
-
plan: (state, event, retainMicrosteps = false) =>
|
|
947
|
-
planIndexedState(machine, indexed, state as OwnedIndexedState, event, retainMicrosteps),
|
|
948
|
-
initial: (args) => {
|
|
990
|
+
plan: (state, event, retainMicrosteps = false, actorScope) =>
|
|
991
|
+
planIndexedState(machine, indexed, state as OwnedIndexedState, event, retainMicrosteps, actorScope),
|
|
992
|
+
initial: (args, actorScope) => {
|
|
949
993
|
const inputArgs = machine.input === undefined
|
|
950
994
|
? args
|
|
951
995
|
: args.length === 0
|
|
952
996
|
? (decodeInputSync(machine, machine.input, undefined), args)
|
|
953
997
|
: [decodeInputSync(machine, machine.input, args[0])]
|
|
954
998
|
const initial = machine.initial(...inputArgs as any)
|
|
955
|
-
const
|
|
999
|
+
const normalized = normalizeConfigurationSync(machine, initial as Machine.Snapshot<any>)
|
|
1000
|
+
const active = actorScope === undefined ? normalized : withActorScope(normalized, actorScope)
|
|
956
1001
|
validateInitialConfiguration(machine, active)
|
|
957
1002
|
const completed = completeConfigurationSync(machine, active, InitialEvent).configuration
|
|
958
1003
|
const configuration = ownedIndexedStateFromActive(indexed, completed)
|
|
@@ -235,9 +235,10 @@ export const startAll = (
|
|
|
235
235
|
.filter((path) => configuration.active.has(path))
|
|
236
236
|
.flatMap((path) => {
|
|
237
237
|
const context = {
|
|
238
|
+
...(Configuration.getActorScope(configuration) ?? { self: scope.self, parent: scope.parent }),
|
|
238
239
|
state: configuration.values.get(path),
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
containingState: Configuration.getParentValue(machine, configuration, path),
|
|
241
|
+
ancestors: Configuration.getParentValues(machine, configuration, path),
|
|
241
242
|
event
|
|
242
243
|
}
|
|
243
244
|
return InvocationEvent.definitions(Configuration.getStateConfigByPath(machine, path)?.invoke).map((definition) =>
|