@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/src/Machine.ts CHANGED
@@ -286,7 +286,7 @@ export interface Definition<
286
286
  * on: {
287
287
  * Increment: (to) =>
288
288
  * to.full.Count().resolve(({ event, state, target }) =>
289
- * target(new Count({ value: state.value + event.by })))
289
+ * target.decoded(new Count({ value: state.value + event.by })))
290
290
  * }
291
291
  * }
292
292
  * })
@@ -972,6 +972,16 @@ type FromMethod<Arguments extends ReadonlyArray<unknown>, Result> = {
972
972
  readonly from: FromCallable<Arguments, Machine.StateConstruction<Result>>
973
973
  }
974
974
 
975
+ type DecodedMethod<Arguments extends ReadonlyArray<unknown>, Result> = {
976
+ /**
977
+ * Constructs the selected state from an already-decoded schema value. The
978
+ * machine validates the value against the schema's type side while planning.
979
+ *
980
+ * @since 0.22.0
981
+ */
982
+ readonly decoded: (...args: Arguments) => Result
983
+ }
984
+
975
985
  type ConstructionResult<Result> = Result | Machine.StateConstruction<Result>
976
986
 
977
987
  type UnwrapConstruction<Result> = Result extends Machine.StateConstruction<infer Value> ? Value : Result
@@ -997,9 +1007,7 @@ type NodeBuilderMethod<
997
1007
  > = Machine.NodeSchema<Node> extends never ? {
998
1008
  readonly from: FromCallable<FromArguments, FromResult>
999
1009
  }
1000
- :
1001
- & ((...args: Arguments) => Result)
1002
- & { readonly from: FromCallable<FromArguments, FromResult> }
1010
+ : DecodedMethod<Arguments, Result> & { readonly from: FromCallable<FromArguments, FromResult> }
1003
1011
 
1004
1012
  type NodeMethod<
1005
1013
  Node,
@@ -1007,7 +1015,7 @@ type NodeMethod<
1007
1015
  Result,
1008
1016
  FromArguments extends ReadonlyArray<unknown>
1009
1017
  > = Machine.NodeSchema<Node> extends never ? FromMethod<FromArguments, Result>
1010
- : ((...args: Arguments) => Result) & FromMethod<FromArguments, Result>
1018
+ : DecodedMethod<Arguments, Result> & FromMethod<FromArguments, Result>
1011
1019
 
1012
1020
  type NodeMethodWithInitial<
1013
1021
  Node,
@@ -1020,7 +1028,7 @@ type NodeMethodWithInitial<
1020
1028
  readonly initial: InitialTargetFactory<Node, Path>
1021
1029
  }
1022
1030
  :
