@eduardorenani/atlasjs 0.1.0-alpha.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/LICENSE +201 -0
- package/README.md +113 -0
- package/dist/actorName.d.ts +2 -0
- package/dist/actorName.d.ts.map +1 -0
- package/dist/actorName.js +24 -0
- package/dist/actorName.js.map +1 -0
- package/dist/buildActions.d.ts +11 -0
- package/dist/buildActions.d.ts.map +1 -0
- package/dist/buildActions.js +23 -0
- package/dist/buildActions.js.map +1 -0
- package/dist/buildActiveState.d.ts +43 -0
- package/dist/buildActiveState.d.ts.map +1 -0
- package/dist/buildActiveState.js +194 -0
- package/dist/buildActiveState.js.map +1 -0
- package/dist/buildActors.d.ts +4 -0
- package/dist/buildActors.d.ts.map +1 -0
- package/dist/buildActors.js +40 -0
- package/dist/buildActors.js.map +1 -0
- package/dist/buildPassiveState.d.ts +19 -0
- package/dist/buildPassiveState.d.ts.map +1 -0
- package/dist/buildPassiveState.js +59 -0
- package/dist/buildPassiveState.js.map +1 -0
- package/dist/compile.d.ts +6 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +164 -0
- package/dist/compile.js.map +1 -0
- package/dist/contextLift.d.ts +35 -0
- package/dist/contextLift.d.ts.map +1 -0
- package/dist/contextLift.js +172 -0
- package/dist/contextLift.js.map +1 -0
- package/dist/defineAgent.d.ts +60 -0
- package/dist/defineAgent.d.ts.map +1 -0
- package/dist/defineAgent.js +79 -0
- package/dist/defineAgent.js.map +1 -0
- package/dist/defineCompoundMode.d.ts +77 -0
- package/dist/defineCompoundMode.d.ts.map +1 -0
- package/dist/defineCompoundMode.js +79 -0
- package/dist/defineCompoundMode.js.map +1 -0
- package/dist/defineMode.d.ts +89 -0
- package/dist/defineMode.d.ts.map +1 -0
- package/dist/defineMode.js +95 -0
- package/dist/defineMode.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/injectEnd.d.ts +10 -0
- package/dist/injectEnd.d.ts.map +1 -0
- package/dist/injectEnd.js +106 -0
- package/dist/injectEnd.js.map +1 -0
- package/dist/types.d.ts +539 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +51 -0
- package/dist/types.js.map +1 -0
- package/dist/validateRoutes.d.ts +2 -0
- package/dist/validateRoutes.d.ts.map +1 -0
- package/dist/validateRoutes.js +107 -0
- package/dist/validateRoutes.js.map +1 -0
- package/dist/validateTargets.d.ts +2 -0
- package/dist/validateTargets.d.ts.map +1 -0
- package/dist/validateTargets.js +132 -0
- package/dist/validateTargets.js.map +1 -0
- package/dist/walk.d.ts +20 -0
- package/dist/walk.d.ts.map +1 -0
- package/dist/walk.js +35 -0
- package/dist/walk.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// `defineAgent` — constructs the root XState machine.
|
|
2
|
+
//
|
|
3
|
+
// Spec: docs/specs/004-xstate-agent-wrapper.md §`defineAgent`
|
|
4
|
+
// + docs/specs/005-agent-deps-and-stringifiable-context.md §`defineAgent`
|
|
5
|
+
//
|
|
6
|
+
// `defineAgent` is the only constructor that touches `xstate`: it returns an
|
|
7
|
+
// `AnyStateMachine` so the rest of the project (`createActor`, the inspector,
|
|
8
|
+
// existing tests) keeps working unchanged. The lowering itself lives in
|
|
9
|
+
// `compile.ts`.
|
|
10
|
+
//
|
|
11
|
+
// Deps lifecycle (spec 005 §Imutabilidade):
|
|
12
|
+
// - `Object.freeze` is applied once, here, before the closure is captured.
|
|
13
|
+
// - The frozen reference is threaded to `compile.ts`, which captures it in
|
|
14
|
+
// every generated callback's closure. There is no runtime path to swap
|
|
15
|
+
// deps after this call returns.
|
|
16
|
+
import { compile } from "./compile.js";
|
|
17
|
+
/**
|
|
18
|
+
* Construct the **root agent** — compiles the declarative `AgentConfig` into
|
|
19
|
+
* a runnable XState machine. This is the single boundary where the wrapper
|
|
20
|
+
* touches `xstate`: the return type is `AnyStateMachine`, so callers feed it
|
|
21
|
+
* straight into `createActor`, the inspector, and existing tests.
|
|
22
|
+
*
|
|
23
|
+
* The agent's `modes` map can mix `Mode`s (leaves) and nested `CompoundMode`s
|
|
24
|
+
* freely. The compile step lowers them, validates sibling-target references,
|
|
25
|
+
* injects the `END` synthetic state per-compound when referenced, and wires
|
|
26
|
+
* the payload-driven `routes` into XState transitions.
|
|
27
|
+
*
|
|
28
|
+
* @template TContext The agent's root context shape. Constrained to
|
|
29
|
+
* `JsonCompatible<TContext>` so the snapshot round-trips
|
|
30
|
+
* through arbitrary storage without custom encoding.
|
|
31
|
+
* @template TEvents The agent's full event union. Each variant must have a
|
|
32
|
+
* `type: string` discriminant. Pass `{} as Ev` to the
|
|
33
|
+
* `events` field — only its type matters; it's a phantom.
|
|
34
|
+
* @template TModes The root `modes` map. `initial` is keyed against this
|
|
35
|
+
* type so a typo is a compile error.
|
|
36
|
+
* @template TDeps Frozen container of external resources. Defaults to
|
|
37
|
+
* `Record<string, never>` when `deps` is omitted —
|
|
38
|
+
* callbacks still receive `deps`, typed as the empty
|
|
39
|
+
* object, so the envelope shape stays uniform.
|
|
40
|
+
*
|
|
41
|
+
* @param config `{ id, initial, context, events, deps?, actions?, modes }`.
|
|
42
|
+
* `actions` registers reusable, deps-aware callbacks (each
|
|
43
|
+
* returning `Partial<TContext>`) referenced by name from
|
|
44
|
+
* passive `on[event].actions`. The wrapper wraps them in
|
|
45
|
+
* `assign(...)` at compile time, so user code never imports
|
|
46
|
+
* from `xstate`.
|
|
47
|
+
*
|
|
48
|
+
* @returns An `AnyStateMachine` ready to pass to `createActor`.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* const agent = defineAgent<Ctx, Ev, Modes, { db: Driver; logger: Logger }>({
|
|
53
|
+
* id: "zoe",
|
|
54
|
+
* initial: "listening",
|
|
55
|
+
* context: { messages: [], attempts: 0 },
|
|
56
|
+
* events: {} as Ev,
|
|
57
|
+
* deps: { db: realDb, logger: pino() },
|
|
58
|
+
* actions: {
|
|
59
|
+
* appendUserMsg: ({ context, event, deps }) =>
|
|
60
|
+
* event.type === "USER_MSG"
|
|
61
|
+
* ? { messages: [...context.messages, { role: "user", content: event.text }] }
|
|
62
|
+
* : {},
|
|
63
|
+
* },
|
|
64
|
+
* modes: { listening, classifying, greetings, socratic },
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* const actor = createActor(agent).start();
|
|
68
|
+
* actor.send({ type: "USER_MSG", text: "hi" });
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export function defineAgent(config) {
|
|
72
|
+
// Spec 005 §Imutabilidade: shallow freeze the deps container once, here,
|
|
73
|
+
// before passing the reference to `compile`. The default-empty branch
|
|
74
|
+
// produces a frozen `{}` so callbacks observe `Object.isFrozen(deps) === true`
|
|
75
|
+
// even when the consumer omits `deps`.
|
|
76
|
+
const frozenDeps = Object.freeze(config.deps ?? {});
|
|
77
|
+
return compile(config, frozenDeps);
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=defineAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineAgent.js","sourceRoot":"","sources":["../src/defineAgent.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,8DAA8D;AAC9D,iFAAiF;AACjF,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,wEAAwE;AACxE,gBAAgB;AAChB,EAAE;AACF,4CAA4C;AAC5C,6EAA6E;AAC7E,6EAA6E;AAC7E,2EAA2E;AAC3E,oCAAoC;AAIpC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,UAAU,WAAW,CAKzB,MAAqD;IACnD,yEAAyE;IACzE,sEAAsE;IACtE,+EAA+E;IAC/E,uCAAuC;IACvC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAK,EAAY,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { CompoundContext, CompoundMode, CompoundModeConfig, LocalContextOf, ModesMap } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime carrier behind the opaque `CompoundMode` brand. Internal —
|
|
4
|
+
* accessed only by `compile.ts` via the `__kind` discriminant.
|
|
5
|
+
*
|
|
6
|
+
* `config` is stored as `unknown` on purpose: the original generic narrowing
|
|
7
|
+
* has already done its job at the call site, and `compile.ts` walks the tree
|
|
8
|
+
* structurally rather than relying on the generic parameters.
|
|
9
|
+
*
|
|
10
|
+
* @template TParentContext Context shape the parent scope provides.
|
|
11
|
+
* @template TEvents The agent's full event union.
|
|
12
|
+
* @template TDeps Frozen deps container this compound demands.
|
|
13
|
+
*/
|
|
14
|
+
export type CompoundModeCarrier<TParentContext, TEvents extends {
|
|
15
|
+
type: string;
|
|
16
|
+
}, TDeps extends Record<string, unknown> = Record<string, never>> = {
|
|
17
|
+
readonly __kind: "compound";
|
|
18
|
+
readonly config: unknown;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Construct a **CompoundMode** — a Mode that contains sub-Modes. Use this to
|
|
22
|
+
* group related leaves under a shared lifecycle, optionally narrowing the
|
|
23
|
+
* context children see via `context: { inherit, local }`.
|
|
24
|
+
*
|
|
25
|
+
* Children's effective context is `LocalContextOf<TParentContext, TCtx>`:
|
|
26
|
+
* - With `context` supplied: `Pick<TParentContext, inherit[number]> & typeof local`.
|
|
27
|
+
* Inherited keys are live-mirrored; locals are reset on every entry.
|
|
28
|
+
* - Without `context`: children see the full `TParentContext`.
|
|
29
|
+
*
|
|
30
|
+
* Children route out of the compound via `END` (defined in `./types.ts`); the
|
|
31
|
+
* compound's `onDone` then fires the parent-level transition.
|
|
32
|
+
*
|
|
33
|
+
* @template TParentContext The context the enclosing scope provides to this
|
|
34
|
+
* compound. Constrained to
|
|
35
|
+
* `JsonCompatible<TParentContext>`.
|
|
36
|
+
* @template TEvents The agent's full event union (each variant has a
|
|
37
|
+
* `type` discriminant).
|
|
38
|
+
* @template TCtx Either `undefined` (no narrowing — children see
|
|
39
|
+
* `TParentContext`) or a `CompoundContext` literal
|
|
40
|
+
* declaring which keys to `inherit` and which `local`
|
|
41
|
+
* variables to declare. The `local` shape must
|
|
42
|
+
* satisfy `JsonCompatible<TLocal>` (enforced at the
|
|
43
|
+
* `CompoundContext` alias level).
|
|
44
|
+
* @template TModes The compound's `modes` map. Each slot is a
|
|
45
|
+
* `Mode` (leaf) or nested `CompoundMode` typed
|
|
46
|
+
* against the compound-local context view.
|
|
47
|
+
* @template TDeps Frozen deps this compound passes to its children.
|
|
48
|
+
* Must match the agent's `TDeps` at the slot site
|
|
49
|
+
* (spec 005 §`defineCompoundMode` "Manual threading").
|
|
50
|
+
*
|
|
51
|
+
* @param config `{ context?, initial, modes, onDone }`. `initial` is keyed
|
|
52
|
+
* against `TModes` so a typo is a compile error. `onDone`
|
|
53
|
+
* accepts a sibling name or `END` (when nested further).
|
|
54
|
+
*
|
|
55
|
+
* @returns An opaque `CompoundMode` brand. Only `defineCompoundMode` /
|
|
56
|
+
* `defineAgent` accept it as a `modes` slot.
|
|
57
|
+
*
|
|
58
|
+
* @example CompoundMode with context narrowing — children see only `messages`.
|
|
59
|
+
* ```ts
|
|
60
|
+
* const socratic = defineCompoundMode<AgentCtx, Ev, {
|
|
61
|
+
* inherit: ["messages"];
|
|
62
|
+
* local: { attempts: number };
|
|
63
|
+
* }, {
|
|
64
|
+
* thinking: Mode<{ messages: Msg[]; attempts: number }, Ev>;
|
|
65
|
+
* evaluating: Mode<{ messages: Msg[]; attempts: number }, Ev, EvalPayload>;
|
|
66
|
+
* }, AgentDeps>({
|
|
67
|
+
* context: { inherit: ["messages"] as const, local: { attempts: 0 } },
|
|
68
|
+
* initial: "thinking",
|
|
69
|
+
* modes: { thinking, evaluating },
|
|
70
|
+
* onDone: "listening",
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function defineCompoundMode<TParentContext, TEvents extends {
|
|
75
|
+
type: string;
|
|
76
|
+
}, TCtx extends CompoundContext<TParentContext, ReadonlyArray<keyof TParentContext & string>, object> | undefined, TModes extends ModesMap<LocalContextOf<TParentContext, TCtx>, TEvents, TDeps>, TDeps extends Record<string, unknown> = Record<string, never>>(config: CompoundModeConfig<TParentContext, TEvents, TCtx, TModes, TDeps>): CompoundMode<TParentContext, TEvents, TDeps>;
|
|
77
|
+
//# sourceMappingURL=defineCompoundMode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineCompoundMode.d.ts","sourceRoot":"","sources":["../src/defineCompoundMode.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACR,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACX,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB,CAC3B,cAAc,EACd,OAAO,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAChC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAC7D;IACA,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAgB,kBAAkB,CAC9B,cAAc,EACd,OAAO,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAChC,IAAI,SACE,eAAe,CACb,cAAc,EACd,aAAa,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,EAO5C,MAAM,CACT,GACC,SAAS,EACf,MAAM,SAAS,QAAQ,CAAC,cAAc,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAC7E,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAE7D,MAAM,EAAE,kBAAkB,CAAC,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,GACzE,YAAY,CAAC,cAAc,EAAE,OAAO,EAAE,KAAK,CAAC,CAM9C"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// `defineCompoundMode` — constructs a CompoundMode (a Mode with sub-Modes).
|
|
2
|
+
//
|
|
3
|
+
// Spec: docs/specs/004-xstate-agent-wrapper.md §`defineCompoundMode`
|
|
4
|
+
// + docs/specs/005-agent-deps-and-stringifiable-context.md §`defineCompoundMode`
|
|
5
|
+
// + docs/specs/006-modes-not-states.md §"Refined vocabulary"
|
|
6
|
+
//
|
|
7
|
+
// Like `defineMode`, this is a thin Phase 3 shell. The generics enforce
|
|
8
|
+
// the compound-local context narrowing at the call site: children's
|
|
9
|
+
// `TContext` is `LocalContextOf<TParentContext, TCtx>`. The compile step in
|
|
10
|
+
// `compile.ts` lowers the carrier to XState states later.
|
|
11
|
+
//
|
|
12
|
+
// `TDeps` is threaded through to the returned `CompoundMode` brand via its
|
|
13
|
+
// contravariant `__phantomDeps` field. See spec 005 §`defineCompoundMode` for
|
|
14
|
+
// the manual-threading rationale: TypeScript cannot infer the agent's `TDeps`
|
|
15
|
+
// from a sub-Mode definition site (Modes are typically declared in separate
|
|
16
|
+
// files and only referenced from `defineAgent.modes`), so each
|
|
17
|
+
// `defineCompoundMode` invocation declares its own `TDeps` generic explicitly.
|
|
18
|
+
/**
|
|
19
|
+
* Construct a **CompoundMode** — a Mode that contains sub-Modes. Use this to
|
|
20
|
+
* group related leaves under a shared lifecycle, optionally narrowing the
|
|
21
|
+
* context children see via `context: { inherit, local }`.
|
|
22
|
+
*
|
|
23
|
+
* Children's effective context is `LocalContextOf<TParentContext, TCtx>`:
|
|
24
|
+
* - With `context` supplied: `Pick<TParentContext, inherit[number]> & typeof local`.
|
|
25
|
+
* Inherited keys are live-mirrored; locals are reset on every entry.
|
|
26
|
+
* - Without `context`: children see the full `TParentContext`.
|
|
27
|
+
*
|
|
28
|
+
* Children route out of the compound via `END` (defined in `./types.ts`); the
|
|
29
|
+
* compound's `onDone` then fires the parent-level transition.
|
|
30
|
+
*
|
|
31
|
+
* @template TParentContext The context the enclosing scope provides to this
|
|
32
|
+
* compound. Constrained to
|
|
33
|
+
* `JsonCompatible<TParentContext>`.
|
|
34
|
+
* @template TEvents The agent's full event union (each variant has a
|
|
35
|
+
* `type` discriminant).
|
|
36
|
+
* @template TCtx Either `undefined` (no narrowing — children see
|
|
37
|
+
* `TParentContext`) or a `CompoundContext` literal
|
|
38
|
+
* declaring which keys to `inherit` and which `local`
|
|
39
|
+
* variables to declare. The `local` shape must
|
|
40
|
+
* satisfy `JsonCompatible<TLocal>` (enforced at the
|
|
41
|
+
* `CompoundContext` alias level).
|
|
42
|
+
* @template TModes The compound's `modes` map. Each slot is a
|
|
43
|
+
* `Mode` (leaf) or nested `CompoundMode` typed
|
|
44
|
+
* against the compound-local context view.
|
|
45
|
+
* @template TDeps Frozen deps this compound passes to its children.
|
|
46
|
+
* Must match the agent's `TDeps` at the slot site
|
|
47
|
+
* (spec 005 §`defineCompoundMode` "Manual threading").
|
|
48
|
+
*
|
|
49
|
+
* @param config `{ context?, initial, modes, onDone }`. `initial` is keyed
|
|
50
|
+
* against `TModes` so a typo is a compile error. `onDone`
|
|
51
|
+
* accepts a sibling name or `END` (when nested further).
|
|
52
|
+
*
|
|
53
|
+
* @returns An opaque `CompoundMode` brand. Only `defineCompoundMode` /
|
|
54
|
+
* `defineAgent` accept it as a `modes` slot.
|
|
55
|
+
*
|
|
56
|
+
* @example CompoundMode with context narrowing — children see only `messages`.
|
|
57
|
+
* ```ts
|
|
58
|
+
* const socratic = defineCompoundMode<AgentCtx, Ev, {
|
|
59
|
+
* inherit: ["messages"];
|
|
60
|
+
* local: { attempts: number };
|
|
61
|
+
* }, {
|
|
62
|
+
* thinking: Mode<{ messages: Msg[]; attempts: number }, Ev>;
|
|
63
|
+
* evaluating: Mode<{ messages: Msg[]; attempts: number }, Ev, EvalPayload>;
|
|
64
|
+
* }, AgentDeps>({
|
|
65
|
+
* context: { inherit: ["messages"] as const, local: { attempts: 0 } },
|
|
66
|
+
* initial: "thinking",
|
|
67
|
+
* modes: { thinking, evaluating },
|
|
68
|
+
* onDone: "listening",
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export function defineCompoundMode(config) {
|
|
73
|
+
const carrier = {
|
|
74
|
+
__kind: "compound",
|
|
75
|
+
config,
|
|
76
|
+
};
|
|
77
|
+
return carrier;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=defineCompoundMode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineCompoundMode.js","sourceRoot":"","sources":["../src/defineCompoundMode.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,qEAAqE;AACrE,wFAAwF;AACxF,oEAAoE;AACpE,EAAE;AACF,wEAAwE;AACxE,oEAAoE;AACpE,4EAA4E;AAC5E,0DAA0D;AAC1D,EAAE;AACF,2EAA2E;AAC3E,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,+DAA+D;AAC/D,+EAA+E;AA+B/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,UAAU,kBAAkB,CAmB9B,MAAwE;IAExE,MAAM,OAAO,GAAwD;QACjE,MAAM,EAAE,UAAU;QAClB,MAAM;KACT,CAAC;IACF,OAAO,OAAkE,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Mode, ModeConfig } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime carrier behind the opaque `Mode` brand. Internal — accessed
|
|
4
|
+
* only by `compile.ts` via the `__kind` discriminant. User code never sees
|
|
5
|
+
* this shape because `defineMode` returns the branded type.
|
|
6
|
+
*
|
|
7
|
+
* @template TContext Context shape this Mode reads/writes.
|
|
8
|
+
* @template TEvents The agent's full event union (each variant has a `type`).
|
|
9
|
+
* @template TPayload Payload shape carried by `ModeOutput<TPayload>`.
|
|
10
|
+
* @template TDeps Frozen deps container this Mode demands.
|
|
11
|
+
*/
|
|
12
|
+
export type ModeCarrier<TContext, TEvents extends {
|
|
13
|
+
type: string;
|
|
14
|
+
}, TPayload, TDeps extends Record<string, unknown> = Record<string, never>> = {
|
|
15
|
+
readonly __kind: "leaf";
|
|
16
|
+
readonly config: ModeConfig<TContext, TEvents, TPayload, TDeps>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Construct a **leaf Mode** — one node in the agent's state tree with no
|
|
20
|
+
* sub-Modes. Modes come in two structural flavors:
|
|
21
|
+
*
|
|
22
|
+
* - **Active** (`{ input, behavior, routes }`) — runs an async `behavior` and
|
|
23
|
+
* dispatches on its `ModeOutput`. Use for LLM calls, tool execution,
|
|
24
|
+
* classifiers — anything that does work and then decides where to go next.
|
|
25
|
+
*
|
|
26
|
+
* - **Passive** (`{ on }`) — waits for an external event. Use for listening
|
|
27
|
+
* states or user-input gates.
|
|
28
|
+
*
|
|
29
|
+
* The two variants are mutually exclusive at the type level: mixing `behavior`
|
|
30
|
+
* and `on` is a compile error.
|
|
31
|
+
*
|
|
32
|
+
* @template TContext Shape of the context this Mode observes. Constrained to
|
|
33
|
+
* `JsonCompatible<TContext>`. At the agent's top level,
|
|
34
|
+
* this is the agent's full context. Inside a
|
|
35
|
+
* `defineCompoundMode` with a narrowing `context`, this is
|
|
36
|
+
* the compound-local view: inherited keys + declared locals.
|
|
37
|
+
* @template TEvents The agent's full event union. Each variant must have a
|
|
38
|
+
* `type: string` discriminant. Passive `on` handlers are
|
|
39
|
+
* typed against this union via `Extract<TEvents, { type: K }>`.
|
|
40
|
+
* @template TPayload Payload type carried on a successful `behavior` return
|
|
41
|
+
* (`ModeOutput<TPayload>`). Flows into `routes.*.when` and
|
|
42
|
+
* `routes.*.assign` for payload-driven dispatch. Defaults
|
|
43
|
+
* to `unknown` (relevant only for passive Modes, which
|
|
44
|
+
* never produce a payload).
|
|
45
|
+
* @template TDeps Frozen deps this Mode wants to see. Defaults to
|
|
46
|
+
* `Record<string, never>` — a Mode with the default
|
|
47
|
+
* slots into any agent. A Mode that declares
|
|
48
|
+
* `<…, { db: Driver }>` can only slot into agents whose
|
|
49
|
+
* `defineAgent.deps` provides at least `db`.
|
|
50
|
+
*
|
|
51
|
+
* @param config An `ActiveModeConfig` or a `PassiveModeConfig`. The
|
|
52
|
+
* discriminator is structural — TypeScript picks the variant
|
|
53
|
+
* from which keys are present.
|
|
54
|
+
*
|
|
55
|
+
* @returns An opaque `Mode` brand. User code cannot inspect it; only
|
|
56
|
+
* `defineCompoundMode` and `defineAgent` accept it as a `modes` slot.
|
|
57
|
+
*
|
|
58
|
+
* @example Active Mode — classify an intent and route on the payload.
|
|
59
|
+
* ```ts
|
|
60
|
+
* const classifying = defineMode<Ctx, Ev, { intent: "greet" | "learn" }>({
|
|
61
|
+
* input: ({ context, deps }) => ({ messages: context.messages }),
|
|
62
|
+
* behavior: async ({ input, deps }) => {
|
|
63
|
+
* const intent = await deps.llm.classify(input);
|
|
64
|
+
* return { outcome: "achieved", payload: { intent } };
|
|
65
|
+
* },
|
|
66
|
+
* routes: {
|
|
67
|
+
* achieved: [
|
|
68
|
+
* { when: (p) => p.intent === "greet", target: "greetings" },
|
|
69
|
+
* { target: "socratic" },
|
|
70
|
+
* ],
|
|
71
|
+
* retry: [],
|
|
72
|
+
* abandoned: { target: END },
|
|
73
|
+
* },
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @example Passive Mode — park here until a `USER_MSG` event arrives.
|
|
78
|
+
* ```ts
|
|
79
|
+
* const listening = defineMode<Ctx, Ev>({
|
|
80
|
+
* on: {
|
|
81
|
+
* USER_MSG: { target: "classifying", actions: "appendUserMsg" },
|
|
82
|
+
* },
|
|
83
|
+
* });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare function defineMode<TContext, TEvents extends {
|
|
87
|
+
type: string;
|
|
88
|
+
}, TPayload = unknown, TDeps extends Record<string, unknown> = Record<string, never>>(config: ModeConfig<TContext, TEvents, TPayload, TDeps>): Mode<TContext, TEvents, TPayload, TDeps>;
|
|
89
|
+
//# sourceMappingURL=defineMode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineMode.d.ts","sourceRoot":"","sources":["../src/defineMode.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,CACnB,QAAQ,EACR,OAAO,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAChC,QAAQ,EACR,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAC7D;IACA,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;CACnE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,wBAAgB,UAAU,CACtB,QAAQ,EACR,OAAO,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAChC,QAAQ,GAAG,OAAO,EAClB,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAE7D,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,GACvD,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAS1C"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// `defineMode` — constructs a leaf agent Mode (active or passive variant).
|
|
2
|
+
//
|
|
3
|
+
// Spec: docs/specs/004-xstate-agent-wrapper.md §`defineMode`
|
|
4
|
+
// + docs/specs/005-agent-deps-and-stringifiable-context.md §`defineMode`
|
|
5
|
+
// + docs/specs/006-modes-not-states.md §"Refined vocabulary"
|
|
6
|
+
//
|
|
7
|
+
// Phase 3 (these constructors) is a thin shell: it stores the user's config
|
|
8
|
+
// plus a runtime `__kind` tag behind the opaque `Mode` brand. The actual
|
|
9
|
+
// XState lowering happens in `compile.ts` (Phase 5) and is reached only via
|
|
10
|
+
// `defineAgent`. Users never inspect the returned object.
|
|
11
|
+
//
|
|
12
|
+
// The `TDeps` generic flows through to the brand via `__phantomDeps`, which
|
|
13
|
+
// puts it in function-argument position — making `Mode` contravariant in
|
|
14
|
+
// `TDeps`. That gives the slot-time variance check in `defineAgent.modes`
|
|
15
|
+
// the right direction structurally: a `Mode` demanding `{ db }` slots into
|
|
16
|
+
// agents whose deps include at least `db`.
|
|
17
|
+
/**
|
|
18
|
+
* Construct a **leaf Mode** — one node in the agent's state tree with no
|
|
19
|
+
* sub-Modes. Modes come in two structural flavors:
|
|
20
|
+
*
|
|
21
|
+
* - **Active** (`{ input, behavior, routes }`) — runs an async `behavior` and
|
|
22
|
+
* dispatches on its `ModeOutput`. Use for LLM calls, tool execution,
|
|
23
|
+
* classifiers — anything that does work and then decides where to go next.
|
|
24
|
+
*
|
|
25
|
+
* - **Passive** (`{ on }`) — waits for an external event. Use for listening
|
|
26
|
+
* states or user-input gates.
|
|
27
|
+
*
|
|
28
|
+
* The two variants are mutually exclusive at the type level: mixing `behavior`
|
|
29
|
+
* and `on` is a compile error.
|
|
30
|
+
*
|
|
31
|
+
* @template TContext Shape of the context this Mode observes. Constrained to
|
|
32
|
+
* `JsonCompatible<TContext>`. At the agent's top level,
|
|
33
|
+
* this is the agent's full context. Inside a
|
|
34
|
+
* `defineCompoundMode` with a narrowing `context`, this is
|
|
35
|
+
* the compound-local view: inherited keys + declared locals.
|
|
36
|
+
* @template TEvents The agent's full event union. Each variant must have a
|
|
37
|
+
* `type: string` discriminant. Passive `on` handlers are
|
|
38
|
+
* typed against this union via `Extract<TEvents, { type: K }>`.
|
|
39
|
+
* @template TPayload Payload type carried on a successful `behavior` return
|
|
40
|
+
* (`ModeOutput<TPayload>`). Flows into `routes.*.when` and
|
|
41
|
+
* `routes.*.assign` for payload-driven dispatch. Defaults
|
|
42
|
+
* to `unknown` (relevant only for passive Modes, which
|
|
43
|
+
* never produce a payload).
|
|
44
|
+
* @template TDeps Frozen deps this Mode wants to see. Defaults to
|
|
45
|
+
* `Record<string, never>` — a Mode with the default
|
|
46
|
+
* slots into any agent. A Mode that declares
|
|
47
|
+
* `<…, { db: Driver }>` can only slot into agents whose
|
|
48
|
+
* `defineAgent.deps` provides at least `db`.
|
|
49
|
+
*
|
|
50
|
+
* @param config An `ActiveModeConfig` or a `PassiveModeConfig`. The
|
|
51
|
+
* discriminator is structural — TypeScript picks the variant
|
|
52
|
+
* from which keys are present.
|
|
53
|
+
*
|
|
54
|
+
* @returns An opaque `Mode` brand. User code cannot inspect it; only
|
|
55
|
+
* `defineCompoundMode` and `defineAgent` accept it as a `modes` slot.
|
|
56
|
+
*
|
|
57
|
+
* @example Active Mode — classify an intent and route on the payload.
|
|
58
|
+
* ```ts
|
|
59
|
+
* const classifying = defineMode<Ctx, Ev, { intent: "greet" | "learn" }>({
|
|
60
|
+
* input: ({ context, deps }) => ({ messages: context.messages }),
|
|
61
|
+
* behavior: async ({ input, deps }) => {
|
|
62
|
+
* const intent = await deps.llm.classify(input);
|
|
63
|
+
* return { outcome: "achieved", payload: { intent } };
|
|
64
|
+
* },
|
|
65
|
+
* routes: {
|
|
66
|
+
* achieved: [
|
|
67
|
+
* { when: (p) => p.intent === "greet", target: "greetings" },
|
|
68
|
+
* { target: "socratic" },
|
|
69
|
+
* ],
|
|
70
|
+
* retry: [],
|
|
71
|
+
* abandoned: { target: END },
|
|
72
|
+
* },
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @example Passive Mode — park here until a `USER_MSG` event arrives.
|
|
77
|
+
* ```ts
|
|
78
|
+
* const listening = defineMode<Ctx, Ev>({
|
|
79
|
+
* on: {
|
|
80
|
+
* USER_MSG: { target: "classifying", actions: "appendUserMsg" },
|
|
81
|
+
* },
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export function defineMode(config) {
|
|
86
|
+
const carrier = {
|
|
87
|
+
__kind: "leaf",
|
|
88
|
+
config,
|
|
89
|
+
};
|
|
90
|
+
// The brand is a phantom — at runtime the object is just the carrier.
|
|
91
|
+
// The cast is the single boundary where the opaque type is minted; user
|
|
92
|
+
// code can only obtain `Mode` values through this function.
|
|
93
|
+
return carrier;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=defineMode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineMode.js","sourceRoot":"","sources":["../src/defineMode.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,6DAA6D;AAC7D,gFAAgF;AAChF,oEAAoE;AACpE,EAAE;AACF,4EAA4E;AAC5E,yEAAyE;AACzE,4EAA4E;AAC5E,0DAA0D;AAC1D,EAAE;AACF,4EAA4E;AAC5E,yEAAyE;AACzE,0EAA0E;AAC1E,2EAA2E;AAC3E,2CAA2C;AAwB3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,MAAM,UAAU,UAAU,CAMtB,MAAsD;IAEtD,MAAM,OAAO,GAAoD;QAC7D,MAAM,EAAE,MAAM;QACd,MAAM;KACT,CAAC;IACF,sEAAsE;IACtE,wEAAwE;IACxE,4DAA4D;IAC5D,OAAO,OAA8D,CAAC;AAC1E,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { defineMode } from "./defineMode.js";
|
|
2
|
+
export { defineCompoundMode } from "./defineCompoundMode.js";
|
|
3
|
+
export { defineAgent } from "./defineAgent.js";
|
|
4
|
+
export { END, RE_THROW } from "./types.js";
|
|
5
|
+
export type { ModeOutput, Outcome, Mode, CompoundMode, ModeConfig, ActiveModeConfig, PassiveModeConfig, CompoundModeConfig, AgentConfig, ModesMap, CompoundContext, Routes, RouteList, RouteTarget, ErrorRouteTarget, EventHandlers, JsonPrimitive, JsonValue, JsonObject, JsonArray, JsonCompatible, } from "./types.js";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EACR,UAAU,EACV,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,QAAQ,EACR,eAAe,EACf,MAAM,EACN,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,SAAS,EACT,UAAU,EACV,SAAS,EACT,cAAc,GACjB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Atlas — XState wrapper for AI agent orchestration.
|
|
2
|
+
//
|
|
3
|
+
// Spec: docs/specs/004-xstate-agent-wrapper.md
|
|
4
|
+
// docs/specs/005-agent-deps-and-stringifiable-context.md
|
|
5
|
+
// Tasks: docs/specs/004-tasks.md
|
|
6
|
+
export { defineMode } from "./defineMode.js";
|
|
7
|
+
export { defineCompoundMode } from "./defineCompoundMode.js";
|
|
8
|
+
export { defineAgent } from "./defineAgent.js";
|
|
9
|
+
export { END, RE_THROW } from "./types.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,+CAA+C;AAC/C,+DAA+D;AAC/D,iCAAiC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LoweredAtomicState } from "./buildPassiveState.js";
|
|
2
|
+
import type { LoweredInvokeState } from "./buildActiveState.js";
|
|
3
|
+
export type LoweredLeafState = LoweredAtomicState | LoweredInvokeState;
|
|
4
|
+
export declare const END_SUBSTATE: {
|
|
5
|
+
type: "final";
|
|
6
|
+
};
|
|
7
|
+
export declare function pickEndName(siblings: readonly string[]): string;
|
|
8
|
+
export declare function hasEndReference(state: LoweredLeafState): boolean;
|
|
9
|
+
export declare function rewriteEndTargets(state: LoweredLeafState, endName: string): LoweredLeafState;
|
|
10
|
+
//# sourceMappingURL=injectEnd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injectEnd.d.ts","sourceRoot":"","sources":["../src/injectEnd.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,kBAAkB,EAAqB,MAAM,wBAAwB,CAAC;AACpF,OAAO,KAAK,EACR,kBAAkB,EAGrB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAGvE,eAAO,MAAM,YAAY;;CAA6B,CAAC;AAgBvD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAM/D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAmBhE;AA6BD,wBAAgB,iBAAiB,CAC7B,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,MAAM,GAChB,gBAAgB,CAwBlB"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Phase 5.11 helpers: `$end` substate injection + END-target rewrite.
|
|
2
|
+
//
|
|
3
|
+
// Spec: docs/specs/004-tasks.md Phase 5.11 + 5.12,
|
|
4
|
+
// docs/specs/004-xstate-agent-wrapper.md §"END and the injected final substate"
|
|
5
|
+
// (lines 631-635).
|
|
6
|
+
//
|
|
7
|
+
// A compound mode whose subtree references `target: END` anywhere needs an
|
|
8
|
+
// injected final substate to exit through — XState requires a concrete state
|
|
9
|
+
// name as a transition target, the spec keeps `END` as a symbol so it cannot
|
|
10
|
+
// collide with user-declared names. This module provides the building blocks:
|
|
11
|
+
// - `pickEndName(siblings)`: collision-safe name (`$end`, `$end1`, ...)
|
|
12
|
+
// - `hasEndReference(state)`: does a lowered leaf state mention END anywhere?
|
|
13
|
+
// - `rewriteEndTargets(state, name)`: same shape with every END target swapped
|
|
14
|
+
// - `END_SUBSTATE`: the XState final-substate config to inject
|
|
15
|
+
//
|
|
16
|
+
// The compound-lowering slice (5.16) composes these:
|
|
17
|
+
// if any direct child references END → pickEndName(Object.keys(states)),
|
|
18
|
+
// rewriteEndTargets on each child, set states[endName] = END_SUBSTATE.
|
|
19
|
+
// Otherwise leave the compound open (5.12 — no final substate emitted).
|
|
20
|
+
import { END } from "./types.js";
|
|
21
|
+
// XState final-substate config — what gets dropped into `states[endName]`.
|
|
22
|
+
export const END_SUBSTATE = { type: "final" };
|
|
23
|
+
// `Array.isArray` widens `readonly T[]` to `any[]` and fails to subtract it
|
|
24
|
+
// from a `T | readonly T[]` union. Typed predicate keeps narrowing precise
|
|
25
|
+
// without leaking `any`. (Same pattern as buildPassiveState / buildActiveState.)
|
|
26
|
+
function isReadonlyArray(value) {
|
|
27
|
+
return Array.isArray(value);
|
|
28
|
+
}
|
|
29
|
+
function isInvoke(state) {
|
|
30
|
+
return "invoke" in state;
|
|
31
|
+
}
|
|
32
|
+
// `$end` if available, then `$end1`, `$end2`, ... — the `$` prefix is unusual
|
|
33
|
+
// enough that collisions with user keys are vanishingly rare, but we still
|
|
34
|
+
// probe and bump for safety.
|
|
35
|
+
export function pickEndName(siblings) {
|
|
36
|
+
const set = new Set(siblings);
|
|
37
|
+
if (!set.has("$end"))
|
|
38
|
+
return "$end";
|
|
39
|
+
let i = 1;
|
|
40
|
+
while (set.has(`$end${i}`))
|
|
41
|
+
i += 1;
|
|
42
|
+
return `$end${i}`;
|
|
43
|
+
}
|
|
44
|
+
export function hasEndReference(state) {
|
|
45
|
+
if (isInvoke(state)) {
|
|
46
|
+
for (const t of state.invoke.onDone) {
|
|
47
|
+
if (t.target === END)
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
if (state.invoke.onError !== undefined) {
|
|
51
|
+
for (const t of state.invoke.onError) {
|
|
52
|
+
if (t.target === END)
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
for (const transitions of Object.values(state.on)) {
|
|
59
|
+
const list = isReadonlyArray(transitions) ? transitions : [transitions];
|
|
60
|
+
for (const t of list) {
|
|
61
|
+
if (t.target === END)
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
function rewritePassiveTransition(t, endName) {
|
|
68
|
+
if (t.target !== END)
|
|
69
|
+
return t;
|
|
70
|
+
return { ...t, target: endName };
|
|
71
|
+
}
|
|
72
|
+
function rewriteOnDoneTransition(t, endName) {
|
|
73
|
+
if (t.target !== END)
|
|
74
|
+
return t;
|
|
75
|
+
return { ...t, target: endName };
|
|
76
|
+
}
|
|
77
|
+
function rewriteOnErrorTransition(t, endName) {
|
|
78
|
+
if (t.target !== END)
|
|
79
|
+
return t;
|
|
80
|
+
return { ...t, target: endName };
|
|
81
|
+
}
|
|
82
|
+
// Returns a new lowered state with every `target === END` rewritten to
|
|
83
|
+
// `endName`. Non-END targets, `actions`, `guard`, and `reenter` flags are
|
|
84
|
+
// preserved by reference. The input is not mutated.
|
|
85
|
+
export function rewriteEndTargets(state, endName) {
|
|
86
|
+
if (isInvoke(state)) {
|
|
87
|
+
const onDone = state.invoke.onDone.map((t) => rewriteOnDoneTransition(t, endName));
|
|
88
|
+
const invoke = {
|
|
89
|
+
src: state.invoke.src,
|
|
90
|
+
input: state.invoke.input,
|
|
91
|
+
onDone,
|
|
92
|
+
};
|
|
93
|
+
if (state.invoke.onError !== undefined) {
|
|
94
|
+
invoke.onError = state.invoke.onError.map((t) => rewriteOnErrorTransition(t, endName));
|
|
95
|
+
}
|
|
96
|
+
return { invoke };
|
|
97
|
+
}
|
|
98
|
+
const on = {};
|
|
99
|
+
for (const [event, transitions] of Object.entries(state.on)) {
|
|
100
|
+
on[event] = isReadonlyArray(transitions)
|
|
101
|
+
? transitions.map((t) => rewritePassiveTransition(t, endName))
|
|
102
|
+
: rewritePassiveTransition(transitions, endName);
|
|
103
|
+
}
|
|
104
|
+
return { on };
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=injectEnd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injectEnd.js","sourceRoot":"","sources":["../src/injectEnd.ts"],"names":[],"mappings":"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"}
|