@typeonce/effect-machine 0.9.0 → 0.11.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 (93) hide show
  1. package/README.md +167 -28
  2. package/dist/Machine.d.ts +491 -283
  3. package/dist/Machine.d.ts.map +1 -1
  4. package/dist/Machine.js +74 -76
  5. package/dist/Machine.js.map +1 -1
  6. package/dist/internal/machine/atom.d.ts +7 -3
  7. package/dist/internal/machine/atom.d.ts.map +1 -1
  8. package/dist/internal/machine/atom.js +42 -6
  9. package/dist/internal/machine/atom.js.map +1 -1
  10. package/dist/internal/machine/cluster.d.ts.map +1 -1
  11. package/dist/internal/machine/cluster.js +2 -1
  12. package/dist/internal/machine/cluster.js.map +1 -1
  13. package/dist/internal/machine/command.js +2 -2
  14. package/dist/internal/machine/command.js.map +1 -1
  15. package/dist/internal/machine/commandRuntime.d.ts.map +1 -1
  16. package/dist/internal/machine/commandRuntime.js +6 -3
  17. package/dist/internal/machine/commandRuntime.js.map +1 -1
  18. package/dist/internal/machine/configuration.d.ts +8 -1
  19. package/dist/internal/machine/configuration.d.ts.map +1 -1
  20. package/dist/internal/machine/configuration.js +9 -4
  21. package/dist/internal/machine/configuration.js.map +1 -1
  22. package/dist/internal/machine/errors.d.ts +1 -1
  23. package/dist/internal/machine/errors.d.ts.map +1 -1
  24. package/dist/internal/machine/executionPlan.d.ts +3 -3
  25. package/dist/internal/machine/executionPlan.d.ts.map +1 -1
  26. package/dist/internal/machine/executionPlan.js +50 -25
  27. package/dist/internal/machine/executionPlan.js.map +1 -1
  28. package/dist/internal/machine/invocation.d.ts.map +1 -1
  29. package/dist/internal/machine/invocation.js +3 -2
  30. package/dist/internal/machine/invocation.js.map +1 -1
  31. package/dist/internal/machine/machine.d.ts +15 -19
  32. package/dist/internal/machine/machine.d.ts.map +1 -1
  33. package/dist/internal/machine/machine.js +16 -10
  34. package/dist/internal/machine/machine.js.map +1 -1
  35. package/dist/internal/machine/planner.d.ts +2 -1
  36. package/dist/internal/machine/planner.d.ts.map +1 -1
  37. package/dist/internal/machine/planner.js +61 -24
  38. package/dist/internal/machine/planner.js.map +1 -1
  39. package/dist/internal/machine/process.d.ts +3 -0
  40. package/dist/internal/machine/process.d.ts.map +1 -1
  41. package/dist/internal/machine/process.js +11 -8
  42. package/dist/internal/machine/process.js.map +1 -1
  43. package/dist/internal/machine/protocol.d.ts +7 -13
  44. package/dist/internal/machine/protocol.d.ts.map +1 -1
  45. package/dist/internal/machine/protocol.js +128 -50
  46. package/dist/internal/machine/protocol.js.map +1 -1
  47. package/dist/internal/machine/runtime.d.ts +22 -2
  48. package/dist/internal/machine/runtime.d.ts.map +1 -1
  49. package/dist/internal/machine/runtime.js +138 -10
  50. package/dist/internal/machine/runtime.js.map +1 -1
  51. package/dist/internal/machine/topology.d.ts +7 -0
  52. package/dist/internal/machine/topology.d.ts.map +1 -1
  53. package/dist/internal/machine/topology.js +6 -0
  54. package/dist/internal/machine/topology.js.map +1 -1
  55. package/dist/internal/testing/machine/finiteModel.js +1 -1
  56. package/dist/internal/testing/machine/finiteModel.js.map +1 -1
  57. package/dist/internal/testing/machine/runtime.d.ts.map +1 -1
  58. package/dist/internal/testing/machine/runtime.js +2 -1
  59. package/dist/internal/testing/machine/runtime.js.map +1 -1
  60. package/dist/internal/testing/machine/verification.d.ts.map +1 -1
  61. package/dist/internal/testing/machine/verification.js +5 -3
  62. package/dist/internal/testing/machine/verification.js.map +1 -1
  63. package/dist/testing/MachineTest.d.ts +7 -7
  64. package/dist/testing/MachineTest.js +7 -7
  65. package/dist/unstable/cluster/ClusterMachine.d.ts +1 -1
  66. package/dist/unstable/cluster/ClusterMachine.js +1 -1
  67. package/dist/unstable/reactivity/AtomMachine.d.ts +27 -8
  68. package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
  69. package/dist/unstable/reactivity/AtomMachine.js +20 -3
  70. package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
  71. package/docs/agent-guide.md +191 -54
  72. package/package.json +1 -1
  73. package/src/Machine.ts +1220 -360
  74. package/src/internal/machine/atom.ts +76 -53
  75. package/src/internal/machine/cluster.ts +2 -1
  76. package/src/internal/machine/command.ts +2 -2
  77. package/src/internal/machine/commandRuntime.ts +9 -4
  78. package/src/internal/machine/configuration.ts +23 -5
  79. package/src/internal/machine/errors.ts +1 -1
  80. package/src/internal/machine/executionPlan.ts +74 -29
  81. package/src/internal/machine/invocation.ts +3 -2
  82. package/src/internal/machine/machine.ts +74 -49
  83. package/src/internal/machine/planner.ts +68 -24
  84. package/src/internal/machine/process.ts +75 -8
  85. package/src/internal/machine/protocol.ts +207 -68
  86. package/src/internal/machine/runtime.ts +266 -11
  87. package/src/internal/machine/topology.ts +15 -0
  88. package/src/internal/testing/machine/finiteModel.ts +1 -1
  89. package/src/internal/testing/machine/runtime.ts +2 -1
  90. package/src/internal/testing/machine/verification.ts +5 -3
  91. package/src/testing/MachineTest.ts +7 -7
  92. package/src/unstable/cluster/ClusterMachine.ts +1 -1
  93. package/src/unstable/reactivity/AtomMachine.ts +44 -10