1023
- & ((...args: Arguments) => Result)
1031
+ & DecodedMethod<Arguments, Result>
1024
1032
  & {
1025
1033
  readonly from: FromCallable<FromArguments, Machine.StateConstruction<Result>>
1026
1034
  readonly initial: InitialTargetFactory<Node, Path>
@@ -1038,11 +1046,11 @@ interface InitialTargetFactory<
1038
1046
  Node,
1039
1047
  Path extends string
1040
1048
  > {
1041
- (...args: WithNodeValue<Node, readonly []>): Machine.InitialTarget<Path>
1042
1049
  readonly from: FromCallable<
1043
1050
  WithNodeInput<Node, readonly []>,
1044
1051
  Machine.StateConstruction<Machine.InitialTarget<Path>>
1045
1052
  >
1053
+ readonly decoded: (...args: WithNodeValue<Node, readonly []>) => Machine.InitialTarget<Path>
1046
1054
  }
1047
1055
 
1048
1056
  type NodeConstructionSelectorFromCallable<Node, Builder, Result> = Machine.NodeSchema<Node> extends never ? {
@@ -1056,15 +1064,14 @@ type NestedTargetMethod<Node, Builder, Result, Path extends string> = Machine.No
1056
1064
  readonly from: NodeConstructionSelectorFromCallable<Node, Builder, Result>
1057
1065
  readonly initial: InitialTargetFactory<Node, Path>
1058
1066
  }
1059
- :
1060
- & (<Selected extends ConstructionResult<Result>>(
1067
+ : {
1068
+ readonly decoded: <Selected extends ConstructionResult<Result>>(
1061
1069
  value: NodeValue<Node>,
1062
1070
  state: (builder: Builder) => Selected
1063
- ) => Selected)
1064
- & {
1065
- readonly from: NodeConstructionSelectorFromCallable<Node, Builder, Result>
1066
- readonly initial: InitialTargetFactory<Node, Path>
1067
- }
1071
+ ) => Selected
1072
+ readonly from: NodeConstructionSelectorFromCallable<Node, Builder, Result>
1073
+ readonly initial: InitialTargetFactory<Node, Path>
1074
+ }
1068
1075
 
1069
1076
  type ConstructionSelectorFromCallable<Input, Builder, Result> = {} extends Input ? {
1070
1077
  <Selected extends ConstructionResult<Result>>(
@@ -1100,9 +1107,10 @@ type InitialSnapshotMethod<
1100
1107
  InitialSnapshotResult<States, StateId, Prefix>
1101
1108
  >
1102
1109
  :
1103
- & ((
1104
- ...args: InitialSnapshotArguments<States, StateId, Prefix>
1105
- ) => InitialSnapshotResult<States, StateId, Prefix>)
1110
+ & DecodedMethod<
1111
+ InitialSnapshotArguments<States, StateId, Prefix>,
1112
+ InitialSnapshotResult<States, StateId, Prefix>
1113
+ >
1106
1114
  & FromMethod<
1107
1115
  InitialSnapshotFromArguments<States, StateId, Prefix>,
1108
1116
  InitialSnapshotResult<States, StateId, Prefix>
@@ -1242,9 +1250,10 @@ type FullSnapshotMethod<
1242
1250
  FullSnapshotResult<States, StateId, Prefix>
1243
1251
  >
1244
1252
  :
1245
- & ((
1246
- ...args: FullSnapshotArguments<States, StateId, Prefix>
1247
- ) => FullSnapshotResult<States, StateId, Prefix>)
1253
+ & DecodedMethod<
1254
+ FullSnapshotArguments<States, StateId, Prefix>,
1255
+ FullSnapshotResult<States, StateId, Prefix>
1256
+ >
1248
1257
  & FromMethod<
1249
1258
  FullSnapshotFromArguments<States, StateId, Prefix>,
1250
1259
  FullSnapshotResult<States, StateId, Prefix>
@@ -1416,9 +1425,10 @@ type HistorySnapshotMethod<
1416
1425
  HistorySnapshotResult<States, StateId, Prefix, Owner>
1417
1426
  >
1418
1427
  :
1419
- & ((
1420
- ...args: HistorySnapshotArguments<States, StateId, Prefix, Owner>
1421
- ) => HistorySnapshotResult<States, StateId, Prefix, Owner>)
1428
+ & DecodedMethod<
1429
+ HistorySnapshotArguments<States, StateId, Prefix, Owner>,
1430
+ HistorySnapshotResult<States, StateId, Prefix, Owner>
1431
+ >
1422
1432
  & FromMethod<
1423
1433
  HistorySnapshotFromArguments<States, StateId, Prefix, Owner>,
1424
1434
  HistorySnapshotResult<States, StateId, Prefix, Owner>
@@ -1645,20 +1655,19 @@ type LocalTargetBuilderForScope<
1645
1655
  *
1646
1656
  * @since 0.4.0
1647
1657
  */
1648
- readonly with:
1649
- & (<Result extends ConstructionResult<LocalTargetResultWithPrefix<States, Children, Scope>>>(
1658
+ readonly with: {
1659
+ readonly decoded: <Result extends ConstructionResult<LocalTargetResultWithPrefix<States, Children, Scope>>>(
1650
1660
  value: Machine.StateByIdentifier<States, Scope>,
1651
1661
  state: (
1652
1662
  builder: LocalTargetBuilderWithPrefix<States, Children, Scope, Source>
1653
1663
  ) => Result
1654
- ) => Result)
1655
- & {
1656
- readonly from: ConstructionSelectorFromCallable<
1657
- Machine.SchemaByIdentifier<States, Scope>["~type.make.in"],
1658
- LocalTargetBuilderWithPrefix<States, Children, Scope, Source>,
1659
- LocalTargetResultWithPrefix<States, Children, Scope>
1660
- >
1661
- }
1664
+ ) => Result
1665
+ readonly from: ConstructionSelectorFromCallable<
1666
+ Machine.SchemaByIdentifier<States, Scope>["~type.make.in"],
1667
+ LocalTargetBuilderWithPrefix<States, Children, Scope, Source>,
1668
+ LocalTargetResultWithPrefix<States, Children, Scope>
1669
+ >
1670
+ }
1662
1671
  } :
1663
1672
  {})
1664
1673
  : {}
@@ -3557,6 +3566,7 @@ export declare namespace Machine {
3557
3566
  readonly type: "direct"
3558
3567
  readonly target: Path | undefined
3559
3568
  readonly selection: TransitionTargetSelection<Path | undefined>
3569
+ readonly updates: ReadonlyArray<string>
3560
3570
  }
3561
3571
  | {
3562
3572
  readonly type: "branch"
@@ -3564,6 +3574,7 @@ export declare namespace Machine {
3564
3574
  readonly title: string
3565
3575
  readonly target: Path | undefined
3566
3576
  readonly selection: TransitionTargetSelection<Path | undefined>
3577
+ readonly updates: ReadonlyArray<string>
3567
3578
  }
3568
3579
 
3569
3580
  /** The statically selected root entry for machine startup. */
@@ -3577,9 +3588,10 @@ export declare namespace Machine {
3577
3588
  *
3578
3589
  * **Details**
3579
3590
  *
3580
- * Every branch exposes its selected target without executing its resolver.
3581
- * A compound local or branch target covers its descendants;
3582
- * `undefined` identifies an explicitly targetless branch.
3591
+ * Every branch exposes its static selection without executing its resolver.
3592
+ * A compound local or branch target covers its descendants. An `update`
3593
+ * selection keeps `target` undefined and records its value owner in
3594
+ * `selection.path`; `none` identifies an explicitly targetless branch.
3583
3595
  *
3584
3596
  * @category models
3585
3597
  * @since 0.4.0
@@ -3634,6 +3646,8 @@ export declare namespace Machine {
3634
3646
  * Choice microsteps retain each intermediate pseudo-state edge separately.
3635
3647
  */
3636
3648
  readonly resolvedTarget: TargetPath | undefined
3649
+ /** Retained valued owners replaced by this transition. */
3650
+ readonly updates: ReadonlyArray<string>
3637
3651
  }
3638
3652
 
3639
3653
  /**
@@ -4461,6 +4475,54 @@ export declare namespace Machine {
4461
4475
  >
4462
4476
  }
4463
4477
 
4478
+ /**
4479
+ * Opaque instruction that replaces one active compound or parallel state's
4480
+ * value without changing its active descendants.
4481
+ *
4482
+ * @category models
4483
+ * @since 0.21.0
4484
+ */
4485
+ export interface StateUpdate<
4486
+ States extends StateSchemas,
4487
+ StateId extends ValuedStateIdentifier<States>
4488
+ > {
4489
+ readonly [Topology.StateUpdateTypeId]: {
4490
+ readonly states: Types.Covariant<States>
4491
+ readonly owner: Types.Covariant<StateId>
4492
+ }
4493
+ }
4494
+
4495
+ /**
4496
+ * Opaque result that combines one topology target with one retained owner
4497
+ * value replacement in the same microstep.
4498
+ *
4499
+ * @category models
4500
+ * @since 0.22.0
4501
+ */
4502
+ export interface CombinedTarget<
4503
+ Result,
4504
+ States extends StateSchemas,
4505
+ Owner extends ValuedStateIdentifier<States>
4506
+ > {
4507
+ readonly [Topology.CombinedTargetTypeId]: {
4508
+ readonly result: Types.Covariant<Result>
4509
+ readonly states: Types.Covariant<States>
4510
+ readonly owner: Types.Covariant<Owner>
4511
+ }
4512
+ }
4513
+
4514
+ /** @internal */
4515
+ type StateUpdateBuilder<
4516
+ States extends StateSchemas,
4517
+ StateId extends ValuedStateIdentifier<States>
4518
+ > = {
4519
+ readonly decoded: (value: StateByIdentifier<States, StateId>) => StateUpdate<States, StateId>
4520
+ readonly from: FromCallable<
4521
+ readonly [input: SchemaByIdentifier<States, StateId>["~type.make.in"]],
4522
+ StateUpdate<States, StateId>
4523
+ >
4524
+ }
4525
+
4464
4526
  /**
4465
4527
  * Opaque result returned by an explicitly targetless transition.
4466
4528
  *
@@ -4692,23 +4754,36 @@ export declare namespace Machine {
4692
4754
  export interface TargetSelection<
4693
4755
  out Result,
4694
4756
  out Path extends string | undefined = string | undefined,
4695
- out Kind extends Topology.TargetSelectionKind = Topology.TargetSelectionKind
4757
+ out Kind extends Topology.TargetSelectionKind = Topology.TargetSelectionKind,
4758
+ out Scope extends Topology.TargetSelectionScope | undefined = Topology.TargetSelectionScope | undefined
4696
4759
  > {
4697
4760
  readonly [Topology.TargetSelectionTypeId]: typeof Topology.TargetSelectionTypeId
4698
4761
  readonly kind: Kind
4699
- readonly scope: Topology.TargetSelectionScope | undefined
4762
+ readonly scope: Scope
4700
4763
  readonly path: Path
4701
4764
  readonly "~effect/Machine/TargetSelectionResult"?: Types.Covariant<Result>
4702
4765
  }
4703
4766
 
4704
- type SelectionValue<Builder, Path extends string, Kind extends Topology.TargetSelectionKind = "state"> =
4705
- TargetSelection<Builder, Path, Kind>
4767
+ type SelectionValue<
4768
+ Builder,
4769
+ Path extends string,
4770
+ Kind extends Topology.TargetSelectionKind = "state",
4771
+ Scope extends Topology.TargetSelectionScope | undefined = Topology.TargetSelectionScope | undefined
4772
+ > = TargetSelection<Builder, Path, Kind, Scope>
4706
4773
 
4707
- type SelectionMethod<Builder, Path extends string, Kind extends Topology.TargetSelectionKind = "state"> = () =>
4708
- SelectionValue<Builder, Path, Kind>
4774
+ type SelectionMethod<
4775
+ Builder,
4776
+ Path extends string,
4777
+ Kind extends Topology.TargetSelectionKind = "state",
4778
+ Scope extends Topology.TargetSelectionScope | undefined = Topology.TargetSelectionScope | undefined
4779
+ > = () => SelectionValue<Builder, Path, Kind, Scope>
4709
4780
 
4710
- type InitialSelectionMethod<Builder, Path extends string> = Builder extends { readonly initial: infer Initial } ? {
4711
- readonly initial: SelectionValue<Initial, Path, "initial">
4781
+ type InitialSelectionMethod<
4782
+ Builder,
4783
+ Path extends string,
4784
+ Scope extends Topology.TargetSelectionScope
4785
+ > = Builder extends { readonly initial: infer Initial } ? {
4786
+ readonly initial: SelectionValue<Initial, Path, "initial", Scope>
4712
4787
  }
4713
4788
  : {}
4714
4789
 
@@ -4737,13 +4812,62 @@ export declare namespace Machine {
4737
4812
  > = Node extends ChoiceStateNodeConfig ? SelectionMethod<
4738
4813
  Builder,
4739
4814
  Path,
4740
- "choice"
4815
+ "choice",
4816
+ Scope
4741
4817
  >
4742
4818
  : Node extends { readonly states: infer Children extends StateSchemas } ?
4743
- & SelectionMethod<Builder, Path>
4744
- & InitialSelectionMethod<Builder, Path>
4819
+ & SelectionMethod<Builder, Path, "state", Scope>
4820
+ & InitialSelectionMethod<Builder, Path, Scope>
4745
4821
  & SelectionTreeWithPrefix<AllStates, Children, Path, Scope, Builder>
4746
- : SelectionMethod<Builder, Path>
4822
+ : SelectionMethod<Builder, Path, "state", Scope>
4823
+
4824
+ /** @internal */
4825
+ type StateUpdateSelectionForNode<
4826
+ AllStates extends StateSchemas,
4827
+ Node,
4828
+ Path extends string,
4829
+ Scope extends "local" | "branch"
4830
+ > = Node extends { readonly states: StateSchemas } ? NodeSchema<Node> extends never ? {}
4831
+ : {
4832
+ readonly update: SelectionValue<
4833
+ StateUpdateBuilder<AllStates, Extract<Path, ValuedStateIdentifier<AllStates>>>,
4834
+ Path,
4835
+ "update",
4836
+ Scope
4837
+ >
4838
+ }
4839
+ : {}
4840
+
4841
+ /** @internal */
4842
+ type BranchUpdateSelectionPath<
4843
+ AllStates extends StateSchemas,
4844
+ Node,
4845
+ Path extends string,
4846
+ Rest extends string,
4847
+ Scope extends "local" | "branch" = "branch"
4848
+ > =
4849
+ & StateUpdateSelectionForNode<AllStates, Node, Path, Scope>
4850
+ & (Node extends { readonly states: infer Children extends StateSchemas } ?
4851
+ Rest extends `${infer Head}.${infer Tail}` ? Head extends keyof Children ? {
4852
+ readonly [Key in Head]: BranchUpdateSelectionPath<
4853
+ AllStates,
4854
+ Children[Head],
4855
+ JoinPath<Path, Head>,
4856
+ Tail,
4857
+ Scope
4858
+ >
4859
+ }
4860
+ : {}
4861
+ : Rest extends keyof Children ? {
4862
+ readonly [Key in Rest]: StateUpdateSelectionForNode<
4863
+ AllStates,
4864
+ Children[Rest],
4865
+ JoinPath<Path, Rest>,
4866
+ Scope
4867
+ >
4868
+ }
4869
+ : {}
4870
+ : {})
4747
4871
 
4748
4872
  type FullSelectionNode<
4749
4873
  AllStates extends StateSchemas,
@@ -4751,9 +4875,9 @@ export declare namespace Machine {
4751
4875
  Path extends StateIdentifier<AllStates>,
4752
4876
  Builder
4753
4877
  > = Node extends { readonly states: StateSchemas } ?
4754
- & SelectionMethod<Builder, Path>
4755
- & InitialSelectionMethod<Builder, Path>
4756
- : SelectionMethod<Builder, Path>
4878
+ & SelectionMethod<Builder, Path, "state", "full">
4879
+ & InitialSelectionMethod<Builder, Path, "full">
4880
+ : SelectionMethod<Builder, Path, "state", "full">
4757
4881
 
4758
4882
  type FullTargetSelector<States extends StateSchemas> = {
4759
4883
  readonly [Key in Extract<ActiveStateKey<States>, keyof FullTargetBuilder<States>>]: FullSelectionNode<
@@ -4769,13 +4893,17 @@ export declare namespace Machine {
4769
4893
  Source extends StateNodeIdentifier<States>,
4770
4894
  Root extends string = Source extends `${infer Head}.${string}` ? Head : Source
4771
4895
  > = Root extends ActiveStateKey<States> ? Root extends keyof BranchTargetBuilder<States, Source> ? {
4772
- readonly [Key in Root]: SelectionNode<
4773
- States,
4774
- States[Key],
4775
- Key,
4776
- "branch",
4777
- BranchTargetBuilder<States, Source>[Key]
4778
- >
4896
+ readonly [Key in Root]:
4897
+ & SelectionNode<
4898
+ States,
4899
+ States[Key],
4900
+ Key,
4901
+ "branch",
4902
+ BranchTargetBuilder<States, Source>[Key]
4903
+ >
4904
+ & (Source extends ChoiceIdentifier<States> ? {}
4905
+ : Source extends `${Key}.${infer Rest}` ? BranchUpdateSelectionPath<States, States[Key], Key, Rest>
4906
+ : StateUpdateSelectionForNode<States, States[Key], Key, "branch">)
4779
4907
  }
4780
4908
  : {}
4781
4909
  : {}
@@ -4783,14 +4911,21 @@ export declare namespace Machine {
4783
4911
  type LocalTargetSelector<
4784
4912
  States extends StateSchemas,
4785
4913
  Source extends StateNodeIdentifier<States>
4786
- > = NearestCompoundScope<States, Source> extends infer Scope extends StateIdentifier<States> ?
4787
- ChildrenOf<States, Scope> extends infer Children extends StateSchemas ?
4788
- LocalTargetBuilder<States, Source> extends infer Builder ?
4789
- & SelectionTreeWithPrefix<States, Children, Scope, "local", Builder>
4790
- & ("with" extends keyof Builder ? {
4791
- readonly with: SelectionValue<Builder["with"], Scope>
4792
- }
4793
- : {})
4914
+ > = NearestCompoundScope<States, Source> extends infer Scope ? [Scope] extends [never] ? {}
4915
+ : Scope extends StateIdentifier<States> ?
4916
+ ChildrenOf<States, Scope> extends infer Children extends StateSchemas ?
4917
+ LocalTargetBuilder<States, Source> extends infer Builder ?
4918
+ & SelectionTreeWithPrefix<States, Children, Scope, "local", Builder>
4919
+ & ("with" extends keyof Builder ? {
4920
+ readonly with: SelectionValue<Builder["with"], Scope, "state", "local">
4921
+ }
4922
+ : {})
4923
+ & (Source extends ChoiceIdentifier<States> ? {}
4924
+ : Scope extends ValuedStateIdentifier<States> ? {
4925
+ readonly update: SelectionValue<StateUpdateBuilder<States, Scope>, Scope, "update", "local">
4926
+ }
4927
+ : {})
4928
+ : {}
4794
4929
  : {}
4795
4930
  : {}
4796
4931
  : {}
@@ -4805,7 +4940,8 @@ export declare namespace Machine {
4805
4940
  SelectionValue<
4806
4941
  Builder[Key],
4807
4942
  JoinPath<Prefix, Key>,
4808
- "history"
4943
+ "history",
4944
+ "full"
4809
4945
  >
4810
4946
  : States[Key] extends { readonly states: infer Children extends StateSchemas } ? HistorySelectionTree<
4811
4947
  AllStates,
@@ -4830,10 +4966,10 @@ export declare namespace Machine {
4830
4966
  Source extends StateNodeIdentifier<States>
4831
4967
  > {
4832
4968
  /** Handles the trigger without selecting a destination. */
4833
- readonly none: SelectionValue<TargetBuilder<States, Source>["none"], never, "none">
4834
- /** Selects a destination inside the nearest active compound scope. */
4969
+ readonly none: SelectionValue<TargetBuilder<States, Source>["none"], never, "none", "local">
4970
+ /** Selects a destination or updates the nearest active compound scope. */
4835
4971
  readonly local: LocalTargetSelector<States, Source>
4836
- /** Selects a destination elsewhere under the currently active root. */
4972
+ /** Selects a destination or updates a valued active ancestor under the current root. */
4837
4973
  readonly branch: BranchTargetSelector<States, Source>
4838
4974
  /** Selects a complete destination under any top-level state. */
4839
4975
  readonly full: FullTargetSelector<States>
@@ -4845,9 +4981,9 @@ export declare namespace Machine {
4845
4981
  type InitialTargetSelector<States extends StateSchemas> = {
4846
4982
  readonly [Key in Extract<ActiveStateKey<States>, keyof InitialBuilder<States>>]: States[Key] extends
4847
4983
  { readonly states: StateSchemas } ? {
4848
- readonly initial: SelectionValue<InitialBuilder<States>[Key], Key, "initial">
4984
+ readonly initial: SelectionValue<InitialBuilder<States>[Key], Key, "initial", "initial">
4849
4985
  }
4850
- : SelectionMethod<InitialBuilder<States>[Key], Key>
4986
+ : SelectionMethod<InitialBuilder<States>[Key], Key, "state", "initial">
4851
4987
  }
4852
4988
 
4853
4989
  /**
@@ -5243,9 +5379,9 @@ export declare namespace Machine {
5243
5379
  * **Details**
5244
5380
  *
5245
5381
  * Handlers return snapshots for complete state replacement, target builder
5246
- * results for path-safe partial transitions, or `target.none()` for an
5247
- * explicitly targetless transition. Raw decoded state values and `void` are
5248
- * not accepted at transition boundaries.
5382
+ * results for path-safe partial transitions, state-value updates, or
5383
+ * `target.none()` for an explicitly targetless transition. Raw decoded state
5384
+ * values and `void` are not accepted at transition boundaries.
5249
5385
  *
5250
5386
  * @category utility types
5251
5387
  * @since 0.4.0
@@ -5255,11 +5391,18 @@ export declare namespace Machine {
5255
5391
  | Target<States, StateIdentifier<States>>
5256
5392
  | HistoryTarget<States, HistoryIdentifier<States>>
5257
5393
  | ChoiceTarget<States, ChoiceIdentifier<States>>
5394
+ | StateUpdate<States, ValuedStateIdentifier<States>>
5395
+ | CombinedTarget<
5396
+ Target<States, StateIdentifier<States>> | Snapshot<States>,
5397
+ States,
5398
+ ValuedStateIdentifier<States>
5399
+ >
5258
5400
  | StateConstruction<
5259
5401
  | Snapshot<States>
5260
5402
  | Target<States, StateIdentifier<States>>
5261
5403
  | HistoryTarget<States, HistoryIdentifier<States>>
5262
5404
  | ChoiceTarget<States, ChoiceIdentifier<States>>
5405
+ | StateUpdate<States, ValuedStateIdentifier<States>>
5263
5406
  >
5264
5407
  | NoTarget
5265
5408
 
@@ -5587,21 +5730,75 @@ export declare namespace Machine {
5587
5730
  Acceptance extends TransitionAcceptance = "required"
5588
5731
  > = TransitionBuilderInput<States, Events, Emits, StateId, Context, Reenter, Acceptance>
5589
5732
 
5590
- export type SelectionBuilder<Selection> = Selection extends TargetSelection<infer Builder, any, any> ? Builder : never
5591
- export type SelectionKind<Selection> = Selection extends TargetSelection<any, any, infer Kind> ? Kind : never
5592
- export type SelectionPath<Selection> = Selection extends TargetSelection<any, infer Path, any> ? Path : never
5733
+ export type SelectionBuilder<Selection> = Selection extends TargetSelection<infer Builder, any, any, any> ? Builder
5734
+ : never
5735
+ export type SelectionKind<Selection> = Selection extends TargetSelection<any, any, infer Kind, any> ? Kind : never
5736
+ export type SelectionPath<Selection> = Selection extends TargetSelection<any, infer Path, any, any> ? Path : never
5737
+ type SelectionScope<Selection> = Selection extends TargetSelection<any, any, any, infer Scope> ? Scope : never
5593
5738
  export type TargetBuilderResult<Builder> =
5594
5739
  | (Builder extends (...args: any) => infer Result ? Result : never)
5740
+ | (Builder extends { readonly decoded: (...args: any) => infer Result } ? Result : never)
5595
5741
  | (Builder extends { readonly from: (...args: any) => infer Result } ? Result : never)
5596
5742
  export type SelectedTargetResult<Selection> = SelectionBuilder<Selection> extends infer Builder ?
5597
5743
  TargetBuilderResult<Builder>
5598
5744
  : never
5599
5745
 
5746
+ type RetainedUpdateOwner<
5747
+ States extends StateSchemas,
5748
+ Source extends StateNodeIdentifier<States>,
5749
+ Selection
5750
+ > = Extract<
5751
+ ParentStateIdentifier<Source>,
5752
+ ParentStateIdentifier<Extract<SelectionPath<Selection>, string>> & ValuedStateIdentifier<States>
5753
+ >
5754
+
5755
+ type RetainedOwnerSelector<Owner extends string> = () => TargetSelection<any, Owner, "state", "branch">
5756
+
5757
+ /**
5758
+ * Destination construction returned when a transition declares one retained
5759
+ * valued owner with `.updating(...)`.
5760
+ *
5761
+ * @category models
5762
+ * @since 0.22.0
5763
+ */
5764
+ export interface UpdatingStateConstruction<
5765
+ Result,
5766
+ States extends StateSchemas,
5767
+ Owner extends ValuedStateIdentifier<States>
5768
+ > {
5769
+ /** Combines the selected topology with the required owner replacement. */
5770
+ readonly update: (
5771
+ update: StateUpdate<States, Owner>
5772
+ ) => CombinedTarget<UnwrapConstruction<Result>, States, Owner>
5773
+ }
5774
+
5775
+ type UpdatingCallable<
5776
+ Callable,
5777
+ States extends StateSchemas,
5778
+ Owner extends ValuedStateIdentifier<States>
5779
+ > = Callable extends {
5780
+ (...args: infer Arguments1): infer Result1
5781
+ (...args: infer Arguments2): infer Result2
5782
+ } ? {
5783
+ (...args: Arguments1): UpdatingStateConstruction<Result1, States, Owner>
5784
+ (...args: Arguments2): UpdatingStateConstruction<Result2, States, Owner>
5785
+ }
5786
+ : Callable extends (...args: infer Arguments) => infer Result ?
5787
+ (...args: Arguments) => UpdatingStateConstruction<Result, States, Owner>
5788
+ : never
5789
+
5790
+ type UpdatingTargetBuilder<
5791
+ Builder,
5792
+ States extends StateSchemas,
5793
+ Owner extends ValuedStateIdentifier<States>
5794
+ > = {
5795
+ readonly [Key in keyof Builder]: Key extends "from" | "decoded" ? UpdatingCallable<Builder[Key], States, Owner>
5796
+ : Builder[Key]
5797
+ }
5798
+
5600
5799
  type SelectionSupportsDefaultConstruction<Selection> = SelectionKind<Selection> extends "none" ? true
5601
5800
  : SelectionBuilder<Selection> extends { readonly from: (...args: infer Args) => any } ? [] extends Args ? true
5602
5801
  : false
5603
- : SelectionBuilder<Selection> extends (...args: infer Args) => any ? [] extends Args ? true
5604
- : false
5605
5802
  : false
5606
5803
 
5607
5804
  export type TransitionResolveContext<
@@ -5611,6 +5808,31 @@ export declare namespace Machine {
5611
5808
  & Omit<Context, "target">
5612
5809
  & (SelectionKind<Selection> extends "none" ? {} : { readonly target: SelectionBuilder<Selection> })
5613
5810
 
5811
+ type StateUpdateResolveContext<
5812
+ States extends StateSchemas,
5813
+ Context,
5814
+ Owner extends ValuedStateIdentifier<States>
5815
+ > = Omit<Context, "target"> & {
5816
+ /** Decoded owner value from the pre-transition snapshot. */
5817
+ readonly current: StateByIdentifier<States, Owner>
5818
+ /** Constructs the complete replacement for the selected owner. */
5819
+ readonly owner: StateUpdateBuilder<States, Owner>
5820
+ }
5821
+
5822
+ type UpdatingTransitionResolveContext<
5823
+ States extends StateSchemas,
5824
+ Context,
5825
+ Selection,
5826
+ Owner extends ValuedStateIdentifier<States>
5827
+ > = Omit<Context, "target"> & {
5828
+ /** Decoded owner value from the pre-transition snapshot. */
5829
+ readonly current: StateByIdentifier<States, Owner>
5830
+ /** Constructs the selected topology and requires `.update(...)`. */
5831
+ readonly target: UpdatingTargetBuilder<SelectionBuilder<Selection>, States, Owner>
5832
+ /** Constructs the complete replacement for the retained owner. */
5833
+ readonly owner: StateUpdateBuilder<States, Owner>
5834
+ }
5835
+
5614
5836
  /** Context capability available only to explicitly declinable resolvers. */
5615
5837
  export interface DeclineCapability {
5616
5838
  /** Declines this candidate and continues hierarchical transition selection. */
@@ -5639,6 +5861,30 @@ export declare namespace Machine {
5639
5861
  | (SelectionKind<Selection> extends "none" ? undefined : SelectedTargetResult<Selection> | undefined)
5640
5862
  | Declined
5641
5863
 
5864
+ /** @internal */
5865
+ type StateUpdateResolver<
5866
+ States extends StateSchemas,
5867
+ Events extends ReadonlyArray<TaggedSchema>,
5868
+ Emits extends ReadonlyArray<TaggedSchema>,
5869
+ Context,
5870
+ Owner extends ValuedStateIdentifier<States>
5871
+ > = (
5872
+ context: StateUpdateResolveContext<States, Context, Owner>,
5873
+ enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>
5874
+ ) => StateUpdate<States, Owner>
5875
+
5876
+ /** @internal */
5877
+ type DeclinableStateUpdateResolver<
5878
+ States extends StateSchemas,
5879
+ Events extends ReadonlyArray<TaggedSchema>,
5880
+ Emits extends ReadonlyArray<TaggedSchema>,
5881
+ Context,
5882
+ Owner extends ValuedStateIdentifier<States>
5883
+ > = (
5884
+ context: StateUpdateResolveContext<States, Context, Owner> & DeclineCapability,
5885
+ enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>
5886
+ ) => StateUpdate<States, Owner> | Declined
5887
+
5642
5888
  /** One named destination declared by a branching transition. */
5643
5889
  export interface TransitionBranchInput<
5644
5890
  Selection extends TargetSelection<any, any, any> = TargetSelection<any, any, any>
@@ -5847,10 +6093,7 @@ export declare namespace Machine {
5847
6093
  >
5848
6094
  : {})
5849
6095
  & {
5850
- /**
5851
- * Evaluates state construction and queued commands only after this
5852
- * transition has been selected.
5853
- */
6096
+ /** Evaluates state construction after this transition is selected. */
5854
6097
  readonly resolve:
5855
6098
  & TransitionResolveRequired<States, Events, Emits, StateId, Context, Reenter, Selection>
5856
6099
  & ("declinable" extends Acceptance ? TransitionResolveDeclinable<
@@ -5879,6 +6122,165 @@ export declare namespace Machine {
5879
6122
  }
5880
6123
  : {}
5881
6124
  : {})
6125
+ & (SelectionKind<Selection> extends "state" ?
6126
+ SelectionScope<Selection> extends "local" | "branch" ?
6127
+ RetainedUpdateOwner<States, StateId, Selection> extends infer Owner extends ValuedStateIdentifier<States> ?
6128
+ [Owner] extends [never] ? {}
6129
+ : {
6130
+ /** Declares one valued owner retained by the selected topology. */
6131
+ readonly updating: <SelectedOwner extends Owner>(
6132
+ owner: RetainedOwnerSelector<SelectedOwner>
6133
+ ) => UpdatingTransitionTarget<
6134
+ States,
6135
+ Events,
6136
+ Emits,
6137
+ StateId,
6138
+ Context,
6139
+ Reenter,
6140
+ Acceptance,
6141
+ Selection,
6142
+ SelectedOwner
6143
+ >
6144
+ }
6145
+ : {}
6146
+ : {}
6147
+ : {})
6148
+
6149
+ /** A topology selection that requires one retained owner replacement. */
6150
+ export type UpdatingTransitionTarget<
6151
+ States extends StateSchemas,
6152
+ Events extends ReadonlyArray<TaggedSchema>,
6153
+ Emits extends ReadonlyArray<TaggedSchema>,
6154
+ StateId extends StateNodeIdentifier<States>,
6155
+ Context,
6156
+ Reenter extends boolean,
6157
+ Acceptance extends TransitionAcceptance,
6158
+ Selection extends TargetSelection<any, any, "state">,
6159
+ Owner extends ValuedStateIdentifier<States>
6160
+ > = Selection & {
6161
+ /** @internal */
6162
+ readonly "~effect/Machine/UpdatingTransitionTarget": Owner
6163
+ readonly resolve:
6164
+ & ((
6165
+ resolve: (
6166
+ context: UpdatingTransitionResolveContext<States, Context, Selection, Owner>,
6167
+ enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>
6168
+ ) => CombinedTarget<UnwrapConstruction<SelectedTargetResult<Selection>>, States, Owner>,
6169
+ options?: TransitionRequiredOptions<Reenter>
6170
+ ) => BuiltTransition<
6171
+ States,
6172
+ Events,
6173
+ Emits,
6174
+ StateId,
6175
+ Context,
6176
+ Reenter,
6177
+ CombinedTarget<UnwrapConstruction<SelectedTargetResult<Selection>>, States, Owner>,
6178
+ "required"
6179
+ >)
6180
+ & ("declinable" extends Acceptance ? (
6181
+ resolve: (
6182
+ context: UpdatingTransitionResolveContext<States, Context, Selection, Owner> & DeclineCapability,
6183
+ enqueue: Enqueue<EventOf<Events>, EmitOf<Emits>>
6184
+ ) => CombinedTarget<UnwrapConstruction<SelectedTargetResult<Selection>>, States, Owner> | Declined,
6185
+ options: TransitionDeclinableOptions<Reenter>
6186
+ ) => BuiltTransition<
6187
+ States,
6188
+ Events,
6189
+ Emits,
6190
+ StateId,
6191
+ Context,
6192
+ Reenter,
6193
+ CombinedTarget<UnwrapConstruction<SelectedTargetResult<Selection>>, States, Owner> | Declined,
6194
+ "declinable"
6195
+ >
6196
+ : {})
6197
+ }
6198
+
6199
+ /** @internal */
6200
+ interface StateUpdateTransitionRequired<
6201
+ States extends StateSchemas,
6202
+ Events extends ReadonlyArray<TaggedSchema>,
6203
+ Emits extends ReadonlyArray<TaggedSchema>,
6204
+ StateId extends StateNodeIdentifier<States>,
6205
+ Context,
6206
+ Reenter extends boolean,
6207
+ Selection extends TargetSelection<any, any, "update">
6208
+ > {
6209
+ (
6210
+ resolve: StateUpdateResolver<
6211
+ States,
6212
+ Events,
6213
+ Emits,
6214
+ Context,
6215
+ Extract<SelectionPath<Selection>, ValuedStateIdentifier<States>>
6216
+ >,
6217
+ options?: TransitionRequiredOptions<Reenter>
6218
+ ): BuiltTransition<
6219
+ States,
6220
+ Events,
6221
+ Emits,
6222
+ StateId,
6223
+ Context,
6224
+ Reenter,
6225
+ SelectedTargetResult<Selection>,
6226
+ "required"
6227
+ >
6228
+ }
6229
+
6230
+ /** @internal */
6231
+ interface StateUpdateTransitionDeclinable<
6232
+ States extends StateSchemas,
6233
+ Events extends ReadonlyArray<TaggedSchema>,
6234
+ Emits extends ReadonlyArray<TaggedSchema>,
6235
+ StateId extends StateNodeIdentifier<States>,
6236
+ Context,
6237
+ Reenter extends boolean,
6238
+ Selection extends TargetSelection<any, any, "update">
6239
+ > {
6240
+ (
6241
+ resolve: DeclinableStateUpdateResolver<
6242
+ States,
6243
+ Events,
6244
+ Emits,
6245
+ Context,
6246
+ Extract<SelectionPath<Selection>, ValuedStateIdentifier<States>>
6247
+ >,
6248
+ options: TransitionDeclinableOptions<Reenter>
6249
+ ): BuiltTransition<
6250
+ States,
6251
+ Events,
6252
+ Emits,
6253
+ StateId,
6254
+ Context,
6255
+ Reenter,
6256
+ SelectedTargetResult<Selection> | Declined,
6257
+ "declinable"
6258
+ >
6259
+ }
6260
+
6261
+ /** @internal */
6262
+ type StateUpdateTransition<
6263
+ States extends StateSchemas,
6264
+ Events extends ReadonlyArray<TaggedSchema>,
6265
+ Emits extends ReadonlyArray<TaggedSchema>,
6266
+ StateId extends StateNodeIdentifier<States>,
6267
+ Context,
6268
+ Reenter extends boolean,
6269
+ Acceptance extends TransitionAcceptance,
6270
+ Selection extends TargetSelection<any, any, "update">
6271
+ > =
6272
+ & Selection
6273
+ & StateUpdateTransitionRequired<States, Events, Emits, StateId, Context, Reenter, Selection>
6274
+ & ("declinable" extends Acceptance ? StateUpdateTransitionDeclinable<
6275
+ States,
6276
+ Events,
6277
+ Emits,
6278
+ StateId,
6279
+ Context,
6280
+ Reenter,
6281
+ Selection
6282
+ >
6283
+ : {})
5882
6284
 
5883
6285
  /** @internal Type evidence retained by a machine initial-entry declaration. */
5884
6286
  export interface InitialBuilderEvidence<out Selection> {
@@ -5933,19 +6335,18 @@ export declare namespace Machine {
5933
6335
  Reenter extends boolean,
5934
6336
  Acceptance extends TransitionAcceptance,
5935
6337
  Node
5936
- > = Node extends (...args: infer Args) => infer Selection ? Selection extends TargetSelection<any, any, any> ?
5937
- & ((...args: Args) => TransitionTarget<
5938
- States,
5939
- Events,
5940
- Emits,
5941
- StateId,
5942
- Context,
5943
- Reenter,
5944
- Acceptance,
5945
- Selection
5946
- >)
5947
- & {
5948
- readonly [Key in keyof Node]: TransitionSelectorNode<
6338
+ > = Node extends TargetSelection<any, any, "update"> ? StateUpdateTransition<
6339
+ States,
6340
+ Events,
6341
+ Emits,
6342
+ StateId,
6343
+ Context,
6344
+ Reenter,
6345
+ Acceptance,
6346
+ Node
6347
+ >
6348
+ : Node extends (...args: infer Args) => infer Selection ? Selection extends TargetSelection<any, any, any> ?
6349
+ & ((...args: Args) => TransitionTarget<
5949
6350
  States,
5950
6351
  Events,
5951
6352
  Emits,
@@ -5953,10 +6354,21 @@ export declare namespace Machine {
5953
6354
  Context,
5954
6355
  Reenter,
5955
6356
  Acceptance,
5956
- Node[Key]
5957
- >
5958
- }
5959
- : never
6357
+ Selection
6358
+ >)
6359
+ & {
6360
+ readonly [Key in keyof Node]: TransitionSelectorNode<
6361
+ States,
6362
+ Events,
6363
+ Emits,
6364
+ StateId,
6365
+ Context,
6366
+ Reenter,
6367
+ Acceptance,
6368
+ Node[Key]
6369
+ >
6370
+ }
6371
+ : never
5960
6372
  : Node extends TargetSelection<any, any, any> ? TransitionTarget<
5961
6373
  States,
5962
6374
  Events,
@@ -8261,13 +8673,13 @@ interface Make {
8261
8673
  * const counter = Machine.make({
8262
8674
  * states: States.states,
8263
8675
  * events: Events,
8264
- * initial: (to) => to.Count().resolve(({ target }) => target(new Count({ value: 0 })))
8676
+ * initial: (to) => to.Count().resolve(({ target }) => target.decoded(new Count({ value: 0 })))
8265
8677
  * }).handle({
8266
8678
  * Count: {
8267
8679
  * on: {
8268
8680
  * Increment: (to) =>
8269
8681
  * to.full.Count().resolve(({ event, state, target }) =>
8270
- * target(new Count({ value: state.value + event.by })))
8682
+ * target.decoded(new Count({ value: state.value + event.by })))
8271
8683
  * }
8272
8684
  * }
8273
8685
  * })
@@ -8594,9 +9006,21 @@ type TransitionBranchRecordError<Message extends string, Key extends PropertyKey
8594
9006
 
8595
9007
  type InvalidStaticTransitionBranchKey<Branches> = Extract<keyof Branches, "" | number | symbol>
8596
9008
 
9009
+ type InvalidUpdatingTransitionBranchKey<Branches> = {
9010
+ readonly [Key in keyof Branches]: Branches[Key] extends {
9011
+ readonly target: { readonly "~effect/Machine/UpdatingTransitionTarget": string }
9012
+ } ? Key
9013
+ : never
9014
+ }[keyof Branches]
9015
+
8597
9016
  type ValidateTransitionBranchRecord<Branches> = [keyof Branches] extends [never] ?
8598
9017
  TransitionBranchRecordError<"Branch records must contain at least one branch">
8599
- : [InvalidStaticTransitionBranchKey<Branches>] extends [never] ? unknown
9018
+ : [InvalidStaticTransitionBranchKey<Branches>] extends [never] ?
9019
+ [InvalidUpdatingTransitionBranchKey<Branches>] extends [never] ? unknown
9020
+ : TransitionBranchRecordError<
9021
+ "Updating targets require a direct resolver",
9022
+ InvalidUpdatingTransitionBranchKey<Branches>
9023
+ >
8600
9024
  : TransitionBranchRecordError<
8601
9025
  "Branch keys must be non-empty, non-index strings",
8602
9026
  InvalidStaticTransitionBranchKey<Branches>
@@ -8760,9 +9184,10 @@ export const initialDefinition: <M extends Machine.Any>(machine: M) => Machine.I
8760
9184
  *
8761
9185
  * Event handlers retain their handler-key order within each source state and
8762
9186
  * are followed by eventless and completion handlers. This function does not
8763
- * execute resolvers. Every direct, named, and targetless branch exposes the
8764
- * destination selected by its required static `target` declaration, while
8765
- * `acceptance` reports whether the resolver may decline the transition.
9187
+ * execute resolvers. Every branch exposes its static selection. State updates
9188
+ * retain the updated owner in `selection.path` while leaving `target`
9189
+ * undefined because they do not change topology. `acceptance` reports whether
9190
+ * the resolver may decline the transition.
8766
9191
  *
8767
9192
  * @category getters
8768
9193
  * @since 0.4.0