@typeonce/effect-machine 0.14.1 → 0.16.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 (74) hide show
  1. package/README.md +99 -48
  2. package/dist/Machine.d.ts +436 -156
  3. package/dist/Machine.d.ts.map +1 -1
  4. package/dist/Machine.js +114 -57
  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/executionPlan.d.ts.map +1 -1
  11. package/dist/internal/machine/executionPlan.js +6 -1
  12. package/dist/internal/machine/executionPlan.js.map +1 -1
  13. package/dist/internal/machine/invocation.d.ts +1 -1
  14. package/dist/internal/machine/invocation.d.ts.map +1 -1
  15. package/dist/internal/machine/invocation.js +25 -3
  16. package/dist/internal/machine/invocation.js.map +1 -1
  17. package/dist/internal/machine/invocationEvent.d.ts +8 -0
  18. package/dist/internal/machine/invocationEvent.d.ts.map +1 -1
  19. package/dist/internal/machine/invocationEvent.js +8 -0
  20. package/dist/internal/machine/invocationEvent.js.map +1 -1
  21. package/dist/internal/machine/machine.d.ts +9 -4
  22. package/dist/internal/machine/machine.d.ts.map +1 -1
  23. package/dist/internal/machine/machine.js +131 -55
  24. package/dist/internal/machine/machine.js.map +1 -1
  25. package/dist/internal/machine/planner.d.ts +7 -0
  26. package/dist/internal/machine/planner.d.ts.map +1 -1
  27. package/dist/internal/machine/planner.js +20 -11
  28. package/dist/internal/machine/planner.js.map +1 -1
  29. package/dist/internal/machine/runtime.d.ts +1 -0
  30. package/dist/internal/machine/runtime.d.ts.map +1 -1
  31. package/dist/internal/machine/runtime.js +25 -16
  32. package/dist/internal/machine/runtime.js.map +1 -1
  33. package/dist/internal/machine/stateDefinition.d.ts +3 -1
  34. package/dist/internal/machine/stateDefinition.d.ts.map +1 -1
  35. package/dist/internal/machine/stateDefinition.js +35 -0
  36. package/dist/internal/machine/stateDefinition.js.map +1 -1
  37. package/dist/internal/machine/topology.d.ts +11 -0
  38. package/dist/internal/machine/topology.d.ts.map +1 -1
  39. package/dist/internal/machine/topology.js +17 -6
  40. package/dist/internal/machine/topology.js.map +1 -1
  41. package/dist/internal/testing/machine/finiteModel.js +1 -1
  42. package/dist/internal/testing/machine/finiteModel.js.map +1 -1
  43. package/dist/internal/testing/machine/transitionCoverage.d.ts.map +1 -1
  44. package/dist/internal/testing/machine/transitionCoverage.js +6 -2
  45. package/dist/internal/testing/machine/transitionCoverage.js.map +1 -1
  46. package/dist/internal/testing/machine/verification.d.ts.map +1 -1
  47. package/dist/internal/testing/machine/verification.js +6 -0
  48. package/dist/internal/testing/machine/verification.js.map +1 -1
  49. package/dist/testing/MachineTest.d.ts +9 -8
  50. package/dist/testing/MachineTest.d.ts.map +1 -1
  51. package/dist/testing/MachineTest.js +7 -7
  52. package/dist/testing/MachineTest.js.map +1 -1
  53. package/dist/unstable/cluster/ClusterMachine.d.ts +1 -1
  54. package/dist/unstable/cluster/ClusterMachine.js +1 -1
  55. package/dist/unstable/reactivity/AtomMachine.d.ts +3 -3
  56. package/dist/unstable/reactivity/AtomMachine.js +3 -3
  57. package/docs/agent-guide.md +207 -88
  58. package/package.json +1 -1
  59. package/src/Machine.ts +871 -256
  60. package/src/internal/machine/activities.ts +7 -0
  61. package/src/internal/machine/executionPlan.ts +6 -1
  62. package/src/internal/machine/invocation.ts +39 -4
  63. package/src/internal/machine/invocationEvent.ts +16 -0
  64. package/src/internal/machine/machine.ts +187 -67
  65. package/src/internal/machine/planner.ts +17 -3
  66. package/src/internal/machine/runtime.ts +61 -25
  67. package/src/internal/machine/stateDefinition.ts +41 -1
  68. package/src/internal/machine/topology.ts +31 -2
  69. package/src/internal/testing/machine/finiteModel.ts +1 -1
  70. package/src/internal/testing/machine/transitionCoverage.ts +6 -2
  71. package/src/internal/testing/machine/verification.ts +11 -0
  72. package/src/testing/MachineTest.ts +9 -7
  73. package/src/unstable/cluster/ClusterMachine.ts +1 -1
  74. package/src/unstable/reactivity/AtomMachine.ts +3 -3
package/src/Machine.ts CHANGED
@@ -53,7 +53,6 @@ declare const MachineTypeId: unique symbol
53
53
  declare const EventConstructionTypeId: unique symbol
54
54
  declare const EmittedEventConstructionTypeId: unique symbol
55
55
  declare const EventProtocolTypeId: unique symbol
56
- declare const TransitionCaseTypeId: unique symbol
57
56
 
58
57
  const ChildMachineLogicTypeId: typeof internal.ChildMachineLogicTypeId = internal.ChildMachineLogicTypeId
59
58
 
@@ -96,7 +95,7 @@ export const isInitialEvent = (u: unknown): u is InitialEvent => hasProperty(u,
96
95
  type IsAny<A> = 0 extends (1 & A) ? true : false
97
96
 
98
97
  /**
99
- * A schema-first machine definition.
98
+ * A schema-first machine implementation.
100
99
  *
101
100
  * **Details**
102
101
  *
@@ -222,12 +221,68 @@ export interface Machine<
222
221
  readonly handlers: Machine.StateConfigs<States, Events, Emits, UnhandledStates, Machine.TagOf<Events[number]>, E, R>
223
222
 
224
223
  /**
225
- * Adds typed state handlers and returns the refined machine definition.
226
- * Successive calls implement the remaining unhandled states while retaining
227
- * accumulated errors, services, final states, and output evidence.
228
- * Event dispatch maps and transition descriptors are captured by value, so
229
- * later mutation of the objects supplied to this call cannot alter the
230
- * resulting machine.
224
+ * Machine-bound equivalent of {@link invoke}. Both forms preserve this
225
+ * machine's public input and parent protocols in invocation callbacks;
226
+ * `Machine.invoke(...)` inside `handle(...)` is the canonical inline form.
227
+ *
228
+ * @since 0.11.0
229
+ */
230
+ readonly invoke: Invoker<States, Events, Emits, InputEvents, ParentEvents>
231
+
232
+ /** @internal */
233
+ readonly initial: (...args: [...Machine.InputArgs<Input>]) => Machine.InitialResult<States, InitialE, InitialR>
234
+ /** @internal */
235
+ readonly initialDefinition: Machine.InitialDefinition
236
+ }
237
+
238
+ /**
239
+ * A schema-first machine definition that can produce independent
240
+ * implementations.
241
+ *
242
+ * **Details**
243
+ *
244
+ * Call `handle` once for each implementation. The returned {@link Machine}
245
+ * does not expose `handle`, so handler configuration cannot be accumulated or
246
+ * replaced through chained calls. Calling `handle` multiple times on the same
247
+ * definition remains supported and creates independent machines.
248
+ *
249
+ * @category models
250
+ * @since 0.15.0
251
+ */
252
+ export interface Definition<
253
+ States extends Machine.StateSchemas,
254
+ Events extends ReadonlyArray<Machine.TaggedSchema>,
255
+ Input extends Schema.Top = typeof Schema.Void,
256
+ InitialE = never,
257
+ InitialR = never,
258
+ FinalStates extends Machine.StateIdentifier<States> = never,
259
+ Output = never,
260
+ Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
261
+ InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events,
262
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
263
+ > extends
264
+ Machine<
265
+ States,
266
+ Events,
267
+ Input,
268
+ Machine.StateIdentifier<States>,
269
+ never,
270
+ never,
271
+ InitialE,
272
+ InitialR,
273
+ FinalStates,
274
+ Output,
275
+ Emits,
276
+ never,
277
+ InputEvents,
278
+ ParentEvents
279
+ >
280
+ {
281
+ /**
282
+ * Adds typed state handlers and returns an independent machine
283
+ * implementation. Event dispatch maps and transition descriptors are
284
+ * captured by value, so later mutation of the supplied objects cannot alter
285
+ * the resulting machine.
231
286
  *
232
287
  * @since 0.4.0
233
288
  */
@@ -236,31 +291,35 @@ export interface Machine<
236
291
  Events,
237
292
  Emits,
238
293
  Input,
239
- UnhandledStates,
240
- E,
241
- R,
294
+ Machine.StateIdentifier<States>,
295
+ never,
296
+ never,
242
297
  InitialE,
243
298
  InitialR,
244
299
  FinalStates,
245
300
  Output,
246
- OutputStates,
301
+ never,
247
302
  InputEvents,
248
303
  ParentEvents
249
304
  >
305
+ }
250
306
 
307
+ /**
308
+ * Namespace containing type-level members associated with {@link Definition}.
309
+ *
310
+ * @category models
311
+ * @since 0.15.0
312
+ */
313
+ export declare namespace Definition {
251
314
  /**
252
- * Preserves invocation inference with this machine's public input and parent
253
- * protocols. Prefer this bound constructor when an invocation source or
254
- * lifecycle handler uses `self` or `parent`.
315
+ * Any schema-first machine definition.
255
316
  *
256
- * @since 0.11.0
317
+ * @category models
318
+ * @since 0.15.0
257
319
  */
258
- readonly invoke: Invoker<States, Events, Emits, InputEvents, ParentEvents>
259
-
260
- /** @internal */
261
- readonly initial: (...args: [...Machine.InputArgs<Input>]) => Machine.InitialResult<States, InitialE, InitialR>
262
- /** @internal */
263
- readonly initialDefinition: Machine.InitialDefinition
320
+ export interface Any extends Machine.Any {
321
+ readonly handle: any
322
+ }
264
323
  }
265
324
 
