machina 7.0.0 → 8.0.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.
- package/README.md +148 -196
- package/dist/index.cjs +24 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +167 -18
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +167 -18
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +24 -31
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -27,8 +27,13 @@ type Subscription = {
|
|
|
27
27
|
* @typeParam TBubbles - String literal union of inputs this FSM declares via
|
|
28
28
|
* `bubbles`. Type-only — carried so `BubblesOfInstance` can extract it from
|
|
29
29
|
* a constructed instance; nothing at runtime reads this generic.
|
|
30
|
+
* @typeParam TInputs - The input payload map (#195). Defaults to the wide
|
|
31
|
+
* map, under which `handle()`'s signature reduces to exactly the untyped
|
|
32
|
+
* behavior: `keyof` of the wide map is `string`, so the key intersection
|
|
33
|
+
* is `TInputNames` and the payload lookup is `unknown[]`. The typed
|
|
34
|
+
* factory forms pass the user's map here.
|
|
30
35
|
*/
|
|
31
|
-
declare class BehavioralFsm<TClient extends object, TStateNames extends string, TInputNames extends string, TBubbles extends string = never> {
|
|
36
|
+
declare class BehavioralFsm<TClient extends object, TStateNames extends string, TInputNames extends string, TBubbles extends string = never, TInputs extends InputMapLike<TInputs> = InputMap> {
|
|
32
37
|
readonly id: string;
|
|
33
38
|
readonly initialState: TStateNames;
|
|
34
39
|
readonly [MACHINA_TYPE]: "BehavioralFsm";
|
|
@@ -50,7 +55,14 @@ declare class BehavioralFsm<TClient extends object, TStateNames extends string,
|
|
|
50
55
|
*
|
|
51
56
|
* No-ops silently when disposed.
|
|
52
57
|
*/
|
|
53
|
-
handle(client: TClient,
|
|
58
|
+
handle(client: TClient, ...call: InputCall<TInputNames, TInputs>): void;
|
|
59
|
+
/**
|
|
60
|
+
* Untyped core of `handle()`, split out for internal callers (deferred
|
|
61
|
+
* replay). Replayed inputs were captured as `unknown[]`, and their
|
|
62
|
+
* payload types were already enforced at the original `handle()` call —
|
|
63
|
+
* so replay need not satisfy the payload-map generics.
|
|
64
|
+
*/
|
|
65
|
+
private dispatch;
|
|
54
66
|
/**
|
|
55
67
|
* Returns true if the client's current state has a handler for `inputName`
|
|
56
68
|
* (or a catch-all `"*"` handler), or if the current state's `_child` chain
|
|
@@ -353,9 +365,9 @@ declare class BehavioralFsm<TClient extends object, TStateNames extends string,
|
|
|
353
365
|
* });
|
|
354
366
|
* ```
|
|
355
367
|
*/
|
|
356
|
-
declare function createBehavioralFsm<TClient extends object>(): <const TStates extends Record<string, Record<string, unknown>>, TStateNames extends string = keyof TStates & string, TBubbles extends string = never>(config: FsmConfig<TClient, TStates, TStateNames, TBubbles>) => BehavioralFsm<TClient, keyof TStates & string, Exclude<{ [S in keyof TStates]: keyof TStates[S] & string }[keyof TStates], SpecialStateKeys> | { [S in keyof TStates]: TStates[S] extends {
|
|
368
|
+
declare function createBehavioralFsm<TClient extends object, TInputs extends InputMapLike<TInputs> = InputMap>(): <const TStates extends Record<string, Record<string, unknown>>, TStateNames extends string = keyof TStates & string, TBubbles extends keyof TInputs & string = never>(config: FsmConfig<TClient, TStates, TStateNames, TBubbles, TInputs>) => BehavioralFsm<TClient, keyof TStates & string, string extends keyof TInputs ? Exclude<{ [S in keyof TStates]: keyof TStates[S] & string }[keyof TStates], SpecialStateKeys> | { [S in keyof TStates]: TStates[S] extends {
|
|
357
369
|
_child: infer C;
|
|
358
|
-
} ? InputNamesOfInstance<C> : never }[keyof TStates] | TBubbles, TBubbles>;
|
|
370
|
+
} ? InputNamesOfInstance<C> : never }[keyof TStates] | TBubbles : keyof TInputs & string, TBubbles, TInputs>;
|
|
359
371
|
declare function createBehavioralFsm<TClient extends object, const TStates extends Record<string, Record<string, unknown>>, TStateNames extends string = keyof TStates & string, TBubbles extends string = never>(config: FsmConfig<TClient, TStates, TStateNames, TBubbles>): BehavioralFsm<TClient, keyof TStates & string, Exclude<{ [S in keyof TStates]: keyof TStates[S] & string }[keyof TStates], SpecialStateKeys> | { [S in keyof TStates]: TStates[S] extends {
|
|
360
372
|
_child: infer C;
|
|
361
373
|
} ? InputNamesOfInstance<C> : never }[keyof TStates] | TBubbles, TBubbles>;
|
|
@@ -466,6 +478,67 @@ type ClientOf<TFsm> = TFsm extends BehavioralFsm<infer TClient extends object, i
|
|
|
466
478
|
* that declared no `bubbles` (the common case) or for a non-machina type.
|
|
467
479
|
*/
|
|
468
480
|
type BubblesOfInstance<TFsm> = TFsm extends Fsm<infer _TCtx extends object, infer _TStateNames extends string, infer _TInputNames extends string, infer TBubbles extends string> ? TBubbles : TFsm extends BehavioralFsm<infer _TClient extends object, infer _TStateNames extends string, infer _TInputNames extends string, infer TBubbles extends string> ? TBubbles : never;
|
|
481
|
+
/**
|
|
482
|
+
* Extracts the input payload map from a concrete machina FSM instance (#195).
|
|
483
|
+
*
|
|
484
|
+
* Falls back to the wide map — not `never` — for non-FSM types and for
|
|
485
|
+
* `any`: tooling (machina-test's walkAll) derives config types from this,
|
|
486
|
+
* and the wide map is what keeps the untyped path's config shape unchanged.
|
|
487
|
+
* The `0 extends 1 & TFsm` clause detects `any`, which would otherwise take
|
|
488
|
+
* both conditional branches and produce a useless union.
|
|
489
|
+
*/
|
|
490
|
+
type InputMapOfInstance<TFsm> = 0 extends 1 & TFsm ? InputMap : TFsm extends Fsm<infer _TCtx extends object, infer _TStateNames extends string, infer _TInputNames extends string, infer _TBubbles extends string, infer TInputs extends InputMapLike<TInputs>> ? TInputs : TFsm extends BehavioralFsm<infer _TClient extends object, infer _TStateNames extends string, infer _TInputNames extends string, infer _TBubbles extends string, infer TInputs extends InputMapLike<TInputs>> ? TInputs : InputMap;
|
|
491
|
+
/**
|
|
492
|
+
* Constraint for input payload maps: input name → argument tuple.
|
|
493
|
+
*
|
|
494
|
+
* An empty tuple means the input carries no payload.
|
|
495
|
+
*
|
|
496
|
+
* @example
|
|
497
|
+
* ```ts
|
|
498
|
+
* type TrafficLightInputs = {
|
|
499
|
+
* timeout: [];
|
|
500
|
+
* emergency: [event: { severity: number }];
|
|
501
|
+
* };
|
|
502
|
+
*
|
|
503
|
+
* const light = createFsm<TrafficLightInputs>()({ ... });
|
|
504
|
+
* light.handle("emergency", { severity: 5 }); // payload enforced
|
|
505
|
+
* ```
|
|
506
|
+
*/
|
|
507
|
+
type InputMap = Record<string, unknown[]>;
|
|
508
|
+
/**
|
|
509
|
+
* The constraint a user-supplied input map must satisfy: every declared
|
|
510
|
+
* property is an argument tuple. Self-mapped instead of `InputMap` because a
|
|
511
|
+
* named interface has no string index signature, and a bare
|
|
512
|
+
* `Record<string, unknown[]>` bound rejects it with TS2344.
|
|
513
|
+
*/
|
|
514
|
+
type InputMapLike<T> = { [K in keyof T]-?: unknown[] };
|
|
515
|
+
/**
|
|
516
|
+
* The complete argument list of one `handle()` call: an input name paired
|
|
517
|
+
* with that input's own payload tuple. The union distributes over the map,
|
|
518
|
+
* which keeps the pair correlated when the caller's input name is itself a
|
|
519
|
+
* union — `handle(name, payload)` with `name: "a" | "b"` only accepts a
|
|
520
|
+
* payload that matches the member it is paired with, never a payload from
|
|
521
|
+
* the other member.
|
|
522
|
+
*/
|
|
523
|
+
type InputCall<TInputNames extends string, TInputs extends InputMapLike<TInputs>> = [TInputNames & keyof TInputs & string] extends [never] ? [inputName: never, ...args: unknown[]] : { [K in TInputNames & keyof TInputs & string]: [inputName: K, ...payload: TInputs[K]] }[TInputNames & keyof TInputs & string];
|
|
524
|
+
/**
|
|
525
|
+
* Builds an input payload map from a discriminated event union, matching the
|
|
526
|
+
* common "dispatch the whole event" pattern: `handle(event.type, event)`.
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```ts
|
|
530
|
+
* type TrafficLightEvent =
|
|
531
|
+
* | { type: "emergency"; severity: number }
|
|
532
|
+
* | { type: "pedestrianRequest"; crossingId: string };
|
|
533
|
+
*
|
|
534
|
+
* type TrafficLightInputs = InputMapFromUnion<TrafficLightEvent>;
|
|
535
|
+
* // => { emergency: [event: { type: "emergency"; severity: number }];
|
|
536
|
+
* // pedestrianRequest: [event: { type: "pedestrianRequest"; crossingId: string }] }
|
|
537
|
+
* ```
|
|
538
|
+
*/
|
|
539
|
+
type InputMapFromUnion<TEvent extends {
|
|
540
|
+
type: string;
|
|
541
|
+
}> = { [E in TEvent as E["type"]]: [event: E] };
|
|
469
542
|
/**
|
|
470
543
|
* The single combined object passed to every handler.
|
|
471
544
|
*
|
|
@@ -545,9 +618,11 @@ interface HandlerArgs<TCtx, TStateNames extends string = string> {
|
|
|
545
618
|
* Guards are just `if` statements. Actions are just code before the return.
|
|
546
619
|
*
|
|
547
620
|
* The `...extra` rest parameter captures additional arguments passed through
|
|
548
|
-
* `handle(inputName, ...extraArgs)`.
|
|
549
|
-
*
|
|
550
|
-
*
|
|
621
|
+
* `handle(inputName, ...extraArgs)`. By default these are untyped
|
|
622
|
+
* (`unknown[]`). An input payload map types them per input (#195): supply it
|
|
623
|
+
* through the curried factory form (`createFsm<TInputs>()`), and `TPayload`
|
|
624
|
+
* becomes that input's declared tuple. Handler parameters are then inferred —
|
|
625
|
+
* no annotation, no cast.
|
|
551
626
|
*
|
|
552
627
|
* @example
|
|
553
628
|
* ```ts
|
|
@@ -569,7 +644,7 @@ interface HandlerArgs<TCtx, TStateNames extends string = string> {
|
|
|
569
644
|
* success({ ctx }, data) { ctx.result = data; }
|
|
570
645
|
* ```
|
|
571
646
|
*/
|
|
572
|
-
type HandlerFn<TCtx, TStateNames extends string = string> = (args: HandlerArgs<TCtx, TStateNames>, ...extra:
|
|
647
|
+
type HandlerFn<TCtx, TStateNames extends string = string, TPayload extends unknown[] = unknown[]> = (args: HandlerArgs<TCtx, TStateNames>, ...extra: TPayload) => TStateNames | void;
|
|
573
648
|
/**
|
|
574
649
|
* The union of valid handler definition forms for a state input.
|
|
575
650
|
*
|
|
@@ -597,7 +672,7 @@ type HandlerFn<TCtx, TStateNames extends string = string> = (args: HandlerArgs<T
|
|
|
597
672
|
* }
|
|
598
673
|
* ```
|
|
599
674
|
*/
|
|
600
|
-
type HandlerDef<TCtx, TStateNames extends string = string> = TStateNames | HandlerFn<TCtx, TStateNames> | MachinaInstance;
|
|
675
|
+
type HandlerDef<TCtx, TStateNames extends string = string, TPayload extends unknown[] = unknown[]> = TStateNames | HandlerFn<TCtx, TStateNames, TPayload> | MachinaInstance;
|
|
601
676
|
/**
|
|
602
677
|
* Validates and constrains the states object at the type level.
|
|
603
678
|
*
|
|
@@ -622,15 +697,21 @@ type HandlerDef<TCtx, TStateNames extends string = string> = TStateNames | Handl
|
|
|
622
697
|
* @typeParam TStateNames - The state-name union. Defaults to
|
|
623
698
|
* `keyof TStates & string`, but callers that already resolved it
|
|
624
699
|
* (the factory functions) pass it through explicitly.
|
|
700
|
+
* @typeParam TInputs - The input payload map (#195). Ordinary inputs are a
|
|
701
|
+
* mapped type over its keys rather than an index signature, which is what
|
|
702
|
+
* makes per-input payload typing possible. The wide default
|
|
703
|
+
* (`keyof = string`) makes the mapped member degenerate to an index
|
|
704
|
+
* signature, reproducing the untyped behavior exactly — one formulation
|
|
705
|
+
* serves both paths. Lifecycle hooks and the catch-all keep `unknown[]`
|
|
706
|
+
* either way: they can receive the arguments of ANY input, so no single
|
|
707
|
+
* tuple fits them.
|
|
625
708
|
*/
|
|
626
|
-
type ValidateStates<TCtx, TStates extends Record<string, Record<string, unknown>>, TStateNames extends string = keyof TStates & string> = Record<TStateNames, {
|
|
709
|
+
type ValidateStates<TCtx, TStates extends Record<string, Record<string, unknown>>, TStateNames extends string = keyof TStates & string, TInputs extends InputMapLike<TInputs> = InputMap> = Record<TStateNames, {
|
|
627
710
|
_onEnter?: HandlerFn<TCtx, NoInfer<TStateNames>>;
|
|
628
711
|
_onExit?: HandlerFn<TCtx, NoInfer<TStateNames>>;
|
|
629
712
|
_child?: MachinaInstance;
|
|
630
713
|
"*"?: HandlerFn<TCtx, NoInfer<TStateNames>>;
|
|
631
|
-
} & {
|
|
632
|
-
[input: string]: HandlerDef<TCtx, NoInfer<TStateNames>>;
|
|
633
|
-
}>;
|
|
714
|
+
} & { [I in keyof TInputs]?: HandlerDef<TCtx, NoInfer<TStateNames>, TInputs[I]> }>;
|
|
634
715
|
/**
|
|
635
716
|
* True when at least one state in `TStates` declares a `"*"` catch-all —
|
|
636
717
|
* a catch-all absorbs every input, including any bubbled one, so it counts
|
|
@@ -673,6 +754,26 @@ type ChildCoverage<TStates extends Record<string, Record<string, unknown>>, TSta
|
|
|
673
754
|
"child bubbles up inputs this FSM neither handles nor re-declares": UncoveredChildBubbles<NoInfer<TStates>, S, NoInfer<TBubbles>>;
|
|
674
755
|
};
|
|
675
756
|
} };
|
|
757
|
+
/**
|
|
758
|
+
* For one state object, the handler keys that are not declared in the input
|
|
759
|
+
* map (special keys excluded). Resolves to `never` in three cases: every key
|
|
760
|
+
* is declared; the map is the wide untyped default (`keyof TInputs` is
|
|
761
|
+
* `string`, so the Exclude strips everything); or the evaluation ran against
|
|
762
|
+
* TStates' wide constraint (the `string extends keyof TState` short-circuit —
|
|
763
|
+
* see the module comment above).
|
|
764
|
+
*/
|
|
765
|
+
type UndeclaredInputsIn<TState, TInputs extends InputMapLike<TInputs>> = string extends keyof TState & string ? never : Exclude<keyof TState & string, (keyof TInputs & string) | SpecialStateKeys>;
|
|
766
|
+
/**
|
|
767
|
+
* Enforces the input vocabulary contract across an entire `states` config.
|
|
768
|
+
* Intersected onto `FsmConfig.states` alongside `ValidateStates` and
|
|
769
|
+
* `ChildCoverage`. Inert (`unknown` per state) on the untyped path; on the
|
|
770
|
+
* typed path, a state declaring an undeclared input gets an
|
|
771
|
+
* impossible-to-satisfy member whose property name IS the error message,
|
|
772
|
+
* naming the offending keys.
|
|
773
|
+
*/
|
|
774
|
+
type InputVocabulary<TStates extends Record<string, Record<string, unknown>>, TStateNames extends string, TInputs extends InputMapLike<TInputs>> = { [S in TStateNames]: UndeclaredInputsIn<TStates[S], TInputs> extends never ? unknown : {
|
|
775
|
+
"state declares a handler for an input missing from the input map": UndeclaredInputsIn<TStates[S], TInputs>;
|
|
776
|
+
} };
|
|
676
777
|
/**
|
|
677
778
|
* Configuration object for creating an FSM.
|
|
678
779
|
*
|
|
@@ -695,6 +796,12 @@ type ChildCoverage<TStates extends Record<string, Record<string, unknown>>, TSta
|
|
|
695
796
|
* @typeParam TBubbles - The union of inputs this FSM declares via `bubbles`.
|
|
696
797
|
* Defaults to `never` — most FSMs bubble nothing.
|
|
697
798
|
*
|
|
799
|
+
* @typeParam TInputs - The input payload map (#195). The curried factory
|
|
800
|
+
* forms fix it before inference starts, so it adds nothing to the
|
|
801
|
+
* inference machinery above. Defaults to the wide map, which keeps
|
|
802
|
+
* `ValidateStates` and `InputVocabulary` behaving exactly as the untyped
|
|
803
|
+
* path always has.
|
|
804
|
+
*
|
|
698
805
|
* @example
|
|
699
806
|
* ```ts
|
|
700
807
|
* // TCtx inferred as { tickCount: number }, TStates inferred from states object:
|
|
@@ -743,7 +850,7 @@ type ChildCoverage<TStates extends Record<string, Record<string, unknown>>, TSta
|
|
|
743
850
|
* });
|
|
744
851
|
* ```
|
|
745
852
|
*/
|
|
746
|
-
interface FsmConfig<TCtx, TStates extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TStateNames extends string = keyof TStates & string, TBubbles extends string = never> {
|
|
853
|
+
interface FsmConfig<TCtx, TStates extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TStateNames extends string = keyof TStates & string, TBubbles extends string = never, TInputs extends InputMapLike<TInputs> = InputMap> {
|
|
747
854
|
/** Unique identifier for this FSM */
|
|
748
855
|
id: string;
|
|
749
856
|
/**
|
|
@@ -793,7 +900,7 @@ interface FsmConfig<TCtx, TStates extends Record<string, Record<string, unknown>
|
|
|
793
900
|
* and the bubble-coverage contract on top without becoming the inference
|
|
794
901
|
* source themselves.
|
|
795
902
|
*/
|
|
796
|
-
states: TStates & ValidateStates<TCtx, TStates, TStateNames> & ChildCoverage<TStates, TStateNames, TBubbles>;
|
|
903
|
+
states: TStates & ValidateStates<TCtx, TStates, TStateNames, TInputs> & ChildCoverage<TStates, TStateNames, TBubbles> & InputVocabulary<TStates, TStateNames, TInputs>;
|
|
797
904
|
}
|
|
798
905
|
/**
|
|
799
906
|
* Symbol used as a property key to identify machina FSM instances at runtime.
|
|
@@ -983,8 +1090,11 @@ interface ClientSnapshot {
|
|
|
983
1090
|
* @typeParam TBubbles - String literal union of inputs this FSM declares via
|
|
984
1091
|
* `bubbles`. Type-only — carried so `BubblesOfInstance` can extract it from
|
|
985
1092
|
* a constructed instance; nothing at runtime reads this generic.
|
|
1093
|
+
* @typeParam TInputs - The input payload map (#195). Defaults to the wide
|
|
1094
|
+
* map, under which `handle()`'s signature reduces to exactly the untyped
|
|
1095
|
+
* behavior. `createFsm<TInputs>()` passes the user's map here.
|
|
986
1096
|
*/
|
|
987
|
-
declare class Fsm<TCtx extends object, TStateNames extends string, TInputNames extends string, TBubbles extends string = never> {
|
|
1097
|
+
declare class Fsm<TCtx extends object, TStateNames extends string, TInputNames extends string, TBubbles extends string = never, TInputs extends InputMapLike<TInputs> = InputMap> {
|
|
988
1098
|
readonly id: string;
|
|
989
1099
|
readonly initialState: TStateNames;
|
|
990
1100
|
readonly [MACHINA_TYPE]: "Fsm";
|
|
@@ -1000,7 +1110,7 @@ declare class Fsm<TCtx extends object, TStateNames extends string, TInputNames e
|
|
|
1000
1110
|
* there first; unhandled inputs bubble up to the parent.
|
|
1001
1111
|
* No-ops silently when disposed.
|
|
1002
1112
|
*/
|
|
1003
|
-
handle(
|
|
1113
|
+
handle(...call: InputCall<TInputNames, TInputs>): void;
|
|
1004
1114
|
/**
|
|
1005
1115
|
* Returns true if the current state has a handler for `inputName`
|
|
1006
1116
|
* (or a catch-all `"*"` handler), or if the current state's `_child`
|
|
@@ -1065,6 +1175,16 @@ declare class Fsm<TCtx extends object, TStateNames extends string, TInputNames e
|
|
|
1065
1175
|
*
|
|
1066
1176
|
* State names, input names, and all handler signatures derive from `TStates`.
|
|
1067
1177
|
*
|
|
1178
|
+
* To type each input's payload as well (#195), call the curried form with an
|
|
1179
|
+
* input payload map: `createFsm<TInputs>()({...})`. The zero-argument call
|
|
1180
|
+
* fixes `TInputs`; the returned function infers everything else from the
|
|
1181
|
+
* config exactly as the direct form does. The split exists because TypeScript
|
|
1182
|
+
* has no partial type-argument inference — the map can't ride along with the
|
|
1183
|
+
* inferred parameters. Under a map, handler payload parameters are inferred
|
|
1184
|
+
* from the map's tuples and `handle()` enforces them at the call site. The
|
|
1185
|
+
* map is also the complete input vocabulary: handler keys outside it are
|
|
1186
|
+
* compile errors.
|
|
1187
|
+
*
|
|
1068
1188
|
* @example
|
|
1069
1189
|
* ```ts
|
|
1070
1190
|
* const light = createFsm({
|
|
@@ -1080,10 +1200,39 @@ declare class Fsm<TCtx extends object, TStateNames extends string, TInputNames e
|
|
|
1080
1200
|
*
|
|
1081
1201
|
* light.handle("timeout"); // transitions green → yellow
|
|
1082
1202
|
* ```
|
|
1203
|
+
*
|
|
1204
|
+
* @example Typed input payloads via the curried form
|
|
1205
|
+
* ```ts
|
|
1206
|
+
* type TrafficLightInputs = {
|
|
1207
|
+
* timeout: [];
|
|
1208
|
+
* emergency: [event: { severity: number }];
|
|
1209
|
+
* };
|
|
1210
|
+
*
|
|
1211
|
+
* const light = createFsm<TrafficLightInputs>()({
|
|
1212
|
+
* id: "traffic-light",
|
|
1213
|
+
* initialState: "green",
|
|
1214
|
+
* context: { minSeverity: 3 },
|
|
1215
|
+
* states: {
|
|
1216
|
+
* green: {
|
|
1217
|
+
* timeout: "yellow",
|
|
1218
|
+
* // `event` is inferred as { severity: number }
|
|
1219
|
+
* emergency({ ctx }, event) {
|
|
1220
|
+
* if (event.severity < ctx.minSeverity) { return; }
|
|
1221
|
+
* return "red";
|
|
1222
|
+
* },
|
|
1223
|
+
* },
|
|
1224
|
+
* yellow: { timeout: "red" },
|
|
1225
|
+
* red: {},
|
|
1226
|
+
* },
|
|
1227
|
+
* });
|
|
1228
|
+
*
|
|
1229
|
+
* light.handle("emergency", { severity: 5 }); // payload enforced
|
|
1230
|
+
* ```
|
|
1083
1231
|
*/
|
|
1232
|
+
declare function createFsm<TInputs extends InputMapLike<TInputs>>(): <TCtx extends object, const TStates extends Record<string, Record<string, unknown>>, TStateNames extends string = keyof TStates & string, TBubbles extends keyof TInputs & string = never>(config: FsmConfig<TCtx, TStates, TStateNames, TBubbles, TInputs>) => Fsm<TCtx, keyof TStates & string, keyof TInputs & string, TBubbles, TInputs>;
|
|
1084
1233
|
declare function createFsm<TCtx extends object = Record<string, never>, const TStates extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TStateNames extends string = keyof TStates & string, TBubbles extends string = never>(config: FsmConfig<TCtx, TStates, TStateNames, TBubbles>): Fsm<TCtx, keyof TStates & string, Exclude<{ [S in keyof TStates]: keyof TStates[S] & string }[keyof TStates], SpecialStateKeys> | { [S in keyof TStates]: TStates[S] extends {
|
|
1085
1234
|
_child: infer C;
|
|
1086
1235
|
} ? InputNamesOfInstance<C> : never }[keyof TStates] | TBubbles, TBubbles>;
|
|
1087
1236
|
//#endregion
|
|
1088
|
-
export { BehavioralFsm, type BehavioralFsmEventMap, type BubblesOfInstance, type ChildLink, type ClientOf, type ClientSnapshot, type ContextOf, type DeferredInput, type DisposeOptions, Fsm, type FsmConfig, type FsmEventMap, type HandlerArgs, type HandlerDef, type HandlerFn, type InputNamesOf, type InputNamesOfInstance, MACHINA_TYPE, type MachinaInstance, type StateNamesOf, type StateNamesOfInstance, type Subscription, createBehavioralFsm, createFsm };
|
|
1237
|
+
export { BehavioralFsm, type BehavioralFsmEventMap, type BubblesOfInstance, type ChildLink, type ClientOf, type ClientSnapshot, type ContextOf, type DeferredInput, type DisposeOptions, Fsm, type FsmConfig, type FsmEventMap, type HandlerArgs, type HandlerDef, type HandlerFn, type InputCall, type InputMap, type InputMapFromUnion, type InputMapLike, type InputMapOfInstance, type InputNamesOf, type InputNamesOfInstance, MACHINA_TYPE, type MachinaInstance, type StateNamesOf, type StateNamesOfInstance, type Subscription, createBehavioralFsm, createFsm };
|
|
1089
1238
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/emitter.ts","../src/behavioral-fsm.ts","../src/types.ts","../src/fsm.ts"],"mappings":";AASA;;;;;AAAA,KAAY,YAAA;EAAiB,GAAA;AAAA;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/emitter.ts","../src/behavioral-fsm.ts","../src/types.ts","../src/fsm.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -194,6 +194,11 @@ const MAX_TRANSITION_DEPTH = 20;
|
|
|
194
194
|
* @typeParam TBubbles - String literal union of inputs this FSM declares via
|
|
195
195
|
* `bubbles`. Type-only — carried so `BubblesOfInstance` can extract it from
|
|
196
196
|
* a constructed instance; nothing at runtime reads this generic.
|
|
197
|
+
* @typeParam TInputs - The input payload map (#195). Defaults to the wide
|
|
198
|
+
* map, under which `handle()`'s signature reduces to exactly the untyped
|
|
199
|
+
* behavior: `keyof` of the wide map is `string`, so the key intersection
|
|
200
|
+
* is `TInputNames` and the payload lookup is `unknown[]`. The typed
|
|
201
|
+
* factory forms pass the user's map here.
|
|
197
202
|
*/
|
|
198
203
|
var BehavioralFsm = class {
|
|
199
204
|
id;
|
|
@@ -223,7 +228,17 @@ var BehavioralFsm = class {
|
|
|
223
228
|
*
|
|
224
229
|
* No-ops silently when disposed.
|
|
225
230
|
*/
|
|
226
|
-
handle(client,
|
|
231
|
+
handle(client, ...call) {
|
|
232
|
+
const [inputName, ...args] = call;
|
|
233
|
+
this.dispatch(client, inputName, args);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Untyped core of `handle()`, split out for internal callers (deferred
|
|
237
|
+
* replay). Replayed inputs were captured as `unknown[]`, and their
|
|
238
|
+
* payload types were already enforced at the original `handle()` call —
|
|
239
|
+
* so replay need not satisfy the payload-map generics.
|
|
240
|
+
*/
|
|
241
|
+
dispatch(client, inputName, args) {
|
|
227
242
|
if (this.disposed) return;
|
|
228
243
|
const meta = this.getOrCreateClientMeta(client);
|
|
229
244
|
meta.currentActionArgs = args;
|
|
@@ -729,7 +744,7 @@ var BehavioralFsm = class {
|
|
|
729
744
|
for (const item of meta.deferredQueue) if (item.untilState === void 0 || item.untilState === meta.state) toReplay.push(item);
|
|
730
745
|
else remaining.push(item);
|
|
731
746
|
meta.deferredQueue = remaining;
|
|
732
|
-
for (const item of toReplay) this.
|
|
747
|
+
for (const item of toReplay) this.dispatch(client, item.inputName, item.args);
|
|
733
748
|
}
|
|
734
749
|
};
|
|
735
750
|
/**
|
|
@@ -827,6 +842,9 @@ function createBehavioralFsm(config) {
|
|
|
827
842
|
* @typeParam TBubbles - String literal union of inputs this FSM declares via
|
|
828
843
|
* `bubbles`. Type-only — carried so `BubblesOfInstance` can extract it from
|
|
829
844
|
* a constructed instance; nothing at runtime reads this generic.
|
|
845
|
+
* @typeParam TInputs - The input payload map (#195). Defaults to the wide
|
|
846
|
+
* map, under which `handle()`'s signature reduces to exactly the untyped
|
|
847
|
+
* behavior. `createFsm<TInputs>()` passes the user's map here.
|
|
830
848
|
*/
|
|
831
849
|
var Fsm = class {
|
|
832
850
|
id;
|
|
@@ -857,9 +875,10 @@ var Fsm = class {
|
|
|
857
875
|
* there first; unhandled inputs bubble up to the parent.
|
|
858
876
|
* No-ops silently when disposed.
|
|
859
877
|
*/
|
|
860
|
-
handle(
|
|
878
|
+
handle(...call) {
|
|
861
879
|
if (this.disposed) return;
|
|
862
|
-
|
|
880
|
+
const [inputName, ...args] = call;
|
|
881
|
+
this.bfsm.handle(this.context, ...[inputName, ...args]);
|
|
863
882
|
}
|
|
864
883
|
/**
|
|
865
884
|
* Returns true if the current state has a handler for `inputName`
|
|
@@ -929,34 +948,8 @@ var Fsm = class {
|
|
|
929
948
|
this.emitter.clear();
|
|
930
949
|
}
|
|
931
950
|
};
|
|
932
|
-
/**
|
|
933
|
-
* Create a single-client FSM from a config object.
|
|
934
|
-
*
|
|
935
|
-
* Generic parameters are inferred automatically:
|
|
936
|
-
* - `TCtx` comes from `config.context` (defaults to `{}` if omitted).
|
|
937
|
-
* - `TStates` is captured with `const` inference to preserve string literal
|
|
938
|
-
* types, enabling compile-time validation of transition targets and `handle()`
|
|
939
|
-
* input names.
|
|
940
|
-
*
|
|
941
|
-
* State names, input names, and all handler signatures derive from `TStates`.
|
|
942
|
-
*
|
|
943
|
-
* @example
|
|
944
|
-
* ```ts
|
|
945
|
-
* const light = createFsm({
|
|
946
|
-
* id: "traffic-light",
|
|
947
|
-
* initialState: "green",
|
|
948
|
-
* context: { tickCount: 0 },
|
|
949
|
-
* states: {
|
|
950
|
-
* green: { timeout: "yellow" },
|
|
951
|
-
* yellow: { timeout: "red" },
|
|
952
|
-
* red: { timeout: "green" },
|
|
953
|
-
* },
|
|
954
|
-
* });
|
|
955
|
-
*
|
|
956
|
-
* light.handle("timeout"); // transitions green → yellow
|
|
957
|
-
* ```
|
|
958
|
-
*/
|
|
959
951
|
function createFsm(config) {
|
|
952
|
+
if (config === void 0) return (curriedConfig) => new Fsm(curriedConfig);
|
|
960
953
|
return new Fsm(config);
|
|
961
954
|
}
|
|
962
955
|
|