@typeonce/effect-machine 0.10.0 → 0.12.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 (58) hide show
  1. package/README.md +76 -13
  2. package/dist/Machine.d.ts +202 -90
  3. package/dist/Machine.d.ts.map +1 -1
  4. package/dist/Machine.js +38 -9
  5. package/dist/Machine.js.map +1 -1
  6. package/dist/internal/machine/atom.d.ts +1 -1
  7. package/dist/internal/machine/atom.d.ts.map +1 -1
  8. package/dist/internal/machine/atom.js +38 -7
  9. package/dist/internal/machine/atom.js.map +1 -1
  10. package/dist/internal/machine/cluster.js +2 -2
  11. package/dist/internal/machine/cluster.js.map +1 -1
  12. package/dist/internal/machine/commandRuntime.d.ts.map +1 -1
  13. package/dist/internal/machine/commandRuntime.js +2 -2
  14. package/dist/internal/machine/commandRuntime.js.map +1 -1
  15. package/dist/internal/machine/configuration.d.ts +7 -7
  16. package/dist/internal/machine/configuration.d.ts.map +1 -1
  17. package/dist/internal/machine/configuration.js +3 -3
  18. package/dist/internal/machine/configuration.js.map +1 -1
  19. package/dist/internal/machine/executionPlan.d.ts +3 -3
  20. package/dist/internal/machine/executionPlan.d.ts.map +1 -1
  21. package/dist/internal/machine/executionPlan.js +25 -25
  22. package/dist/internal/machine/executionPlan.js.map +1 -1
  23. package/dist/internal/machine/invocation.js +1 -1
  24. package/dist/internal/machine/invocation.js.map +1 -1
  25. package/dist/internal/machine/machine.d.ts +1 -0
  26. package/dist/internal/machine/machine.d.ts.map +1 -1
  27. package/dist/internal/machine/machine.js +4 -0
  28. package/dist/internal/machine/machine.js.map +1 -1
  29. package/dist/internal/machine/planner.d.ts +2 -2
  30. package/dist/internal/machine/planner.d.ts.map +1 -1
  31. package/dist/internal/machine/planner.js +20 -20
  32. package/dist/internal/machine/planner.js.map +1 -1
  33. package/dist/internal/machine/process.d.ts +3 -0
  34. package/dist/internal/machine/process.d.ts.map +1 -1
  35. package/dist/internal/machine/process.js +6 -3
  36. package/dist/internal/machine/process.js.map +1 -1
  37. package/dist/internal/machine/runtime.d.ts +17 -3
  38. package/dist/internal/machine/runtime.d.ts.map +1 -1
  39. package/dist/internal/machine/runtime.js +82 -32
  40. package/dist/internal/machine/runtime.js.map +1 -1
  41. package/dist/unstable/reactivity/AtomMachine.d.ts +4 -2
  42. package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
  43. package/dist/unstable/reactivity/AtomMachine.js +4 -2
  44. package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
  45. package/docs/agent-guide.md +78 -19
  46. package/package.json +1 -1
  47. package/src/Machine.ts +704 -96
  48. package/src/internal/machine/atom.ts +50 -52
  49. package/src/internal/machine/cluster.ts +2 -2
  50. package/src/internal/machine/commandRuntime.ts +4 -2
  51. package/src/internal/machine/configuration.ts +10 -10
  52. package/src/internal/machine/executionPlan.ts +35 -35
  53. package/src/internal/machine/invocation.ts +1 -1
  54. package/src/internal/machine/machine.ts +6 -0
  55. package/src/internal/machine/planner.ts +30 -24
  56. package/src/internal/machine/process.ts +60 -3
  57. package/src/internal/machine/runtime.ts +176 -47
  58. package/src/unstable/reactivity/AtomMachine.ts +4 -2
@@ -7,11 +7,12 @@
7
7
  import * as Data from "effect/Data"
8
8
  import * as Effect from "effect/Effect"
9
9
  import * as Equal from "effect/Equal"
10
+ import * as Fiber from "effect/Fiber"
10
11
  import * as Option from "effect/Option"
11
12
  import type * as Schema from "effect/Schema"
12
13
  import type * as Scope from "effect/Scope"
13
14
  import * as Stream from "effect/Stream"
14
- import { AsyncResult, Atom, type AtomRegistry } from "effect/unstable/reactivity"
15
+ import { AsyncResult, Atom, AtomRegistry } from "effect/unstable/reactivity"
15
16
  import type * as Machine from "../../Machine.js"
16
17
  import type { Bound, ChildMachineAtom, MachineAtom } from "../../unstable/reactivity/AtomMachine.js"
17
18
  import * as internalMachine from "./machine.js"
