@@ -536,20 +536,43 @@ type SnapshotBuilderComplete<Regions, Constructed extends boolean = false> = {
536536 readonly [ SnapshotBuilderConstructionTypeId ] : Constructed
537537}
538538
539+ type FromCallable < Arguments extends ReadonlyArray < unknown > , Result > = Arguments extends
540+ readonly [ infer Input , ...infer Rest extends ReadonlyArray < unknown > ] ? { } extends Input ? {
541+ ( ...args : Rest ) : Result
542+ ( ...args : Arguments ) : Result
543+ }
544+ : ( ...args : Arguments ) => Result
545+ : ( ...args : Arguments ) => Result
546+
539547type FromMethod < Arguments extends ReadonlyArray < unknown > , Result > = {
540548 /**
541549 * Constructs the selected state from its schema make input while the
542- * machine plans the resulting configuration.
550+ * machine plans the resulting configuration. The input may be omitted when
551+ * the schema accepts an empty constructor object.
543552 *
544553 * @since 4.0.0
545554 */
546- readonly from : ( ... args : Arguments ) => Machine . StateConstruction < Result >
555+ readonly from : FromCallable < Arguments , Machine . StateConstruction < Result > >
547556}
548557
549558type ConstructionResult < Result > = Result | Machine . StateConstruction < Result >
550559
551560type UnwrapConstruction < Result > = Result extends Machine . StateConstruction < infer Value > ? Value : Result
552561
562+ type ConstructionSelectorFromCallable < Input , Builder , Result > = { } extends Input ? {
563+ < Selected extends ConstructionResult < Result > > (
564+ state : ( builder : Builder ) => Selected
565+ ) : Machine . StateConstruction < UnwrapConstruction < Selected > >
566+ < Selected extends ConstructionResult < Result > > (
567+ input : Input ,
568+ state : ( builder : Builder ) => Selected
569+ ) : Machine . StateConstruction < UnwrapConstruction < Selected > >
570+ }
571+ : < Selected extends ConstructionResult < Result > > (
572+ input : Input ,
573+ state : ( builder : Builder ) => Selected
574+ ) => Machine . StateConstruction < UnwrapConstruction < Selected > >
575+
553576type InitialSnapshotBuilderWithPrefix <
554577 States extends Machine . StateSchemas ,
555578 Prefix extends string = ""
@@ -665,14 +688,15 @@ type InitialParallelBuilder<
665688 Constructed
666689 > )
667690 & {
668- readonly from : (
669- ...args : InitialSnapshotFromArguments < States , Key , Prefix >
670- ) => InitialParallelBuilder <
671- States ,
672- Prefix ,
673- Exclude < Remaining , Key > ,
674- Regions & { readonly [ Region in Key ] : InitialSnapshotResult < States , Key , Prefix > } ,
675- true
691+ readonly from : FromCallable <
692+ InitialSnapshotFromArguments < States , Key , Prefix > ,
693+ InitialParallelBuilder <
694+ States ,
695+ Prefix ,
696+ Exclude < Remaining , Key > ,
697+ Regions & { readonly [ Region in Key ] : InitialSnapshotResult < States , Key , Prefix > } ,
698+ true
699+ >
676700 >
677701 }
678702 }
@@ -766,14 +790,15 @@ type FullParallelBuilder<
766790 Constructed
767791 > )
768792 & {
769- readonly from : (
770- ...args : FullSnapshotFromArguments < States , Key , Prefix >
771- ) => FullParallelBuilder <
772- States ,
773- Prefix ,
774- Exclude < Remaining , Key > ,
775- Regions & { readonly [ Region in Key ] : FullSnapshotResult < States , Key , Prefix > } ,
776- true
793+ readonly from : FromCallable <
794+ FullSnapshotFromArguments < States , Key , Prefix > ,
795+ FullParallelBuilder <
796+ States ,
797+ Prefix ,
798+ Exclude < Remaining , Key > ,
799+ Regions & { readonly [ Region in Key ] : FullSnapshotResult < States , Key , Prefix > } ,
800+ true
801+ >
777802 >
778803 }
779804 }
@@ -852,12 +877,11 @@ type LocalTargetMethod<
852877 ) => Result
853878 ) => Result )
854879 & {
855- readonly from : < Result extends ConstructionResult < LocalTargetResultWithPrefix < AllStates , Children , Path > > > (
856- input : Machine . NodeSchema < Node > [ "~type.make.in" ] ,
857- state : (
858- builder : LocalTargetBuilderWithPrefix < AllStates , Children , Path , Source >
859- ) => Result
860- ) => Machine . StateConstruction < UnwrapConstruction < Result > >
880+ readonly from : ConstructionSelectorFromCallable <
881+ Machine . NodeSchema < Node > [ "~type.make.in" ] ,
882+ LocalTargetBuilderWithPrefix < AllStates , Children , Path , Source > ,
883+ LocalTargetResultWithPrefix < AllStates , Children , Path >
884+ >
861885 }
862886 :
863887 & ( (
@@ -883,12 +907,11 @@ type LocalTargetMethod<
883907 ) => Result
884908 ) => Result )
885909 & {
886- readonly from : < Result extends ConstructionResult < LocalTargetResultWithPrefix < AllStates , Children , Path > > > (
887- input : Machine . NodeSchema < Node > [ "~type.make.in" ] ,
888- state : (
889- builder : LocalTargetBuilderWithPrefix < AllStates , Children , Path , Source >
890- ) => Result
891- ) => Machine . StateConstruction < UnwrapConstruction < Result > >
910+ readonly from : ConstructionSelectorFromCallable <
911+ Machine . NodeSchema < Node > [ "~type.make.in" ] ,
912+ LocalTargetBuilderWithPrefix < AllStates , Children , Path , Source > ,
913+ LocalTargetResultWithPrefix < AllStates , Children , Path >
914+ >
892915 }
893916 :
894917 & ( ( value : Machine . NodeSchema < Node > [ "Type" ] ) => Machine . Target <
@@ -922,12 +945,11 @@ type LocalTargetBuilderForScope<
922945 ) => Result
923946 ) => Result )
924947 & {
925- readonly from : < Result extends ConstructionResult < LocalTargetResultWithPrefix < States , Children , Scope > > > (
926- input : Machine . SchemaByIdentifier < States , Scope > [ "~type.make.in" ] ,
927- state : (
928- builder : LocalTargetBuilderWithPrefix < States , Children , Scope , Source >
929- ) => Result
930- ) => Machine . StateConstruction < UnwrapConstruction < Result > >
948+ readonly from : ConstructionSelectorFromCallable <
949+ Machine . SchemaByIdentifier < States , Scope > [ "~type.make.in" ] ,
950+ LocalTargetBuilderWithPrefix < States , Children , Scope , Source > ,
951+ LocalTargetResultWithPrefix < States , Children , Scope >
952+ >
931953 }
932954 }
933955 : { }
@@ -978,12 +1000,11 @@ type BranchTargetMethod<
9781000 ) => Result
9791001 ) => Result )
9801002 & {
981- readonly from : < Result extends ConstructionResult < BranchTargetResultWithPrefix < AllStates , Children , Path > > > (
982- input : Machine . NodeSchema < Node > [ "~type.make.in" ] ,
983- state : (
984- builder : BranchTargetBuilderWithPrefix < AllStates , Children , Path , Source >
985- ) => Result
986- ) => Machine . StateConstruction < UnwrapConstruction < Result > >
1003+ readonly from : ConstructionSelectorFromCallable <
1004+ Machine . NodeSchema < Node > [ "~type.make.in" ] ,
1005+ BranchTargetBuilderWithPrefix < AllStates , Children , Path , Source > ,
1006+ BranchTargetResultWithPrefix < AllStates , Children , Path >
1007+ >
9871008 }
9881009 & BranchTargetBuilderWithPrefix < AllStates , Children , Path , Source >
9891010 :
@@ -1010,12 +1031,11 @@ type BranchTargetMethod<
10101031 ) => Result
10111032 ) => Result )
10121033 & {
1013- readonly from : < Result extends ConstructionResult < BranchTargetResultWithPrefix < AllStates , Children , Path > > > (
1014- input : Machine . NodeSchema < Node > [ "~type.make.in" ] ,
1015- state : (
1016- builder : BranchTargetBuilderWithPrefix < AllStates , Children , Path , Source >
1017- ) => Result
1018- ) => Machine . StateConstruction < UnwrapConstruction < Result > >
1034+ readonly from : ConstructionSelectorFromCallable <
1035+ Machine . NodeSchema < Node > [ "~type.make.in" ] ,
1036+ BranchTargetBuilderWithPrefix < AllStates , Children , Path , Source > ,
1037+ BranchTargetResultWithPrefix < AllStates , Children , Path >
1038+ >
10191039 }
10201040 & BranchTargetBuilderWithPrefix < AllStates , Children , Path , Source >
10211041 :
@@ -4058,15 +4078,22 @@ type SnapshotBuilderOptions = {
40584078 readonly prefix : string
40594079}
40604080
4081+ type FromMethodKind = "leaf" | "nested"
4082+
40614083const withFrom = < Method extends ( value : unknown , ...args : ReadonlyArray < any > ) => unknown > (
4062- method : Method
4063- ) : Method & { readonly from : ( input : unknown , ...args : ReadonlyArray < any > ) => unknown } => {
4084+ method : Method ,
4085+ kind : FromMethodKind
4086+ ) : Method & { readonly from : ( ...args : ReadonlyArray < any > ) => unknown } => {
40644087 Object . defineProperty ( method , "from" , {
4065- value : ( input : unknown , ...args : ReadonlyArray < any > ) =>
4066- Model . markStateConstruction ( method ( Model . makeStateInput ( input ) , ...args ) ) ,
4088+ value : ( ...args : ReadonlyArray < any > ) => {
4089+ const omitted = args . length === 0 || ( kind === "nested" && args . length === 1 && typeof args [ 0 ] === "function" )
4090+ const input = omitted ? { } : args [ 0 ]
4091+ const rest = omitted ? args : args . slice ( 1 )
4092+ return Model . markStateConstruction ( method ( Model . makeStateInput ( input ) , ...rest ) )
4093+ } ,
40674094 enumerable : false
40684095 } )
4069- return method as Method & { readonly from : ( input : unknown , ...args : ReadonlyArray < any > ) => unknown }
4096+ return method as Method & { readonly from : ( ...args : ReadonlyArray < any > ) => unknown }
40704097}
40714098
40724099const makeSnapshotBuilder = (
@@ -4075,8 +4102,12 @@ const makeSnapshotBuilder = (
40754102) : unknown => {
40764103 const builder : Record < string , unknown > = { }
40774104 for ( const key of Object . keys ( states ) ) {
4078- builder [ key ] = withFrom ( ( value : unknown , selector ?: ( builder : unknown ) => unknown ) =>
4079- makeSnapshotForNode ( states [ key ] , key , value , selector , options )
4105+ const path = options . prefix === "" ? key : `${ options . prefix } .${ key } `
4106+ const node = Model . getStateNodeDefinition ( path , states [ key ] )
4107+ builder [ key ] = withFrom (
4108+ ( value : unknown , selector ?: ( builder : unknown ) => unknown ) =>
4109+ makeSnapshotForNode ( states [ key ] , key , value , selector , options ) ,
4110+ node . states === undefined ? "leaf" : "nested"
40804111 )
40814112 }
40824113 return builder
@@ -4100,6 +4131,8 @@ const makeParallelSnapshotBuilder = (
41004131 if ( hasProperty ( regions , key ) ) {
41014132 continue
41024133 }
4134+ const path = options . prefix === "" ? key : `${ options . prefix } .${ key } `
4135+ const node = Model . getStateNodeDefinition ( path , states [ key ] )
41034136 builder [ key ] = withFrom ( ( value : unknown , selector ?: ( builder : unknown ) => unknown ) => {
41044137 const nextRegions : Record < string , unknown > = { }
41054138 for ( const regionKey of Object . keys ( regions ) ) {
@@ -4108,7 +4141,7 @@ const makeParallelSnapshotBuilder = (
41084141 nextRegions [ key ] = makeSnapshotForNode ( states [ key ] , key , value , selector , options )
41094142 const next = makeParallelSnapshotBuilder ( states , options , nextRegions )
41104143 return Model . isStateConstruction ( builder ) ? Model . markStateConstruction ( next ) : next
4111- } )
4144+ } , node . states === undefined ? "leaf" : "nested" )
41124145 }
41134146 return builder
41144147}
@@ -4304,7 +4337,7 @@ const makeLocalTargetChildBuilder = (
43044337 extendTargetValues ( values , child . path , value ) ,
43054338 source
43064339 ) )
4307- } )
4340+ } , child . type === "atomic" || child . type === "final" ? "leaf" : "nested" )
43084341 }
43094342 return builder
43104343}
@@ -4324,7 +4357,7 @@ const makeLocalTargetBuilder = (
43244357 throw new Error ( `Machine expected target "${ scope } " builder to provide an active child state` )
43254358 }
43264359 return selector ( makeLocalTargetChildBuilder ( states , stateNodes , scope , { [ scope ] : value } , source ) )
4327- } )
4360+ } , "nested" )
43284361 return builder
43294362}
43304363
@@ -4352,7 +4385,7 @@ const makeBranchTargetNodeBuilder = (
43524385) : unknown => {
43534386 const node = getTargetBuilderNode ( stateNodes , path )
43544387 if ( node . type === "atomic" || node . type === "final" ) {
4355- return withFrom ( ( value : unknown ) => makeTargetWithValues ( node . path , value , values ) )
4388+ return withFrom ( ( value : unknown ) => makeTargetWithValues ( node . path , value , values ) , "leaf" )
43564389 }
43574390 const builder = withFrom ( ( value : unknown , selector ?: ( builder : unknown ) => unknown ) => {
43584391 if ( node . type === "parallel" ) {
@@ -4386,7 +4419,7 @@ const makeBranchTargetNodeBuilder = (
43864419 source
43874420 )
43884421 return selector ( nextBuilder )
4389- } ) as unknown as Record < string , unknown >
4422+ } , "nested" ) as unknown as Record < string , unknown >
43904423 if ( node . type !== "parallel" || source === node . path || source . startsWith ( `${ node . path } .` ) ) {
43914424 addBranchTargetChildren ( builder , states , stateNodes , node . path , values , source )
43924425 }
@@ -4445,7 +4478,7 @@ const makeTargetBuilder = <const States extends Machine.StateSchemas>(
44454478 * Machine.make({
44464479 * states: States.states,
44474480 * events: [],
4448- * initial: () => States.initial.idle(new Idle({}) )
4481+ * initial: () => States.initial.idle.from( )
44494482 * })
44504483 * ```
44514484 *
0 commit comments