@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.
Files changed (85) hide show
  1. package/README.md +115 -95
  2. package/dist/Machine.d.ts +464 -337
  3. package/dist/Machine.d.ts.map +1 -1
  4. package/dist/Machine.js +72 -107
  5. package/dist/Machine.js.map +1 -1
  6. package/dist/internal/machine/activities.d.ts +2 -0
  7. package/dist/internal/machine/activities.d.ts.map +1 -1
  8. package/dist/internal/machine/activities.js +4 -0
  9. package/dist/internal/machine/activities.js.map +1 -1
  10. package/dist/internal/machine/atom.d.ts +7 -7
  11. package/dist/internal/machine/atom.d.ts.map +1 -1
  12. package/dist/internal/machine/atom.js.map +1 -1
  13. package/dist/internal/machine/cluster.d.ts +2 -2
  14. package/dist/internal/machine/cluster.d.ts.map +1 -1
  15. package/dist/internal/machine/cluster.js +6 -5
  16. package/dist/internal/machine/cluster.js.map +1 -1
  17. package/dist/internal/machine/executionPlan.d.ts.map +1 -1
  18. package/dist/internal/machine/executionPlan.js +16 -4
  19. package/dist/internal/machine/executionPlan.js.map +1 -1
  20. package/dist/internal/machine/invocation.d.ts +1 -1
  21. package/dist/internal/machine/invocation.d.ts.map +1 -1
  22. package/dist/internal/machine/invocation.js +25 -3
  23. package/dist/internal/machine/invocation.js.map +1 -1
  24. package/dist/internal/machine/invocationEvent.d.ts +8 -0
  25. package/dist/internal/machine/invocationEvent.d.ts.map +1 -1
  26. package/dist/internal/machine/invocationEvent.js +8 -0
  27. package/dist/internal/machine/invocationEvent.js.map +1 -1
  28. package/dist/internal/machine/machine.d.ts +8 -6
  29. package/dist/internal/machine/machine.d.ts.map +1 -1
  30. package/dist/internal/machine/machine.js +308 -71
  31. package/dist/internal/machine/machine.js.map +1 -1
  32. package/dist/internal/machine/planner.d.ts +26 -4
  33. package/dist/internal/machine/planner.d.ts.map +1 -1
  34. package/dist/internal/machine/planner.js +76 -31
  35. package/dist/internal/machine/planner.js.map +1 -1
  36. package/dist/internal/machine/runtime.d.ts +1 -0
  37. package/dist/internal/machine/runtime.d.ts.map +1 -1
  38. package/dist/internal/machine/runtime.js +25 -16
  39. package/dist/internal/machine/runtime.js.map +1 -1
  40. package/dist/internal/machine/stateDefinition.d.ts.map +1 -1
  41. package/dist/internal/machine/stateDefinition.js +14 -0
  42. package/dist/internal/machine/stateDefinition.js.map +1 -1
  43. package/dist/internal/machine/topology.d.ts +20 -0
  44. package/dist/internal/machine/topology.d.ts.map +1 -1
  45. package/dist/internal/machine/topology.js +33 -6
  46. package/dist/internal/machine/topology.js.map +1 -1
  47. package/dist/internal/testing/machine/finiteModel.d.ts.map +1 -1
  48. package/dist/internal/testing/machine/finiteModel.js +15 -20
  49. package/dist/internal/testing/machine/finiteModel.js.map +1 -1
  50. package/dist/internal/testing/machine/transitionCoverage.d.ts.map +1 -1
  51. package/dist/internal/testing/machine/transitionCoverage.js +8 -2
  52. package/dist/internal/testing/machine/transitionCoverage.js.map +1 -1
  53. package/dist/internal/testing/machine/verification.d.ts.map +1 -1
  54. package/dist/internal/testing/machine/verification.js +6 -0
  55. package/dist/internal/testing/machine/verification.js.map +1 -1
  56. package/dist/testing/MachineTest.d.ts +13 -12
  57. package/dist/testing/MachineTest.d.ts.map +1 -1
  58. package/dist/testing/MachineTest.js +5 -8
  59. package/dist/testing/MachineTest.js.map +1 -1
  60. package/dist/unstable/cluster/ClusterMachine.d.ts +2 -2
  61. package/dist/unstable/cluster/ClusterMachine.d.ts.map +1 -1
  62. package/dist/unstable/cluster/ClusterMachine.js.map +1 -1
  63. package/dist/unstable/reactivity/AtomMachine.d.ts +12 -12
  64. package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
  65. package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
  66. package/docs/agent-guide.md +182 -159
  67. package/package.json +1 -1
  68. package/src/Machine.ts +1073 -700
  69. package/src/internal/machine/activities.ts +7 -0
  70. package/src/internal/machine/atom.ts +20 -15
  71. package/src/internal/machine/cluster.ts +14 -9
  72. package/src/internal/machine/executionPlan.ts +14 -4
  73. package/src/internal/machine/invocation.ts +39 -4
  74. package/src/internal/machine/invocationEvent.ts +16 -0
  75. package/src/internal/machine/machine.ts +460 -86
  76. package/src/internal/machine/planner.ts +106 -30
  77. package/src/internal/machine/runtime.ts +61 -25
  78. package/src/internal/machine/stateDefinition.ts +39 -0
  79. package/src/internal/machine/topology.ts +59 -2
  80. package/src/internal/testing/machine/finiteModel.ts +18 -21
  81. package/src/internal/testing/machine/transitionCoverage.ts +8 -2
  82. package/src/internal/testing/machine/verification.ts +11 -0
  83. package/src/testing/MachineTest.ts +16 -11
  84. package/src/unstable/cluster/ClusterMachine.ts +8 -4
  85. 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(machine, checkpoint.snapshot).pipe(
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(machine, ...input as any)
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(machine, current)) {
328
- const planned = yield* internalMachine.plan(machine, current, request.payload)
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(machine, current)
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
- ): PlanningMachineReferences =>
90
- machineReferences === undefined
89
+ ): { readonly self: MachineTarget<any>; readonly parent?: MachineTarget<any> | undefined } => {
90
+ const resolved = machineReferences === undefined
91
91
  ? getPlanningMachineReferences(machine)
92
- : { self: machineReferences.self, parent: machineReferences.parent }
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 type * as Runtime from "./runtime.js"
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,