@typeonce/effect-machine 0.20.0 → 0.22.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 (46) hide show
  1. package/README.md +115 -5
  2. package/dist/Machine.d.ts +188 -52
  3. package/dist/Machine.d.ts.map +1 -1
  4. package/dist/Machine.js +6 -5
  5. package/dist/Machine.js.map +1 -1
  6. package/dist/internal/machine/executionPlan.d.ts.map +1 -1
  7. package/dist/internal/machine/executionPlan.js +50 -6
  8. package/dist/internal/machine/executionPlan.js.map +1 -1
  9. package/dist/internal/machine/initialization.d.ts.map +1 -1
  10. package/dist/internal/machine/initialization.js +7 -2
  11. package/dist/internal/machine/initialization.js.map +1 -1
  12. package/dist/internal/machine/machine.d.ts.map +1 -1
  13. package/dist/internal/machine/machine.js +132 -22
  14. package/dist/internal/machine/machine.js.map +1 -1
  15. package/dist/internal/machine/planner.d.ts +16 -2
  16. package/dist/internal/machine/planner.d.ts.map +1 -1
  17. package/dist/internal/machine/planner.js +67 -13
  18. package/dist/internal/machine/planner.js.map +1 -1
  19. package/dist/internal/machine/topology.d.ts +19 -2
  20. package/dist/internal/machine/topology.d.ts.map +1 -1
  21. package/dist/internal/machine/topology.js +17 -2
  22. package/dist/internal/machine/topology.js.map +1 -1
  23. package/dist/internal/testing/machine/finiteModel.d.ts.map +1 -1
  24. package/dist/internal/testing/machine/finiteModel.js +3 -3
  25. package/dist/internal/testing/machine/finiteModel.js.map +1 -1
  26. package/dist/internal/testing/machine/verification.d.ts.map +1 -1
  27. package/dist/internal/testing/machine/verification.js +17 -3
  28. package/dist/internal/testing/machine/verification.js.map +1 -1
  29. package/dist/testing/MachineTest.d.ts +5 -3
  30. package/dist/testing/MachineTest.d.ts.map +1 -1
  31. package/dist/testing/MachineTest.js +3 -3
  32. package/dist/testing/MachineTest.js.map +1 -1
  33. package/dist/unstable/reactivity/AtomMachine.d.ts +1 -1
  34. package/dist/unstable/reactivity/AtomMachine.js +1 -1
  35. package/docs/agent-guide.md +51 -3
  36. package/package.json +1 -1
  37. package/src/Machine.ts +532 -107
  38. package/src/internal/machine/executionPlan.ts +62 -6
  39. package/src/internal/machine/initialization.ts +10 -2
  40. package/src/internal/machine/machine.ts +188 -24
  41. package/src/internal/machine/planner.ts +86 -15
  42. package/src/internal/machine/topology.ts +40 -3
  43. package/src/internal/testing/machine/finiteModel.ts +7 -3
  44. package/src/internal/testing/machine/verification.ts +24 -3
  45. package/src/testing/MachineTest.ts +5 -3
  46. package/src/unstable/reactivity/AtomMachine.ts +1 -1
package/README.md CHANGED
@@ -149,16 +149,26 @@ parallel root.
149
149
 
150
150
  ### Construct state through builders
151
151
 
152
- Use `.from(...)` when constructing a new state from fields:
152
+ Use `.from(...)` when constructing a new state from schema make input:
153
153
 
154
154
  ```ts
155
155
  target.from({ draft: event.draft })
156
156
  ```
157
157
 
158
158
  The machine runs these inputs through the state schema while planning. Schema
159
- defaults, refinements, and tagged-class identity are therefore preserved, and
160
- decode failures remain typed machine failures. Pass a value directly only when
161
- it is already decoded.
159
+ defaults, transformations, refinements, and tagged-class identity are
160
+ therefore preserved, and decode failures remain typed machine failures. This
161
+ is the default construction path.
162
+
163
+ Use `.decoded(...)` when the value is already a `Schema.Type`:
164
+
165
+ ```ts
166
+ target.decoded(new Ready({ notice: null }))
167
+ ```
168
+
169
+ The machine still validates the value against the schema's type side. It does
170
+ not run encoded-input transformations again. State builders are not callable;
171
+ the method name always makes the construction mode visible.
162
172
 
163
173
  When sibling states share fields, remove the source discriminator and pass the
164
174
  remaining fields through the target schema:
@@ -190,7 +200,7 @@ const States = Machine.states({
190
200
  const definition = Machine.make({
191
201
  states: States.states,
192
202
  events: Machine.events(),
193
- initial: (to) => to.Form.initial.resolve(({ target }) => target((form) => form.Editing.from()))
203
+ initial: (to) => to.Form.initial.resolve(({ target }) => target.from((form) => form.Editing.from()))
194
204
  })
195
205
  ```
196
206
 
@@ -420,6 +430,106 @@ choice destinations remain calls such as `to.full.Running()`. Runtime named
420
430
  branch builders remain callable, including `select.unchanged()`, because their
421
431
  result carries the selected branch evidence.
422
432
 
433
+ ### Update an active scope value
434
+
435
+ Use `to.local.update(...)` to replace the value owned by the nearest active
436
+ compound scope without rebuilding its active child. Use
437
+ `to.branch.<path>.update(...)` for a valued compound or parallel ancestor of the
438
+ handler source:
439
+
440
+ ```ts
441
+ const handlers = {
442
+ Increment: (to) => to.branch.root.session.update(({ current, owner }) => owner.from({ count: current.count + 1 }))
443
+ }
444
+ ```
445
+
446
+ The update keeps the exact active descendants, their values, history records,
447
+ completion outputs, and unrelated parallel regions. It runs no exit or entry
448
+ actions and does not restart state-owned work. Eventless stabilization still
449
+ runs, so an `always` transition can react to the new value.
450
+
451
+ The plain update method remains useful when topology does not change. It is
452
+ also a static selection for a named branch:
453
+
454
+ ```ts
455
+ to.branches({
456
+ changed: { target: to.local.update },
457
+ unchanged: { target: to.none }
458
+ }).resolve(({ select, event }) =>
459
+ event.changed
460
+ ? select.changed.from({ count: event.count })
461
+ : select.unchanged()
462
+ )
463
+ ```
464
+
465
+ ### Change topology and a retained owner together
466
+
467
+ When a transition enters another child and also replaces a valued ancestor
468
+ that stays active, declare both operations on the same target:
469
+
470
+ ```ts
471
+ const handlers = {
472
+ CreatePlan: (to) =>
473
+ to.local.SavingPlan()
474
+ .updating(to.branch.Ready)
475
+ .resolve(({ current, event, owner, target }) =>
476
+ target.from({
477
+ request: { _tag: "Create", input: event.input }
478
+ }).update(
479
+ owner.decoded(new Ready({ ...current, notice: null }))
480
+ )
481
+ )
482
+ }
483
+ ```
484
+
485
+ `to.local.SavingPlan()` selects topology. `.updating(to.branch.Ready)` names
486
+ the retained valued owner and makes its replacement mandatory: the resolver
487
+ does not type-check unless destination construction finishes with
488
+ `.update(...)`. `current` is that owner's decoded value from the
489
+ pre-transition snapshot. `target` constructs the destination; `owner`
490
+ constructs the complete replacement owner value.
491
+
492
+ The topology change and owner replacement apply atomically in one microstep.
493
+ The owner does not exit or reenter, its work is not restarted, and destination
494
+ entry actions observe the new owner value. Eventless stabilization follows.
495
+ Only one retained owner may be replaced by a combined target. A `full` target,
496
+ or any target that exits the selected owner, does not expose `.updating`.
497
+ Combined updates use a direct resolver in this release; named branches continue
498
+ to support value-only updates.
499
+
500
+ For a schema-less destination, construction remains explicit:
501
+
502
+ ```ts
503
+ to.local.Idle()
504
+ .updating(to.branch.Ready)
505
+ .resolve(({ current, output, owner, target }) =>
506
+ target.from().update(
507
+ owner.decoded(
508
+ new Ready({
509
+ ...current,
510
+ day: output,
511
+ notice: "Plan changed."
512
+ })
513
+ )
514
+ )
515
+ )
516
+ ```
517
+
518
+ Both values derive from the same pre-transition snapshot and are validated
519
+ before lifecycle actions run. Competing transitions that write the same owner
520
+ conflict; document order and hierarchy select one writer rather than applying
521
+ last-write-wins behavior.
522
+
523
+ The resolver must return `target.decoded(value)` or `target.from(input)`. It
524
+ may return `decline()` only with `{ declinable: true }`. Pass `{ reenter: true }`
525
+ on event or invocation transitions when the handler source should exit and
526
+ enter again. Reentry applies to that source, not to the ancestor whose value
527
+ changed.
528
+
529
+ The selector omits `update` for schema-less scopes, atomic and final states,
530
+ inactive branches, parallel sibling regions, and choice resolvers. Updating a
531
+ parallel sibling requires an event handled by that region.
532
+
423
533
  Use `declinable: true` when a resolver may decide that its transition is not
424
534
  enabled. Only that resolver receives `decline()`, and its return type expands to
425
535
  accept the opaque declined result:
package/dist/Machine.d.ts CHANGED
@@ -191,7 +191,7 @@ export interface Definition<States extends Machine.StateSchemas, Events extends
191
191
  * on: {
192
192
  * Increment: (to) =>
193
193
  * to.full.Count().resolve(({ event, state, target }) =>
194
- * target(new Count({ value: state.value + event.by })))
194
+ * target.decoded(new Count({ value: state.value + event.by })))
195
195
  * }
196
196
  * }
197
197
  * })
@@ -616,6 +616,15 @@ type FromMethod<Arguments extends ReadonlyArray<unknown>, Result> = {
616
616
  */
617
617
  readonly from: FromCallable<Arguments, Machine.StateConstruction<Result>>;
618
618
  };
619
+ type DecodedMethod<Arguments extends ReadonlyArray<unknown>, Result> = {
620
+ /**
621
+ * Constructs the selected state from an already-decoded schema value. The
622
+ * machine validates the value against the schema's type side while planning.
623
+ *
624
+ * @since 0.22.0
625
+ */
626
+ readonly decoded: (...args: Arguments) => Result;
627
+ };
619
628
  type ConstructionResult<Result> = Result | Machine.StateConstruction<Result>;
620
629
  type UnwrapConstruction<Result> = Result extends Machine.StateConstruction<infer Value> ? Value : Result;
621
630
  type NodeValue<Node> = [Machine.NodeSchema<Node>] extends [never] ? undefined : Machine.NodeSchema<Node>["Type"];
@@ -624,14 +633,14 @@ type WithNodeValue<Node, Rest extends ReadonlyArray<unknown>> = Machine.NodeSche
624
633
  type WithNodeInput<Node, Rest extends ReadonlyArray<unknown>> = Machine.NodeSchema<Node> extends never ? Rest : readonly [input: NodeMakeInput<Node>, ...Rest];
625
634
  type NodeBuilderMethod<Node, Arguments extends ReadonlyArray<unknown>, Result, FromArguments extends ReadonlyArray<unknown>, FromResult> = Machine.NodeSchema<Node> extends never ? {
626
635
  readonly from: FromCallable<FromArguments, FromResult>;
627
- } : ((...args: Arguments) => Result) & {
636
+ } : DecodedMethod<Arguments, Result> & {
628
637
  readonly from: FromCallable<FromArguments, FromResult>;
629
638
  };
630
- type NodeMethod<Node, Arguments extends ReadonlyArray<unknown>, Result, FromArguments extends ReadonlyArray<unknown>> = Machine.NodeSchema<Node> extends never ? FromMethod<FromArguments, Result> : ((...args: Arguments) => Result) & FromMethod<FromArguments, Result>;
639
+ type NodeMethod<Node, Arguments extends ReadonlyArray<unknown>, Result, FromArguments extends ReadonlyArray<unknown>> = Machine.NodeSchema<Node> extends never ? FromMethod<FromArguments, Result> : DecodedMethod<Arguments, Result> & FromMethod<FromArguments, Result>;
631
640
  type NodeMethodWithInitial<Node, Arguments extends ReadonlyArray<unknown>, Result, FromArguments extends ReadonlyArray<unknown>, Path extends string> = Machine.NodeSchema<Node> extends never ? {
632
641
  readonly from: FromCallable<FromArguments, Machine.StateConstruction<Result>>;
633
642
  readonly initial: InitialTargetFactory<Node, Path>;
634
- } : ((...args: Arguments) => Result) & {
643
+ } : DecodedMethod<Arguments, Result> & {
635
644
  readonly from: FromCallable<FromArguments, Machine.StateConstruction<Result>>;
636
645
  readonly initial: InitialTargetFactory<Node, Path>;
637
646
  };
@@ -640,8 +649,8 @@ interface InitialTargetMethod<Node, Path extends string> {
640
649
  readonly initial: InitialTargetFactory<Node, Path>;
641
650
  }
642
651
  interface InitialTargetFactory<Node, Path extends string> {
643
- (...args: WithNodeValue<Node, readonly []>): Machine.InitialTarget<Path>;
644
652
  readonly from: FromCallable<WithNodeInput<Node, readonly []>, Machine.StateConstruction<Machine.InitialTarget<Path>>>;
653
+ readonly decoded: (...args: WithNodeValue<Node, readonly []>) => Machine.InitialTarget<Path>;
645
654
  }
646
655
  type NodeConstructionSelectorFromCallable<Node, Builder, Result> = Machine.NodeSchema<Node> extends never ? {
647
656
  <Selected extends ConstructionResult<Result>>(state: (builder: Builder) => Selected): Machine.StateConstruction<UnwrapConstruction<Selected>>;
@@ -649,7 +658,8 @@ type NodeConstructionSelectorFromCallable<Node, Builder, Result> = Machine.NodeS
649
658
  type NestedTargetMethod<Node, Builder, Result, Path extends string> = Machine.NodeSchema<Node> extends never ? {
650
659
  readonly from: NodeConstructionSelectorFromCallable<Node, Builder, Result>;
651
660
  readonly initial: InitialTargetFactory<Node, Path>;
652
- } : (<Selected extends ConstructionResult<Result>>(value: NodeValue<Node>, state: (builder: Builder) => Selected) => Selected) & {
661
+ } : {
662
+ readonly decoded: <Selected extends ConstructionResult<Result>>(value: NodeValue<Node>, state: (builder: Builder) => Selected) => Selected;
653
663
  readonly from: NodeConstructionSelectorFromCallable<Node, Builder, Result>;
654
664
  readonly initial: InitialTargetFactory<Node, Path>;
655
665
  };
@@ -662,7 +672,7 @@ type InitialSnapshotBuilderWithPrefix<States extends Machine.StateSchemas, Prefi
662
672
  } & {
663
673
  readonly [Key in ChoiceStateKey<States>]: () => Machine.ChoiceTargetInstruction<Machine.JoinPath<Prefix, Key>>;
664
674
  };
665
- type InitialSnapshotMethod<States extends Machine.StateSchemas, StateId extends ActiveStateKey<States>, Prefix extends string> = Machine.NodeSchema<States[StateId]> extends never ? FromMethod<InitialSnapshotFromArguments<States, StateId, Prefix>, InitialSnapshotResult<States, StateId, Prefix>> : ((...args: InitialSnapshotArguments<States, StateId, Prefix>) => InitialSnapshotResult<States, StateId, Prefix>) & FromMethod<InitialSnapshotFromArguments<States, StateId, Prefix>, InitialSnapshotResult<States, StateId, Prefix>>;
675
+ type InitialSnapshotMethod<States extends Machine.StateSchemas, StateId extends ActiveStateKey<States>, Prefix extends string> = Machine.NodeSchema<States[StateId]> extends never ? FromMethod<InitialSnapshotFromArguments<States, StateId, Prefix>, InitialSnapshotResult<States, StateId, Prefix>> : DecodedMethod<InitialSnapshotArguments<States, StateId, Prefix>, InitialSnapshotResult<States, StateId, Prefix>> & FromMethod<InitialSnapshotFromArguments<States, StateId, Prefix>, InitialSnapshotResult<States, StateId, Prefix>>;
666
676
  type InitialSnapshotArguments<States extends Machine.StateSchemas, StateId extends ActiveStateKey<States>, Prefix extends string, Path extends string = Machine.JoinPath<Prefix, StateId>> = States[StateId] extends infer Node ? Node extends {
667
677
  readonly type: "parallel";
668
678
  readonly states: infer Children extends Machine.StateSchemas;
@@ -711,7 +721,7 @@ type FullSnapshotBuilderWithPrefix<States extends Machine.StateSchemas, Prefix e
711
721
  } & {
712
722
  readonly [Key in ChoiceStateKey<States>]: () => Machine.ChoiceTargetInstruction<Machine.JoinPath<Prefix, Key>>;
713
723
  };
714
- type FullSnapshotMethod<States extends Machine.StateSchemas, StateId extends ActiveStateKey<States>, Prefix extends string> = Machine.NodeSchema<States[StateId]> extends never ? FromMethod<FullSnapshotFromArguments<States, StateId, Prefix>, FullSnapshotResult<States, StateId, Prefix>> : ((...args: FullSnapshotArguments<States, StateId, Prefix>) => FullSnapshotResult<States, StateId, Prefix>) & FromMethod<FullSnapshotFromArguments<States, StateId, Prefix>, FullSnapshotResult<States, StateId, Prefix>>;
724
+ type FullSnapshotMethod<States extends Machine.StateSchemas, StateId extends ActiveStateKey<States>, Prefix extends string> = Machine.NodeSchema<States[StateId]> extends never ? FromMethod<FullSnapshotFromArguments<States, StateId, Prefix>, FullSnapshotResult<States, StateId, Prefix>> : DecodedMethod<FullSnapshotArguments<States, StateId, Prefix>, FullSnapshotResult<States, StateId, Prefix>> & FromMethod<FullSnapshotFromArguments<States, StateId, Prefix>, FullSnapshotResult<States, StateId, Prefix>>;
715
725
  type FullSnapshotArguments<States extends Machine.StateSchemas, StateId extends ActiveStateKey<States>, Prefix extends string, Path extends string = Machine.JoinPath<Prefix, StateId>> = States[StateId] extends infer Node ? Node extends {
716
726
  readonly type: "parallel";
717
727
  readonly states: infer Children extends Machine.StateSchemas;
@@ -774,7 +784,7 @@ type HistorySnapshotResult<States extends Machine.StateSchemas, StateId extends
774
784
  } ? Machine.ParallelSnapshot<Path, NodeValue<Node>, HistorySnapshotRegions<Children, Path, Owner>> : Node extends {
775
785
  readonly states: infer Children extends Machine.StateSchemas;
776
786
  } ? Machine.CompoundSnapshot<Path, NodeValue<Node>, HistorySnapshotWithPrefix<Children, Owner, Path>> : never : never;
777
- type HistorySnapshotMethod<States extends Machine.StateSchemas, StateId extends ActiveStateKey<States>, Prefix extends string, Owner extends string> = Machine.NodeSchema<States[StateId]> extends never ? FromMethod<HistorySnapshotFromArguments<States, StateId, Prefix, Owner>, HistorySnapshotResult<States, StateId, Prefix, Owner>> : ((...args: HistorySnapshotArguments<States, StateId, Prefix, Owner>) => HistorySnapshotResult<States, StateId, Prefix, Owner>) & FromMethod<HistorySnapshotFromArguments<States, StateId, Prefix, Owner>, HistorySnapshotResult<States, StateId, Prefix, Owner>>;
787
+ type HistorySnapshotMethod<States extends Machine.StateSchemas, StateId extends ActiveStateKey<States>, Prefix extends string, Owner extends string> = Machine.NodeSchema<States[StateId]> extends never ? FromMethod<HistorySnapshotFromArguments<States, StateId, Prefix, Owner>, HistorySnapshotResult<States, StateId, Prefix, Owner>> : DecodedMethod<HistorySnapshotArguments<States, StateId, Prefix, Owner>, HistorySnapshotResult<States, StateId, Prefix, Owner>> & FromMethod<HistorySnapshotFromArguments<States, StateId, Prefix, Owner>, HistorySnapshotResult<States, StateId, Prefix, Owner>>;
778
788
  type HistorySnapshotWithPrefix<States extends Machine.StateSchemas, Owner extends string, Prefix extends string> = {
779
789
  readonly [Key in ActiveStateKey<States>]: Owner extends Machine.JoinPath<Prefix, Key> | `${Machine.JoinPath<Prefix, Key>}.${string}` ? HistorySnapshotResult<States, Key, Prefix, Owner> : never;
780
790
  }[ActiveStateKey<States>];
@@ -836,7 +846,8 @@ type LocalTargetBuilderForScope<States extends Machine.StateSchemas, Scope exten
836
846
  *
837
847
  * @since 0.4.0
838
848
  */
839
- readonly with: (<Result extends ConstructionResult<LocalTargetResultWithPrefix<States, Children, Scope>>>(value: Machine.StateByIdentifier<States, Scope>, state: (builder: LocalTargetBuilderWithPrefix<States, Children, Scope, Source>) => Result) => Result) & {
849
+ readonly with: {
850
+ readonly decoded: <Result extends ConstructionResult<LocalTargetResultWithPrefix<States, Children, Scope>>>(value: Machine.StateByIdentifier<States, Scope>, state: (builder: LocalTargetBuilderWithPrefix<States, Children, Scope, Source>) => Result) => Result;
840
851
  readonly from: ConstructionSelectorFromCallable<Machine.SchemaByIdentifier<States, Scope>["~type.make.in"], LocalTargetBuilderWithPrefix<States, Children, Scope, Source>, LocalTargetResultWithPrefix<States, Children, Scope>>;
841
852
  };
842
853
  } : {}) : {};
@@ -2217,12 +2228,14 @@ export declare namespace Machine {
2217
2228
  readonly type: "direct";
2218
2229
  readonly target: Path | undefined;
2219
2230
  readonly selection: TransitionTargetSelection<Path | undefined>;
2231
+ readonly updates: ReadonlyArray<string>;
2220
2232
  } | {
2221
2233
  readonly type: "branch";
2222
2234
  readonly key: string;
2223
2235
  readonly title: string;
2224
2236
  readonly target: Path | undefined;
2225
2237
  readonly selection: TransitionTargetSelection<Path | undefined>;
2238
+ readonly updates: ReadonlyArray<string>;
2226
2239
  };
2227
2240
  /** The statically selected root entry for machine startup. */
2228
2241
  interface InitialDefinition<Path extends string = string> {
@@ -2234,9 +2247,10 @@ export declare namespace Machine {
2234
2247
  *
2235
2248
  * **Details**
2236
2249
  *
2237
- * Every branch exposes its selected target without executing its resolver.
2238
- * A compound local or branch target covers its descendants;
2239
- * `undefined` identifies an explicitly targetless branch.
2250
+ * Every branch exposes its static selection without executing its resolver.
2251
+ * A compound local or branch target covers its descendants. An `update`
2252
+ * selection keeps `target` undefined and records its value owner in
2253
+ * `selection.path`; `none` identifies an explicitly targetless branch.
2240
2254
  *
2241
2255
  * @category models
2242
2256
  * @since 0.4.0
@@ -2281,6 +2295,8 @@ export declare namespace Machine {
2281
2295
  * Choice microsteps retain each intermediate pseudo-state edge separately.
2282
2296
  */
2283
2297
  readonly resolvedTarget: TargetPath | undefined;
2298
+ /** Retained valued owners replaced by this transition. */
2299
+ readonly updates: ReadonlyArray<string>;
2284
2300
  }
2285
2301
  /**
2286
2302
  * Constructor arguments for a machine initial state function.
@@ -2841,6 +2857,38 @@ export declare namespace Machine {
2841
2857
  readonly [AncestorStateId in ValuedStateIdentifier<States>]: StateByIdentifier<States, AncestorStateId>;
2842
2858
  }>;
2843
2859
  }
2860
+ /**
2861
+ * Opaque instruction that replaces one active compound or parallel state's
2862
+ * value without changing its active descendants.
2863
+ *
2864
+ * @category models
2865
+ * @since 0.21.0
2866
+ */
2867
+ interface StateUpdate<States extends StateSchemas, StateId extends ValuedStateIdentifier<States>> {
2868
+ readonly [Topology.StateUpdateTypeId]: {
2869
+ readonly states: Types.Covariant<States>;
2870
+ readonly owner: Types.Covariant<StateId>;
2871
+ };
2872
+ }
2873
+ /**
2874
+ * Opaque result that combines one topology target with one retained owner
2875
+ * value replacement in the same microstep.
2876
+ *
2877
+ * @category models
2878
+ * @since 0.22.0
2879
+ */
2880
+ interface CombinedTarget<Result, States extends StateSchemas, Owner extends ValuedStateIdentifier<States>> {
2881
+ readonly [Topology.CombinedTargetTypeId]: {
2882
+ readonly result: Types.Covariant<Result>;
2883
+ readonly states: Types.Covariant<States>;
2884
+ readonly owner: Types.Covariant<Owner>;
2885
+ };
2886
+ }
2887
+ /** @internal */
2888
+ type StateUpdateBuilder<States extends StateSchemas, StateId extends ValuedStateIdentifier<States>> = {
2889
+ readonly decoded: (value: StateByIdentifier<States, StateId>) => StateUpdate<States, StateId>;
2890
+ readonly from: FromCallable<readonly [input: SchemaByIdentifier<States, StateId>["~type.make.in"]], StateUpdate<States, StateId>>;
2891
+ };
2844
2892
  /**
2845
2893
  * Opaque result returned by an explicitly targetless transition.
2846
2894
  *
@@ -3025,40 +3073,56 @@ export declare namespace Machine {
3025
3073
  * @category models
3026
3074
  * @since 0.14.0
3027
3075
  */
3028
- interface TargetSelection<out Result, out Path extends string | undefined = string | undefined, out Kind extends Topology.TargetSelectionKind = Topology.TargetSelectionKind> {
3076
+ interface TargetSelection<out Result, out Path extends string | undefined = string | undefined, out Kind extends Topology.TargetSelectionKind = Topology.TargetSelectionKind, out Scope extends Topology.TargetSelectionScope | undefined = Topology.TargetSelectionScope | undefined> {
3029
3077
  readonly [Topology.TargetSelectionTypeId]: typeof Topology.TargetSelectionTypeId;
3030
3078
  readonly kind: Kind;
3031
- readonly scope: Topology.TargetSelectionScope | undefined;
3079
+ readonly scope: Scope;
3032
3080
  readonly path: Path;
3033
3081
  readonly "~effect/Machine/TargetSelectionResult"?: Types.Covariant<Result>;
3034
3082
  }
3035
- type SelectionValue<Builder, Path extends string, Kind extends Topology.TargetSelectionKind = "state"> = TargetSelection<Builder, Path, Kind>;
3036
- type SelectionMethod<Builder, Path extends string, Kind extends Topology.TargetSelectionKind = "state"> = () => SelectionValue<Builder, Path, Kind>;
3037
- type InitialSelectionMethod<Builder, Path extends string> = Builder extends {
3083
+ type SelectionValue<Builder, Path extends string, Kind extends Topology.TargetSelectionKind = "state", Scope extends Topology.TargetSelectionScope | undefined = Topology.TargetSelectionScope | undefined> = TargetSelection<Builder, Path, Kind, Scope>;
3084
+ type SelectionMethod<Builder, Path extends string, Kind extends Topology.TargetSelectionKind = "state", Scope extends Topology.TargetSelectionScope | undefined = Topology.TargetSelectionScope | undefined> = () => SelectionValue<Builder, Path, Kind, Scope>;
3085
+ type InitialSelectionMethod<Builder, Path extends string, Scope extends Topology.TargetSelectionScope> = Builder extends {
3038
3086
  readonly initial: infer Initial;
3039
3087
  } ? {
3040
- readonly initial: SelectionValue<Initial, Path, "initial">;
3088
+ readonly initial: SelectionValue<Initial, Path, "initial", Scope>;
3041
3089
  } : {};
3042
3090
  type SelectionTreeWithPrefix<AllStates extends StateSchemas, States extends StateSchemas, Prefix extends string, Scope extends "local" | "branch", Builder> = {
3043
3091
  readonly [Key in Extract<ActiveStateKey<States> | ChoiceStateKey<States>, keyof Builder>]: SelectionNode<AllStates, States[Key], JoinPath<Prefix, Key>, Scope, Builder[Key]>;
3044
3092
  };
3045
- type SelectionNode<AllStates extends StateSchemas, Node, Path extends string, Scope extends "local" | "branch", Builder> = Node extends ChoiceStateNodeConfig ? SelectionMethod<Builder, Path, "choice"> : Node extends {
3093
+ type SelectionNode<AllStates extends StateSchemas, Node, Path extends string, Scope extends "local" | "branch", Builder> = Node extends ChoiceStateNodeConfig ? SelectionMethod<Builder, Path, "choice", Scope> : Node extends {
3046
3094
  readonly states: infer Children extends StateSchemas;
3047
- } ? SelectionMethod<Builder, Path> & InitialSelectionMethod<Builder, Path> & SelectionTreeWithPrefix<AllStates, Children, Path, Scope, Builder> : SelectionMethod<Builder, Path>;
3095
+ } ? SelectionMethod<Builder, Path, "state", Scope> & InitialSelectionMethod<Builder, Path, Scope> & SelectionTreeWithPrefix<AllStates, Children, Path, Scope, Builder> : SelectionMethod<Builder, Path, "state", Scope>;
3096
+ /** @internal */
3097
+ type StateUpdateSelectionForNode<AllStates extends StateSchemas, Node, Path extends string, Scope extends "local" | "branch"> = Node extends {
3098
+ readonly states: StateSchemas;
3099
+ } ? NodeSchema<Node> extends never ? {} : {
3100
+ readonly update: SelectionValue<StateUpdateBuilder<AllStates, Extract<Path, ValuedStateIdentifier<AllStates>>>, Path, "update", Scope>;
3101
+ } : {};
3102
+ /** @internal */
3103
+ type BranchUpdateSelectionPath<AllStates extends StateSchemas, Node, Path extends string, Rest extends string, Scope extends "local" | "branch" = "branch"> = StateUpdateSelectionForNode<AllStates, Node, Path, Scope> & (Node extends {
3104
+ readonly states: infer Children extends StateSchemas;
3105
+ } ? Rest extends `${infer Head}.${infer Tail}` ? Head extends keyof Children ? {
3106
+ readonly [Key in Head]: BranchUpdateSelectionPath<AllStates, Children[Head], JoinPath<Path, Head>, Tail, Scope>;
3107
+ } : {} : Rest extends keyof Children ? {
3108
+ readonly [Key in Rest]: StateUpdateSelectionForNode<AllStates, Children[Rest], JoinPath<Path, Rest>, Scope>;
3109
+ } : {} : {});
3048
3110
  type FullSelectionNode<AllStates extends StateSchemas, Node, Path extends StateIdentifier<AllStates>, Builder> = Node extends {
3049
3111
  readonly states: StateSchemas;
3050
- } ? SelectionMethod<Builder, Path> & InitialSelectionMethod<Builder, Path> : SelectionMethod<Builder, Path>;
3112
+ } ? SelectionMethod<Builder, Path, "state", "full"> & InitialSelectionMethod<Builder, Path, "full"> : SelectionMethod<Builder, Path, "state", "full">;
3051
3113
  type FullTargetSelector<States extends StateSchemas> = {
3052
3114
  readonly [Key in Extract<ActiveStateKey<States>, keyof FullTargetBuilder<States>>]: FullSelectionNode<States, States[Key], Extract<Key, StateIdentifier<States>>, FullTargetBuilder<States>[Key]>;
3053
3115
  };
3054
3116
  type BranchTargetSelector<States extends StateSchemas, Source extends StateNodeIdentifier<States>, Root extends string = Source extends `${infer Head}.${string}` ? Head : Source> = Root extends ActiveStateKey<States> ? Root extends keyof BranchTargetBuilder<States, Source> ? {
3055
- readonly [Key in Root]: SelectionNode<States, States[Key], Key, "branch", BranchTargetBuilder<States, Source>[Key]>;
3117
+ readonly [Key in Root]: SelectionNode<States, States[Key], Key, "branch", BranchTargetBuilder<States, Source>[Key]> & (Source extends ChoiceIdentifier<States> ? {} : Source extends `${Key}.${infer Rest}` ? BranchUpdateSelectionPath<States, States[Key], Key, Rest> : StateUpdateSelectionForNode<States, States[Key], Key, "branch">);
3056
3118
  } : {} : {};
3057
- type LocalTargetSelector<States extends StateSchemas, Source extends StateNodeIdentifier<States>> = NearestCompoundScope<States, Source> extends infer Scope extends StateIdentifier<States> ? ChildrenOf<States, Scope> extends infer Children extends StateSchemas ? LocalTargetBuilder<States, Source> extends infer Builder ? SelectionTreeWithPrefix<States, Children, Scope, "local", Builder> & ("with" extends keyof Builder ? {
3058
- readonly with: SelectionValue<Builder["with"], Scope>;
3059
- } : {}) : {} : {} : {};
3119
+ type LocalTargetSelector<States extends StateSchemas, Source extends StateNodeIdentifier<States>> = NearestCompoundScope<States, Source> extends infer Scope ? [Scope] extends [never] ? {} : Scope extends StateIdentifier<States> ? ChildrenOf<States, Scope> extends infer Children extends StateSchemas ? LocalTargetBuilder<States, Source> extends infer Builder ? SelectionTreeWithPrefix<States, Children, Scope, "local", Builder> & ("with" extends keyof Builder ? {
3120
+ readonly with: SelectionValue<Builder["with"], Scope, "state", "local">;
3121
+ } : {}) & (Source extends ChoiceIdentifier<States> ? {} : Scope extends ValuedStateIdentifier<States> ? {
3122
+ readonly update: SelectionValue<StateUpdateBuilder<States, Scope>, Scope, "update", "local">;
3123
+ } : {}) : {} : {} : {} : {};
3060
3124
  type HistorySelectionTree<AllStates extends StateSchemas, States extends StateSchemas, Prefix extends string, Builder> = {
3061
- readonly [Key in Extract<HistoryContainingKey<States>, keyof Builder>]: States[Key] extends HistoryStateNodeConfig ? SelectionValue<Builder[Key], JoinPath<Prefix, Key>, "history"> : States[Key] extends {
3125
+ readonly [Key in Extract<HistoryContainingKey<States>, keyof Builder>]: States[Key] extends HistoryStateNodeConfig ? SelectionValue<Builder[Key], JoinPath<Prefix, Key>, "history", "full"> : States[Key] extends {
3062
3126
  readonly states: infer Children extends StateSchemas;
3063
3127
  } ? HistorySelectionTree<AllStates, Children, JoinPath<Prefix, Key>, Builder[Key]> : never;
3064
3128
  };
@@ -3073,10 +3137,10 @@ export declare namespace Machine {
3073
3137
  */
3074
3138
  interface TargetSelector<States extends StateSchemas, Source extends StateNodeIdentifier<States>> {
3075
3139
  /** Handles the trigger without selecting a destination. */
3076
- readonly none: SelectionValue<TargetBuilder<States, Source>["none"], never, "none">;
3077
- /** Selects a destination inside the nearest active compound scope. */
3140
+ readonly none: SelectionValue<TargetBuilder<States, Source>["none"], never, "none", "local">;
3141
+ /** Selects a destination or updates the nearest active compound scope. */
3078
3142
  readonly local: LocalTargetSelector<States, Source>;
3079
- /** Selects a destination elsewhere under the currently active root. */
3143
+ /** Selects a destination or updates a valued active ancestor under the current root. */
3080
3144
  readonly branch: BranchTargetSelector<States, Source>;
3081
3145
  /** Selects a complete destination under any top-level state. */
3082
3146
  readonly full: FullTargetSelector<States>;
@@ -3088,8 +3152,8 @@ export declare namespace Machine {
3088
3152
  readonly [Key in Extract<ActiveStateKey<States>, keyof InitialBuilder<States>>]: States[Key] extends {
3089
3153
  readonly states: StateSchemas;
3090
3154
  } ? {
3091
- readonly initial: SelectionValue<InitialBuilder<States>[Key], Key, "initial">;
3092
- } : SelectionMethod<InitialBuilder<States>[Key], Key>;
3155
+ readonly initial: SelectionValue<InitialBuilder<States>[Key], Key, "initial", "initial">;
3156
+ } : SelectionMethod<InitialBuilder<States>[Key], Key, "state", "initial">;
3093
3157
  };
3094
3158
  /**
3095
3159
  * Context passed to a state/event handler.
@@ -3365,14 +3429,14 @@ export declare namespace Machine {
3365
3429
  * **Details**
3366
3430
  *
3367
3431
  * Handlers return snapshots for complete state replacement, target builder
3368
- * results for path-safe partial transitions, or `target.none()` for an
3369
- * explicitly targetless transition. Raw decoded state values and `void` are
3370
- * not accepted at transition boundaries.
3432
+ * results for path-safe partial transitions, state-value updates, or
3433
+ * `target.none()` for an explicitly targetless transition. Raw decoded state
3434
+ * values and `void` are not accepted at transition boundaries.
3371
3435
  *
3372
3436
  * @category utility types
3373
3437
  * @since 0.4.0
3374
3438
  */
3375
- type HandlerResult<States extends StateSchemas, E, R> = Snapshot<States> | Target<States, StateIdentifier<States>> | HistoryTarget<States, HistoryIdentifier<States>> | ChoiceTarget<States, ChoiceIdentifier<States>> | StateConstruction<Snapshot<States> | Target<States, StateIdentifier<States>> | HistoryTarget<States, HistoryIdentifier<States>> | ChoiceTarget<States, ChoiceIdentifier<States>>> | NoTarget;
3439
+ type HandlerResult<States extends StateSchemas, E, R> = Snapshot<States> | Target<States, StateIdentifier<States>> | HistoryTarget<States, HistoryIdentifier<States>> | ChoiceTarget<States, ChoiceIdentifier<States>> | StateUpdate<States, ValuedStateIdentifier<States>> | CombinedTarget<Target<States, StateIdentifier<States>> | Snapshot<States>, States, ValuedStateIdentifier<States>> | StateConstruction<Snapshot<States> | Target<States, StateIdentifier<States>> | HistoryTarget<States, HistoryIdentifier<States>> | ChoiceTarget<States, ChoiceIdentifier<States>> | StateUpdate<States, ValuedStateIdentifier<States>>> | NoTarget;
3376
3440
  /** A choice resolver must always select a typed target synchronously. */
3377
3441
  type ChoiceResult<States extends StateSchemas, E, R> = Snapshot<States> | Target<States, StateIdentifier<States>> | HistoryTarget<States, HistoryIdentifier<States>> | ChoiceTarget<States, ChoiceIdentifier<States>> | StateConstruction<Snapshot<States> | Target<States, StateIdentifier<States>> | HistoryTarget<States, HistoryIdentifier<States>> | ChoiceTarget<States, ChoiceIdentifier<States>>>;
3378
3442
  /**
@@ -3613,19 +3677,59 @@ export declare namespace Machine {
3613
3677
  }
3614
3678
  /** The only transition value accepted by machine handler APIs. */
3615
3679
  type TransitionConfig<States extends StateSchemas, Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, StateId extends StateNodeIdentifier<States>, Context, Reenter extends boolean = false, Acceptance extends TransitionAcceptance = "required"> = TransitionBuilderInput<States, Events, Emits, StateId, Context, Reenter, Acceptance>;
3616
- type SelectionBuilder<Selection> = Selection extends TargetSelection<infer Builder, any, any> ? Builder : never;
3617
- type SelectionKind<Selection> = Selection extends TargetSelection<any, any, infer Kind> ? Kind : never;
3618
- type SelectionPath<Selection> = Selection extends TargetSelection<any, infer Path, any> ? Path : never;
3680
+ type SelectionBuilder<Selection> = Selection extends TargetSelection<infer Builder, any, any, any> ? Builder : never;
3681
+ type SelectionKind<Selection> = Selection extends TargetSelection<any, any, infer Kind, any> ? Kind : never;
3682
+ type SelectionPath<Selection> = Selection extends TargetSelection<any, infer Path, any, any> ? Path : never;
3683
+ type SelectionScope<Selection> = Selection extends TargetSelection<any, any, any, infer Scope> ? Scope : never;
3619
3684
  type TargetBuilderResult<Builder> = (Builder extends (...args: any) => infer Result ? Result : never) | (Builder extends {
3685
+ readonly decoded: (...args: any) => infer Result;
3686
+ } ? Result : never) | (Builder extends {
3620
3687
  readonly from: (...args: any) => infer Result;
3621
3688
  } ? Result : never);
3622
3689
  type SelectedTargetResult<Selection> = SelectionBuilder<Selection> extends infer Builder ? TargetBuilderResult<Builder> : never;
3690
+ type RetainedUpdateOwner<States extends StateSchemas, Source extends StateNodeIdentifier<States>, Selection> = Extract<ParentStateIdentifier<Source>, ParentStateIdentifier<Extract<SelectionPath<Selection>, string>> & ValuedStateIdentifier<States>>;
3691
+ type RetainedOwnerSelector<Owner extends string> = () => TargetSelection<any, Owner, "state", "branch">;
3692
+ /**
3693
+ * Destination construction returned when a transition declares one retained
3694
+ * valued owner with `.updating(...)`.
3695
+ *
3696
+ * @category models
3697
+ * @since 0.22.0
3698
+ */
3699
+ interface UpdatingStateConstruction<Result, States extends StateSchemas, Owner extends ValuedStateIdentifier<States>> {
3700
+ /** Combines the selected topology with the required owner replacement. */
3701
+ readonly update: (update: StateUpdate<States, Owner>) => CombinedTarget<UnwrapConstruction<Result>, States, Owner>;
3702
+ }
3703
+ type UpdatingCallable<Callable, States extends StateSchemas, Owner extends ValuedStateIdentifier<States>> = Callable extends {
3704
+ (...args: infer Arguments1): infer Result1;
3705
+ (...args: infer Arguments2): infer Result2;
3706
+ } ? {
3707
+ (...args: Arguments1): UpdatingStateConstruction<Result1, States, Owner>;
3708
+ (...args: Arguments2): UpdatingStateConstruction<Result2, States, Owner>;
3709
+ } : Callable extends (...args: infer Arguments) => infer Result ? (...args: Arguments) => UpdatingStateConstruction<Result, States, Owner> : never;
3710
+ type UpdatingTargetBuilder<Builder, States extends StateSchemas, Owner extends ValuedStateIdentifier<States>> = {
3711
+ readonly [Key in keyof Builder]: Key extends "from" | "decoded" ? UpdatingCallable<Builder[Key], States, Owner> : Builder[Key];
3712
+ };
3623
3713
  type SelectionSupportsDefaultConstruction<Selection> = SelectionKind<Selection> extends "none" ? true : SelectionBuilder<Selection> extends {
3624
3714
  readonly from: (...args: infer Args) => any;
3625
- } ? [] extends Args ? true : false : SelectionBuilder<Selection> extends (...args: infer Args) => any ? [] extends Args ? true : false : false;
3715
+ } ? [] extends Args ? true : false : false;
3626
3716
  type TransitionResolveContext<Context, Selection> = Omit<Context, "target"> & (SelectionKind<Selection> extends "none" ? {} : {
3627
3717
  readonly target: SelectionBuilder<Selection>;
3628
3718
  });
3719
+ type StateUpdateResolveContext<States extends StateSchemas, Context, Owner extends ValuedStateIdentifier<States>> = Omit<Context, "target"> & {
3720
+ /** Decoded owner value from the pre-transition snapshot. */
3721
+ readonly current: StateByIdentifier<States, Owner>;
3722
+ /** Constructs the complete replacement for the selected owner. */
3723
+ readonly owner: StateUpdateBuilder<States, Owner>;
3724
+ };
3725
+ type UpdatingTransitionResolveContext<States extends StateSchemas, Context, Selection, Owner extends ValuedStateIdentifier<States>> = Omit<Context, "target"> & {
3726
+ /** Decoded owner value from the pre-transition snapshot. */
3727
+ readonly current: StateByIdentifier<States, Owner>;
3728
+ /** Constructs the selected topology and requires `.update(...)`. */
3729
+ readonly target: UpdatingTargetBuilder<SelectionBuilder<Selection>, States, Owner>;
3730
+ /** Constructs the complete replacement for the retained owner. */
3731
+ readonly owner: StateUpdateBuilder<States, Owner>;
3732
+ };
3629
3733
  /** Context capability available only to explicitly declinable resolvers. */
3630
3734
  interface DeclineCapability {
3631
3735
  /** Declines this candidate and continues hierarchical transition selection. */
@@ -3633,6 +3737,10 @@ export declare namespace Machine {
3633
3737
  }
3634
3738
  type TransitionResolver<Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, Context, Selection> = (context: TransitionResolveContext<Context, Selection>, enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>) => SelectionKind<Selection> extends "none" ? undefined : SelectedTargetResult<Selection> | undefined;
3635
3739
  type DeclinableTransitionResolver<Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, Context, Selection> = (context: TransitionResolveContext<Context, Selection> & DeclineCapability, enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>) => (SelectionKind<Selection> extends "none" ? undefined : SelectedTargetResult<Selection> | undefined) | Declined;
3740
+ /** @internal */
3741
+ type StateUpdateResolver<States extends StateSchemas, Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, Context, Owner extends ValuedStateIdentifier<States>> = (context: StateUpdateResolveContext<States, Context, Owner>, enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>) => StateUpdate<States, Owner>;
3742
+ /** @internal */
3743
+ type DeclinableStateUpdateResolver<States extends StateSchemas, Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, Context, Owner extends ValuedStateIdentifier<States>> = (context: StateUpdateResolveContext<States, Context, Owner> & DeclineCapability, enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>) => StateUpdate<States, Owner> | Declined;
3636
3744
  /** One named destination declared by a branching transition. */
3637
3745
  interface TransitionBranchInput<Selection extends TargetSelection<any, any, any> = TargetSelection<any, any, any>> {
3638
3746
  /** Exact topology destination available to the branching resolver. */
@@ -3716,15 +3824,33 @@ export declare namespace Machine {
3716
3824
  * @inlineType TransitionReenterOption
3717
3825
  */
3718
3826
  type TransitionTarget<States extends StateSchemas, Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, StateId extends StateNodeIdentifier<States>, Context, Reenter extends boolean, Acceptance extends TransitionAcceptance, Selection extends TargetSelection<any, any, any>> = Selection & (SelectionSupportsDefaultConstruction<Selection> extends true ? BuiltTransition<States, Events, Emits, StateId, Context, Reenter, SelectionKind<Selection> extends "none" ? undefined : SelectedTargetResult<Selection> | undefined, "required"> : {}) & {
3719
- /**
3720
- * Evaluates state construction and queued commands only after this
3721
- * transition has been selected.
3722
- */
3827
+ /** Evaluates state construction after this transition is selected. */
3723
3828
  readonly resolve: TransitionResolveRequired<States, Events, Emits, StateId, Context, Reenter, Selection> & ("declinable" extends Acceptance ? TransitionResolveDeclinable<States, Events, Emits, StateId, Context, Reenter, Selection> : {});
3724
3829
  } & ([Reenter] extends [true] ? SelectionSupportsDefaultConstruction<Selection> extends true ? {
3725
3830
  /** Reenters the source using the selected target's default construction. */
3726
3831
  readonly reenter: () => BuiltTransition<States, Events, Emits, StateId, Context, Reenter, SelectionKind<Selection> extends "none" ? undefined : SelectedTargetResult<Selection> | undefined, "required">;
3727
- } : {} : {});
3832
+ } : {} : {}) & (SelectionKind<Selection> extends "state" ? SelectionScope<Selection> extends "local" | "branch" ? RetainedUpdateOwner<States, StateId, Selection> extends infer Owner extends ValuedStateIdentifier<States> ? [
3833
+ Owner
3834
+ ] extends [never] ? {} : {
3835
+ /** Declares one valued owner retained by the selected topology. */
3836
+ readonly updating: <SelectedOwner extends Owner>(owner: RetainedOwnerSelector<SelectedOwner>) => UpdatingTransitionTarget<States, Events, Emits, StateId, Context, Reenter, Acceptance, Selection, SelectedOwner>;
3837
+ } : {} : {} : {});
3838
+ /** A topology selection that requires one retained owner replacement. */
3839
+ type UpdatingTransitionTarget<States extends StateSchemas, Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, StateId extends StateNodeIdentifier<States>, Context, Reenter extends boolean, Acceptance extends TransitionAcceptance, Selection extends TargetSelection<any, any, "state">, Owner extends ValuedStateIdentifier<States>> = Selection & {
3840
+ /** @internal */
3841
+ readonly "~effect/Machine/UpdatingTransitionTarget": Owner;
3842
+ readonly resolve: ((resolve: (context: UpdatingTransitionResolveContext<States, Context, Selection, Owner>, enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>) => CombinedTarget<UnwrapConstruction<SelectedTargetResult<Selection>>, States, Owner>, options?: TransitionRequiredOptions<Reenter>) => BuiltTransition<States, Events, Emits, StateId, Context, Reenter, CombinedTarget<UnwrapConstruction<SelectedTargetResult<Selection>>, States, Owner>, "required">) & ("declinable" extends Acceptance ? (resolve: (context: UpdatingTransitionResolveContext<States, Context, Selection, Owner> & DeclineCapability, enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>) => CombinedTarget<UnwrapConstruction<SelectedTargetResult<Selection>>, States, Owner> | Declined, options: TransitionDeclinableOptions<Reenter>) => BuiltTransition<States, Events, Emits, StateId, Context, Reenter, CombinedTarget<UnwrapConstruction<SelectedTargetResult<Selection>>, States, Owner> | Declined, "declinable"> : {});
3843
+ };
3844
+ /** @internal */
3845
+ interface StateUpdateTransitionRequired<States extends StateSchemas, Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, StateId extends StateNodeIdentifier<States>, Context, Reenter extends boolean, Selection extends TargetSelection<any, any, "update">> {
3846
+ (resolve: StateUpdateResolver<States, Events, Emits, Context, Extract<SelectionPath<Selection>, ValuedStateIdentifier<States>>>, options?: TransitionRequiredOptions<Reenter>): BuiltTransition<States, Events, Emits, StateId, Context, Reenter, SelectedTargetResult<Selection>, "required">;
3847
+ }
3848
+ /** @internal */
3849
+ interface StateUpdateTransitionDeclinable<States extends StateSchemas, Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, StateId extends StateNodeIdentifier<States>, Context, Reenter extends boolean, Selection extends TargetSelection<any, any, "update">> {
3850
+ (resolve: DeclinableStateUpdateResolver<States, Events, Emits, Context, Extract<SelectionPath<Selection>, ValuedStateIdentifier<States>>>, options: TransitionDeclinableOptions<Reenter>): BuiltTransition<States, Events, Emits, StateId, Context, Reenter, SelectedTargetResult<Selection> | Declined, "declinable">;
3851
+ }
3852
+ /** @internal */
3853
+ type StateUpdateTransition<States extends StateSchemas, Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, StateId extends StateNodeIdentifier<States>, Context, Reenter extends boolean, Acceptance extends TransitionAcceptance, Selection extends TargetSelection<any, any, "update">> = Selection & StateUpdateTransitionRequired<States, Events, Emits, StateId, Context, Reenter, Selection> & ("declinable" extends Acceptance ? StateUpdateTransitionDeclinable<States, Events, Emits, StateId, Context, Reenter, Selection> : {});
3728
3854
  /** @internal Type evidence retained by a machine initial-entry declaration. */
3729
3855
  interface InitialBuilderEvidence<out Selection> {
3730
3856
  readonly [InitialBuilderTypeId]: Types.Covariant<Selection>;
@@ -3748,7 +3874,7 @@ export declare namespace Machine {
3748
3874
  type InitialSelector<States extends StateSchemas, Input = void> = InitialSelectorNode<Input, InitialTargetSelector<States>>;
3749
3875
  /** Target-first initial-entry declaration accepted by {@link make}. */
3750
3876
  type InitialBuilderInput<States extends StateSchemas, Input> = (to: InitialSelector<States, Input>) => InitialBuilderEvidence<TargetSelection<any, any, any>>;
3751
- type TransitionSelectorNode<States extends StateSchemas, Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, StateId extends StateNodeIdentifier<States>, Context, Reenter extends boolean, Acceptance extends TransitionAcceptance, Node> = Node extends (...args: infer Args) => infer Selection ? Selection extends TargetSelection<any, any, any> ? ((...args: Args) => TransitionTarget<States, Events, Emits, StateId, Context, Reenter, Acceptance, Selection>) & {
3877
+ type TransitionSelectorNode<States extends StateSchemas, Events extends ReadonlyArray<TaggedSchema>, Emits extends ReadonlyArray<TaggedSchema>, StateId extends StateNodeIdentifier<States>, Context, Reenter extends boolean, Acceptance extends TransitionAcceptance, Node> = Node extends TargetSelection<any, any, "update"> ? StateUpdateTransition<States, Events, Emits, StateId, Context, Reenter, Acceptance, Node> : Node extends (...args: infer Args) => infer Selection ? Selection extends TargetSelection<any, any, any> ? ((...args: Args) => TransitionTarget<States, Events, Emits, StateId, Context, Reenter, Acceptance, Selection>) & {
3752
3878
  readonly [Key in keyof Node]: TransitionSelectorNode<States, Events, Emits, StateId, Context, Reenter, Acceptance, Node[Key]>;
3753
3879
  } : never : Node extends TargetSelection<any, any, any> ? TransitionTarget<States, Events, Emits, StateId, Context, Reenter, Acceptance, Node> : {
3754
3880
  readonly [Key in keyof Node]: TransitionSelectorNode<States, Events, Emits, StateId, Context, Reenter, Acceptance, Node[Key]>;
@@ -4580,13 +4706,13 @@ interface Make {
4580
4706
  * const counter = Machine.make({
4581
4707
  * states: States.states,
4582
4708
  * events: Events,
4583
- * initial: (to) => to.Count().resolve(({ target }) => target(new Count({ value: 0 })))
4709
+ * initial: (to) => to.Count().resolve(({ target }) => target.decoded(new Count({ value: 0 })))
4584
4710
  * }).handle({
4585
4711
  * Count: {
4586
4712
  * on: {
4587
4713
  * Increment: (to) =>
4588
4714
  * to.full.Count().resolve(({ event, state, target }) =>
4589
- * target(new Count({ value: state.value + event.by })))
4715
+ * target.decoded(new Count({ value: state.value + event.by })))
4590
4716
  * }
4591
4717
  * }
4592
4718
  * })
@@ -4810,7 +4936,16 @@ type TransitionBranchRecordError<Message extends string, Key extends PropertyKey
4810
4936
  readonly key: Key;
4811
4937
  };
4812
4938
  type InvalidStaticTransitionBranchKey<Branches> = Extract<keyof Branches, "" | number | symbol>;
4813
- type ValidateTransitionBranchRecord<Branches> = [keyof Branches] extends [never] ? TransitionBranchRecordError<"Branch records must contain at least one branch"> : [InvalidStaticTransitionBranchKey<Branches>] extends [never] ? unknown : TransitionBranchRecordError<"Branch keys must be non-empty, non-index strings", InvalidStaticTransitionBranchKey<Branches>>;
4939
+ type InvalidUpdatingTransitionBranchKey<Branches> = {
4940
+ readonly [Key in keyof Branches]: Branches[Key] extends {
4941
+ readonly target: {
4942
+ readonly "~effect/Machine/UpdatingTransitionTarget": string;
4943
+ };
4944
+ } ? Key : never;
4945
+ }[keyof Branches];
4946
+ type ValidateTransitionBranchRecord<Branches> = [keyof Branches] extends [never] ? TransitionBranchRecordError<"Branch records must contain at least one branch"> : [InvalidStaticTransitionBranchKey<Branches>] extends [never] ? [
4947
+ InvalidUpdatingTransitionBranchKey<Branches>
4948
+ ] extends [never] ? unknown : TransitionBranchRecordError<"Updating targets require a direct resolver", InvalidUpdatingTransitionBranchKey<Branches>> : TransitionBranchRecordError<"Branch keys must be non-empty, non-index strings", InvalidStaticTransitionBranchKey<Branches>>;
4814
4949
  /**
4815
4950
  * Plans the initial state for a machine without executing machine commands.
4816
4951
  *
@@ -4908,9 +5043,10 @@ export declare const initialDefinition: <M extends Machine.Any>(machine: M) => M
4908
5043
  *
4909
5044
  * Event handlers retain their handler-key order within each source state and
4910
5045
  * are followed by eventless and completion handlers. This function does not
4911
- * execute resolvers. Every direct, named, and targetless branch exposes the
4912
- * destination selected by its required static `target` declaration, while
4913
- * `acceptance` reports whether the resolver may decline the transition.
5046
+ * execute resolvers. Every branch exposes its static selection. State updates
5047
+ * retain the updated owner in `selection.path` while leaving `target`
5048
+ * undefined because they do not change topology. `acceptance` reports whether
5049
+ * the resolver may decline the transition.
4914
5050
  *
4915
5051
  * @category getters
4916
5052
  * @since 0.4.0