@@ -86,7 +86,8 @@ interface DefineStates {
86
86
  ): Machine.DefinedStates<States>
87
87
  <const States extends Machine.StateSchemas>(states: InvalidDefinedStateTreeInput<States>): never
88
88
  }
89
- type ValidateInputEventProtocol<InputEvents extends ReadonlyArray<Machine.TaggedSchema>> = InputEvents
89
+ type ValidateInputEventProtocol<InputEvents extends ReadonlyArray<Machine.TaggedSchema>> = InputEvents extends
90
+ ReadonlyArray<Machine.TaggedSchema> ? unknown : never
90
91
  type ValidateInternalEventProtocol<
91
92
  InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
92
93
  InternalEvents extends ReadonlyArray<Machine.TaggedSchema>
@@ -103,6 +104,8 @@ const Proto = {
103
104
  }
104
105
  }
105
106
 
107
+ const makeBoundInvoke = (config: unknown): unknown => config
108
+
106
109
  const cloneWithHandlers = (
107
110
  self: Machine.Any,
108
111
  handlers: Machine.StateConfigs<any, any, any, any, any, any, any>
@@ -111,7 +114,8 @@ const cloneWithHandlers = (
111
114
  machine.states = self.states
112
115
  machine.events = self.events
113
116
  machine.internalEvents = self.internalEvents
114
- machine.emits = self.emits
117
+ machine.emittedEvents = self.emittedEvents
118
+ machine.parentEvents = self.parentEvents
115
119
  machine.input = self.input
116
120
  machine.id = self.id
117
121
  machine.initial = self.initial
@@ -119,6 +123,7 @@ const cloneWithHandlers = (
119
123
  machine.makeTargetBuilder = self.makeTargetBuilder
120
124
  machine.handlers = handlers
121
125
  machine.handle = makeHandle(machine)
126
+ machine.invoke = makeBoundInvoke
122
127
  Protocol.copyProtocol(self, machine)
123
128
  return machine
124
129
  }
@@ -726,6 +731,7 @@ const makeTargetBuilder = <const States extends Machine.StateSchemas>(
726
731
  const history = makeHistoryTargetBuilder(states, "") as Machine.HistoryTargetBuilder<States>
727
732
  return <Source extends Machine.StateNodeIdentifier<States>>(source: Source): Machine.TargetBuilder<States, Source> =>
728
733
  ({
734
+ none: Topology.makeNoTarget,
729
735
  local: makeLocalTargetBuilder(states, stateNodes, source),
730
736
  branch: makeBranchTargetBuilder(states, stateNodes, source),
731
737
  full,
@@ -765,18 +771,22 @@ type MakeConfig<
765
771
  Input extends Schema.Top,
766
772
  InitialE,
767
773
  InitialR,
768
- InternalEvents extends ReadonlyArray<Machine.TaggedSchema>
774
+ InternalEvents extends ReadonlyArray<Machine.TaggedSchema>,
775
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>
769
776
  > = {
770
777
  readonly id?: string
771
778
  readonly states: States & DefineStateTreeInput<NoInfer<States>>
772
- readonly events: InputEvents & ValidateInputEventProtocol<NoInfer<InputEvents>>
779
+ readonly events:
780
+ & Machine.EventProtocol<"public", InputEvents>
781
+ & ValidateInputEventProtocol<NoInfer<InputEvents>>
773
782
  readonly internalEvents?:
774
- & InternalEvents
783
+ & Machine.EventProtocol<"internal", InternalEvents>
775
784
  & ValidateInternalEventProtocol<
776
785
  NoInfer<InputEvents>,
777
786
  NoInfer<InternalEvents>
778
787
  >
779
- readonly emits?: Emits
788
+ readonly emittedEvents?: Machine.EventProtocol<"emitted", Emits>
789
+ readonly parentEvents?: Machine.EventProtocol<"public", ParentEvents>
780
790
  readonly input?: Input
781
791
  readonly initial: (...args: [...Machine.InputArgs<Input>]) => Machine.InitialResult<States, InitialE, InitialR>
782
792
  }
@@ -788,7 +798,8 @@ type MakeResult<
788
798
  Input extends Schema.Top,
789
799
  InitialE,
790
800
  InitialR,
791
- InternalEvents extends ReadonlyArray<Machine.TaggedSchema>
801
+ InternalEvents extends ReadonlyArray<Machine.TaggedSchema>,
802
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>
792
803
  > = Machine<
793
804
  States,
794
805
  readonly [...InputEvents, ...InternalEvents],
@@ -802,7 +813,8 @@ type MakeResult<
802
813
  Machine.TerminalOutput<States>,
803
814
  Emits,
804
815
  never,
805
- InputEvents
816
+ InputEvents,
817
+ ParentEvents
806
818
  >
807
819
 
808
820
  interface Make {
@@ -813,11 +825,12 @@ interface Make {
813
825
  const Input extends Schema.Top = typeof Schema.Void,
814
826
  InitialE = never,
815
827
  InitialR = never,
816
- const InternalEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
828
+ const InternalEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
829
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
817
830
  >(
818
- config: MakeConfig<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents>,
831
+ config: MakeConfig<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents, ParentEvents>,
819
832
  ..._validation: ValidateDefinedStates<NoInfer<States>>
820
- ): MakeResult<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents>
833
+ ): MakeResult<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents, ParentEvents>
821
834
  <
822
835
  const States extends Machine.StateSchemas,
823
836
  const InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
@@ -825,10 +838,11 @@ interface Make {
825
838
  const Input extends Schema.Top = typeof Schema.Void,
826
839
  InitialE = never,
827
840
  InitialR = never,
828
- const InternalEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
841
+ const InternalEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
842
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
829
843
  >(
830
844
  config:
831
- & Omit<MakeConfig<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents>, "states">
845
+ & Omit<MakeConfig<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents, ParentEvents>, "states">
832
846
  & { readonly states: InvalidDefinedStateTreeInput<States> }
833
847
  ): never
834
848
  }
@@ -840,24 +854,27 @@ export const make: Make = (<
840
854
  const Input extends Schema.Top = typeof Schema.Void,
841
855
  InitialE = never,
842
856
  InitialR = never,
843
- const InternalEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
857
+ const InternalEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
858
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
844
859
  >(
845
860
  config: {
846
861
  readonly id?: string
847
862
  readonly states: States
848
- readonly events: InputEvents
849
- readonly internalEvents?: InternalEvents
850
- readonly emits?: Emits
863
+ readonly events: Machine.EventProtocol<"public", InputEvents>
864
+ readonly internalEvents?: Machine.EventProtocol<"internal", InternalEvents>
865
+ readonly emittedEvents?: Machine.EventProtocol<"emitted", Emits>
866
+ readonly parentEvents?: Machine.EventProtocol<"public", ParentEvents>
851
867
  readonly input?: Input
852
868
  readonly initial: (...args: [...Machine.InputArgs<Input>]) => Machine.InitialResult<States, InitialE, InitialR>
853
869
  }
854
- ): MakeResult<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents> => {
870
+ ): MakeResult<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents, ParentEvents> => {
855
871
  StateDefinition.validateStateDefinitions(config.states, "Machine.make")
856
872
  const self = Object.create(Proto)
857
873
  self.states = config.states
858
874
  self.events = config.events
859
- self.internalEvents = config.internalEvents ?? []
860
- self.emits = config.emits ?? []
875
+ self.internalEvents = config.internalEvents ?? Protocol.makeEventProtocol("internal", [] as const)
876
+ self.emittedEvents = config.emittedEvents ?? Protocol.makeEventProtocol("emitted", [] as const)
877
+ self.parentEvents = config.parentEvents ?? Protocol.makeEventProtocol("public", [] as const)
861
878
  self.input = config.input
862
879
  self.id = config.id
863
880
  self.initial = config.initial
@@ -865,32 +882,44 @@ export const make: Make = (<
865
882
  self.makeTargetBuilder = makeTargetBuilder(config.states, self.stateNodes)
866
883
  self.handlers = Object.create(null)
867
884
  self.handle = makeHandle(self)
885
+ self.invoke = makeBoundInvoke
868
886
  Protocol.setProtocol(self)
869
887
  return self
870
888
  }) as Make
871
889
 
872
- type EventConstructorArgs<EventSchema extends Machine.TaggedSchema> = {} extends EventSchema["~type.make.in"] ?
873
- [input?: EventSchema["~type.make.in"]]
874
- : [input: EventSchema["~type.make.in"]]
890
+ const flattenEventProtocolInputs = <Kind extends Machine.EventProtocolKind>(
891
+ kind: Kind,
892
+ inputs: ReadonlyArray<Machine.EventProtocolInput<Kind>>
893
+ ): ReadonlyArray<Machine.TaggedSchema> =>
894
+ inputs.flatMap((input) =>
895
+ Protocol.isEventProtocol(input, kind)
896
+ ? Protocol.eventProtocolSchemas(input)
897
+ : [input as Machine.TaggedSchema]
898
+ )
875
899
 
876
- export const event = <
877
- const M extends Machine.Any,
878
- const EventSchema extends Machine.TaggedSchema
879
- >(
880
- machine: M,
881
- schema: EventSchema & ([EventSchema["Type"]] extends [Machine.Event<M>] ? unknown : never),
882
- ...args: EventConstructorArgs<EventSchema>
883
- ): EventSchema["Type"] => Protocol.makeEvent(machine, schema, args.length === 0 ? {} : args[0])
900
+ export const events = <const Inputs extends ReadonlyArray<Machine.EventProtocolInput<"public">>>(
901
+ ...inputs: Inputs
902
+ ): Machine.EventProtocol<"public", Machine.EventProtocolInputSchemasOf<"public", Inputs>> =>
903
+ Protocol.makeEventProtocol(
904
+ "public",
905
+ flattenEventProtocolInputs("public", inputs)
906
+ ) as Machine.EventProtocol<"public", Machine.EventProtocolInputSchemasOf<"public", Inputs>>
884
907
 
885
- export const events = <M extends Machine.Any>(
886
- machine: M
887
- ): Machine.EventConstructors<Machine.InputEvents<M>> =>
888
- Protocol.eventConstructors(machine.events) as Machine.EventConstructors<Machine.InputEvents<M>>
908
+ export const internalEvents = <const Inputs extends ReadonlyArray<Machine.EventProtocolInput<"internal">>>(
909
+ ...inputs: Inputs
910
+ ): Machine.EventProtocol<"internal", Machine.EventProtocolInputSchemasOf<"internal", Inputs>> =>
911
+ Protocol.makeEventProtocol(
912
+ "internal",
913
+ flattenEventProtocolInputs("internal", inputs)
914
+ ) as Machine.EventProtocol<"internal", Machine.EventProtocolInputSchemasOf<"internal", Inputs>>
889
915
 
890
- export const internalEvents = <M extends Machine.Any>(
891
- machine: M
892
- ): Machine.EventConstructors<Machine.InternalEvents<M>> =>
893
- Protocol.eventConstructors(machine.internalEvents) as Machine.EventConstructors<Machine.InternalEvents<M>>
916
+ export const emittedEvents = <const Inputs extends ReadonlyArray<Machine.EventProtocolInput<"emitted">>>(
917
+ ...inputs: Inputs
918
+ ): Machine.EventProtocol<"emitted", Machine.EventProtocolInputSchemasOf<"emitted", Inputs>> =>
919
+ Protocol.makeEventProtocol(
920
+ "emitted",
921
+ flattenEventProtocolInputs("emitted", inputs)
922
+ ) as Machine.EventProtocol<"emitted", Machine.EventProtocolInputSchemasOf<"emitted", Inputs>>
894
923
 
895
924
  export const encodeSnapshot: <
896
925
  const States extends Machine.StateSchemas,
@@ -966,14 +995,6 @@ export const decodeSnapshot: <
966
995
  Machine.SnapshotDecodingServices<States>
967
996
  > = Serialization.decodeSnapshot as any
968
997
 
969
- export const retag = (
970
- target: Machine.TaggedSchema,
971
- source: { readonly _tag: PropertyKey },
972
- patch?: unknown
973
- ): any => {
974
- const { _tag: _, ...fields } = source
975
- return target.make({ ...fields, ...((patch ?? {}) as object) } as never)
976
- }
977
998
  export const planInitial: <
978
999
  const States extends Machine.StateSchemas,
979
1000
  const Events extends ReadonlyArray<Machine.TaggedSchema>,
@@ -1341,6 +1362,8 @@ export const watch = <State, Event, Error = never, Output = never>(
1341
1362
  ref: MachineRef<State, Event, Error, Output>
1342
1363
  ): Stream.Stream<RuntimeOutcome<State, Error, Output>> => internalRuntime.watch(ref)
1343
1364
 
1365
+ export const prepare = internalProcess.prepare
1366
+
1344
1367
  export const start: <
1345
1368
  const States extends Machine.StateSchemas,
1346
1369
  const Events extends ReadonlyArray<Machine.TaggedSchema>,
@@ -1383,7 +1406,8 @@ export const start: <
1383
1406
  | InfiniteTransitionError
1384
1407
  | MachineSchemaDecodeError
1385
1408
  | StoppedError,
1386
- Output
1409
+ Output,
1410
+ Machine.EmittedEventOf<Emits>
1387
1411
  >,
1388
1412
  | InitialE
1389
1413
  | E
@@ -1441,7 +1465,8 @@ export const resume: <
1441
1465
  | InfiniteTransitionError
1442
1466
  | MachineSchemaDecodeError
1443
1467
  | StoppedError,
1444
- Output
1468
+ Output,
1469
+ Machine.EmittedEventOf<Emits>
1445
1470
  >,
1446
1471
  MachineSchemaDecodeError,
1447
1472
  ExcludeCompatibleRuntime<
@@ -7,7 +7,7 @@
7
7
  import * as Cause from "effect/Cause"
8
8
  import * as Effect from "effect/Effect"
9
9
  import type * as Schema from "effect/Schema"
10
- import type { Enqueue, InitialEvent as MachineInitialEvent, Machine } from "../../Machine.js"
10
+ import type { ActorContext, ActorRef, Enqueue, InitialEvent as MachineInitialEvent, Machine } from "../../Machine.js"
11
11
  import { getTargetBuilder, makeCollector, type RuntimeCommand } from "./command.js"
12
12
  import {
13
13
  type ActiveConfiguration,
@@ -37,7 +37,7 @@ import {
37
37
  snapshotFromConfigurationAtPath,
38
38
  validateInitialConfiguration
39
39
  } from "./configuration.js"
40
- import { InfiniteTransitionError, MachineSchemaDecodeError, StartupError } from "./errors.js"
40
+ import { InfiniteTransitionError, MachineSchemaDecodeError, StartupError, StoppedError } from "./errors.js"
41
41
  import * as InvocationEvent from "./invocationEvent.js"
42
42
  import { decodeEventSync, decodeInputSync, decodeStateValueSync } from "./protocol.js"
43
43
  import { InitialEventTypeId } from "./symbols.js"
@@ -45,6 +45,7 @@ import {
45
45
  getNode,
46
46
  isChoiceTarget,
47
47
  isHistoryTarget,
48
+ isNoTarget,
48
49
  isSnapshot,
49
50
  isTarget,
50
51
  makeChoiceTarget,
@@ -93,6 +94,38 @@ export type TransitionHandler<States extends Machine.StateSchemas, E, R, Context
93
94
  enqueue: Enqueue<any, any>
94
95
  ) => Machine.HandlerResult<States, E, R>
95
96
 
97
+ const rootActorScopes = new WeakMap<Machine.Any, ActorContext<any, any>>()
98
+ const machineActorScopes = new WeakMap<Machine.Any, ActorContext<any, any>>()
99
+
100
+ export const withActorScope = (
101
+ machine: Machine.Any,
102
+ actorScope: ActorContext<any, any>
103
+ ): Machine.Any => {
104
+ const scoped = Object.create(machine) as Machine.Any
105
+ machineActorScopes.set(scoped, { self: actorScope.self, parent: actorScope.parent })
106
+ return scoped
107
+ }
108
+
109
+ const getActorContext = (
110
+ machine: Machine.Any,
111
+ configuration: ActiveConfiguration
112
+ ): ActorContext<any, any> => {
113
+ const scope = configuration.actorScope
114
+ if (scope !== undefined) return scope
115
+ const machineScope = machineActorScopes.get(machine)
116
+ if (machineScope !== undefined) return machineScope
117
+ const cached = rootActorScopes.get(machine)
118
+ if (cached !== undefined) return cached
119
+ const self: ActorRef<unknown> = {
120
+ id: machine.id ?? "Machine",
121
+ sessionId: "Machine.plan",
122
+ send: () => Effect.fail(new StoppedError())
123
+ }
124
+ const root = { self, parent: undefined }
125
+ rootActorScopes.set(machine, root)
126
+ return root
127
+ }
128
+
96
129
  type EventTransition<States extends Machine.StateSchemas, E, R, Context> =
97
130
  | TransitionHandler<States, E, R, Context>
98
131
  | {
@@ -155,9 +188,9 @@ const collectTransition = <
155
188
  context: Context
156
189
  ) => {
157
190
  const collected = makeCollector<Event>(machine)
158
- const state = transition(context, collected.enqueue)
191
+ const result = transition(context, collected.enqueue)
159
192
  return {
160
- state,
193
+ state: isNoTarget(result) ? undefined : result,
161
194
  commands: collected.commands,
162
195
  raisedEvents: collected.raisedEvents,
163
196
  emittedEvents: collected.emittedEvents
@@ -206,7 +239,8 @@ const completeHistoryConfiguration = (
206
239
  active,
207
240
  values,
208
241
  outputs: configuration.outputs,
209
- history: configuration.history
242
+ history: configuration.history,
243
+ actorScope: configuration.actorScope
210
244
  } as ActiveConfiguration
211
245
  active.add(child.path)
212
246
  if (child.schema !== undefined) {
@@ -215,9 +249,10 @@ const completeHistoryConfiguration = (
215
249
  throw new Error(`Machine shallow history requires an initial value implementation for state "${path}"`)
216
250
  }
217
251
  const initialized = collectStateInitializer(machine, initializer, {
252
+ ...getActorContext(machine, current),
218
253
  state: current.values.get(path),
219
- parent: getParentValue(machine, current, path),
220
- parents: getParentValues(machine, current, path),
254
+ containingState: getParentValue(machine, current, path),
255
+ ancestors: getParentValues(machine, current, path),
221
256
  event
222
257
  })
223
258
  values.set(child.path, decodeStateValueSync(machine, child, initialized.value))
@@ -235,16 +270,18 @@ const completeHistoryConfiguration = (
235
270
  active,
236
271
  values,
237
272
  outputs: configuration.outputs,
238
- history: configuration.history
273
+ history: configuration.history,
274
+ actorScope: configuration.actorScope
239
275
  } as ActiveConfiguration
240
276
  const initializer = valuedMissing.length === 0 ? undefined : machine.handlers[path]?.initial
241
277
  if (valuedMissing.length > 0 && initializer === undefined) {
242
278
  throw new Error(`Machine shallow history requires an initial value implementation for state "${path}"`)
243
279
  }
244
280
  const initialized = initializer === undefined ? undefined : collectStateInitializer(machine, initializer, {
281
+ ...getActorContext(machine, current),
245
282
  state: current.values.get(path),
246
- parent: getParentValue(machine, current, path),
247
- parents: getParentValues(machine, current, path),
283
+ containingState: getParentValue(machine, current, path),
284
+ ancestors: getParentValues(machine, current, path),
248
285
  event
249
286
  })
250
287
  if (initialized !== undefined && (typeof initialized.value !== "object" || initialized.value === null)) {
@@ -328,7 +365,7 @@ const resolveHistoryTarget = (
328
365
  const collected = collectTransition(machine, fallback, {
329
366
  event,
330
367
  target: getTargetBuilder(machine, target.parent).full,
331
- parent: target.parent
368
+ owner: target.parent
332
369
  })
333
370
  if (collected.state === undefined || isHistoryTarget(collected.state) || !isSnapshot(collected.state)) {
334
371
  throw new Error(`Machine history default for "${target.path}" must return a complete snapshot containing its owner`)
@@ -505,9 +542,10 @@ const makeStateActionContext = <
505
542
  path: string,
506
543
  event: Machine.LifecycleEvent<Events>
507
544
  ): Machine.StateActionContext<States, Events, Emits, StateId> => ({
545
+ ...getActorContext(machine, configuration),
508
546
  state: configuration.values.get(path) as Machine.StateByIdentifier<States, StateId>,
509
- parent: getParentValue(machine, configuration, path) as Machine.ParentStateValue<States, StateId>,
510
- parents: getParentValues(machine, configuration, path) as Machine.ParentStateValues<States, StateId>,
547
+ containingState: getParentValue(machine, configuration, path) as Machine.ParentStateValue<States, StateId>,
548
+ ancestors: getParentValues(machine, configuration, path) as Machine.ParentStateValues<States, StateId>,
511
549
  event
512
550
  })
513
551
 
@@ -524,9 +562,10 @@ const makeTransitionContext = <
524
562
  event: Machine.EventByTag<Events, EventTag>,
525
563
  snapshot: Machine.Snapshot<States>
526
564
  ): Machine.HandlerContext<States, Events, Emits, StateId, EventTag, any, any> => ({
565
+ ...getActorContext(machine, configuration),
527
566
  state: configuration.values.get(path) as Machine.StateByIdentifier<States, StateId>,
528
- parent: getParentValue(machine, configuration, path) as Machine.ParentStateValue<States, StateId>,
529
- parents: getParentValues(machine, configuration, path) as Machine.ParentStateValues<States, StateId>,
567
+ containingState: getParentValue(machine, configuration, path) as Machine.ParentStateValue<States, StateId>,
568
+ ancestors: getParentValues(machine, configuration, path) as Machine.ParentStateValues<States, StateId>,
530
569
  event,
531
570
  snapshot,
532
571
  target: getTargetBuilder(machine, path)
@@ -545,9 +584,10 @@ const makeDoneContext = <
545
584
  output: unknown,
546
585
  snapshot: Machine.Snapshot<States>
547
586
  ): Machine.DoneContext<States, Events, Emits, StateId> => ({
587
+ ...getActorContext(machine, configuration),
548
588
  state: configuration.values.get(path) as Machine.StateByIdentifier<States, StateId>,
549
- parent: getParentValue(machine, configuration, path) as Machine.ParentStateValue<States, StateId>,
550
- parents: getParentValues(machine, configuration, path) as Machine.ParentStateValues<States, StateId>,
589
+ containingState: getParentValue(machine, configuration, path) as Machine.ParentStateValue<States, StateId>,
590
+ ancestors: getParentValues(machine, configuration, path) as Machine.ParentStateValues<States, StateId>,
551
591
  event,
552
592
  output: output as Machine.CompletionOutputByIdentifier<States, StateId>,
553
593
  snapshot,
@@ -639,15 +679,16 @@ const selectAlwaysTransitions = <
639
679
  Machine.AlwaysContext<States, Events, Emits, Machine.StateIdentifier<States>>
640
680
  >,
641
681
  context: {
682
+ ...getActorContext(machine, configuration),
642
683
  state: configuration.values.get(path) as Machine.StateByIdentifier<
643
684
  States,
644
685
  Machine.StateIdentifier<States>
645
686
  >,
646
- parent: getParentValue(machine, configuration, path) as Machine.ParentStateValue<
687
+ containingState: getParentValue(machine, configuration, path) as Machine.ParentStateValue<
647
688
  States,
648
689
  Machine.StateIdentifier<States>
649
690
  >,
650
- parents: getParentValues(machine, configuration, path) as Machine.ParentStateValues<
691
+ ancestors: getParentValues(machine, configuration, path) as Machine.ParentStateValues<
651
692
  States,
652
693
  Machine.StateIdentifier<States>
653
694
  >,
@@ -826,9 +867,10 @@ const selectInvocationTransition = <
826
867
  if (transition === undefined) return []
827
868
  const snapshot = snapshotFromConfiguration<States>(machine, configuration)
828
869
  const context = {
870
+ ...getActorContext(machine, configuration),
829
871
  state: configuration.values.get(event.path),
830
- parent: getParentValue(machine, configuration, event.path),
831
- parents: getParentValues(machine, configuration, event.path),
872
+ containingState: getParentValue(machine, configuration, event.path),
873
+ ancestors: getParentValues(machine, configuration, event.path),
832
874
  snapshot,
833
875
  target: getTargetBuilder(machine, event.path),
834
876
  id: event.id,
@@ -1064,11 +1106,13 @@ const resolveChoiceTarget = (
1064
1106
  ...Object.entries(extracted.values)
1065
1107
  ]),
1066
1108
  outputs: configuration.outputs,
1067
- history: configuration.history
1109
+ history: configuration.history,
1110
+ ...(configuration.actorScope === undefined ? {} : { actorScope: configuration.actorScope })
1068
1111
  }
1069
1112
  const collected = collectTransition(machine, choice.transition, {
1070
- parent: getParentValue(machine, provisional, node.path),
1071
- parents: getParentValues(machine, provisional, node.path),
1113
+ ...getActorContext(machine, provisional),
1114
+ containingState: getParentValue(machine, provisional, node.path),
1115
+ ancestors: getParentValues(machine, provisional, node.path),
1072
1116
  event,
1073
1117
  target: getTargetBuilder(machine, node.path)
1074
1118
  })
@@ -131,7 +131,8 @@ const makeChildlessCompiledDrain = (
131
131
  planned = executionPlan.plan(
132
132
  configuration ?? executionPlan.fromConfiguration(Configuration.normalizeConfigurationSync(machine, current)),
133
133
  event,
134
- acknowledged
134
+ acknowledged,
135
+ context.scope
135
136
  )
136
137
  } catch (error) {
137
138
  return error instanceof InfiniteTransitionError || error instanceof MachineSchemaDecodeError
@@ -255,7 +256,8 @@ const makeInvokingCompiledDrain = (
255
256
  configuration ??
256
257
  executionPlan.fromConfiguration(Configuration.normalizeConfigurationSync(machine, current)),
257
258
  event,
258
- acknowledged
259
+ acknowledged,
260
+ scope
259
261
  )
260
262
  } catch (error) {
261
263
  return error instanceof InfiniteTransitionError || error instanceof MachineSchemaDecodeError
@@ -426,9 +428,11 @@ const makeProcessLogic: <
426
428
  const executionPlan = ExecutionPlan.compileExecutionPlan(machine)
427
429
  const initialArgs = entry._tag === "Initial" ? entry.args : []
428
430
  const compiledInitial = entry._tag === "Initial" ? executionPlan.initial : undefined
429
- const makeCompiledInitial = compiledInitial === undefined ? undefined : () => {
431
+ const makeCompiledInitial = compiledInitial === undefined ? undefined : (
432
+ scope: internalRuntime.ProcessScope<Machine.EventOf<Events>>
433
+ ) => {
430
434
  try {
431
- const planned = compiledInitial(initialArgs)
435
+ const planned = compiledInitial(initialArgs, scope)
432
436
  const result = {
433
437
  state: planned.state as Machine.Snapshot<States>,
434
438
  done: planned.done,
@@ -455,7 +459,7 @@ const makeProcessLogic: <
455
459
  ) =>
456
460
  compiledInitial === undefined
457
461
  ? internalRuntime.provideMachineRuntime(
458
- internalPlanner.planInitial(machine, ...initialArgs).pipe(
462
+ internalPlanner.planInitial(internalPlanner.withActorScope(machine, scope), ...initialArgs).pipe(
459
463
  Effect.flatMap((planned) => {
460
464
  const commands = planned.commands.length === 0
461
465
  ? undefined
@@ -480,7 +484,7 @@ const makeProcessLogic: <
480
484
  ),
481
485
  scope
482
486
  )
483
- : Effect.try({ try: makeCompiledInitial!, catch: (error) => error as any })
487
+ : Effect.try({ try: () => makeCompiledInitial!(scope), catch: (error) => error as any })
484
488
  return ({
485
489
  execution: {
486
490
  _tag: "Compiled",
@@ -536,7 +540,10 @@ const makeProcessLogic: <
536
540
  try {
537
541
  planned = internalPlanner.planConfiguration(
538
542
  machine,
539
- configuration ?? Configuration.normalizeConfigurationSync(machine, current),
543
+ Configuration.withActorScope(
544
+ configuration ?? Configuration.normalizeConfigurationSync(machine, current),
545
+ context
546
+ ),
540
547
  event
541
548
  )
542
549
  } catch (error) {
@@ -644,7 +651,10 @@ const makeProcessLogic: <
644
651
  try {
645
652
  planned = internalPlanner.planConfiguration(
646
653
  machine,
647
- configuration ?? Configuration.normalizeConfigurationSync(machine, current),
654
+ Configuration.withActorScope(
655
+ configuration ?? Configuration.normalizeConfigurationSync(machine, current),
656
+ context
657
+ ),
648
658
  event
649
659
  )
650
660
  } catch (error) {
@@ -815,6 +825,18 @@ export const startWithRuntimeStrategyForTesting = (
815
825
  machine.id === undefined ? undefined : { id: machine.id }
816
826
  )
817
827
 
828
+ /** @internal Test-only prepared startup strategy selection for a fresh machine. */
829
+ export const prepareWithRuntimeStrategyForTesting = (
830
+ machine: Machine.Any,
831
+ strategy: internalRuntime.ProcessRuntimeStrategy,
832
+ ...args: ReadonlyArray<unknown>
833
+ ): Effect.Effect<internalRuntime.PreparedProcess<any, any, any, any, any, any, any>, any, any> =>
834
+ internalRuntime.prepareProcessWithStrategyForTesting(
835
+ (toProcessLogic as any)(machine, ...args),
836
+ strategy,
837
+ machine.id === undefined ? undefined : { id: machine.id }
838
+ )
839
+
818
840
  /** @internal Test-only runtime strategy selection for a resumed machine. */
819
841
  export const resumeWithRuntimeStrategyForTesting = (
820
842
  machine: Machine.Any,
@@ -871,6 +893,51 @@ export const start: <
871
893
  machine.id === undefined ? undefined : { id: machine.id }
872
894
  ) as any
873
895
 
896
+ export const prepare: <
897
+ const States extends Machine.StateSchemas,
898
+ const Events extends ReadonlyArray<Machine.TaggedSchema>,
899
+ const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
900
+ const Input extends Schema.Top = typeof Schema.Void,
901
+ UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
902
+ E = never,
903
+ R = never,
904
+ InitialE = never,
905
+ InitialR = never,
906
+ FinalStates extends Machine.StateIdentifier<States> = never,
907
+ Output = never
908
+ >(
909
+ machine: Machine<States, Events, Input, UnhandledStates, E, R, InitialE, InitialR, FinalStates, Output, Emits>,
910
+ ...args: [...Machine.InputArgs<Input>]
911
+ ) => Effect.Effect<
912
+ internalRuntime.PreparedProcess<
913
+ Machine.Snapshot<States>,
914
+ Machine.EventOf<Events>,
915
+ | E
916
+ | ActionError<R>
917
+ | InfiniteTransitionError
918
+ | MachineSchemaDecodeError
919
+ | StoppedError,
920
+ Output,
921
+ Machine.EmittedEventOf<Emits>,
922
+ | InitialE
923
+ | E
924
+ | ActionError<InitialR | R>
925
+ | InfiniteTransitionError
926
+ | MachineSchemaDecodeError
927
+ | StartupError
928
+ | StoppedError,
929
+ ExcludeCompatibleRuntime<
930
+ Exclude<ExecutionServices<InitialR | R>, internalRuntime.MachineRuntime>,
931
+ Machine.EventOf<Events>,
932
+ Machine.EmitOf<Emits>
933
+ >
934
+ >
935
+ > = (machine, ...args) =>
936
+ internalRuntime.prepareProcess(
937
+ toProcessLogic(machine, ...args),
938
+ machine.id === undefined ? undefined : { id: machine.id }
939
+ ) as any
940
+
874
941
  export const resume: <
875
942
  const States extends Machine.StateSchemas,
876
943
  const Events extends ReadonlyArray<Machine.TaggedSchema>,