@@ -72,6 +73,11 @@ type MachineStartError<InitialE, E, InitialR, R, RuntimeError = never> =
72
73
  | Machine.StoppedError
73
74
  | RuntimeError
74
75
 
76
+ const preparedByMachineAtom = new WeakMap<
77
+ object,
78
+ Atom.Atom<AsyncResult.AsyncResult<Machine.Prepared<any, any, any, any, any, any, any>, any>>
79
+ >()
80
+
75
81
  const runMachineAtomEffect = <State, Event, Error, Output, Emitted, StartError, Requirements>(
76
82
  get: Atom.AtomContext,
77
83
  start: Effect.Effect<Machine.MachineRef<State, Event, Error, Output, Emitted>, StartError, Requirements>
@@ -83,53 +89,16 @@ const runMachineAtomEffect = <State, Event, Error, Output, Emitted, StartError,
83
89
  )
84
90
  )
85
91
 
86
- const startMachineAtomEffect = <
87
- const States extends Machine.Machine.StateSchemas,
88
- const Events extends ReadonlyArray<Machine.Machine.TaggedSchema>,
89
- const Emits extends ReadonlyArray<Machine.Machine.TaggedSchema> = any,
90
- const Input extends Schema.Top = typeof Schema.Void,
91
- UnhandledStates extends Machine.Machine.StateIdentifier<States> = Machine.Machine.StateIdentifier<States>,
92
- E = never,
93
- R = never,
94
- InitialE = never,
95
- InitialR = never,
96
- FinalStates extends Machine.Machine.StateIdentifier<States> = never,
97
- Output = never,
98
- OutputStates extends Machine.Machine.StateIdentifier<States> = never,
99
- InputEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = Events,
100
- ParentEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = readonly []
101
- >(
92
+ const startPreparedMachineAtomEffect = <State, Event, Error, Output, Emitted, StartError, Requirements>(
102
93
  get: Atom.AtomContext,
103
- machine:
104
- & Machine.Machine<
105
- States,
106
- Events,
107
- Input,
108
- UnhandledStates,
109
- E,
110
- R,
111
- InitialE,
112
- InitialR,
113
- FinalStates,
114
- Output,
115
- Emits,
116
- OutputStates,
117
- InputEvents,
118
- ParentEvents
94
+ prepared: Atom.Atom<
95
+ AsyncResult.AsyncResult<
96
+ Machine.Prepared<State, Event, Error, Output, Emitted, StartError, Requirements>,
97
+ never
119
98
  >
120
- & EnsureExecutable<States, UnhandledStates, OutputStates>,
121
- args: [...Machine.Machine.InputArgs<Input>]
122
- ): Effect.Effect<
123
- Machine.MachineRef<
124
- Machine.Machine.Snapshot<States>,
125
- Machine.Machine.EventInputOf<InputEvents>,
126
- MachineRuntimeError<E, R>,
127
- Output,
128
- Machine.Machine.EmittedEventOf<Emits>
129
- >,
130
- MachineStartError<InitialE, E, InitialR, R>,
131
- MachineRequirements<InitialR, R, Machine.Machine.EventOf<Events>, Machine.Machine.EmitOf<Emits>>
132
- > => runMachineAtomEffect(get, internalMachine.start(machine as any, ...args) as any)
99
+ >
100
+ ): Effect.Effect<never, StartError, Requirements> =>
101
+ runMachineAtomEffect(get, get.result(prepared).pipe(Effect.flatMap((prepared) => prepared.start)))
133
102
 
134
103
  const resumeMachineAtomEffect = (
135
104
  get: Atom.AtomContext,
@@ -144,8 +113,31 @@ type RefEmitted<Ref> = Ref extends Machine.MachineRef<any, any, any, any, infer
144
113
 
145
114
  export const emissions = <State, Event, Error, Output, StartError, Emitted>(
146
115
  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))
116
+ ): Stream.Stream<Emitted, StartError, AtomRegistry.AtomRegistry> => {
117
+ const prepared = preparedByMachineAtom.get(self as object)
118
+ if (prepared === undefined) {
119
+ return Atom.toStreamResult(self.ref).pipe(Stream.flatMap((ref) => ref.emissions))
120
+ }
121
+ return Stream.unwrap(
122
+ Effect.gen(function*() {
123
+ const registry = yield* AtomRegistry.AtomRegistry
124
+ const releasePrepared = yield* Effect.sync(() => registry.mount(prepared))
125
+ yield* Effect.addFinalizer(() => Effect.sync(releasePrepared))
126
+ const machine = yield* Atom.getResult(prepared)
127
+ const pull = yield* Stream.toPull(machine.emissions as Stream.Stream<Emitted>)
128
+ const firstPull = yield* pull.pipe(Effect.forkScoped({ startImmediately: true }))
129
+ const releaseRef = yield* Effect.sync(() => registry.mount(self.ref))
130
+ yield* Effect.addFinalizer(() => Effect.sync(releaseRef))
131
+ yield* Atom.getResult(self.ref)
132
+ let first = true
133
+ return Stream.fromPull(Effect.succeed(Effect.suspend(() => {
134
+ if (!first) return pull
135
+ first = false
136
+ return Fiber.join(firstPull)
137
+ })))
138
+ })
139
+ )
140
+ }
149
141
 
