@typeonce/effect-machine 0.15.0 → 0.17.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 +115 -95
- package/dist/Machine.d.ts +464 -337
- package/dist/Machine.d.ts.map +1 -1
- package/dist/Machine.js +72 -107
- package/dist/Machine.js.map +1 -1
- package/dist/internal/machine/activities.d.ts +2 -0
- package/dist/internal/machine/activities.d.ts.map +1 -1
- package/dist/internal/machine/activities.js +4 -0
- package/dist/internal/machine/activities.js.map +1 -1
- package/dist/internal/machine/atom.d.ts +7 -7
- package/dist/internal/machine/atom.d.ts.map +1 -1
- package/dist/internal/machine/atom.js.map +1 -1
- package/dist/internal/machine/cluster.d.ts +2 -2
- package/dist/internal/machine/cluster.d.ts.map +1 -1
- package/dist/internal/machine/cluster.js +6 -5
- package/dist/internal/machine/cluster.js.map +1 -1
- package/dist/internal/machine/executionPlan.d.ts.map +1 -1
- package/dist/internal/machine/executionPlan.js +16 -4
- package/dist/internal/machine/executionPlan.js.map +1 -1
- package/dist/internal/machine/invocation.d.ts +1 -1
- package/dist/internal/machine/invocation.d.ts.map +1 -1
- package/dist/internal/machine/invocation.js +25 -3
- package/dist/internal/machine/invocation.js.map +1 -1
- package/dist/internal/machine/invocationEvent.d.ts +8 -0
- package/dist/internal/machine/invocationEvent.d.ts.map +1 -1
- package/dist/internal/machine/invocationEvent.js +8 -0
- package/dist/internal/machine/invocationEvent.js.map +1 -1
- package/dist/internal/machine/machine.d.ts +8 -6
- package/dist/internal/machine/machine.d.ts.map +1 -1
- package/dist/internal/machine/machine.js +308 -71
- package/dist/internal/machine/machine.js.map +1 -1
- package/dist/internal/machine/planner.d.ts +26 -4
- package/dist/internal/machine/planner.d.ts.map +1 -1
- package/dist/internal/machine/planner.js +76 -31
- package/dist/internal/machine/planner.js.map +1 -1
- package/dist/internal/machine/runtime.d.ts +1 -0
- package/dist/internal/machine/runtime.d.ts.map +1 -1
- package/dist/internal/machine/runtime.js +25 -16
- package/dist/internal/machine/runtime.js.map +1 -1
- package/dist/internal/machine/stateDefinition.d.ts.map +1 -1
- package/dist/internal/machine/stateDefinition.js +14 -0
- package/dist/internal/machine/stateDefinition.js.map +1 -1
- package/dist/internal/machine/topology.d.ts +20 -0
- package/dist/internal/machine/topology.d.ts.map +1 -1
- package/dist/internal/machine/topology.js +33 -6
- package/dist/internal/machine/topology.js.map +1 -1
- package/dist/internal/testing/machine/finiteModel.d.ts.map +1 -1
- package/dist/internal/testing/machine/finiteModel.js +15 -20
- package/dist/internal/testing/machine/finiteModel.js.map +1 -1
- package/dist/internal/testing/machine/transitionCoverage.d.ts.map +1 -1
- package/dist/internal/testing/machine/transitionCoverage.js +8 -2
- package/dist/internal/testing/machine/transitionCoverage.js.map +1 -1
- package/dist/internal/testing/machine/verification.d.ts.map +1 -1
- package/dist/internal/testing/machine/verification.js +6 -0
- package/dist/internal/testing/machine/verification.js.map +1 -1
- package/dist/testing/MachineTest.d.ts +13 -12
- package/dist/testing/MachineTest.d.ts.map +1 -1
- package/dist/testing/MachineTest.js +5 -8
- package/dist/testing/MachineTest.js.map +1 -1
- package/dist/unstable/cluster/ClusterMachine.d.ts +2 -2
- package/dist/unstable/cluster/ClusterMachine.d.ts.map +1 -1
- package/dist/unstable/cluster/ClusterMachine.js.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.d.ts +12 -12
- package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
- package/docs/agent-guide.md +182 -159
- package/package.json +1 -1
- package/src/Machine.ts +1073 -700
- package/src/internal/machine/activities.ts +7 -0
- package/src/internal/machine/atom.ts +20 -15
- package/src/internal/machine/cluster.ts +14 -9
- package/src/internal/machine/executionPlan.ts +14 -4
- package/src/internal/machine/invocation.ts +39 -4
- package/src/internal/machine/invocationEvent.ts +16 -0
- package/src/internal/machine/machine.ts +460 -86
- package/src/internal/machine/planner.ts +106 -30
- package/src/internal/machine/runtime.ts +61 -25
- package/src/internal/machine/stateDefinition.ts +39 -0
- package/src/internal/machine/topology.ts +59 -2
- package/src/internal/testing/machine/finiteModel.ts +18 -21
- package/src/internal/testing/machine/transitionCoverage.ts +8 -2
- package/src/internal/testing/machine/verification.ts +11 -0
- package/src/testing/MachineTest.ts +16 -11
- package/src/unstable/cluster/ClusterMachine.ts +8 -4
- package/src/unstable/reactivity/AtomMachine.ts +19 -12
|
@@ -22,6 +22,9 @@ export type StaticActivityMetadata =
|
|
|
22
22
|
readonly type: "timer"
|
|
23
23
|
readonly duration: string | "dynamic"
|
|
24
24
|
}
|
|
25
|
+
| {
|
|
26
|
+
readonly type: "stream"
|
|
27
|
+
}
|
|
25
28
|
| {
|
|
26
29
|
readonly type: "machine"
|
|
27
30
|
readonly child: {
|
|
@@ -94,6 +97,10 @@ const appendStaticDefinition = (
|
|
|
94
97
|
})
|
|
95
98
|
return
|
|
96
99
|
}
|
|
100
|
+
if (Reflect.has(descriptor, "stream")) {
|
|
101
|
+
definitions.push({ source, id, type: "stream" })
|
|
102
|
+
return
|
|
103
|
+
}
|
|
97
104
|
if (Reflect.has(descriptor, "logic")) {
|
|
98
105
|
definitions.push({ source, id, type: "process" })
|
|
99
106
|
}
|
|
@@ -106,9 +106,9 @@ const resumeMachineAtomEffect = (
|
|
|
106
106
|
snapshot: Machine.Machine.Snapshot<any>
|
|
107
107
|
) => runMachineAtomEffect(get, internalMachine.resume(machine as any, snapshot as any))
|
|
108
108
|
|
|
109
|
-
type RefState<Ref> = Ref extends Machine.MachineRef<infer State, any, any, any> ? State : never
|
|
110
|
-
type RefError<Ref> = Ref extends Machine.MachineRef<any, any, infer Error, any> ? Error : never
|
|
111
|
-
type RefOutput<Ref> = Ref extends Machine.MachineRef<any, any, any, infer Output> ? Output : never
|
|
109
|
+
type RefState<Ref> = Ref extends Machine.MachineRef<infer State, any, any, any, any> ? State : never
|
|
110
|
+
type RefError<Ref> = Ref extends Machine.MachineRef<any, any, infer Error, any, any> ? Error : never
|
|
111
|
+
type RefOutput<Ref> = Ref extends Machine.MachineRef<any, any, any, infer Output, any> ? Output : never
|
|
112
112
|
type RefEmitted<Ref> = Ref extends Machine.MachineRef<any, any, any, any, infer Emitted> ? Emitted : never
|
|
113
113
|
|
|
114
114
|
export const emissions = <State, Event, Error, Output, StartError, Emitted>(
|
|
@@ -235,7 +235,7 @@ const makeChildRuntimeResultAtom = <State, Error, Output, StartError>(
|
|
|
235
235
|
|
|
236
236
|
const makeChildRefAtom = <Child extends Machine.ChildMachine.Any, StartError>(
|
|
237
237
|
parentRef: Atom.Atom<
|
|
238
|
-
AsyncResult.AsyncResult<Option.Option<Machine.MachineRef<any, any, any, any>>, StartError>
|
|
238
|
+
AsyncResult.AsyncResult<Option.Option<Machine.MachineRef<any, any, any, any, any>>, StartError>
|
|
239
239
|
>,
|
|
240
240
|
child: Child
|
|
241
241
|
): Atom.Atom<AsyncResult.AsyncResult<Option.Option<Machine.ChildMachine.Ref<Child>>, StartError>> =>
|
|
@@ -292,7 +292,7 @@ const makeChildFromRefAtom = <Child extends Machine.ChildMachine.Any, StartError
|
|
|
292
292
|
return AsyncResult.success(Option.none())
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
const handle = result.value.value as unknown as Machine.MachineRef<State, any, Error, Output>
|
|
295
|
+
const handle = result.value.value as unknown as Machine.MachineRef<State, any, Error, Output, any>
|
|
296
296
|
const cancel = Effect.runCallback(
|
|
297
297
|
handle.changes.pipe(
|
|
298
298
|
Stream.runForEach((snapshot) => Effect.sync(() => get.setSelf(AsyncResult.success(Option.some(snapshot)))))
|
|
@@ -363,9 +363,9 @@ const makeChildFromRefAtom = <Child extends Machine.ChildMachine.Any, StartError
|
|
|
363
363
|
}
|
|
364
364
|
}
|
|
365
365
|
|
|
366
|
-
const makeFromRefAtom = <State, Event, Error, Output, StartError>(
|
|
367
|
-
ref: Atom.Atom<AsyncResult.AsyncResult<Machine.MachineRef<State, Event, Error, Output>, StartError>>
|
|
368
|
-
): MachineAtom<State, Event, Error, Output, StartError> => {
|
|
366
|
+
const makeFromRefAtom = <State, Event, Error, Output, StartError, Emitted>(
|
|
367
|
+
ref: Atom.Atom<AsyncResult.AsyncResult<Machine.MachineRef<State, Event, Error, Output, Emitted>, StartError>>
|
|
368
|
+
): MachineAtom<State, Event, Error, Output, StartError, Emitted> => {
|
|
369
369
|
const snapshot = Atom.readable((
|
|
370
370
|
get
|
|
371
371
|
): AsyncResult.AsyncResult<Machine.RuntimeSnapshot<State, Error, Output>, StartError> => {
|
|
@@ -513,9 +513,10 @@ export const select = <
|
|
|
513
513
|
Error,
|
|
514
514
|
Output,
|
|
515
515
|
StartError,
|
|
516
|
+
Emitted,
|
|
516
517
|
const Path extends ValuedSnapshotIdentifier<State>
|
|
517
518
|
>(
|
|
518
|
-
self: MachineAtom<State, Event, Error, Output, StartError>,
|
|
519
|
+
self: MachineAtom<State, Event, Error, Output, StartError, Emitted>,
|
|
519
520
|
path: Path
|
|
520
521
|
): Atom.Atom<
|
|
521
522
|
AsyncResult.AsyncResult<Option.Option<SnapshotValueByIdentifier<State, Path>>, StartError | Error>
|
|
@@ -530,9 +531,10 @@ export const selectSnapshot = <
|
|
|
530
531
|
Error,
|
|
531
532
|
Output,
|
|
532
533
|
StartError,
|
|
534
|
+
Emitted,
|
|
533
535
|
const Path extends SnapshotIdentifier<State>
|
|
534
536
|
>(
|
|
535
|
-
self: MachineAtom<State, Event, Error, Output, StartError>,
|
|
537
|
+
self: MachineAtom<State, Event, Error, Output, StartError, Emitted>,
|
|
536
538
|
path: Path
|
|
537
539
|
): Atom.Atom<
|
|
538
540
|
AsyncResult.AsyncResult<Option.Option<SnapshotByIdentifier<State, Path>>, StartError | Error>
|
|
@@ -583,9 +585,10 @@ export const matches = <
|
|
|
583
585
|
Error,
|
|
584
586
|
Output,
|
|
585
587
|
StartError,
|
|
588
|
+
Emitted,
|
|
586
589
|
const Path extends SnapshotIdentifier<State>
|
|
587
590
|
>(
|
|
588
|
-
self: MachineAtom<State, Event, Error, Output, StartError>,
|
|
591
|
+
self: MachineAtom<State, Event, Error, Output, StartError, Emitted>,
|
|
589
592
|
path: Path
|
|
590
593
|
): Atom.Atom<AsyncResult.AsyncResult<boolean, StartError | Error>> =>
|
|
591
594
|
Atom.mapResult(self.result, (snapshot) => Option.isSome(Topology.getSnapshotByPath(snapshot, path))).pipe(
|
|
@@ -673,7 +676,8 @@ export const make: {
|
|
|
673
676
|
Machine.Machine.EmitOf<Emits>
|
|
674
677
|
>
|
|
675
678
|
>
|
|
676
|
-
& EnsureExecutable<States, UnhandledStates, OutputStates
|
|
679
|
+
& EnsureExecutable<States, UnhandledStates, OutputStates>
|
|
680
|
+
& Machine.Machine.RootCompatible<ParentEvents>,
|
|
677
681
|
...args: [...Machine.Machine.InputArgs<Input>]
|
|
678
682
|
): MachineAtom<
|
|
679
683
|
Machine.Machine.Snapshot<States>,
|
|
@@ -696,7 +700,8 @@ export const resume: {
|
|
|
696
700
|
machine:
|
|
697
701
|
& M
|
|
698
702
|
& EnsureNoExternalRequirements<MachineResumeRequirementsOf<NoInfer<M>>>
|
|
699
|
-
& EnsureMachineExecutable<NoInfer<M
|
|
703
|
+
& EnsureMachineExecutable<NoInfer<M>>
|
|
704
|
+
& Machine.Machine.RootCompatible<Machine.Machine.ParentEvents<NoInfer<M>>>,
|
|
700
705
|
snapshot: Machine.Machine.Snapshot<Machine.Machine.States<M>>
|
|
701
706
|
): ResumedMachineAtomOf<M, never>
|
|
702
707
|
} = ((machine: Machine.Machine.Any, snapshot: Machine.Machine.Snapshot<any>) => {
|
|
@@ -708,7 +713,7 @@ const makeWithRuntime = (
|
|
|
708
713
|
runtime: Atom.AtomRuntime<any, any>,
|
|
709
714
|
machine: Machine.Machine.Any,
|
|
710
715
|
args: ReadonlyArray<unknown>
|
|
711
|
-
): MachineAtom<any, any, any, any, any> => {
|
|
716
|
+
): MachineAtom<any, any, any, any, any, any> => {
|
|
712
717
|
const prepared = runtime.atom(() => internalMachine.prepare(machine as any, ...(args as [])))
|
|
713
718
|
const ref = runtime.atom((get) => startPreparedMachineAtomEffect(get, prepared as any))
|
|
714
719
|
const result = makeFromRefAtom(ref as any)
|
|
@@ -720,7 +725,7 @@ const resumeWithRuntime = (
|
|
|
720
725
|
runtime: Atom.AtomRuntime<any, any>,
|
|
721
726
|
machine: Machine.Machine.Any,
|
|
722
727
|
snapshot: Machine.Machine.Snapshot<any>
|
|
723
|
-
): MachineAtom<any, any, any, any, any> => {
|
|
728
|
+
): MachineAtom<any, any, any, any, any, any> => {
|
|
724
729
|
const ref = runtime.atom((get) => resumeMachineAtomEffect(get, machine, snapshot))
|
|
725
730
|
return makeFromRefAtom(ref as any)
|
|
726
731
|
}
|
|
@@ -185,7 +185,8 @@ export const make = <
|
|
|
185
185
|
Output,
|
|
186
186
|
Emits extends ReadonlyArray<Machine.Machine.TaggedSchema>,
|
|
187
187
|
OutputStates extends Machine.Machine.StateIdentifier<States>,
|
|
188
|
-
InputEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = Events
|
|
188
|
+
InputEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = Events,
|
|
189
|
+
ParentEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = readonly []
|
|
189
190
|
>(
|
|
190
191
|
type: Type,
|
|
191
192
|
machine:
|
|
@@ -202,9 +203,11 @@ export const make = <
|
|
|
202
203
|
Output,
|
|
203
204
|
Emits,
|
|
204
205
|
OutputStates,
|
|
205
|
-
InputEvents
|
|
206
|
+
InputEvents,
|
|
207
|
+
ParentEvents
|
|
206
208
|
>
|
|
207
|
-
& EnsureExecutable<States, UnhandledStates, OutputStates
|
|
209
|
+
& EnsureExecutable<States, UnhandledStates, OutputStates>
|
|
210
|
+
& Machine.Machine.RootCompatible<ParentEvents>,
|
|
208
211
|
options: {
|
|
209
212
|
readonly version: string
|
|
210
213
|
},
|
|
@@ -224,7 +227,8 @@ export const make = <
|
|
|
224
227
|
Output,
|
|
225
228
|
Emits,
|
|
226
229
|
OutputStates,
|
|
227
|
-
InputEvents
|
|
230
|
+
InputEvents,
|
|
231
|
+
ParentEvents
|
|
228
232
|
>,
|
|
229
233
|
| ExcludeCompatibleRuntime<
|
|
230
234
|
Machine.ExecutionServices<R | InitialR>,
|
|
@@ -249,6 +253,7 @@ export const make = <
|
|
|
249
253
|
OutputStates,
|
|
250
254
|
InputEvents
|
|
251
255
|
>
|
|
256
|
+
const rootMachine = machine as M & EnsureExecutable<States, UnhandledStates, OutputStates>
|
|
252
257
|
const eventSchema = Schema.Union(Protocol.inputEventSchemas(machine) as MachineEvents<M>)
|
|
253
258
|
const rpc = Rpc.make("send", {
|
|
254
259
|
payload: eventSchema,
|
|
@@ -305,7 +310,7 @@ export const make = <
|
|
|
305
310
|
`Expected version ${options.version}, received ${checkpoint.version}`
|
|
306
311
|
)
|
|
307
312
|
}
|
|
308
|
-
current = yield* internalMachine.decodeSnapshot(
|
|
313
|
+
current = yield* internalMachine.decodeSnapshot(rootMachine, checkpoint.snapshot).pipe(
|
|
309
314
|
Effect.mapError((error) => reject("InvalidCheckpoint", String(error.cause)))
|
|
310
315
|
)
|
|
311
316
|
} else if (loaded.processed) {
|
|
@@ -313,7 +318,7 @@ export const make = <
|
|
|
313
318
|
}
|
|
314
319
|
|
|
315
320
|
if (current === undefined) {
|
|
316
|
-
const initial = yield* internalMachine.planInitial(
|
|
321
|
+
const initial = yield* internalMachine.planInitial(rootMachine, ...input)
|
|
317
322
|
if (initial.commands.length > 0) {
|
|
318
323
|
return yield* fail(
|
|
319
324
|
"UnsupportedProcessLocal",
|
|
@@ -324,8 +329,8 @@ export const make = <
|
|
|
324
329
|
emitted.push(...initial.emittedEvents as any)
|
|
325
330
|
}
|
|
326
331
|
|
|
327
|
-
if (!internalMachine.isFinal(
|
|
328
|
-
const planned = yield* internalMachine.plan(
|
|
332
|
+
if (!internalMachine.isFinal(rootMachine, current)) {
|
|
333
|
+
const planned = yield* internalMachine.plan(rootMachine, current, request.payload)
|
|
329
334
|
if (planned.commands.length > 0) {
|
|
330
335
|
return yield* fail(
|
|
331
336
|
"UnsupportedProcessLocal",
|
|
@@ -336,7 +341,7 @@ export const make = <
|
|
|
336
341
|
emitted.push(...planned.emittedEvents as any)
|
|
337
342
|
}
|
|
338
343
|
|
|
339
|
-
const encoded = yield* internalMachine.encodeSnapshot(
|
|
344
|
+
const encoded = yield* internalMachine.encodeSnapshot(rootMachine, current)
|
|
340
345
|
if (emitted.length > 0 && layerOptions?.enqueue === undefined) {
|
|
341
346
|
return yield* fail("EmissionFailure", "No durable enqueue handler was configured")
|
|
342
347
|
}
|
|
@@ -86,10 +86,14 @@ const getPlanningMachineReferences = (machine: Machine.Any): PlanningMachineRefe
|
|
|
86
86
|
const resolveMachineReferences = (
|
|
87
87
|
machine: Machine.Any,
|
|
88
88
|
machineReferences: PlanningMachineReferences | undefined
|
|
89
|
-
):
|
|
90
|
-
machineReferences === undefined
|
|
89
|
+
): { readonly self: MachineTarget<any>; readonly parent?: MachineTarget<any> | undefined } => {
|
|
90
|
+
const resolved = machineReferences === undefined
|
|
91
91
|
? getPlanningMachineReferences(machine)
|
|
92
|
-
:
|
|
92
|
+
: machineReferences
|
|
93
|
+
return machine.parent === undefined
|
|
94
|
+
? { self: resolved.self }
|
|
95
|
+
: { self: resolved.self, parent: resolved.parent }
|
|
96
|
+
}
|
|
93
97
|
|
|
94
98
|
const indexedStateConfigKeys: ReadonlySet<PropertyKey> = new Set([
|
|
95
99
|
"initialize",
|
|
@@ -152,6 +156,7 @@ const compileIndexedExecutionDescriptor = (
|
|
|
152
156
|
for (const tag of Reflect.ownKeys(config.on)) {
|
|
153
157
|
const transition = normalizeTransition(config.on[tag] as Parameters<typeof normalizeTransition>[0])
|
|
154
158
|
if (transition !== undefined) {
|
|
159
|
+
if (transition.declinable) return undefined
|
|
155
160
|
byEvent.set(tag, transition)
|
|
156
161
|
}
|
|
157
162
|
}
|
|
@@ -445,11 +450,12 @@ const collectIndexedTransition = (
|
|
|
445
450
|
}
|
|
446
451
|
}
|
|
447
452
|
const evaluated = evaluate === undefined
|
|
448
|
-
? { result: transition(context, enqueue), branchIndex: 0 }
|
|
453
|
+
? { result: transition(context, enqueue), branchIndex: 0, branchKey: undefined }
|
|
449
454
|
: evaluate(context, enqueue)
|
|
450
455
|
return {
|
|
451
456
|
state: isNoTarget(evaluated.result) ? undefined : evaluated.result,
|
|
452
457
|
branchIndex: evaluated.branchIndex,
|
|
458
|
+
branchKey: evaluated.branchKey,
|
|
453
459
|
commands: commands ?? emptyExecutionValues,
|
|
454
460
|
raisedEvents: raisedEvents ?? emptyExecutionValues,
|
|
455
461
|
emittedEvents: emittedEvents ?? emptyExecutionValues
|
|
@@ -569,6 +575,7 @@ const collectIndexedEvaluatedTransition = (
|
|
|
569
575
|
return {
|
|
570
576
|
selection,
|
|
571
577
|
branchIndex: transitionResult.branchIndex,
|
|
578
|
+
branchKey: transitionResult.branchKey,
|
|
572
579
|
unresolvedTarget: unresolvedTarget as any,
|
|
573
580
|
target: target as any,
|
|
574
581
|
next,
|
|
@@ -593,6 +600,7 @@ const collectIndexedEvaluatedTransition = (
|
|
|
593
600
|
return {
|
|
594
601
|
selection,
|
|
595
602
|
branchIndex: transitionResult.branchIndex,
|
|
603
|
+
branchKey: transitionResult.branchKey,
|
|
596
604
|
unresolvedTarget: unresolvedTarget as any,
|
|
597
605
|
target: target as any,
|
|
598
606
|
next,
|
|
@@ -619,6 +627,7 @@ const indexedMicrostep = (
|
|
|
619
627
|
trigger: transition.selection.trigger,
|
|
620
628
|
reenter: transition.selection.transition.reenter,
|
|
621
629
|
branchIndex: transition.branchIndex,
|
|
630
|
+
branchKey: transition.branchKey,
|
|
622
631
|
target: transition.unresolvedTarget === undefined ? undefined : getTargetNodePath(transition.unresolvedTarget),
|
|
623
632
|
resolvedTarget: transition.target === undefined ? undefined : getTargetNodePath(transition.target)
|
|
624
633
|
})
|
|
@@ -804,6 +813,7 @@ const planIndexedFlatState = (
|
|
|
804
813
|
trigger: { type: "event", event: event._tag },
|
|
805
814
|
reenter: transition.reenter,
|
|
806
815
|
branchIndex: transitionResult.branchIndex,
|
|
816
|
+
branchKey: transitionResult.branchKey,
|
|
807
817
|
target: target === undefined ? undefined : getTargetNodePath(target as any),
|
|
808
818
|
resolvedTarget: target === undefined ? undefined : getTargetNodePath(target as any)
|
|
809
819
|
}]
|
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
import * as Cause from "effect/Cause"
|
|
8
8
|
import * as Effect from "effect/Effect"
|
|
9
|
+
import * as Stream from "effect/Stream"
|
|
9
10
|
import type { ChildMachine, Inspection, Logic, Machine } from "../../Machine.js"
|
|
10
11
|
import * as Configuration from "./configuration.js"
|
|
11
12
|
import { InfiniteTransitionError, MachineSchemaDecodeError, StoppedError } from "./errors.js"
|
|
12
13
|
import * as InvocationEvent from "./invocationEvent.js"
|
|
13
14
|
import * as Planner from "./planner.js"
|
|
14
|
-
import
|
|
15
|
+
import * as Runtime from "./runtime.js"
|
|
15
16
|
import { ChildMachineLogicTypeId } from "./symbols.js"
|
|
16
17
|
|
|
17
18
|
/** @internal */
|
|
@@ -37,12 +38,35 @@ const oneShot = (effect: Effect.Effect<any, any, any>): Logic<void, never, any,
|
|
|
37
38
|
run: () => effect
|
|
38
39
|
})
|
|
39
40
|
|
|
41
|
+
const streamLogic = (
|
|
42
|
+
stream: Stream.Stream<any, any, any>,
|
|
43
|
+
path: string,
|
|
44
|
+
id: string
|
|
45
|
+
): Runtime.ProcessLogic<void, never, any, any, void> => ({
|
|
46
|
+
initial: () => Effect.void,
|
|
47
|
+
run: ({ parent }) => {
|
|
48
|
+
const send = parent?.[Runtime.acknowledgedSend]
|
|
49
|
+
if (send === undefined) {
|
|
50
|
+
return Effect.die(new Error("Stream invocation requires an acknowledged parent machine"))
|
|
51
|
+
}
|
|
52
|
+
return Stream.runForEach(
|
|
53
|
+
stream,
|
|
54
|
+
(element) =>
|
|
55
|
+
send(InvocationEvent.element(path, id, element)).pipe(
|
|
56
|
+
Effect.asVoid,
|
|
57
|
+
Effect.catchCause(() => Effect.interrupt)
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
|
|
40
63
|
const resolveValue = (value: unknown, context: Machine.InvokeContext<any, any, any, any>): unknown =>
|
|
41
64
|
typeof value === "function" ? value(context) : value
|
|
42
65
|
|
|
43
66
|
const resolveOne = (
|
|
44
67
|
raw: Record<PropertyKey, any>,
|
|
45
|
-
context: Machine.InvokeContext<any, any, any, any
|
|
68
|
+
context: Machine.InvokeContext<any, any, any, any>,
|
|
69
|
+
path: string
|
|
46
70
|
): AnyConfig => {
|
|
47
71
|
if ("effect" in raw) {
|
|
48
72
|
return {
|
|
@@ -78,6 +102,17 @@ const resolveOne = (
|
|
|
78
102
|
activityKind: "Timer"
|
|
79
103
|
}
|
|
80
104
|
}
|
|
105
|
+
if ("stream" in raw) {
|
|
106
|
+
const id = String(raw.id)
|
|
107
|
+
return {
|
|
108
|
+
id,
|
|
109
|
+
src: () =>
|
|
110
|
+
streamLogic(raw.stream(context), path, id) as unknown as Runtime.ProcessLogic<any, any, any, any, any, any>,
|
|
111
|
+
onDone: raw.onDone,
|
|
112
|
+
onFailure: raw.onFailure,
|
|
113
|
+
activityKind: "Stream"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
81
116
|
if ("logic" in raw) {
|
|
82
117
|
return {
|
|
83
118
|
id: String(raw.id),
|
|
@@ -103,7 +138,7 @@ const resolveOne = (
|
|
|
103
138
|
onSnapshot: raw.onSnapshot
|
|
104
139
|
}
|
|
105
140
|
}
|
|
106
|
-
throw new Error("Machine invoke must define exactly one of effect, after, logic, or child")
|
|
141
|
+
throw new Error("Machine invoke must define exactly one of effect, stream, after, logic, or child")
|
|
107
142
|
}
|
|
108
143
|
|
|
109
144
|
/** @internal */
|
|
@@ -269,7 +304,7 @@ export const startAll = (
|
|
|
269
304
|
return InvocationEvent.definitions(Configuration.getStateConfigByPath(machine, path)?.invoke).map((definition) =>
|
|
270
305
|
"child" in definition && !("input" in definition)
|
|
271
306
|
? startStaticChild(scope, ownedChildren, path, definition)
|
|
272
|
-
: start(scope, ownedChildren, path, resolveOne(definition, context))
|
|
307
|
+
: start(scope, ownedChildren, path, resolveOne(definition, context, path))
|
|
273
308
|
)
|
|
274
309
|
})
|
|
275
310
|
return effects.length === 0 ? undefined : runSequentialDiscard(effects)
|
|
@@ -10,6 +10,13 @@ export const InvocationEventTypeId: unique symbol = Symbol("effect/Machine/Invoc
|
|
|
10
10
|
|
|
11
11
|
/** @internal */
|
|
12
12
|
export type InvocationEvent =
|
|
13
|
+
| {
|
|
14
|
+
readonly [InvocationEventTypeId]: true
|
|
15
|
+
readonly path: string
|
|
16
|
+
readonly id: string
|
|
17
|
+
readonly type: "element"
|
|
18
|
+
readonly element: unknown
|
|
19
|
+
}
|
|
13
20
|
| {
|
|
14
21
|
readonly [InvocationEventTypeId]: true
|
|
15
22
|
readonly path: string
|
|
@@ -41,6 +48,15 @@ export const done = (path: string, id: string, output: unknown): InvocationEvent
|
|
|
41
48
|
output
|
|
42
49
|
})
|
|
43
50
|
|
|
51
|
+
/** @internal */
|
|
52
|
+
export const element = (path: string, id: string, value: unknown): InvocationEvent => ({
|
|
53
|
+
[InvocationEventTypeId]: true,
|
|
54
|
+
path,
|
|
55
|
+
id,
|
|
56
|
+
type: "element",
|
|
57
|
+
element: value
|
|
58
|
+
})
|
|
59
|
+
|
|
44
60
|
/** @internal */
|
|
45
61
|
export const failure = (path: string, id: string, error: unknown): InvocationEvent => ({
|
|
46
62
|
[InvocationEventTypeId]: true,
|