266
325
  export {
@@ -687,8 +746,12 @@ type ValidateCompoundStateNode<
687
746
  Initial extends ActiveStateKey<Children> | ChoiceStateKey<Children> ? {
688
747
  readonly states: ValidateStateTree<Children, true, Extract<Path, string>>
689
748
  }
690
- : StateDefinitionError<"Compound initial must be one of its direct child keys">
691
- : StateDefinitionError<"Compound states must declare an initial child">
749
+ : StateDefinitionError<
750
+ "Compound initial must be one of its direct child keys",
751
+ Path,
752
+ Extract<Initial, PropertyKey>
753
+ >
754
+ : StateDefinitionError<"Compound states must declare an initial child", Path>
692
755
 
693
756
  type ValidateStateNodeWithoutChildren<Node extends Machine.StateNodeConfig> = "initial" extends keyof Node ?
694
757
  StateDefinitionError<"Atomic states cannot declare an initial child">
@@ -723,7 +786,29 @@ type InvalidDefinedStateTreeInput<States extends Machine.StateSchemas> = [States
723
786
  [Machine.ValidateStateSchemas<States>] ? never
724
787
  : States & Machine.ValidateStateSchemas<States>
725
788
 
726
- interface DefineStates {
789
+ type ReusableStateNodeConfig =
790
+ | Machine.AtomicStateNodeConfig
791
+ | Machine.CompoundStateNodeConfig
792
+ | Machine.ParallelStateNodeConfig
793
+
794
+ type ReusableStateValidation<Node> = Node extends ReusableStateNodeConfig ? ValidateStateNode<Node, false, "state">
795
+ : StateDefinitionError<"Reusable states must be active state nodes", "state">
796
+
797
+ type ValidateDefinedState<Node> = [Node] extends [ReusableStateValidation<Node>] ? []
798
+ : [validation: ReusableStateValidation<Node>]
799
+
800
+ type InvalidDefinedStateInput<Node> = [Node] extends [ReusableStateValidation<Node>] ? never
801
+ : Node & ReusableStateValidation<Node>
802
+
803
+ interface StateConstructor {
804
+ <const Node>(
805
+ node: Node & DefineStateNodeInput<NoInfer<Node>>,
806
+ ..._validation: ValidateDefinedState<NoInfer<Node>>
807
+ ): Node
808
+ <const Node>(node: InvalidDefinedStateInput<Node>): never
809
+ }
810
+
811
+ interface StatesConstructor {
727
812
  <const States extends Machine.StateSchemas>(
728
813
  states: States & DefineStateTreeInput<NoInfer<States>>,
729
814
  ..._validation: ValidateDefinedStates<NoInfer<States>>
@@ -1867,10 +1952,10 @@ export declare namespace Inspection {
1867
1952
  readonly sessionId: string
1868
1953
  readonly owner: Subject
1869
1954
  readonly ownerPath: string
1870
- readonly kind: "Effect" | "Timer"
1955
+ readonly kind: "Effect" | "Stream" | "Timer"
1871
1956
  }
1872
1957
 
1873
- /** Announces an Effect or timer invocation starting. */
1958
+ /** Announces an Effect, Stream, or timer invocation starting. */
1874
1959
  export interface ActivityStarted extends Base {
1875
1960
  readonly _tag: "ActivityStarted"
1876
1961
  readonly activity: Activity
@@ -2410,8 +2495,6 @@ export declare namespace Machine {
2410
2495
  /** @internal */
2411
2496
  readonly handlers: any
2412
2497
  /** @internal */
2413
- readonly handle: any
2414
- /** @internal */
2415
2498
  readonly invoke: any
2416
2499
  /** @internal */
2417
2500
  readonly initial: any
@@ -2882,12 +2965,12 @@ export declare namespace Machine {
2882
2965
  export type StateSchemas = StateTree
2883
2966
 
2884
2967
  /**
2885
- * Builder for initial state snapshots generated by `defineStates`.
2968
+ * Builder for initial state snapshots generated by `states`.
2886
2969
  *
2887
2970
  * **When to use**
2888
2971
  *
2889
2972
  * Use when you need the type of the `initial` property returned by
2890
- * `defineStates` or want to expose an initial snapshot builder from a helper.
2973
+ * `states` or want to expose an initial snapshot builder from a helper.
2891
2974
  *
2892
2975
  * **Details**
2893
2976
  *
@@ -2900,7 +2983,7 @@ export declare namespace Machine {
2900
2983
  type InitialBuilder<States extends StateSchemas> = InitialSnapshotBuilderWithPrefix<States>
2901
2984
 
2902
2985
  /**
2903
- * State definitions and snapshot access helpers returned by `defineStates`.
2986
+ * State definitions and snapshot access helpers returned by `states`.
2904
2987
  *
2905
2988
  * **Details**
2906
2989
  *
@@ -2912,9 +2995,19 @@ export declare namespace Machine {
2912
2995
  * @since 0.4.0
2913
2996
  */
2914
2997
  export interface DefinedStates<States extends StateSchemas> {
2915
- /** Original state tree supplied to {@link defineStates}. */
2998
+ /** Captured state tree supplied to {@link states}. */
2916
2999
  readonly states: States
2917
3000
 
3001
+ /**
3002
+ * Checks and preserves one active state path from this definition.
3003
+ *
3004
+ * This is useful for named path helpers, including finite template-literal
3005
+ * families. Every member of a path union must exist in the state tree.
3006
+ *
3007
+ * @since 0.15.0
3008
+ */
3009
+ readonly path: <const Path extends StateIdentifier<States>>(path: Path) => Path
3010
+
2918
3011
  /**
2919
3012
  * Returns the decoded value for an active state path. The supplied
2920
3013
  * snapshot may be a complete root snapshot or a snapshot previously
@@ -3158,7 +3251,7 @@ export declare namespace Machine {
3158
3251
  | {
3159
3252
  readonly type: "invoke"
3160
3253
  readonly id: string
3161
- readonly outcome: "done" | "failure" | "snapshot"
3254
+ readonly outcome: "element" | "done" | "failure" | "snapshot"
3162
3255
  }
3163
3256
 
3164
3257
  /** Static topology selected by a transition branch. */
@@ -3180,16 +3273,12 @@ export declare namespace Machine {
3180
3273
  readonly selection: TransitionTargetSelection<Path | undefined>
3181
3274
  }
3182
3275
  | {
3183
- readonly type: "case"
3276
+ readonly type: "branch"
3277
+ readonly key: string
3184
3278
  readonly title: string
3185
3279
  readonly target: Path | undefined
3186
3280
  readonly selection: TransitionTargetSelection<Path | undefined>
3187
3281
  }
3188
- | {
3189
- readonly type: "otherwise"
3190
- readonly target: Path | undefined
3191
- readonly selection: TransitionTargetSelection<Path | undefined>
3192
- }
3193
3282
 
3194
3283
  /** The statically selected root entry for machine startup. */
3195
3284
  export interface InitialDefinition<Path extends string = string> {
@@ -3202,8 +3291,8 @@ export declare namespace Machine {
3202
3291
  *
3203
3292
  * **Details**
3204
3293
  *
3205
- * Every branch exposes its selected target without executing its predicate
3206
- * or resolver. A compound local or branch target covers its descendants;
3294
+ * Every branch exposes its selected target without executing its resolver.
3295
+ * A compound local or branch target covers its descendants;
3207
3296
  * `undefined` identifies an explicitly targetless branch.
3208
3297
  *
3209
3298
  * @category models
@@ -3249,6 +3338,8 @@ export declare namespace Machine {
3249
3338
  readonly reenter: boolean
3250
3339
  /** Zero-based index of the selected static branch. */
3251
3340
  readonly branchIndex: number
3341
+ /** Stable key of a named branch, or `undefined` for a direct transition. */
3342
+ readonly branchKey: string | undefined
3252
3343
  /** Path returned by the handler, including a choice or history pseudo-state. */
3253
3344
  readonly target: TargetPath | undefined
3254
3345
  /**
@@ -4557,6 +4648,25 @@ export declare namespace Machine {
4557
4648
  readonly output: Output
4558
4649
  }
4559
4650
 
4651
+ /** Context passed to a Stream invocation's element transition. */
4652
+ export interface InvokeElementContext<
4653
+ States extends StateSchemas,
4654
+ Events extends ReadonlyArray<TaggedSchema>,
4655
+ Emits extends ReadonlyArray<TaggedSchema>,
4656
+ StateId extends StateIdentifier<States>,
4657
+ Element,
4658
+ InputEvents extends ReadonlyArray<TaggedSchema> = Events,
4659
+ ParentEvents extends ReadonlyArray<TaggedSchema> = readonly []
4660
+ > extends MachineReferences<InputEvents, ParentEvents> {
4661
+ readonly id: string
4662
+ readonly state: StateByIdentifier<States, StateId>
4663
+ readonly containingState: ParentStateValue<States, StateId>
4664
+ readonly ancestors: ParentStateValues<States, StateId>
4665
+ readonly snapshot: Snapshot<States>
4666
+ readonly target: TargetBuilder<States, StateId>
4667
+ readonly element: Element
4668
+ }
4669
+
4560
4670
  /** Context passed to an invocation typed-failure transition. */
4561
4671
  export interface InvokeFailureContext<
4562
4672
  States extends StateSchemas,
@@ -4837,14 +4947,9 @@ export declare namespace Machine {
4837
4947
  * @category utility types
4838
4948
  * @since 0.4.0
4839
4949
  */
4840
- export type EventTransitionReturn<Transition> =
4841
- | (Transition extends { readonly resolve?: infer Resolve } ?
4842
- NonNullable<Resolve> extends (...args: any) => infer Ret ? Ret : never
4843
- : never)
4844
- | (Transition extends { readonly cases: infer Cases extends ReadonlyArray<unknown> } ?
4845
- EventTransitionReturn<Cases[number]>
4846
- : never)
4847
- | (Transition extends { readonly otherwise: infer Otherwise } ? EventTransitionReturn<Otherwise> : never)
4950
+ export type EventTransitionReturn<Transition> = Transition extends { readonly resolve?: infer Resolve } ?
4951
+ NonNullable<Resolve> extends (...args: any) => infer Ret ? Ret : never
4952
+ : never
4848
4953
  /**
4849
4954
  * Extracts the return value from a state's event handlers.
4850
4955
  *
@@ -4909,6 +5014,15 @@ export declare namespace Machine {
4909
5014
  Effect.Success<Fx>
4910
5015
  >
4911
5016
  : never
5017
+ : Invoke extends { readonly stream: infer Source } ?
5018
+ InvokeFactoryResult<Source> extends infer SourceStream extends Stream.Stream<any, any, any> ? Logic<
5019
+ void,
5020
+ never,
5021
+ Stream.Error<SourceStream>,
5022
+ Stream.Services<SourceStream>,
5023
+ void
5024
+ >
5025
+ : never
4912
5026
  : Invoke extends { readonly after: unknown } ? Logic<void, never, never, never, void>
4913
5027
  : Invoke extends { readonly logic: infer Source } ? InvokeResolvedSource<Source>
4914
5028
  : Invoke extends { readonly child: infer Child } ? ChildMachineLogic<Child>
@@ -4980,6 +5094,7 @@ export declare namespace Machine {
4980
5094
  export type InvokeOutcomeReturn<Invoke> = Invoke extends unknown ?
4981
5095
  | (Invoke extends { readonly onDone?: infer Handler } ? EventTransitionReturn<NonNullable<Handler>> : never)
4982
5096
  | (Invoke extends { readonly onFailure?: infer Handler } ? EventTransitionReturn<NonNullable<Handler>> : never)
5097
+ | (Invoke extends { readonly onElement?: infer Handler } ? EventTransitionReturn<NonNullable<Handler>> : never)
4983
5098
  | (Invoke extends { readonly onSnapshot?: infer Handler } ? EventTransitionReturn<NonNullable<Handler>> : never)
4984
5099
  : never
4985
5100
  /**
@@ -5050,8 +5165,6 @@ export declare namespace Machine {
5050
5165
  | Effect.Services<ChoiceReturn<Config>>
5051
5166
  | InvokeRequirements<Config>
5052
5167
 
5053
- type TransitionWhenContext<Context> = Omit<Context, "target">
5054
-
5055
5168
  /** Type evidence retained by {@link transition} without affecting runtime data. */
5056
5169
  export interface TransitionTyped<
5057
5170
  States extends StateSchemas,
@@ -5082,11 +5195,40 @@ export declare namespace Machine {
5082
5195
  Context,
5083
5196
  Reenter extends boolean = false
5084
5197
  > =
5085
- & (TransitionTyped<States, Events, Emits, StateId, Context, Reenter> | TargetlessTransitionTyped)
5198
+ & (
5199
+ | TransitionTyped<States, Events, Emits, StateId, Context, Reenter>
5200
+ | TargetlessTransitionTyped
5201
+ | TargetlessTransitionInput<Events, Emits, Context>
5202
+ )
5086
5203
  & {
5087
5204
  readonly reenter?: [Reenter] extends [true] ? boolean : never
5088
5205
  }
5089
5206
 
5207
+ /** Direct shorthand for a non-reentering targetless transition. */
5208
+ // Keep the context generic so omitting `target` is deferred until a resolver
5209
+ // is actually authored instead of expanding every TransitionConfig eagerly.
5210
+ interface TargetlessTransitionResolver<
5211
+ Events extends ReadonlyArray<TaggedSchema>,
5212
+ Emits extends ReadonlyArray<TaggedSchema>,
5213
+ Context
5214
+ > {
5215
+ <ResolvedContext extends Omit<Context, "target">>(
5216
+ context: ResolvedContext,
5217
+ enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>
5218
+ ): undefined
5219
+ }
5220
+
5221
+ export type TargetlessTransitionInput<
5222
+ Events extends ReadonlyArray<TaggedSchema>,
5223
+ Emits extends ReadonlyArray<TaggedSchema>,
5224
+ Context
5225
+ > = {
5226
+ readonly target: TargetlessSelector
5227
+ readonly resolve?: TargetlessTransitionResolver<Events, Emits, Context>
5228
+ readonly branches?: never
5229
+ readonly reenter?: never
5230
+ }
5231
+
5090
5232
  export type SelectionBuilder<Selection> = Selection extends TargetSelection<infer Builder, any, any> ? Builder : never
5091
5233
  export type SelectionKind<Selection> = Selection extends TargetSelection<any, any, infer Kind> ? Kind : never
5092
5234
  export type SelectionPath<Selection> = Selection extends TargetSelection<any, infer Path, any> ? Path : never
@@ -5099,21 +5241,18 @@ export declare namespace Machine {
5099
5241
 
5100
5242
  export type TransitionResolveContext<
5101
5243
  Context,
5102
- Selection,
5103
- Match = never
5244
+ Selection
5104
5245
  > =
5105
5246
  & Omit<Context, "target">
5106
- & ([Match] extends [never] ? {} : { readonly match: Match })
5107
5247
  & (SelectionKind<Selection> extends "none" ? {} : { readonly target: SelectionBuilder<Selection> })
5108
5248
 
5109
5249
  export type TransitionResolver<
5110
5250
  Events extends ReadonlyArray<TaggedSchema>,
5111
5251
  Emits extends ReadonlyArray<TaggedSchema>,
5112
5252
  Context,
5113
- Selection,
5114
- Match = never
5253
+ Selection
5115
5254
  > = (
5116
- context: TransitionResolveContext<Context, Selection, Match>,
5255
+ context: TransitionResolveContext<Context, Selection>,
5117
5256
  enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>
5118
5257
  ) => SelectionKind<Selection> extends "none" ? undefined : SelectedTargetResult<Selection> | undefined
5119
5258
 
@@ -5128,51 +5267,95 @@ export declare namespace Machine {
5128
5267
  > = {
5129
5268
  readonly target: (to: TargetSelector<States, StateId>) => Selection
5130
5269
  readonly resolve?: TransitionResolver<Events, Emits, Context, Selection>
5131
- readonly cases?: never
5132
- readonly otherwise?: never
5270
+ readonly branches?: never
5133
5271
  readonly reenter?: Reenter
5134
5272
  }
5135
5273
 
5136
- export type TransitionCaseInput<
5137
- States extends StateSchemas,
5274
+ /** One named destination declared by a branching transition. */
5275
+ export interface TransitionBranchInput<
5276
+ Selection extends TargetSelection<any, any, any> = TargetSelection<any, any, any>
5277
+ > {
5278
+ readonly target: Selection
5279
+ readonly title?: string
5280
+ }
5281
+
5282
+ /** Opaque evidence that a branching resolver selected one declared branch. */
5283
+ export interface SelectedBranch<out Key extends string, out Result> {
5284
+ readonly [Topology.SelectedBranchTypeId]: {
5285
+ readonly key: Types.Covariant<Key>
5286
+ readonly result: Types.Covariant<Result>
5287
+ }
5288
+ }
5289
+
5290
+ type SelectedBranchCallable<Callable, Key extends string> = Callable extends {
5291
+ (...args: infer Arguments1): infer Result1
5292
+ (...args: infer Arguments2): infer Result2
5293
+ } ? {
5294
+ (...args: Arguments1): SelectedBranch<Key, Result1>
5295
+ (...args: Arguments2): SelectedBranch<Key, Result2>
5296
+ }
5297
+ : Callable extends (...args: infer Arguments) => infer Result ? (...args: Arguments) => SelectedBranch<Key, Result>
5298
+ : {}
5299
+
5300
+ type SelectedBranchBuilderProperties<Builder, Key extends string> = {
5301
+ readonly [Property in keyof Builder]: Builder[Property] extends (...args: any) => any ?
5302
+ SelectedBranchCallable<Builder[Property], Key>
5303
+ : Builder[Property]
5304
+ }
5305
+
5306
+ /** Target-specific builder that brands every construction with its branch key. */
5307
+ export type SelectedBranchBuilder<Builder, Key extends string> =
5308
+ & SelectedBranchCallable<Builder, Key>
5309
+ & SelectedBranchBuilderProperties<Builder, Key>
5310
+
5311
+ export type BranchSelectors<Branches extends Readonly<Record<string, TransitionBranchInput>>> = {
5312
+ readonly [Key in Extract<keyof Branches, string>]: SelectedBranchBuilder<
5313
+ SelectionBuilder<Branches[Key]["target"]>,
5314
+ Key
5315
+ >
5316
+ }
5317
+
5318
+ export type BranchSelectionResult<Branches extends Readonly<Record<string, TransitionBranchInput>>> = {
5319
+ readonly [Key in Extract<keyof Branches, string>]: SelectedBranch<
5320
+ Key,
5321
+ SelectedTargetResult<Branches[Key]["target"]>
5322
+ >
5323
+ }[Extract<keyof Branches, string>]
5324
+
5325
+ export type TransitionBranchesResolveContext<
5326
+ Context,
5327
+ Branches extends Readonly<Record<string, TransitionBranchInput>>
5328
+ > = Omit<Context, "target"> & { readonly select: BranchSelectors<Branches> }
5329
+
5330
+ export type TransitionBranchesResolver<
5138
5331
  Events extends ReadonlyArray<TaggedSchema>,
5139
5332
  Emits extends ReadonlyArray<TaggedSchema>,
5140
- StateId extends StateNodeIdentifier<States>,
5141
5333
  Context,
5142
- Selection extends TargetSelection<any, any, any>,
5143
- Match
5144
- > = {
5145
- readonly title: string
5146
- readonly when: (context: TransitionWhenContext<Context>) => Option.Option<Match>
5147
- readonly target: (to: TargetSelector<States, StateId>) => Selection
5148
- readonly resolve?: TransitionResolver<Events, Emits, Context, Selection, NoInfer<Match>>
5149
- readonly cases?: never
5150
- readonly otherwise?: never
5151
- readonly reenter?: never
5152
- }
5334
+ Branches extends Readonly<Record<string, TransitionBranchInput>>
5335
+ > = (
5336
+ context: TransitionBranchesResolveContext<Context, Branches>,
5337
+ enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>
5338
+ ) => BranchSelectionResult<Branches>
5153
5339
 
5154
- export type TransitionConditionalInput<
5340
+ export type TransitionBranchesInput<
5155
5341
  States extends StateSchemas,
5156
5342
  Events extends ReadonlyArray<TaggedSchema>,
5157
5343
  Emits extends ReadonlyArray<TaggedSchema>,
5158
5344
  StateId extends StateNodeIdentifier<States>,
5159
5345
  Context,
5160
5346
  Reenter extends boolean,
5161
- Cases extends readonly [TransitionCaseTyped, ...ReadonlyArray<TransitionCaseTyped>],
5162
- OtherwiseSelection extends TargetSelection<any, any, any>
5347
+ Branches extends Readonly<Record<string, TransitionBranchInput>>
5163
5348
  > = {
5164
5349
  readonly target?: never
5165
- readonly resolve?: never
5166
- readonly cases: (branch: TransitionCaseConstructor<States, Events, Emits, StateId, Context>) => Cases
5167
- readonly otherwise: TransitionDirectInput<
5168
- States,
5169
- Events,
5170
- Emits,
5171
- StateId,
5172
- Context,
5173
- never,
5174
- OtherwiseSelection
5175
- >
5350
+ /**
5351
+ * Declares every possible destination under a stable semantic key.
5352
+ *
5353
+ * Branches are captured once in ECMAScript property order. Array-index
5354
+ * keys are rejected so reordering ordinary named properties affects only
5355
+ * presentation order; the key remains the testing and inspection identity.
5356
+ */
5357
+ readonly branches: (to: TargetSelector<States, StateId>) => Branches
5358
+ readonly resolve: TransitionBranchesResolver<Events, Emits, Context, Branches>
5176
5359
  readonly reenter?: Reenter
5177
5360
  }
5178
5361
 
@@ -5223,12 +5406,29 @@ export declare namespace Machine {
5223
5406
  readonly effect: (
5224
5407
  context: InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
5225
5408
  ) => Effect.Effect<any, any, any>
5409
+ readonly stream?: never
5226
5410
  readonly after?: never
5227
5411
  readonly logic?: never
5228
5412
  readonly child?: never
5229
5413
  readonly address?: never
5230
5414
  readonly onDone?: unknown
5231
5415
  readonly onFailure?: unknown
5416
+ readonly onElement?: never
5417
+ readonly onSnapshot?: never
5418
+ }
5419
+ | {
5420
+ readonly id: string
5421
+ readonly stream: (
5422
+ context: InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
5423
+ ) => Stream.Stream<any, any, any>
5424
+ readonly effect?: never
5425
+ readonly after?: never
5426
+ readonly logic?: never
5427
+ readonly child?: never
5428
+ readonly address?: never
5429
+ readonly onElement?: unknown
5430
+ readonly onDone: unknown
5431
+ readonly onFailure?: unknown
5232
5432
  readonly onSnapshot?: never
5233
5433
  }
5234
5434
  | {
@@ -5238,11 +5438,13 @@ export declare namespace Machine {
5238
5438
  InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
5239
5439
  >
5240
5440
  readonly effect?: never
5441
+ readonly stream?: never
5241
5442
  readonly logic?: never
5242
5443
  readonly child?: never
5243
5444
  readonly address?: never
5244
5445
  readonly onDone: unknown
5245
5446
  readonly onFailure?: never
5447
+ readonly onElement?: never
5246
5448
  readonly onSnapshot?: never
5247
5449
  }
5248
5450
  | {
@@ -5253,10 +5455,12 @@ export declare namespace Machine {
5253
5455
  InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
5254
5456
  >
5255
5457
  readonly effect?: never
5458
+ readonly stream?: never
5256
5459
  readonly after?: never
5257
5460
  readonly child?: never
5258
5461
  readonly onDone?: unknown
5259
5462
  readonly onFailure?: unknown
5463
+ readonly onElement?: never
5260
5464
  readonly onSnapshot?: unknown
5261
5465
  }
5262
5466
  | {
@@ -5268,10 +5472,12 @@ export declare namespace Machine {
5268
5472
  readonly id?: never
5269
5473
  readonly address?: never
5270
5474
  readonly effect?: never
5475
+ readonly stream?: never
5271
5476
  readonly after?: never
5272
5477
  readonly logic?: never
5273
5478
  readonly onDone?: unknown
5274
5479
  readonly onFailure?: unknown
5480
+ readonly onElement?: never
5275
5481
  readonly onSnapshot?: unknown
5276
5482
  }
5277
5483
  )
@@ -5306,6 +5512,11 @@ export declare namespace Machine {
5306
5512
  : { readonly onFailure?: never }
5307
5513
  : never
5308
5514
 
5515
+ export type InvokeElementRequirement<Value, Handler> = InvokeHandlerRequirement<Value, Handler> extends
5516
+ infer Requirement ? Requirement extends { readonly handler: infer Required } ? { readonly onElement: Required }
5517
+ : { readonly onElement?: never }
5518
+ : never
5519
+
5309
5520
  export type TimerInvokeArgs<
5310
5521
  States extends StateSchemas,
5311
5522
  Events extends ReadonlyArray<TaggedSchema>,
@@ -5320,10 +5531,12 @@ export declare namespace Machine {
5320
5531
  InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
5321
5532
  >
5322
5533
  readonly effect?: never
5534
+ readonly stream?: never
5323
5535
  readonly logic?: never
5324
5536
  readonly child?: never
5325
5537
  readonly address?: never
5326
5538
  readonly onFailure?: never
5539
+ readonly onElement?: never
5327
5540
  readonly onSnapshot?: never
5328
5541
  readonly onDone: InvokeTransition<
5329
5542
  States,
@@ -5355,8 +5568,10 @@ export declare namespace Machine {
5355
5568
  readonly address: Address & ChildAddress.Compatibility<Address, ChildEvent>
5356
5569
  readonly logic: Source
5357
5570
  readonly effect?: never
5571
+ readonly stream?: never
5358
5572
  readonly after?: never
5359
5573
  readonly child?: never
5574
+ readonly onElement?: never
5360
5575
  readonly onSnapshot?: InvokeTransition<
5361
5576
  States,
5362
5577
  Events,
@@ -5418,8 +5633,10 @@ export declare namespace Machine {
5418
5633
  readonly id?: never
5419
5634
  readonly address?: never
5420
5635
  readonly effect?: never
5636
+ readonly stream?: never
5421
5637
  readonly after?: never
5422
5638
  readonly logic?: never
5639
+ readonly onElement?: never
5423
5640
  readonly onSnapshot?: InvokeTransition<
5424
5641
  States,
5425
5642
  Events,
@@ -5533,6 +5750,55 @@ export declare namespace Machine {
5533
5750
  >
5534
5751
  & { readonly onSnapshot?: never }
5535
5752
  : never
5753
+ : Raw extends { readonly stream: infer Source } ?
5754
+ InvokeFactoryResult<Source> extends infer SourceStream extends Stream.Stream<any, any, any> ?
5755
+ & InvokeElementRequirement<
5756
+ Stream.Success<SourceStream>,
5757
+ InvokeTransition<
5758
+ States,
5759
+ Events,
5760
+ Emits,
5761
+ StateId,
5762
+ InvokeElementContext<
5763
+ States,
5764
+ Events,
5765
+ Emits,
5766
+ StateId,
5767
+ Stream.Success<SourceStream>,
5768
+ InputEvents,
5769
+ ParentEvents
5770
+ >
5771
+ >
5772
+ >
5773
+ & {
5774
+ readonly onDone: InvokeTransition<
5775
+ States,
5776
+ Events,
5777
+ Emits,
5778
+ StateId,
5779
+ InvokeDoneContext<States, Events, Emits, StateId, void, InputEvents, ParentEvents>
5780
+ >
5781
+ }
5782
+ & InvokeFailureRequirement<
5783
+ Stream.Error<SourceStream>,
5784
+ InvokeTransition<
5785
+ States,
5786
+ Events,
5787
+ Emits,
5788
+ StateId,
5789
+ InvokeFailureContext<
5790
+ States,
5791
+ Events,
5792
+ Emits,
5793
+ StateId,
5794
+ Stream.Error<SourceStream>,
5795
+ InputEvents,
5796
+ ParentEvents
5797
+ >
5798
+ >
5799
+ >
5800
+ & { readonly onSnapshot?: never }
5801
+ : never
5536
5802
  : Raw extends { readonly after: unknown } ? {
5537
5803
  readonly onDone: InvokeTransition<
5538
5804
  States,
@@ -6280,6 +6546,7 @@ export declare namespace Machine {
6280
6546
 
6281
6547
  type TransitionResultInitialTargetPath<Result> = IsAny<Result> extends true ? never
6282
6548
  : Result extends Effect.Effect<infer Success, any, any> ? TransitionResultInitialTargetPath<Success>
6549
+ : Result extends SelectedBranch<any, infer Selected> ? TransitionResultInitialTargetPath<Selected>
6283
6550
  : Result extends StateConstruction<infer Constructed> ? TransitionResultInitialTargetPath<Constructed>
6284
6551
  : Result extends {
6285
6552
  readonly [Topology.InitialTargetTypeId]: typeof Topology.InitialTargetTypeId
@@ -6827,6 +7094,16 @@ export declare namespace Machine {
6827
7094
  >
6828
7095
  }
6829
7096
 
7097
+ /**
7098
+ * Extracts the complete logical snapshot represented by a state definition.
7099
+ *
7100
+ * @category utility types
7101
+ * @since 0.15.0
7102
+ */
7103
+ export type Snapshot<Defined extends Machine.DefinedStates<any>> = Defined extends Machine.DefinedStates<infer States>
7104
+ ? Machine.Snapshot<States>
7105
+ : never
7106
+
6830
7107
  /**
6831
7108
  * Returns `true` if a value is a `Machine`.
6832
7109
  *
@@ -6877,7 +7154,44 @@ export const isFinal: <
6877
7154
  ) => state is Machine.SnapshotContainingFinal<States, FinalStates> = internal.isFinal as any
6878
7155
 
6879
7156
  /**
6880
- * Defines a state tree while preserving literal state paths.
7157
+ * Defines one reusable active state while preserving its exact child topology.
7158
+ *
7159
+ * Prefer declaring state nodes inline in {@link states}. Use this constructor
7160
+ * only when the same state definition is mounted more than once.
7161
+ * Tagged schemas are already reusable and do not need this constructor.
7162
+ *
7163
+ * **Example** (Repeated compound state)
7164
+ *
7165
+ * ```ts
7166
+ * import { Schema } from "effect"
7167
+ * import { Machine } from "@typeonce/effect-machine"
7168
+ *
7169
+ * const TradingState = Schema.TaggedUnion({
7170
+ * InSession: {},
7171
+ * Applying: {}
7172
+ * })
7173
+ * const TradingSlot = Machine.state({
7174
+ * initial: "Idle",
7175
+ * states: {
7176
+ * Idle: {},
7177
+ * InSession: TradingState.cases.InSession,
7178
+ * Applying: TradingState.cases.Applying
7179
+ * }
7180
+ * })
7181
+ *
7182
+ * const States = Machine.states({
7183
+ * slot1: TradingSlot,
7184
+ * slot2: TradingSlot
7185
+ * })
7186
+ * ```
7187
+ *
7188
+ * @category constructors
7189
+ * @since 0.15.0
7190
+ */
7191
+ export const state: StateConstructor = internal.state as StateConstructor
7192
+
7193
+ /**
7194
+ * Defines the complete state tree while preserving literal state paths.
6881
7195
  *
6882
7196
  * **When to use**
6883
7197
  *
@@ -6886,7 +7200,8 @@ export const isFinal: <
6886
7200
  *
6887
7201
  * **Details**
6888
7202
  *
6889
- * The returned `states` property is the same object passed to `defineStates`.
7203
+ * The returned `states` property is an immutable structural capture of the
7204
+ * supplied tree.
6890
7205
  * `Machine.make` derives its initial target selector from that tree and
6891
7206
  * enforces compound and parallel initial-state rules. Active nodes may omit
6892
7207
  * `schema` when they own no value and still participate fully in targeting,
@@ -6900,7 +7215,7 @@ export const isFinal: <
6900
7215
  *
6901
7216
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
6902
7217
  *
6903
- * const States = Machine.defineStates({ idle: Idle })
7218
+ * const States = Machine.states({ idle: Idle })
6904
7219
  *
6905
7220
  * Machine.make({
6906
7221
  * states: States.states,
@@ -6915,7 +7230,7 @@ export const isFinal: <
6915
7230
  * @category constructors
6916
7231
  * @since 0.4.0
6917
7232
  */
6918
- export const defineStates: DefineStates = internal.defineStates
7233
+ export const states: StatesConstructor = internal.states
6919
7234
 
6920
7235
  type InitialDirectInput<
6921
7236
  States extends Machine.StateSchemas,
@@ -6967,19 +7282,15 @@ type MakeResult<
6967
7282
  InitialR,
6968
7283
  InternalEvents extends ReadonlyArray<Machine.TaggedSchema>,
6969
7284
  ParentEvents extends ReadonlyArray<Machine.TaggedSchema>
6970
- > = Machine<
7285
+ > = Definition<
6971
7286
  States,
6972
7287
  readonly [...InputEvents, ...InternalEvents],
6973
7288
  Input,
6974
- Machine.StateIdentifier<States>,
6975
- never,
6976
- never,
6977
7289
  InitialE,
6978
7290
  InitialR,
6979
7291
  Machine.FinalStateFromDefinition<States>,
6980
7292
  Machine.TerminalOutput<States>,
6981
7293
  Emits,
6982
- never,
6983
7294
  InputEvents,
6984
7295
  ParentEvents
6985
7296
  >
@@ -7028,7 +7339,7 @@ interface Make {
7028
7339
  * State and event schemas provide runtime boundary validation while their
7029
7340
  * decoded types drive handler, state, event, target, error, and service
7030
7341
  * inference. State-tree validation is applied whether `states` comes from
7031
- * `defineStates` or is passed inline. Call `handle` on the returned definition
7342
+ * `states` or is passed inline. Call `handle` on the returned definition
7032
7343
  * to implement state behavior with ordinary TypeScript control flow.
7033
7344
  *
7034
7345
  * `Machine.events` defines the public input protocol. `Machine.internalEvents`
@@ -7053,7 +7364,7 @@ interface Make {
7053
7364
  * by: Schema.Number
7054
7365
  * }) {}
7055
7366
  *
7056
- * const States = Machine.defineStates({ Count })
7367
+ * const States = Machine.states({ Count })
7057
7368
  * const Events = Machine.events(Increment)
7058
7369
  *
7059
7370
  * const counter = Machine.make({
@@ -7076,7 +7387,7 @@ interface Make {
7076
7387
  * })
7077
7388
  * ```
7078
7389
  *
7079
- * @see {@link defineStates} for typed state-tree helpers.
7390
+ * @see {@link states} for typed state-tree helpers.
7080
7391
  * @category constructors
7081
7392
  * @since 0.4.0
7082
7393
  */
@@ -7104,9 +7415,14 @@ export type EventOf<Protocol extends Machine.EventProtocol.Any> = Machine.EventO
7104
7415
  * **Example**
7105
7416
  *
7106
7417
  * ```ts
7107
- * const Events = Machine.events(Increment, Reset)
7108
- * const machine = Machine.make({ events: Events, ... })
7109
- * yield* ref.send(Events.Increment({ by: 1 }))
7418
+ * export const Event = Machine.events(
7419
+ * Schema.TaggedUnion({
7420
+ * Increment: { by: Schema.Number },
7421
+ * Reset: {}
7422
+ * })
7423
+ * )
7424
+ * const machine = Machine.make({ events: Event, ... })
7425
+ * yield* ref.send(Event.Increment({ by: 1 }))
7110
7426
  * ```
7111
7427
  *
7112
7428
  * @category constructors
@@ -7132,11 +7448,16 @@ export const events: {
7132
7448
  * **Example**
7133
7449
  *
7134
7450
  * ```ts
7135
- * const InternalEvents = Machine.internalEvents(Loaded, Failed)
7136
- * const machine = Machine.make({ internalEvents: InternalEvents, ... })
7451
+ * const Internal = Machine.internalEvents(
7452
+ * Schema.TaggedUnion({
7453
+ * Loaded: { value: Schema.String },
7454
+ * Failed: { message: Schema.String }
7455
+ * })
7456
+ * )
7457
+ * const machine = Machine.make({ internalEvents: Internal, ... })
7137
7458
  *
7138
7459
  * // Inside a transition callback:
7139
- * enqueue.raise(InternalEvents.Loaded({ value }))
7460
+ * enqueue.raise(Internal.Loaded({ value }))
7140
7461
  * ```
7141
7462
  *
7142
7463
  * @category constructors
@@ -7157,6 +7478,17 @@ export const internalEvents: {
7157
7478
  * implicitly to a parent machine. Observe them through `MachineRef.emissions` or
7158
7479
  * the AtomMachine emission stream adapters.
7159
7480
  *
7481
+ * **Example**
7482
+ *
7483
+ * ```ts
7484
+ * const Emitted = Machine.emittedEvents(
7485
+ * Schema.TaggedUnion({
7486
+ * Saved: { id: Schema.String }
7487
+ * })
7488
+ * )
7489
+ * const machine = Machine.make({ emittedEvents: Emitted, ... })
7490
+ * ```
7491
+ *
7160
7492
  * @category constructors
7161
7493
  * @since 0.10.0
7162
7494
  */
@@ -7199,7 +7531,7 @@ export const emittedEvents: {
7199
7531
  * import { Machine } from "@typeonce/effect-machine"
7200
7532
  *
7201
7533
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
7202
- * const States = Machine.defineStates({ Idle })
7534
+ * const States = Machine.states({ Idle })
7203
7535
  * const machine = Machine.make({
7204
7536
  * states: States.states,
7205
7537
  * events: Machine.events(),
@@ -7284,7 +7616,7 @@ export const encodeSnapshot: <
7284
7616
  * import { Machine } from "@typeonce/effect-machine"
7285
7617
  *
7286
7618
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
7287
- * const States = Machine.defineStates({ Idle })
7619
+ * const States = Machine.states({ Idle })
7288
7620
  * const machine = Machine.make({
7289
7621
  * states: States.states,
7290
7622
  * events: Machine.events(),
@@ -7348,17 +7680,21 @@ type EffectInvokeSource<
7348
7680
  States extends Machine.StateSchemas,
7349
7681
  Events extends ReadonlyArray<Machine.TaggedSchema>,
7350
7682
  Emits extends ReadonlyArray<Machine.TaggedSchema>,
7683
+ InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
7684
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>,
7351
7685
  StateId extends Machine.StateIdentifier<States>,
7352
7686
  Source extends (
7353
- context: Machine.InvokeContext<States, Events, Emits, StateId, readonly [], readonly []>
7687
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
7354
7688
  ) => Effect.Effect<unknown, unknown, unknown>
7355
7689
  > = {
7356
7690
  readonly id: InvokeLifecycleId
7357
7691
  readonly effect: Source
7692
+ readonly stream?: never
7358
7693
  readonly after?: never
7359
7694
  readonly logic?: never
7360
7695
  readonly child?: never
7361
7696
  readonly address?: never
7697
+ readonly onElement?: never
7362
7698
  readonly onSnapshot?: never
7363
7699
  }
7364
7700
 
@@ -7366,6 +7702,8 @@ type EffectDoneHandler<
7366
7702
  States extends Machine.StateSchemas,
7367
7703
  Events extends ReadonlyArray<Machine.TaggedSchema>,
7368
7704
  Emits extends ReadonlyArray<Machine.TaggedSchema>,
7705
+ InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
7706
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>,
7369
7707
  StateId extends Machine.StateIdentifier<States>,
7370
7708
  Source extends (...args: ReadonlyArray<never>) => Effect.Effect<unknown, unknown, unknown>
7371
7709
  > = Machine.InvokeTransition<
@@ -7379,8 +7717,8 @@ type EffectDoneHandler<
7379
7717
  Emits,
7380
7718
  StateId,
7381
7719
  Effect.Success<ReturnType<NoInfer<Source>>>,
7382
- readonly [],
7383
- readonly []
7720
+ InputEvents,
7721
+ ParentEvents
7384
7722
  >
7385
7723
  >
7386
7724
 
@@ -7388,6 +7726,8 @@ type EffectFailureHandler<
7388
7726
  States extends Machine.StateSchemas,
7389
7727
  Events extends ReadonlyArray<Machine.TaggedSchema>,
7390
7728
  Emits extends ReadonlyArray<Machine.TaggedSchema>,
7729
+ InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
7730
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>,
7391
7731
  StateId extends Machine.StateIdentifier<States>,
7392
7732
  Source extends (...args: ReadonlyArray<never>) => Effect.Effect<unknown, unknown, unknown>
7393
7733
  > = Machine.InvokeTransition<
@@ -7401,8 +7741,8 @@ type EffectFailureHandler<
7401
7741
  Emits,
7402
7742
  StateId,
7403
7743
  Effect.Error<ReturnType<NoInfer<Source>>>,
7404
- readonly [],
7405
- readonly []
7744
+ InputEvents,
7745
+ ParentEvents
7406
7746
  >
7407
7747
  >
7408
7748
 
@@ -7410,10 +7750,12 @@ type EffectInvokeResult<
7410
7750
  States extends Machine.StateSchemas,
7411
7751
  Events extends ReadonlyArray<Machine.TaggedSchema>,
7412
7752
  Emits extends ReadonlyArray<Machine.TaggedSchema>,
7753
+ InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
7754
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>,
7413
7755
  StateId extends Machine.StateIdentifier<States>,
7414
7756
  Source extends (...args: ReadonlyArray<never>) => Effect.Effect<unknown, unknown, unknown>
7415
7757
  > =
7416
- & Machine.InvokeConfig<States, Events, Emits, StateId, readonly [], readonly []>
7758
+ & Machine.InvokeConfig<States, Events, Emits, StateId, InputEvents, ParentEvents>
7417
7759
  & Machine.InvokeTyped<
7418
7760
  Effect.Success<ReturnType<Source>>,
7419
7761
  Effect.Error<ReturnType<Source>>,
@@ -7421,6 +7763,110 @@ type EffectInvokeResult<
7421
7763
  never
7422
7764
  >
7423
7765
 
7766
+ type StreamInvokeSource<
7767
+ States extends Machine.StateSchemas,
7768
+ Events extends ReadonlyArray<Machine.TaggedSchema>,
7769
+ Emits extends ReadonlyArray<Machine.TaggedSchema>,
7770
+ InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
7771
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>,
7772
+ StateId extends Machine.StateIdentifier<States>,
7773
+ Source extends (...args: ReadonlyArray<any>) => unknown
7774
+ > = {
7775
+ readonly id: InvokeLifecycleId
7776
+ readonly stream:
7777
+ & Source
7778
+ & ((context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>) => unknown)
7779
+ readonly effect?: never
7780
+ readonly after?: never
7781
+ readonly logic?: never
7782
+ readonly child?: never
7783
+ readonly address?: never
7784
+ readonly onSnapshot?: never
7785
+ }
7786
+
7787
+ type StreamSourceResult<Source extends (...args: ReadonlyArray<any>) => unknown> = ReturnType<Source> extends
7788
+ infer Result extends Stream.Stream<any, any, any> ? Result : never
7789
+
7790
+ type StreamElementHandler<
7791
+ States extends Machine.StateSchemas,
7792
+ Events extends ReadonlyArray<Machine.TaggedSchema>,
7793
+ Emits extends ReadonlyArray<Machine.TaggedSchema>,
7794
+ InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
7795
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>,
7796
+ StateId extends Machine.StateIdentifier<States>,
7797
+ Source extends (...args: ReadonlyArray<any>) => unknown
7798
+ > = Machine.InvokeTransition<
7799
+ States,
7800
+ Events,
7801
+ Emits,
7802
+ StateId,
7803
+ Machine.InvokeElementContext<
7804
+ States,
7805
+ Events,
7806
+ Emits,
7807
+ StateId,
7808
+ Stream.Success<StreamSourceResult<NoInfer<Source>>>,
7809
+ InputEvents,
7810
+ ParentEvents
7811
+ >
7812
+ >
7813
+
7814
+ type StreamDoneHandler<
7815
+ States extends Machine.StateSchemas,
7816
+ Events extends ReadonlyArray<Machine.TaggedSchema>,
7817
+ Emits extends ReadonlyArray<Machine.TaggedSchema>,
7818
+ InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
7819
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>,
7820
+ StateId extends Machine.StateIdentifier<States>
7821
+ > = Machine.InvokeTransition<
7822
+ States,
7823
+ Events,
7824
+ Emits,
7825
+ StateId,
7826
+ Machine.InvokeDoneContext<States, Events, Emits, StateId, void, InputEvents, ParentEvents>
7827
+ >
7828
+
7829
+ type StreamFailureHandler<
7830
+ States extends Machine.StateSchemas,
7831
+ Events extends ReadonlyArray<Machine.TaggedSchema>,
7832
+ Emits extends ReadonlyArray<Machine.TaggedSchema>,
7833
+ InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
7834
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>,
7835
+ StateId extends Machine.StateIdentifier<States>,
7836
+ Source extends (...args: ReadonlyArray<any>) => unknown
7837
+ > = Machine.InvokeTransition<
7838
+ States,
7839
+ Events,
7840
+ Emits,
7841
+ StateId,
7842
+ Machine.InvokeFailureContext<
7843
+ States,
7844
+ Events,
7845
+ Emits,
7846
+ StateId,
7847
+ Stream.Error<StreamSourceResult<NoInfer<Source>>>,
7848
+ InputEvents,
7849
+ ParentEvents
7850
+ >
7851
+ >
7852
+
7853
+ type StreamInvokeResult<
7854
+ States extends Machine.StateSchemas,
7855
+ Events extends ReadonlyArray<Machine.TaggedSchema>,
7856
+ Emits extends ReadonlyArray<Machine.TaggedSchema>,
7857
+ InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
7858
+ ParentEvents extends ReadonlyArray<Machine.TaggedSchema>,
7859
+ StateId extends Machine.StateIdentifier<States>,
7860
+ Source extends (...args: ReadonlyArray<any>) => unknown
7861
+ > =
7862
+ & Machine.InvokeConfig<States, Events, Emits, StateId, InputEvents, ParentEvents>
7863
+ & Machine.InvokeTyped<
7864
+ void,
7865
+ Stream.Error<StreamSourceResult<Source>>,
7866
+ Stream.Services<StreamSourceResult<Source>>,
7867
+ never
7868
+ >
7869
+
7424
7870
  type InvokeChannelIsNever<Value> = IsAny<Value> extends true ? false : [Value] extends [never] ? true : false
7425
7871
 
7426
7872
  type BoundEffectInvokeSource<
@@ -7436,10 +7882,12 @@ type BoundEffectInvokeSource<
7436
7882
  > = {
7437
7883
  readonly id: InvokeLifecycleId
7438
7884
  readonly effect: Source
7885
+ readonly stream?: never
7439
7886
  readonly after?: never
7440
7887
  readonly logic?: never
7441
7888
  readonly child?: never
7442
7889
  readonly address?: never
7890
+ readonly onElement?: never
7443
7891
  readonly onSnapshot?: never
7444
7892
  }
7445
7893
 
@@ -7508,66 +7956,36 @@ type BoundEffectInvokeResult<
7508
7956
  never
7509
7957
  >
7510
7958
 
7511
- /** Type evidence retained for a case created by a conditional transition's local builder. */
7512
- interface TransitionCaseTyped {
7513
- readonly [TransitionCaseTypeId]: true
7514
- }
7515
-
7516
- /** Locally bound constructor that preserves each conditional transition case independently. */
7517
- interface TransitionCaseConstructor<
7518
- States extends Machine.StateSchemas,
7519
- Events extends ReadonlyArray<Machine.TaggedSchema>,
7520
- Emits extends ReadonlyArray<Machine.TaggedSchema>,
7521
- StateId extends Machine.StateNodeIdentifier<States>,
7522
- Context
7523
- > {
7524
- <
7525
- const Selection extends Machine.TargetSelection<any, any, any>,
7526
- const Match
7527
- >(
7528
- config: Machine.TransitionCaseInput<States, Events, Emits, StateId, Context, Selection, Match>
7529
- ):
7530
- & Machine.TransitionCaseInput<States, Events, Emits, StateId, Context, Selection, Match>
7531
- & TransitionCaseTyped
7532
- }
7533
-
7534
- /**
7535
- * Captures one exact transition topology while preserving handler inference.
7536
- *
7537
- * @category constructors
7538
- * @since 0.14.0
7539
- */
7540
- type ConditionalTransitionResult<
7959
+ /** Captures one exact named-branch topology while preserving handler inference. */
7960
+ type BranchingTransitionResult<
7541
7961
  States extends Machine.StateSchemas,
7542
7962
  Events extends ReadonlyArray<Machine.TaggedSchema>,
7543
7963
  Emits extends ReadonlyArray<Machine.TaggedSchema>,
7544
7964
  StateId extends Machine.StateNodeIdentifier<States>,
7545
7965
  Context,
7546
7966
  Reenter extends boolean,
7547
- Cases extends readonly [
7548
- TransitionCaseTyped,
7549
- ...ReadonlyArray<TransitionCaseTyped>
7550
- ],
7551
- OtherwiseSelection extends Machine.TargetSelection<any, any, any>
7967
+ Branches extends Readonly<Record<string, Machine.TransitionBranchInput>>
7552
7968
  > =
7553
- & Omit<
7554
- Machine.TransitionConditionalInput<
7555
- States,
7556
- Events,
7557
- Emits,
7558
- StateId,
7559
- Context,
7560
- Reenter,
7561
- Cases,
7562
- OtherwiseSelection
7563
- >,
7564
- "cases"
7565
- >
7566
- & { readonly cases: Cases }
7969
+ & Machine.TransitionBranchesInput<States, Events, Emits, StateId, Context, Reenter, Branches>
7567
7970
  & Machine.TransitionTyped<States, Events, Emits, StateId, Context, Reenter>
7568
7971
 
7972
+ type TransitionBranchRecordError<Message extends string, Key extends PropertyKey = never> = {
7973
+ readonly "~effect/Machine/TransitionBranchRecordError": Message
7974
+ readonly key: Key
7975
+ }
7976
+
7977
+ type InvalidStaticTransitionBranchKey<Branches> = Extract<keyof Branches, "" | number | symbol>
7978
+
7979
+ type ValidateTransitionBranchRecord<Branches> = [keyof Branches] extends [never] ?
7980
+ TransitionBranchRecordError<"Branch records must contain at least one branch">
7981
+ : [InvalidStaticTransitionBranchKey<Branches>] extends [never] ? unknown
7982
+ : TransitionBranchRecordError<
7983
+ "Branch keys must be non-empty, non-index strings",
7984
+ InvalidStaticTransitionBranchKey<Branches>
7985
+ >
7986
+
7569
7987
  /**
7570
- * Contextually types direct and conditional transition definitions.
7988
+ * Contextually types direct and branching transition definitions.
7571
7989
  *
7572
7990
  * @category constructors
7573
7991
  * @since 0.14.0
@@ -7593,32 +8011,28 @@ export interface TransitionConstructor {
7593
8011
  const Emits extends ReadonlyArray<Machine.TaggedSchema>,
7594
8012
  StateId extends Machine.StateNodeIdentifier<States>,
7595
8013
  Context,
7596
- const Cases extends readonly [
7597
- TransitionCaseTyped,
7598
- ...ReadonlyArray<TransitionCaseTyped>
7599
- ],
7600
- const OtherwiseSelection extends Machine.TargetSelection<any, any, any>,
8014
+ const Branches extends Readonly<Record<string, Machine.TransitionBranchInput>>,
7601
8015
  Reenter extends boolean = never
7602
8016
  >(
7603
- config: Machine.TransitionConditionalInput<
7604
- States,
7605
- Events,
7606
- Emits,
7607
- StateId,
7608
- Context,
7609
- Reenter,
7610
- Cases,
7611
- OtherwiseSelection
7612
- >
7613
- ): ConditionalTransitionResult<
8017
+ config:
8018
+ & Machine.TransitionBranchesInput<
8019
+ States,
8020
+ Events,
8021
+ Emits,
8022
+ StateId,
8023
+ Context,
8024
+ Reenter,
8025
+ Branches
8026
+ >
8027
+ & ValidateTransitionBranchRecord<NoInfer<Branches>>
8028
+ ): BranchingTransitionResult<
7614
8029
  States,
7615
8030
  Events,
7616
8031
  Emits,
7617
8032
  StateId,
7618
8033
  Context,
7619
8034
  Reenter,
7620
- Cases,
7621
- OtherwiseSelection
8035
+ Branches
7622
8036
  >
7623
8037
  }
7624
8038
 
@@ -7627,9 +8041,9 @@ export interface TransitionConstructor {
7627
8041
  *
7628
8042
  * It is required for every event, lifecycle, choice, and invocation transition
7629
8043
  * so the destination selected by `target` can contextually type the
7630
- * corresponding resolver. Conditional transitions use the locally bound
7631
- * `branch` constructor so every case independently infers its matched value and
7632
- * selected destination, with no limit on the number of cases.
8044
+ * corresponding resolver. Branching transitions declare every possible
8045
+ * destination up front, then select one through ordinary TypeScript control
8046
+ * flow in `resolve`.
7633
8047
  *
7634
8048
  * ```ts
7635
8049
  * Machine.transition({
@@ -7638,31 +8052,61 @@ export interface TransitionConstructor {
7638
8052
  * })
7639
8053
  *
7640
8054
  * Machine.transition({
7641
- * cases: (branch) => [
7642
- * branch({
7643
- * title: "has cached data",
7644
- * when: ({ event }) => event.cached,
7645
- * target: (to) => to.full.Ready(),
7646
- * resolve: ({ match, target }) => target.from({ data: match })
7647
- * })
7648
- * ],
7649
- * otherwise: {
7650
- * target: (to) => to.full.Loading(),
7651
- * resolve: ({ target }) => target.from()
7652
- * }
8055
+ * branches: (to) => ({
8056
+ * cached: { target: to.full.Ready() },
8057
+ * loading: { target: to.full.Loading() }
8058
+ * }),
8059
+ * resolve: ({ event, select }) => event.cached
8060
+ * ? select.cached.from({ data: event.cached })
8061
+ * : select.loading.from()
7653
8062
  * })
7654
8063
  * ```
7655
8064
  *
7656
8065
  * @category constructors
7657
8066
  * @since 0.14.0
7658
8067
  */
7659
- export const transition: TransitionConstructor = ((config: unknown) => {
7660
- if (!hasProperty(config, "cases") || typeof config.cases !== "function") return config
7661
- return {
7662
- ...config,
7663
- cases: config.cases(<Case extends object>(branch: Case): Case => branch)
7664
- }
7665
- }) as TransitionConstructor
8068
+ export const transition: TransitionConstructor = ((config: unknown) => config) as TransitionConstructor
8069
+
8070
+ /**
8071
+ * Sentinel used by direct targetless transition shorthands.
8072
+ *
8073
+ * This is the concise form of `target: (to) => to.none()`.
8074
+ *
8075
+ * ```ts
8076
+ * onElement: {
8077
+ * target: Machine.targetless,
8078
+ * resolve: ({ element }, enqueue) => {
8079
+ * enqueue.raise(new MeasurementReceived({ value: element }))
8080
+ * }
8081
+ * }
8082
+ *
8083
+ * onDone: { target: Machine.targetless }
8084
+ * ```
8085
+ *
8086
+ * @category constructors
8087
+ * @since 0.16.0
8088
+ */
8089
+ export interface TargetlessSelector {
8090
+ readonly "~effect/Machine/TargetlessSelector": true
8091
+ <
8092
+ const States extends Machine.StateSchemas,
8093
+ StateId extends Machine.StateNodeIdentifier<States>
8094
+ >(to: Machine.TargetSelector<States, StateId>): ReturnType<Machine.TargetSelector<States, StateId>["none"]>
8095
+ }
8096
+
8097
+ /**
8098
+ * Selects no transition target while keeping enqueue operations explicit.
8099
+ *
8100
+ * Use as the `target` of a direct handler object when the handler should keep
8101
+ * the current state configuration and only raise, emit, or send events.
8102
+ *
8103
+ * @category constructors
8104
+ * @since 0.16.0
8105
+ */
8106
+ export const targetless: TargetlessSelector = Object.assign(
8107
+ (to: Machine.TargetSelector<any, any>) => to.none(),
8108
+ { "~effect/Machine/TargetlessSelector": true as const }
8109
+ )
7666
8110
 
7667
8111
  /**
7668
8112
  * Machine-bound invocation constructor that preserves the owning machine's
@@ -7777,6 +8221,73 @@ export interface Invoker<
7777
8221
  readonly onFailure?: never
7778
8222
  }
7779
8223
  ): BoundEffectInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8224
+ <
8225
+ StateId extends Machine.StateIdentifier<States>,
8226
+ const Source extends (
8227
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8228
+ ) => Stream.Stream<unknown, unknown, any>
8229
+ >(
8230
+ config:
8231
+ & StreamInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8232
+ & {
8233
+ readonly onElement: StreamElementHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8234
+ readonly onDone: StreamDoneHandler<States, Events, Emits, InputEvents, ParentEvents, StateId>
8235
+ readonly onFailure: StreamFailureHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8236
+ },
8237
+ ..._validation: InvokeChannelIsNever<Stream.Success<ReturnType<Source>>> extends true ? [
8238
+ "onElement must be omitted when the Stream element is never"
8239
+ ]
8240
+ : InvokeChannelIsNever<Stream.Error<ReturnType<Source>>> extends true ? [
8241
+ "onFailure must be omitted when the Stream error is never"
8242
+ ]
8243
+ : []
8244
+ ): StreamInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8245
+ <
8246
+ StateId extends Machine.StateIdentifier<States>,
8247
+ const Source extends (
8248
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8249
+ ) => Stream.Stream<never, unknown, any>
8250
+ >(
8251
+ config:
8252
+ & StreamInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8253
+ & {
8254
+ readonly onElement?: never
8255
+ readonly onDone: StreamDoneHandler<States, Events, Emits, InputEvents, ParentEvents, StateId>
8256
+ readonly onFailure: StreamFailureHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8257
+ },
8258
+ ..._validation: InvokeChannelIsNever<Stream.Error<ReturnType<Source>>> extends true ? [
8259
+ "onFailure must be omitted when the Stream error is never"
8260
+ ]
8261
+ : []
8262
+ ): StreamInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8263
+ <
8264
+ StateId extends Machine.StateIdentifier<States>,
8265
+ const Source extends (
8266
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8267
+ ) => Stream.Stream<never, never, any>
8268
+ >(
8269
+ config:
8270
+ & StreamInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8271
+ & {
8272
+ readonly onElement?: never
8273
+ readonly onDone: StreamDoneHandler<States, Events, Emits, InputEvents, ParentEvents, StateId>
8274
+ readonly onFailure?: never
8275
+ }
8276
+ ): StreamInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8277
+ <
8278
+ StateId extends Machine.StateIdentifier<States>,
8279
+ const Source extends (
8280
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8281
+ ) => Stream.Stream<unknown, never, any>
8282
+ >(
8283
+ config:
8284
+ & StreamInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8285
+ & {
8286
+ readonly onElement: StreamElementHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8287
+ readonly onDone: StreamDoneHandler<States, Events, Emits, InputEvents, ParentEvents, StateId>
8288
+ readonly onFailure?: never
8289
+ }
8290
+ ): StreamInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
7780
8291
  <StateId extends Machine.StateIdentifier<States>, const Config extends object>(
7781
8292
  config: Config & Machine.TimerInvokeArgs<States, Events, Emits, StateId, InputEvents, ParentEvents>
7782
8293
  ): Config & Machine.InvokeOwned<States, Events, Emits, StateId> & Machine.InvokeTyped<void, never, never, never>
@@ -7883,25 +8394,27 @@ export interface Invoker<
7883
8394
  /**
7884
8395
  * Preserves inference for a state-owned invocation configuration.
7885
8396
  *
7886
- * Use `effect` for one-shot work, `after` for a cancellable timer, `logic` for
7887
- * reusable process logic, or `child` for a complete child machine. `onDone` is
7888
- * required whenever the source can complete with an output, while `onFailure`
7889
- * is required only when the source has a typed failure channel.
8397
+ * Use `effect` for one-shot work, `stream` for repeated values, `after` for a
8398
+ * cancellable timer, `logic` for reusable process logic, or `child` for a
8399
+ * complete child machine. Stream elements are handled by `onElement` before
8400
+ * the next element is pulled. `onDone` is required whenever the source can
8401
+ * complete, while `onFailure` is required only when the source has a typed
8402
+ * failure channel.
7890
8403
  *
7891
8404
  * This constructor is an identity at runtime, but preserves lifecycle callback
7892
- * inference through published declarations. Effect factories run when their
7893
- * owning state is entered and infer the owner context, output, error, and
7894
- * service channels together without a return annotation. Durations may be
8405
+ * inference through published declarations. Effect and Stream factories run
8406
+ * when their owning state is entered and infer the owner context, value,
8407
+ * output, error, and service channels together without a return annotation.
8408
+ * Durations may be
7895
8409
  * supplied directly or derived from the owning state's entry context. Logic
7896
8410
  * invocations require both a lifecycle `id` and a typed communication
7897
8411
  * `address`. Child descriptors already own their identity, so `id` and
7898
8412
  * `address` must not be repeated.
7899
8413
  *
7900
- * Owner references are intentionally non-sendable here because this standalone
7901
- * constructor does not know the owning definition. When a callback sends to
7902
- * `self` or `parent`, use the bound constructor on the owning definition
7903
- * (`definition.invoke(...)`) so the exact public input and `parentEvents`
7904
- * protocols are available.
8414
+ * Inside `handle(...)`, the owning definition contextually supplies its public
8415
+ * input and `parentEvents` protocols. Invocation sources and lifecycle handlers
8416
+ * can therefore send through `self` and `parent` without naming the definition.
8417
+ * The bound `definition.invoke(...)` constructor remains an equivalent form.
7905
8418
  *
7906
8419
  * ```ts
7907
8420
  * invoke: Machine.invoke({
@@ -7932,14 +8445,16 @@ export const invoke: {
7932
8445
  const Emits extends ReadonlyArray<Machine.TaggedSchema>,
7933
8446
  StateId extends Machine.StateIdentifier<States>,
7934
8447
  const Source extends (
7935
- context: Machine.InvokeContext<States, Events, Emits, StateId, readonly [], readonly []>
7936
- ) => Effect.Effect<unknown, unknown, unknown>
8448
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8449
+ ) => Effect.Effect<unknown, unknown, unknown>,
8450
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8451
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
7937
8452
  >(
7938
8453
  config:
7939
- & EffectInvokeSource<States, Events, Emits, StateId, Source>
8454
+ & EffectInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
7940
8455
  & {
7941
- readonly onDone: EffectDoneHandler<States, Events, Emits, StateId, Source>
7942
- readonly onFailure: EffectFailureHandler<States, Events, Emits, StateId, Source>
8456
+ readonly onDone: EffectDoneHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8457
+ readonly onFailure: EffectFailureHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
7943
8458
  },
7944
8459
  ..._validation: InvokeChannelIsNever<Effect.Success<ReturnType<Source>>> extends true ? [
7945
8460
  "onDone must be omitted when the Effect output is never"
@@ -7948,71 +8463,166 @@ export const invoke: {
7948
8463
  "onFailure must be omitted when the Effect error is never"
7949
8464
  ]
7950
8465
  : []
7951
- ): EffectInvokeResult<States, Events, Emits, StateId, Source>
8466
+ ): EffectInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
7952
8467
  <
7953
8468
  const States extends Machine.StateSchemas,
7954
8469
  const Events extends ReadonlyArray<Machine.TaggedSchema>,
7955
8470
  const Emits extends ReadonlyArray<Machine.TaggedSchema>,
7956
8471
  StateId extends Machine.StateIdentifier<States>,
7957
8472
  const Source extends (
7958
- context: Machine.InvokeContext<States, Events, Emits, StateId, readonly [], readonly []>
7959
- ) => Effect.Effect<unknown, never, unknown>
8473
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8474
+ ) => Effect.Effect<unknown, never, unknown>,
8475
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8476
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
7960
8477
  >(
7961
8478
  config:
7962
- & EffectInvokeSource<States, Events, Emits, StateId, Source>
8479
+ & EffectInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
7963
8480
  & {
7964
- readonly onDone: EffectDoneHandler<States, Events, Emits, StateId, Source>
8481
+ readonly onDone: EffectDoneHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
7965
8482
  readonly onFailure?: never
7966
8483
  },
7967
8484
  ..._validation: InvokeChannelIsNever<Effect.Success<ReturnType<Source>>> extends true ? [
7968
8485
  "onDone must be omitted when the Effect output is never"
7969
8486
  ]
7970
8487
  : []
7971
- ): EffectInvokeResult<States, Events, Emits, StateId, Source>
8488
+ ): EffectInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
7972
8489
  <
7973
8490
  const States extends Machine.StateSchemas,
7974
8491
  const Events extends ReadonlyArray<Machine.TaggedSchema>,
7975
8492
  const Emits extends ReadonlyArray<Machine.TaggedSchema>,
7976
8493
  StateId extends Machine.StateIdentifier<States>,
7977
8494
  const Source extends (
7978
- context: Machine.InvokeContext<States, Events, Emits, StateId, readonly [], readonly []>
7979
- ) => Effect.Effect<never, unknown, unknown>
8495
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8496
+ ) => Effect.Effect<never, unknown, unknown>,
8497
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8498
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
7980
8499
  >(
7981
8500
  config:
7982
- & EffectInvokeSource<States, Events, Emits, StateId, Source>
8501
+ & EffectInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
7983
8502
  & {
7984
8503
  readonly onDone?: never
7985
- readonly onFailure: EffectFailureHandler<States, Events, Emits, StateId, Source>
8504
+ readonly onFailure: EffectFailureHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
7986
8505
  },
7987
8506
  ..._validation: InvokeChannelIsNever<Effect.Error<ReturnType<Source>>> extends true ? [
7988
8507
  "onFailure must be omitted when the Effect error is never"
7989
8508
  ]
7990
8509
  : []
7991
- ): EffectInvokeResult<States, Events, Emits, StateId, Source>
8510
+ ): EffectInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
7992
8511
  <
7993
8512
  const States extends Machine.StateSchemas,
7994
8513
  const Events extends ReadonlyArray<Machine.TaggedSchema>,
7995
8514
  const Emits extends ReadonlyArray<Machine.TaggedSchema>,
7996
8515
  StateId extends Machine.StateIdentifier<States>,
7997
8516
  const Source extends (
7998
- context: Machine.InvokeContext<States, Events, Emits, StateId, readonly [], readonly []>
7999
- ) => Effect.Effect<never, never, unknown>
8517
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8518
+ ) => Effect.Effect<never, never, unknown>,
8519
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8520
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
8000
8521
  >(
8001
8522
  config:
8002
- & EffectInvokeSource<States, Events, Emits, StateId, Source>
8523
+ & EffectInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8003
8524
  & {
8004
8525
  readonly onDone?: never
8005
8526
  readonly onFailure?: never
8006
8527
  }
8007
- ): EffectInvokeResult<States, Events, Emits, StateId, Source>
8528
+ ): EffectInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8008
8529
  <
8009
8530
  const States extends Machine.StateSchemas,
8010
8531
  const Events extends ReadonlyArray<Machine.TaggedSchema>,
8011
8532
  const Emits extends ReadonlyArray<Machine.TaggedSchema>,
8012
8533
  StateId extends Machine.StateIdentifier<States>,
8013
- const Config extends object
8534
+ const Source extends (
8535
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8536
+ ) => Stream.Stream<unknown, unknown, any>,
8537
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8538
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
8014
8539
  >(
8015
- config: Config & Machine.TimerInvokeArgs<States, Events, Emits, StateId, readonly [], readonly []>
8540
+ config:
8541
+ & StreamInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8542
+ & {
8543
+ readonly onElement: StreamElementHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8544
+ readonly onDone: StreamDoneHandler<States, Events, Emits, InputEvents, ParentEvents, StateId>
8545
+ readonly onFailure: StreamFailureHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8546
+ },
8547
+ ..._validation: InvokeChannelIsNever<Stream.Success<ReturnType<Source>>> extends true ? [
8548
+ "onElement must be omitted when the Stream element is never"
8549
+ ]
8550
+ : InvokeChannelIsNever<Stream.Error<ReturnType<Source>>> extends true ? [
8551
+ "onFailure must be omitted when the Stream error is never"
8552
+ ]
8553
+ : []
8554
+ ): StreamInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8555
+ <
8556
+ const States extends Machine.StateSchemas,
8557
+ const Events extends ReadonlyArray<Machine.TaggedSchema>,
8558
+ const Emits extends ReadonlyArray<Machine.TaggedSchema>,
8559
+ StateId extends Machine.StateIdentifier<States>,
8560
+ const Source extends (
8561
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8562
+ ) => Stream.Stream<never, unknown, any>,
8563
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8564
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
8565
+ >(
8566
+ config:
8567
+ & StreamInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8568
+ & {
8569
+ readonly onElement?: never
8570
+ readonly onDone: StreamDoneHandler<States, Events, Emits, InputEvents, ParentEvents, StateId>
8571
+ readonly onFailure: StreamFailureHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8572
+ },
8573
+ ..._validation: InvokeChannelIsNever<Stream.Error<ReturnType<Source>>> extends true ? [
8574
+ "onFailure must be omitted when the Stream error is never"
8575
+ ]
8576
+ : []
8577
+ ): StreamInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8578
+ <
8579
+ const States extends Machine.StateSchemas,
8580
+ const Events extends ReadonlyArray<Machine.TaggedSchema>,
8581
+ const Emits extends ReadonlyArray<Machine.TaggedSchema>,
8582
+ StateId extends Machine.StateIdentifier<States>,
8583
+ const Source extends (
8584
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8585
+ ) => Stream.Stream<never, never, any>,
8586
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8587
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
8588
+ >(
8589
+ config:
8590
+ & StreamInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8591
+ & {
8592
+ readonly onElement?: never
8593
+ readonly onDone: StreamDoneHandler<States, Events, Emits, InputEvents, ParentEvents, StateId>
8594
+ readonly onFailure?: never
8595
+ }
8596
+ ): StreamInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8597
+ <
8598
+ const States extends Machine.StateSchemas,
8599
+ const Events extends ReadonlyArray<Machine.TaggedSchema>,
8600
+ const Emits extends ReadonlyArray<Machine.TaggedSchema>,
8601
+ StateId extends Machine.StateIdentifier<States>,
8602
+ const Source extends (
8603
+ context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>
8604
+ ) => Stream.Stream<unknown, never, any>,
8605
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8606
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
8607
+ >(
8608
+ config:
8609
+ & StreamInvokeSource<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8610
+ & {
8611
+ readonly onElement: StreamElementHandler<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8612
+ readonly onDone: StreamDoneHandler<States, Events, Emits, InputEvents, ParentEvents, StateId>
8613
+ readonly onFailure?: never
8614
+ }
8615
+ ): StreamInvokeResult<States, Events, Emits, InputEvents, ParentEvents, StateId, Source>
8616
+ <
8617
+ const States extends Machine.StateSchemas,
8618
+ const Events extends ReadonlyArray<Machine.TaggedSchema>,
8619
+ const Emits extends ReadonlyArray<Machine.TaggedSchema>,
8620
+ StateId extends Machine.StateIdentifier<States>,
8621
+ const Config extends object,
8622
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8623
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
8624
+ >(
8625
+ config: Config & Machine.TimerInvokeArgs<States, Events, Emits, StateId, InputEvents, ParentEvents>
8016
8626
  ): Config & Machine.InvokeOwned<States, Events, Emits, StateId> & Machine.InvokeTyped<void, never, never, never>
8017
8627
  <
8018
8628
  const States extends Machine.StateSchemas,
@@ -8025,7 +8635,9 @@ export const invoke: {
8025
8635
  ChildRequirements,
8026
8636
  ChildOutput,
8027
8637
  ChildInitialError,
8028
- Address extends ChildAddress<never>
8638
+ Address extends ChildAddress<never>,
8639
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8640
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
8029
8641
  >(
8030
8642
  config: Machine.LogicInvokeArgs<
8031
8643
  States,
@@ -8039,7 +8651,7 @@ export const invoke: {
8039
8651
  ChildOutput,
8040
8652
  ChildInitialError,
8041
8653
  Address,
8042
- (context: Machine.InvokeContext<States, Events, Emits, StateId, readonly [], readonly []>) => Logic<
8654
+ (context: Machine.InvokeContext<States, Events, Emits, StateId, InputEvents, ParentEvents>) => Logic<
8043
8655
  ChildState,
8044
8656
  ChildEvent,
8045
8657
  ChildError,
@@ -8047,11 +8659,11 @@ export const invoke: {
8047
8659
  ChildOutput,
8048
8660
  ChildInitialError
8049
8661
  >,
8050
- readonly [],
8051
- readonly []
8662
+ InputEvents,
8663
+ ParentEvents
8052
8664
  >
8053
8665
  ):
8054
- & Machine.InvokeConfig<States, Events, Emits, StateId, readonly [], readonly []>
8666
+ & Machine.InvokeConfig<States, Events, Emits, StateId, InputEvents, ParentEvents>
8055
8667
  & Machine.InvokeTyped<
8056
8668
  ChildOutput,
8057
8669
  ChildError,
@@ -8070,7 +8682,9 @@ export const invoke: {
8070
8682
  ChildOutput,
8071
8683
  ChildInitialError,
8072
8684
  Address extends ChildAddress<never>,
8073
- const Config extends object
8685
+ const Config extends object,
8686
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8687
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
8074
8688
  >(
8075
8689
  config:
8076
8690
  & Config
@@ -8087,8 +8701,8 @@ export const invoke: {
8087
8701
  ChildInitialError,
8088
8702
  Address,
8089
8703
  Logic<ChildState, ChildEvent, ChildError, ChildRequirements, ChildOutput, ChildInitialError>,
8090
- readonly [],
8091
- readonly []
8704
+ InputEvents,
8705
+ ParentEvents
8092
8706
  >
8093
8707
  ):
8094
8708
  & Config
@@ -8105,11 +8719,13 @@ export const invoke: {
8105
8719
  const Emits extends ReadonlyArray<Machine.TaggedSchema>,
8106
8720
  StateId extends Machine.StateIdentifier<States>,
8107
8721
  const Child extends ChildMachine.Any,
8108
- const Config extends object
8722
+ const Config extends object,
8723
+ const InputEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
8724
+ const ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
8109
8725
  >(
8110
8726
  config:
8111
8727
  & Config
8112
- & Machine.ChildInvokeArgs<States, Events, Emits, StateId, Child["machine"], Child, readonly [], readonly []>
8728
+ & Machine.ChildInvokeArgs<States, Events, Emits, StateId, Child["machine"], Child, InputEvents, ParentEvents>
8113
8729
  ):
8114
8730
  & Config
8115
8731
  & Machine.InvokeOwned<States, Events, Emits, StateId>
@@ -8147,7 +8763,7 @@ export const invoke: {
8147
8763
  * import { Machine } from "@typeonce/effect-machine"
8148
8764
  *
8149
8765
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
8150
- * const States = Machine.defineStates({ Idle })
8766
+ * const States = Machine.states({ Idle })
8151
8767
  * const machine = Machine.make({
8152
8768
  * states: States.states,
8153
8769
  * events: Machine.events(),
@@ -8282,9 +8898,8 @@ export const initialDefinition: <M extends Machine.Any>(machine: M) => Machine.I
8282
8898
  *
8283
8899
  * Event handlers retain their handler-key order within each source state and
8284
8900
  * are followed by eventless and completion handlers. This function does not
8285
- * execute predicates or resolvers. Every direct, conditional, fallback, and
8286
- * targetless branch exposes the destination selected by its required static
8287
- * `target` declaration.
8901
+ * execute resolvers. Every direct, named, and targetless branch exposes the
8902
+ * destination selected by its required static `target` declaration.
8288
8903
  *
8289
8904
  * @category getters
8290
8905
  * @since 0.4.0
@@ -8403,7 +9018,7 @@ export const enabled: <
8403
9018
  * class Off extends Schema.TaggedClass<Off>("Off")("Off", {}) {}
8404
9019
  * class On extends Schema.TaggedClass<On>("On")("On", {}) {}
8405
9020
  * class Toggle extends Schema.TaggedClass<Toggle>("Toggle")("Toggle", {}) {}
8406
- * const States = Machine.defineStates({ Off, On })
9021
+ * const States = Machine.states({ Off, On })
8407
9022
  * const machine = Machine.make({
8408
9023
  * states: States.states,
8409
9024
  * events: Machine.events(Toggle),
@@ -8786,7 +9401,7 @@ export const prepare: <
8786
9401
  * import { Machine } from "@typeonce/effect-machine"
8787
9402
  *
8788
9403
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
8789
- * const States = Machine.defineStates({ Idle })
9404
+ * const States = Machine.states({ Idle })
8790
9405
  * const machine = Machine.make({
8791
9406
  * states: States.states,
8792
9407
  * events: Machine.events(),
@@ -8899,7 +9514,7 @@ export const start: <
8899
9514
  * import { Machine } from "@typeonce/effect-machine"
8900
9515
  *
8901
9516
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
8902
- * const States = Machine.defineStates({ Idle })
9517
+ * const States = Machine.states({ Idle })
8903
9518
  * const machine = Machine.make({
8904
9519
  * states: States.states,
8905
9520
  * events: Machine.events(),