150
142
  export const childEmissions = <Child extends Machine.ChildMachine.Any, StartError>(
151
143
  self: ChildMachineAtom<Child, StartError>
@@ -666,8 +658,11 @@ export const make: {
666
658
  Machine.Machine.EmittedEventOf<Emits>
667
659
  >
668
660
  } = ((machine: Machine.Machine.Any, ...args: ReadonlyArray<unknown>) => {
669
- const ref = Atom.make((get) => startMachineAtomEffect(get, machine as any, args as []))
670
- return makeFromRefAtom(ref as any)
661
+ const prepared = Atom.make(() => internalMachine.prepare(machine as any, ...(args as [])))
662
+ const ref = Atom.make((get) => startPreparedMachineAtomEffect(get, prepared as any))
663
+ const result = makeFromRefAtom(ref as any)
664
+ preparedByMachineAtom.set(result, prepared as any)
665
+ return result
671
666
  }) as any
672
667
 
673
668
  export const resume: {
@@ -688,8 +683,11 @@ const makeWithRuntime = (
688
683
  machine: Machine.Machine.Any,
689
684
  args: ReadonlyArray<unknown>
690
685
  ): MachineAtom<any, any, any, any, any> => {
691
- const ref = runtime.atom((get) => startMachineAtomEffect(get, machine as any, args as []))
692
- return makeFromRefAtom(ref as any)
686
+ const prepared = runtime.atom(() => internalMachine.prepare(machine as any, ...(args as [])))
687
+ const ref = runtime.atom((get) => startPreparedMachineAtomEffect(get, prepared as any))
688
+ const result = makeFromRefAtom(ref as any)
689
+ preparedByMachineAtom.set(result, prepared as any)
690
+ return result
693
691
  }
694
692
 
695
693
  const resumeWithRuntime = (
@@ -317,7 +317,7 @@ export const make = <
317
317
  if (initial.commands.length > 0) {
318
318
  return yield* fail(
319
319
  "UnsupportedProcessLocal",
320
- "Machine actor commands require a managed local process"
320
+ "Machine commands require a managed local process"
321
321
  )
322
322
  }
323
323
  current = initial.state
@@ -329,7 +329,7 @@ export const make = <
329
329
  if (planned.commands.length > 0) {
330
330
  return yield* fail(
331
331
  "UnsupportedProcessLocal",
332
- "Machine actor commands require a managed local process"
332
+ "Machine commands require a managed local process"
333
333
  )
334
334
  }
335
335
  current = planned.next
@@ -10,7 +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> } =>
13
+ const isMachineTarget = (
14
+ target: unknown
15
+ ): target is { readonly send: (event: unknown) => Effect.Effect<void, unknown> } =>
14
16
  typeof target === "object" && target !== null && "send" in target && typeof target.send === "function"
15
17
 
16
18
  export const makeLiveRuntime = <Events, Emits>(
@@ -33,7 +35,7 @@ export const runCommands = <Event>(
33
35
  ) =>
34
36
  Effect.forEach(commands, (command) =>
35
37
  command._tag === "SendTo"
36
- ? isActorRef(command.target)
38
+ ? isMachineTarget(command.target)
37
39
  ? command.target.send(command.event)
38
40
  : scope.sendTo(command.target as never, command.event)
39
41
  : scope.stopChild(command.child as never), { discard: true })
@@ -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 { ActorRef, Machine } from "../../Machine.js"
11
+ import type { Machine, MachineTarget } from "../../Machine.js"
12
12
  import { MachineSchemaDecodeError } from "./errors.js"
13
13
  import {
14
14
  decodeBoundary,
@@ -252,25 +252,25 @@ 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
+ readonly machineReferences?: PlanningMachineReferences
256
256
  }
257
257
 
258
- export interface PlanningActorScope {
259
- readonly self: ActorRef<any>
260
- readonly parent: ActorRef<any> | undefined
258
+ export interface PlanningMachineReferences {
259
+ readonly self: MachineTarget<any>
260
+ readonly parent: MachineTarget<any> | undefined
261
261
  }
262
262
 
263
- export const withActorScope = (
263
+ export const withMachineReferences = (
264
264
  configuration: ActiveConfiguration,
265
- actorScope: PlanningActorScope
265
+ machineReferences: PlanningMachineReferences
266
266
  ): ActiveConfiguration => ({
267
267
  ...configuration,
268
- actorScope: { self: actorScope.self, parent: actorScope.parent }
268
+ machineReferences: { self: machineReferences.self, parent: machineReferences.parent }
269
269
  })
270
270
 
271
- export const getActorScope = (
271
+ export const getMachineReferences = (
272
272
  configuration: ActiveConfiguration
273
- ): PlanningActorScope | undefined => configuration.actorScope
273
+ ): PlanningMachineReferences | undefined => configuration.machineReferences
274
274
 
275
275
  export interface FinalCompletion {
276
276
  readonly path: string
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import * as Effect from "effect/Effect"
8
- import type { ActorRef, Machine } from "../../Machine.js"
8
+ import type { Machine, MachineTarget } from "../../Machine.js"
9
9
  import { getTargetBuilder, type RuntimeCommand } from "./command.js"
10
10
  import {
11
11
  type ActiveConfiguration,
@@ -18,10 +18,10 @@ import {
18
18
  isDescendantOf,
19
19
  normalizeConfigurationSync,
20
20
  normalizeTargetConfigurationSync,
21
- type PlanningActorScope,
21
+ type PlanningMachineReferences,
22
22
  snapshotFromConfiguration,
23
23
  validateInitialConfiguration,
24
- withActorScope
24
+ withMachineReferences
25
25
  } from "./configuration.js"
26
26
  import { InfiniteTransitionError, StoppedError } from "./errors.js"
27
27
  import * as InvocationEvent from "./invocationEvent.js"
@@ -67,28 +67,28 @@ interface IndexedExecutionDescriptor {
67
67
  >
68
68
  }
69
69
 
70
- const planningActorScopes = new WeakMap<Machine.Any, PlanningActorScope>()
70
+ const planningMachineReferences = new WeakMap<Machine.Any, PlanningMachineReferences>()
71
71
 
72
- const getPlanningActorScope = (machine: Machine.Any): PlanningActorScope => {
73
- const cached = planningActorScopes.get(machine)
72
+ const getPlanningMachineReferences = (machine: Machine.Any): PlanningMachineReferences => {
73
+ const cached = planningMachineReferences.get(machine)
74
74
  if (cached !== undefined) return cached
75
- const self: ActorRef<unknown> = {
75
+ const self: MachineTarget<unknown> = {
76
76
  id: machine.id ?? "Machine",
77
77
  sessionId: "Machine.plan",
78
78
  send: () => Effect.fail(new StoppedError())
79
79
  }
80
80
  const scope = { self, parent: undefined }
81
- planningActorScopes.set(machine, scope)
81
+ planningMachineReferences.set(machine, scope)
82
82
  return scope
83
83
  }
84
84
 
85
- const getActorContext = (
85
+ const resolveMachineReferences = (
86
86
  machine: Machine.Any,
87
- actorScope: PlanningActorScope | undefined
88
- ): PlanningActorScope =>
89
- actorScope === undefined
90
- ? getPlanningActorScope(machine)
91
- : { self: actorScope.self, parent: actorScope.parent }
87
+ machineReferences: PlanningMachineReferences | undefined
88
+ ): PlanningMachineReferences =>
89
+ machineReferences === undefined
90
+ ? getPlanningMachineReferences(machine)
91
+ : { self: machineReferences.self, parent: machineReferences.parent }
92
92
 
93
93
  const indexedStateConfigKeys: ReadonlySet<PropertyKey> = new Set([
94
94
  "initial",
@@ -363,7 +363,7 @@ const makeIndexedTransitionContext = (
363
363
  configuration: OwnedIndexedState,
364
364
  sourceIndex: number,
365
365
  event: any,
366
- actorScope?: PlanningActorScope
366
+ machineReferences?: PlanningMachineReferences
367
367
  ): any => {
368
368
  const source = descriptor.nodes[sourceIndex]!
369
369
  const parentIndex = descriptor.parentIndices[sourceIndex]!
@@ -372,7 +372,7 @@ const makeIndexedTransitionContext = (
372
372
  ancestors[descriptor.nodes[ancestorIndex]!.path] = configuration.values[ancestorIndex]
373
373
  }
374
374
  return {
375
- ...getActorContext(machine, actorScope),
375
+ ...resolveMachineReferences(machine, machineReferences),
376
376
  state: configuration.values[sourceIndex],
377
377
  containingState: parentIndex < 0 ? undefined : configuration.values[parentIndex],
378
378
  ancestors,
@@ -454,7 +454,7 @@ const selectIndexedEventTransitions = (
454
454
  descriptor: IndexedExecutionDescriptor,
455
455
  configuration: OwnedIndexedState,
456
456
  event: any,
457
- actorScope?: PlanningActorScope
457
+ machineReferences?: PlanningMachineReferences
458
458
  ): ReadonlyArray<IndexedSelectedTransition> => {
459
459
  const selected: Array<IndexedSelectedTransition> = []
460
460
  for (const leafIndex of configuration.activeLeaves) {
@@ -476,7 +476,7 @@ const selectIndexedEventTransitions = (
476
476
  configuration,
477
477
  sourceIndex,
478
478
  event,
479
- actorScope
479
+ machineReferences
480
480
  )
481
481
  })
482
482
  }
@@ -660,7 +660,7 @@ const planIndexedFlatState = (
660
660
  configuration: OwnedIndexedState,
661
661
  decoded: { readonly _tag: PropertyKey },
662
662
  retainMicrosteps: boolean,
663
- actorScope?: PlanningActorScope
663
+ machineReferences?: PlanningMachineReferences
664
664
  ): ExecutionMacrostep<OwnedIndexedState> => {
665
665
  let current = configuration
666
666
  let event: any = decoded
@@ -712,7 +712,7 @@ const planIndexedFlatState = (
712
712
  machine,
713
713
  transition.transition,
714
714
  {
715
- ...getActorContext(machine, actorScope),
715
+ ...resolveMachineReferences(machine, machineReferences),
716
716
  state: current.values[sourceIndex],
717
717
  containingState: undefined,
718
718
  ancestors: {},
@@ -807,7 +807,7 @@ const planIndexedState = (
807
807
  configuration: OwnedIndexedState,
808
808
  input: unknown,
809
809
  retainMicrosteps: boolean,
810
- actorScope?: PlanningActorScope
810
+ machineReferences?: PlanningMachineReferences
811
811
  ): ExecutionMacrostep<OwnedIndexedState> => {
812
812
  if (InvocationEvent.isInvocationEvent(input)) {
813
813
  // Invocation lifecycle transitions retain the generic planner as their
@@ -816,9 +816,9 @@ const planIndexedState = (
816
816
  // the representation boundary.
817
817
  const planned = planConfiguration(
818
818
  machine as any,
819
- actorScope === undefined
819
+ machineReferences === undefined
820
820
  ? activeConfigurationFromIndexedState(descriptor, configuration)
821
- : withActorScope(activeConfigurationFromIndexedState(descriptor, configuration), actorScope),
821
+ : withMachineReferences(activeConfigurationFromIndexedState(descriptor, configuration), machineReferences),
822
822
  input
823
823
  )
824
824
  return {
@@ -841,7 +841,7 @@ const planIndexedState = (
841
841
  }
842
842
  const decoded = decodeEventSync(machine, input)
843
843
  if (descriptor.flat) {
844
- return planIndexedFlatState(machine, descriptor, configuration, decoded, retainMicrosteps, actorScope)
844
+ return planIndexedFlatState(machine, descriptor, configuration, decoded, retainMicrosteps, machineReferences)
845
845
  }
846
846
  if (descriptor.finalIndices.some((index) => configuration.active[index] === 1)) {
847
847
  const active = activeConfigurationFromIndexedState(descriptor, configuration)
@@ -862,7 +862,7 @@ const planIndexedState = (
862
862
  }
863
863
  }
864
864
 
865
- const selections = selectIndexedEventTransitions(machine, descriptor, configuration, decoded, actorScope)
865
+ const selections = selectIndexedEventTransitions(machine, descriptor, configuration, decoded, machineReferences)
866
866
  if (selections.length === 0) {
867
867
  return {
868
868
  next: configuration,
@@ -930,7 +930,7 @@ const planIndexedState = (
930
930
  }
931
931
  raisedIndex += 1
932
932
  currentEvent = raised
933
- const raisedSelections = selectIndexedEventTransitions(machine, descriptor, current, raised, actorScope)
933
+ const raisedSelections = selectIndexedEventTransitions(machine, descriptor, current, raised, machineReferences)
934
934
  if (raisedSelections.length === 0) continue
935
935
  const step = indexedMicrostep(machine, descriptor, current, raised, raisedSelections)
936
936
  current = step.next
@@ -949,11 +949,11 @@ export interface CompiledExecutionPlan {
949
949
  state: unknown,
950
950
  event: unknown,
951
951
  retainMicrosteps?: boolean,
952
- actorScope?: PlanningActorScope
952
+ machineReferences?: PlanningMachineReferences
953
953
  ) => ExecutionMacrostep
954
954
  readonly initial?: (
955
955
  args: ReadonlyArray<unknown>,
956
- actorScope?: PlanningActorScope
956
+ machineReferences?: PlanningMachineReferences
957
957
  ) => {
958
958
  readonly state: Machine.Snapshot<any>
959
959
  readonly configuration: unknown
@@ -970,12 +970,12 @@ const makeActiveExecutionPlan = (machine: Machine.Any): CompiledExecutionPlan =>
970
970
  fromConfiguration: (configuration) => configuration,
971
971
  toConfiguration: (state) => state as ActiveConfiguration,
972
972
  snapshot: (state) => snapshotFromConfiguration(machine, state as ActiveConfiguration),
973
- plan: (state, event, _retainMicrosteps, actorScope) =>
973
+ plan: (state, event, _retainMicrosteps, machineReferences) =>
974
974
  planConfiguration(
975
975
  machine as any,
976
- actorScope === undefined
976
+ machineReferences === undefined
977
977
  ? state as ActiveConfiguration
978
- : withActorScope(state as ActiveConfiguration, actorScope),
978
+ : withMachineReferences(state as ActiveConfiguration, machineReferences),
979
979
  event as any
980
980
  )
981
981
  })
@@ -987,9 +987,9 @@ const makeIndexedExecutionPlan = (
987
987
  fromConfiguration: (configuration) => ownedIndexedStateFromActive(indexed, configuration),
988
988
  toConfiguration: (state) => activeConfigurationFromIndexedState(indexed, state as OwnedIndexedState),
989
989
  snapshot: (state) => snapshotFromIndexedState(indexed, state as OwnedIndexedState),
990
- plan: (state, event, retainMicrosteps = false, actorScope) =>
991
- planIndexedState(machine, indexed, state as OwnedIndexedState, event, retainMicrosteps, actorScope),
992
- initial: (args, actorScope) => {
990
+ plan: (state, event, retainMicrosteps = false, machineReferences) =>
991
+ planIndexedState(machine, indexed, state as OwnedIndexedState, event, retainMicrosteps, machineReferences),
992
+ initial: (args, machineReferences) => {
993
993
  const inputArgs = machine.input === undefined
994
994
  ? args
995
995
  : args.length === 0
@@ -997,7 +997,7 @@ const makeIndexedExecutionPlan = (
997
997
  : [decodeInputSync(machine, machine.input, args[0])]
998
998
  const initial = machine.initial(...inputArgs as any)
999
999
  const normalized = normalizeConfigurationSync(machine, initial as Machine.Snapshot<any>)
1000
- const active = actorScope === undefined ? normalized : withActorScope(normalized, actorScope)
1000
+ const active = machineReferences === undefined ? normalized : withMachineReferences(normalized, machineReferences)
1001
1001
  validateInitialConfiguration(machine, active)
1002
1002
  const completed = completeConfigurationSync(machine, active, InitialEvent).configuration
1003
1003
  const configuration = ownedIndexedStateFromActive(indexed, completed)
@@ -235,7 +235,7 @@ 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
+ ...(Configuration.getMachineReferences(configuration) ?? { self: scope.self, parent: scope.parent }),
239
239
  state: configuration.values.get(path),
240
240
  containingState: Configuration.getParentValue(machine, configuration, path),
241
241
  ancestors: Configuration.getParentValues(machine, configuration, path),
@@ -104,6 +104,8 @@ const Proto = {
104
104
  }
105
105
  }
106
106
 
107
+ const makeBoundInvoke = (config: unknown): unknown => config
108
+
107
109
  const cloneWithHandlers = (
108
110
  self: Machine.Any,
109
111
  handlers: Machine.StateConfigs<any, any, any, any, any, any, any>
@@ -121,6 +123,7 @@ const cloneWithHandlers = (
121
123
  machine.makeTargetBuilder = self.makeTargetBuilder
122
124
  machine.handlers = handlers
123
125
  machine.handle = makeHandle(machine)
126
+ machine.invoke = makeBoundInvoke
124
127
  Protocol.copyProtocol(self, machine)
125
128
  return machine
126
129
  }
@@ -879,6 +882,7 @@ export const make: Make = (<
879
882
  self.makeTargetBuilder = makeTargetBuilder(config.states, self.stateNodes)
880
883
  self.handlers = Object.create(null)
881
884
  self.handle = makeHandle(self)
885
+ self.invoke = makeBoundInvoke
882
886
  Protocol.setProtocol(self)
883
887
  return self
884
888
  }) as Make
@@ -1358,6 +1362,8 @@ export const watch = <State, Event, Error = never, Output = never>(
1358
1362
  ref: MachineRef<State, Event, Error, Output>
1359
1363
  ): Stream.Stream<RuntimeOutcome<State, Error, Output>> => internalRuntime.watch(ref)
1360
1364
 
1365
+ export const prepare = internalProcess.prepare
1366
+
1361
1367
  export const start: <
1362
1368
  const States extends Machine.StateSchemas,
1363
1369
  const Events extends ReadonlyArray<Machine.TaggedSchema>,
@@ -7,7 +7,13 @@
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 { ActorContext, ActorRef, Enqueue, InitialEvent as MachineInitialEvent, Machine } from "../../Machine.js"
10
+ import type {
11
+ Enqueue,
12
+ InitialEvent as MachineInitialEvent,
13
+ Machine,
14
+ MachineReferences,
15
+ MachineTarget
16
+ } from "../../Machine.js"
11
17
  import { getTargetBuilder, makeCollector, type RuntimeCommand } from "./command.js"
12
18
  import {
13
19
  type ActiveConfiguration,
@@ -94,35 +100,35 @@ export type TransitionHandler<States extends Machine.StateSchemas, E, R, Context
94
100
  enqueue: Enqueue<any, any>
95
101
  ) => Machine.HandlerResult<States, E, R>
96
102
 
97
- const rootActorScopes = new WeakMap<Machine.Any, ActorContext<any, any>>()
98
- const machineActorScopes = new WeakMap<Machine.Any, ActorContext<any, any>>()
103
+ const rootMachineReferences = new WeakMap<Machine.Any, MachineReferences<any, any>>()
104
+ const scopedMachineReferences = new WeakMap<Machine.Any, MachineReferences<any, any>>()
99
105
 
100
- export const withActorScope = (
106
+ export const withMachineReferences = (
101
107
  machine: Machine.Any,
102
- actorScope: ActorContext<any, any>
108
+ machineReferences: MachineReferences<any, any>
103
109
  ): Machine.Any => {
104
110
  const scoped = Object.create(machine) as Machine.Any
105
- machineActorScopes.set(scoped, { self: actorScope.self, parent: actorScope.parent })
111
+ scopedMachineReferences.set(scoped, { self: machineReferences.self, parent: machineReferences.parent })
106
112
  return scoped
107
113
  }
108
114
 
109
- const getActorContext = (
115
+ const resolveMachineReferences = (
110
116
  machine: Machine.Any,
111
117
  configuration: ActiveConfiguration
112
- ): ActorContext<any, any> => {
113
- const scope = configuration.actorScope
118
+ ): MachineReferences<any, any> => {
119
+ const scope = configuration.machineReferences
114
120
  if (scope !== undefined) return scope
115
- const machineScope = machineActorScopes.get(machine)
121
+ const machineScope = scopedMachineReferences.get(machine)
116
122
  if (machineScope !== undefined) return machineScope
117
- const cached = rootActorScopes.get(machine)
123
+ const cached = rootMachineReferences.get(machine)
118
124
  if (cached !== undefined) return cached
119
- const self: ActorRef<unknown> = {
125
+ const self: MachineTarget<unknown> = {
120
126
  id: machine.id ?? "Machine",
121
127
  sessionId: "Machine.plan",
122
128
  send: () => Effect.fail(new StoppedError())
123
129
  }
124
130
  const root = { self, parent: undefined }
125
- rootActorScopes.set(machine, root)
131
+ rootMachineReferences.set(machine, root)
126
132
  return root
127
133
  }
128
134
 
@@ -240,7 +246,7 @@ const completeHistoryConfiguration = (
240
246
  values,
241
247
  outputs: configuration.outputs,
242
248
  history: configuration.history,
243
- actorScope: configuration.actorScope
249
+ machineReferences: configuration.machineReferences
244
250
  } as ActiveConfiguration
245
251
  active.add(child.path)
246
252
  if (child.schema !== undefined) {
@@ -249,7 +255,7 @@ const completeHistoryConfiguration = (
249
255
  throw new Error(`Machine shallow history requires an initial value implementation for state "${path}"`)
250
256
  }
251
257
  const initialized = collectStateInitializer(machine, initializer, {
252
- ...getActorContext(machine, current),
258
+ ...resolveMachineReferences(machine, current),
253
259
  state: current.values.get(path),
254
260
  containingState: getParentValue(machine, current, path),
255
261
  ancestors: getParentValues(machine, current, path),
@@ -271,14 +277,14 @@ const completeHistoryConfiguration = (
271
277
  values,
272
278
  outputs: configuration.outputs,
273
279
  history: configuration.history,
274
- actorScope: configuration.actorScope
280
+ machineReferences: configuration.machineReferences
275
281
  } as ActiveConfiguration
276
282
  const initializer = valuedMissing.length === 0 ? undefined : machine.handlers[path]?.initial
277
283
  if (valuedMissing.length > 0 && initializer === undefined) {
278
284
  throw new Error(`Machine shallow history requires an initial value implementation for state "${path}"`)
279
285
  }
280
286
  const initialized = initializer === undefined ? undefined : collectStateInitializer(machine, initializer, {
281
- ...getActorContext(machine, current),
287
+ ...resolveMachineReferences(machine, current),
282
288
  state: current.values.get(path),
283
289
  containingState: getParentValue(machine, current, path),
284
290
  ancestors: getParentValues(machine, current, path),
@@ -542,7 +548,7 @@ const makeStateActionContext = <
542
548
  path: string,
543
549
  event: Machine.LifecycleEvent<Events>
544
550
  ): Machine.StateActionContext<States, Events, Emits, StateId> => ({
545
- ...getActorContext(machine, configuration),
551
+ ...resolveMachineReferences(machine, configuration),
546
552
  state: configuration.values.get(path) as Machine.StateByIdentifier<States, StateId>,
547
553
  containingState: getParentValue(machine, configuration, path) as Machine.ParentStateValue<States, StateId>,
548
554
  ancestors: getParentValues(machine, configuration, path) as Machine.ParentStateValues<States, StateId>,
@@ -562,7 +568,7 @@ const makeTransitionContext = <
562
568
  event: Machine.EventByTag<Events, EventTag>,
563
569
  snapshot: Machine.Snapshot<States>
564
570
  ): Machine.HandlerContext<States, Events, Emits, StateId, EventTag, any, any> => ({
565
- ...getActorContext(machine, configuration),
571
+ ...resolveMachineReferences(machine, configuration),
566
572
  state: configuration.values.get(path) as Machine.StateByIdentifier<States, StateId>,
567
573
  containingState: getParentValue(machine, configuration, path) as Machine.ParentStateValue<States, StateId>,
568
574
  ancestors: getParentValues(machine, configuration, path) as Machine.ParentStateValues<States, StateId>,
@@ -584,7 +590,7 @@ const makeDoneContext = <
584
590
  output: unknown,
585
591
  snapshot: Machine.Snapshot<States>
586
592
  ): Machine.DoneContext<States, Events, Emits, StateId> => ({
587
- ...getActorContext(machine, configuration),
593
+ ...resolveMachineReferences(machine, configuration),
588
594
  state: configuration.values.get(path) as Machine.StateByIdentifier<States, StateId>,
589
595
  containingState: getParentValue(machine, configuration, path) as Machine.ParentStateValue<States, StateId>,
590
596
  ancestors: getParentValues(machine, configuration, path) as Machine.ParentStateValues<States, StateId>,
@@ -679,7 +685,7 @@ const selectAlwaysTransitions = <
679
685
  Machine.AlwaysContext<States, Events, Emits, Machine.StateIdentifier<States>>
680
686
  >,
681
687
  context: {
682
- ...getActorContext(machine, configuration),
688
+ ...resolveMachineReferences(machine, configuration),
683
689
  state: configuration.values.get(path) as Machine.StateByIdentifier<
684
690
  States,
685
691
  Machine.StateIdentifier<States>
@@ -867,7 +873,7 @@ const selectInvocationTransition = <
867
873
  if (transition === undefined) return []
868
874
  const snapshot = snapshotFromConfiguration<States>(machine, configuration)
869
875
  const context = {
870
- ...getActorContext(machine, configuration),
876
+ ...resolveMachineReferences(machine, configuration),
871
877
  state: configuration.values.get(event.path),
872
878
  containingState: getParentValue(machine, configuration, event.path),
873
879
  ancestors: getParentValues(machine, configuration, event.path),
@@ -1107,10 +1113,10 @@ const resolveChoiceTarget = (
1107
1113
  ]),
1108
1114
  outputs: configuration.outputs,
1109
1115
  history: configuration.history,
1110
- ...(configuration.actorScope === undefined ? {} : { actorScope: configuration.actorScope })
1116
+ ...(configuration.machineReferences === undefined ? {} : { machineReferences: configuration.machineReferences })
1111
1117
  }
1112
1118
  const collected = collectTransition(machine, choice.transition, {
1113
- ...getActorContext(machine, provisional),
1119
+ ...resolveMachineReferences(machine, provisional),
1114
1120
  containingState: getParentValue(machine, provisional, node.path),
1115
1121
  ancestors: getParentValues(machine, provisional, node.path),
1116
1122
  event,