@demlik/tea 0.1.1 → 0.1.2
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/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +8 -8
- package/dist/authed-call/index.d.ts +3 -3
- package/dist/authed-call/index.js +5 -5
- package/dist/await-terminal/index.d.ts +1 -1
- package/dist/await-terminal/index.js +2 -2
- package/dist/batch-window/index.d.ts +2 -2
- package/dist/batch-window/index.js +4 -4
- package/dist/cache/index.d.ts +2 -2
- package/dist/{chunk-RVJFGRGK.js → chunk-27N2SPTN.js} +4 -4
- package/dist/chunk-27N2SPTN.js.map +1 -0
- package/dist/{chunk-FH5RUIIL.js → chunk-3XJWC7VW.js} +3 -3
- package/dist/{chunk-FH5RUIIL.js.map → chunk-3XJWC7VW.js.map} +1 -1
- package/dist/{chunk-IFBQJYGI.js → chunk-5DEQ5I3U.js} +3 -3
- package/dist/{chunk-IFBQJYGI.js.map → chunk-5DEQ5I3U.js.map} +1 -1
- package/dist/{chunk-XRXKH7KA.js → chunk-6RGBKODV.js} +3 -3
- package/dist/{chunk-XRXKH7KA.js.map → chunk-6RGBKODV.js.map} +1 -1
- package/dist/{chunk-D5EQDLDV.js → chunk-7W4LMPUW.js} +4 -4
- package/dist/{chunk-D5EQDLDV.js.map → chunk-7W4LMPUW.js.map} +1 -1
- package/dist/{chunk-A56GNPI7.js → chunk-DILMKOZ7.js} +5 -23
- package/dist/chunk-DILMKOZ7.js.map +1 -0
- package/dist/{chunk-EIZJTYKR.js → chunk-EHIX7NYZ.js} +4 -4
- package/dist/{chunk-EIZJTYKR.js.map → chunk-EHIX7NYZ.js.map} +1 -1
- package/dist/{chunk-WUV3PSCZ.js → chunk-HCEVHFJ7.js} +2 -2
- package/dist/chunk-HCEVHFJ7.js.map +1 -0
- package/dist/{chunk-EQRUAP2A.js → chunk-J6527VRQ.js} +2 -2
- package/dist/chunk-J6527VRQ.js.map +1 -0
- package/dist/{chunk-QGZW4W3E.js → chunk-K7Q23EQ4.js} +3 -3
- package/dist/{chunk-QGZW4W3E.js.map → chunk-K7Q23EQ4.js.map} +1 -1
- package/dist/{chunk-RGTPPF4U.js → chunk-LP7VQBRG.js} +3 -3
- package/dist/{chunk-RGTPPF4U.js.map → chunk-LP7VQBRG.js.map} +1 -1
- package/dist/{chunk-2WZHS4P2.js → chunk-MMH7CW5K.js} +4 -16
- package/dist/chunk-MMH7CW5K.js.map +1 -0
- package/dist/{chunk-EDGDR5XX.js → chunk-ON24RKSE.js} +3 -3
- package/dist/{chunk-EDGDR5XX.js.map → chunk-ON24RKSE.js.map} +1 -1
- package/dist/{chunk-TAO4YOLO.js → chunk-PS23H6KQ.js} +3 -3
- package/dist/{chunk-TAO4YOLO.js.map → chunk-PS23H6KQ.js.map} +1 -1
- package/dist/{chunk-BNJYE4AU.js → chunk-QLA76GIT.js} +21 -16
- package/dist/chunk-QLA76GIT.js.map +1 -0
- package/dist/{chunk-TC4HWABA.js → chunk-S3FQN4SL.js} +7 -7
- package/dist/{chunk-TC4HWABA.js.map → chunk-S3FQN4SL.js.map} +1 -1
- package/dist/{chunk-RVU3RBE6.js → chunk-SQTCS44W.js} +6 -4
- package/dist/chunk-SQTCS44W.js.map +1 -0
- package/dist/{chunk-7VEG4KHB.js → chunk-VLGARN6H.js} +3 -3
- package/dist/{chunk-7VEG4KHB.js.map → chunk-VLGARN6H.js.map} +1 -1
- package/dist/{core-CymXZCeY.d.ts → core-BoB6t7dB.d.ts} +11 -1
- package/dist/deadline/index.d.ts +2 -2
- package/dist/deadline/index.js +3 -3
- package/dist/debounce/index.d.ts +6 -0
- package/dist/debounce/index.js +1 -1
- package/dist/do/index.d.ts +15 -24
- package/dist/do/index.js +9 -13
- package/dist/do/index.js.map +1 -1
- package/dist/{durable-effects-2MDxDs45.d.ts → durable-effects-CO9Uh971.d.ts} +1 -1
- package/dist/extension/index.d.ts +1 -1
- package/dist/extension/index.js +3 -3
- package/dist/extension/react.js +3 -3
- package/dist/extension/subs/index.d.ts +2 -2
- package/dist/fan-out/index.d.ts +1 -1
- package/dist/idempotent-intake/index.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/llm-call/index.d.ts +2 -2
- package/dist/llm-call/index.js +5 -5
- package/dist/machine-viz/index.d.ts +4 -4
- package/dist/machine-viz/index.js +4 -8
- package/dist/machine-viz/index.js.map +1 -1
- package/dist/mem/index.d.ts +1 -1
- package/dist/monitored-run/index.d.ts +2 -2
- package/dist/monitored-run/index.js +5 -5
- package/dist/node/index.d.ts +1 -1
- package/dist/paginated-walk/index.d.ts +2 -2
- package/dist/paginated-walk/index.js +5 -5
- package/dist/parity/index.d.ts +10 -4
- package/dist/parity/index.js +6 -5
- package/dist/parity/index.js.map +1 -1
- package/dist/pbt/arbitraries/index.d.ts +1 -1
- package/dist/pbt/index.d.ts +15 -8
- package/dist/pbt/index.js +5 -11
- package/dist/pbt/index.js.map +1 -1
- package/dist/pbt/runners/index.d.ts +1 -1
- package/dist/pbt/runners/index.js +3 -3
- package/dist/poller/index.d.ts +2 -2
- package/dist/poller/index.js +3 -3
- package/dist/prediction/index.d.ts +23 -2
- package/dist/prediction/index.js +2 -2
- package/dist/pure/index.d.ts +2 -2
- package/dist/pure/index.js +2 -2
- package/dist/raft/demo.d.ts +2 -2
- package/dist/raft/demo.js +5 -5
- package/dist/raft/index.d.ts +3 -3
- package/dist/raft/index.js +4 -4
- package/dist/raft/sim.d.ts +2 -2
- package/dist/raft/sim.js +5 -5
- package/dist/raft/timeline.d.ts +2 -2
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +8 -4
- package/dist/react/index.js.map +1 -1
- package/dist/reconciler/index.d.ts +2 -2
- package/dist/reconciler/index.js +5 -5
- package/dist/recorder/index.d.ts +1 -1
- package/dist/resilient-call/index.d.ts +45 -2
- package/dist/resilient-call/index.js +4 -4
- package/dist/retry-to-success/index.d.ts +109 -0
- package/dist/retry-to-success/index.js +35 -0
- package/dist/retry-to-success/index.js.map +1 -0
- package/dist/saga/index.d.ts +14 -1
- package/dist/saga/index.js.map +1 -1
- package/dist/snapshot/index.d.ts +1 -1
- package/dist/snapshot/index.js +3 -3
- package/dist/subs/index.d.ts +2 -2
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +2 -2
- package/dist/throttle/index.d.ts +9 -0
- package/dist/throttle/index.js +1 -1
- package/dist/throttled-input/index.d.ts +10 -2
- package/dist/throttled-input/index.js +6 -6
- package/dist/throttled-input/index.js.map +1 -1
- package/dist/token-refresh/index.d.ts +1 -1
- package/dist/token-refresh/index.js +3 -3
- package/dist/trace-replay/index.d.ts +1 -1
- package/dist/trace-replay/index.js +3 -3
- package/dist/{types-N9LZbdnr.d.ts → types-B-8bcAp8.d.ts} +1 -1
- package/dist/with-deadline/index.d.ts +1 -1
- package/dist/with-deadline/index.js +5 -24
- package/dist/with-deadline/index.js.map +1 -1
- package/dist/with-resilience/index.d.ts +2 -2
- package/dist/with-resilience/index.js +13 -36
- package/dist/with-resilience/index.js.map +1 -1
- package/dist/with-telemetry/index.d.ts +1 -1
- package/dist/with-telemetry/index.js +4 -29
- package/dist/with-telemetry/index.js.map +1 -1
- package/dist/work-queue/adapter.d.ts +1 -1
- package/dist/work-queue/index.d.ts +1 -1
- package/dist/work-queue/ops.d.ts +1 -1
- package/dist/workflow/index.d.ts +16 -10
- package/dist/workflow/index.js.map +1 -1
- package/package.json +8 -2
- package/dist/chunk-2WZHS4P2.js.map +0 -1
- package/dist/chunk-A56GNPI7.js.map +0 -1
- package/dist/chunk-BNJYE4AU.js.map +0 -1
- package/dist/chunk-EQRUAP2A.js.map +0 -1
- package/dist/chunk-RVJFGRGK.js.map +0 -1
- package/dist/chunk-RVU3RBE6.js.map +0 -1
- package/dist/chunk-WUV3PSCZ.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pure/core.ts"],"names":[],"mappings":"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","file":"chunk-QLA76GIT.js","sourcesContent":["/**\n * @demlik/tea — pure-core leaf (ADR 0006).\n *\n * This is the runtime-free pure core of the substrate. It holds the\n * client-prediction fold seam (`foldMsgs`), the form reader\n * (`formOf`/`detectUpdateForm`), and the pure type vocabulary (`Machine`,\n * `Reducer`, `Transitions`, `Cmd`, `Sub`, `Port`, …).\n *\n * **Dependency direction (the actual decoupling):** this module imports\n * NOTHING from the runtime — no `better-result`, no `run`/host/`Store`. The\n * runtime (`run`, the host, interpret, `Store`, subscribe — all in\n * `../index.ts`) imports *from* here; never the reverse. The\n * `@demlik/tea/pure` subpath re-exports this surface, and\n * `pure/import-graph.test.ts` is the regression fence asserting the pure\n * entrypoint's import graph never reaches `run`.\n */\n\n// === Dev-mode invariant enforcement ===\n//\n// Three runtime guards that catch TEA invariant violations during development.\n// Dead-code-eliminated in production by any bundler that replaces\n// `import.meta.env.DEV` (Vite) or `process.env.NODE_ENV` (webpack/esbuild).\n//\n// 1. deepFreeze(state) before passing to update — catches mutation\n// 2. Thenable check on return value — catches async update\n// 3. Walk cmd fields for function types — catches closures-as-data\n//\n// These enforce invariants 1 and 2 at runtime where the type system cannot.\nexport const __DEV__: boolean = (() => {\n try {\n const meta = import.meta as unknown as { env?: { DEV?: boolean } };\n if (meta.env?.DEV !== undefined) {\n return meta.env.DEV;\n }\n } catch {\n // import.meta not available (Node CJS, service workers)\n }\n try {\n return (\n typeof process !== \"undefined\" && process.env?.NODE_ENV !== \"production\"\n );\n } catch {\n return false;\n }\n})();\n\nexport function deepFreeze<T>(obj: T, seen?: WeakSet<object>): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== Array.prototype && proto !== null)\n return obj;\n const visited = seen ?? new WeakSet();\n if (visited.has(obj as object)) return obj;\n visited.add(obj as object);\n Object.freeze(obj);\n for (const v of Object.values(obj as Record<string, unknown>))\n deepFreeze(v, visited);\n return obj;\n}\n\nexport function hasFunctionValues(obj: unknown): string | null {\n if (obj === null || typeof obj !== \"object\") return null;\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n if (typeof value === \"function\") return key;\n }\n return null;\n}\n\nexport function assertPureResult(result: unknown, msgType: string): void {\n if (result && typeof (result as { then?: unknown }).then === \"function\") {\n throw new Error(\n `@demlik/tea: update cell \"${msgType}\" returned a Promise. ` +\n `update must be synchronous. Move async work to interpret.`,\n );\n }\n if (\n !Array.isArray(result) ||\n result.length < 2 ||\n !Array.isArray(result[1])\n ) {\n throw new Error(\n `@demlik/tea: update cell \"${msgType}\" returned a non-tuple. ` +\n `Expected [State, Cmd[]], got ${typeof result}.`,\n );\n }\n const cmds = result[1] as readonly { type: string }[];\n for (const cmd of cmds) {\n const fnField = hasFunctionValues(cmd);\n if (fnField !== null) {\n throw new Error(\n `@demlik/tea: Cmd \"${cmd.type}\" has function field \"${fnField}\". ` +\n `Cmds must be plain data, not closures.`,\n );\n }\n }\n}\n\n// === Cmd: tagged-union, one-shot effect ===\nexport type Cmd<T extends string = string> = { type: T };\n\n// === SyncReturn<S, C>: the compile-time reentrancy guard (ADR 0003 #5) ===\n//\n// The canon rule (`.patterns/tea-do/reentrancy.md`,\n// `.patterns/tea-do/reentrancy-deadlock.md`): a reducer must never\n// inline-`await` a re-entrant result. \"Non-reentrant by default\" ≡ \"the reducer\n// is pure AND synchronous\": a reducer that returns a `Promise` (because it is\n// `async`, or inline-`await`s) is the suspended-but-still-blocking turn Orleans\n// serializes against — it occupies the single-writer slot across a suspension\n// point and can be re-entered mid-flight → deadlock.\n//\n// So the guard is purely type-level: every reducer/transition cell returns\n// `SyncReturn<S, C>` — the synchronous result tuple, intersected with `{ then?:\n// never }` to make it *non-thenable*. A `Promise<readonly [S, readonly C[]]>`\n// is an object with a `then` method, so it fails to satisfy `then?: never`; an\n// `async (s, m) => [...]` (or one that inline-`await`s) is therefore\n// unrepresentable at compile time — `tsc` rejects it *at the cell*, not at a\n// runtime hang. A plain synchronous tuple `[next, cmds]` has no `then` property,\n// so the optional-absent `then?: never` is satisfied and existing pure reducers\n// compile unchanged. `SyncReturn<S, C>` is also assignable *to* `readonly [S,\n// readonly C[]]` (the intersection is narrower), so the runtime dispatch in\n// `run`/`replay` consumes a cell result exactly as before.\n//\n// This mirrors `retry-backoff`'s `Rng` brand (#63): the obligation lives in the\n// type at the construction boundary (\"parse, don't validate\"), not in a comment.\nexport type SyncReturn<S, C extends Cmd> = readonly [S, readonly C[]] & {\n // A thenable carries a callable `then`; forbidding it rejects every Promise.\n // Optional + `never` means \"absent on a sync tuple, impossible on a Promise\".\n readonly then?: never;\n};\n\n// === update form: Reducer vs Transitions, tagged once ===\n//\n// The substrate accepts two `update` shapes (see the `Machine.update` union and\n// the `defineMachine` overloads):\n//\n// - \"reducer\" — flat record keyed by Msg.type, every cell a function.\n// - \"transitions\" — 2D table keyed by State.type then Msg.type, every cell a\n// record of functions.\n//\n// Which one a given machine is must be known at runtime by `run`, `replay`, and\n// the `withX` wrappers (their dispatch / key-enumeration / reserved-namespace\n// scans differ per form). Rather than re-derive it structurally at every reader\n// — a `typeof update[firstKey] === \"function\"` heuristic that breaks the day a\n// reducer cell is itself an object-with-a-call — `defineMachine` computes the\n// form ONCE at construction and stamps it on the machine as a non-enumerable\n// `__form` (so it never serializes, never collides with a Msg.type key, never\n// shows up in `Object.keys(machine)`). Every reader calls `formOf(machine)`.\nexport type UpdateForm = \"reducer\" | \"transitions\";\n\n// The single structural heuristic, defined ONCE. Used only by `defineMachine`\n// (and `formOf`'s fallback for machines built without it, e.g. a plain object\n// literal annotated as `Machine`). A Reducer's first own value is a function; a\n// Transitions table's first own value is a record (of functions). An empty\n// record (`M` is `never`) can never dispatch a Msg, so the form is irrelevant —\n// \"reducer\" is returned arbitrarily.\nexport function detectUpdateForm(update: object): UpdateForm {\n const firstKey = Object.keys(update)[0];\n if (firstKey === undefined) return \"reducer\";\n const firstValue = (update as Record<string, unknown>)[firstKey];\n return typeof firstValue === \"function\" ? \"reducer\" : \"transitions\";\n}\n\n// The single reader every form-sensitive site goes through. Prefers the\n// `__form` tag stamped by `defineMachine` (authoritative — computed once at the\n// typed construction boundary); falls back to `detectUpdateForm` only for a\n// machine that never passed through `defineMachine`. No reader re-implements the\n// heuristic.\nexport function formOf(machine: {\n update: object;\n __form?: UpdateForm;\n}): UpdateForm {\n return machine.__form ?? detectUpdateForm(machine.update);\n}\n\n// === applyCell: THE single reducer-vs-transitions dispatch primitive ===\n//\n// Applies the one update cell selected by `(formOf(machine), state, msg)` and\n// returns its `[nextState, cmds]` verbatim. Every site that steps a machine —\n// `run`'s applyUpdate, `foldUpdates` (replay/foldMsgs), the PBT fold runner,\n// and the withX wrappers — dispatches through THIS function, so production and\n// the verification tools agree on the update form by construction (#275).\n// Pure and dev-check-free: `deepFreeze`/`assertPureResult` stay at the call\n// sites that want them.\nexport function applyCell<S, M extends { type: string }, C extends Cmd>(\n machine: { update: object; __form?: UpdateForm },\n state: S,\n msg: M,\n): readonly [S, readonly C[]] {\n type CellFn = (state: S, msg: M) => readonly [S, readonly C[]];\n if (formOf(machine) === \"reducer\") {\n const record = machine.update as Record<string, CellFn>;\n // biome-ignore lint/style/noNonNullAssertion: the Reducer mapped type guarantees a cell for every dispatched Msg.type; `!` required under noUncheckedIndexedAccess and cannot miss for a Msg the machine accepts\n return record[msg.type]!(state, msg);\n }\n const table = machine.update as Record<string, Record<string, CellFn>>;\n // The ONE sanctioned `state as unknown as { type }` read: the Transitions\n // overload constrains S to `{ type: string }` at the `defineMachine`\n // boundary, but that constraint is erased on the runtime-facing `object`\n // here — every former per-site copy of this double-cast collapsed into\n // this line (#275).\n const stateKey = (state as unknown as { type: string }).type;\n // biome-ignore lint/style/noNonNullAssertion: the Transitions overload guarantees every (state.type × msg.type) cell exists; `!` required under noUncheckedIndexedAccess and cannot miss at runtime\n return table[stateKey]![msg.type]!(state, msg);\n}\n\n// === msgKeysOf: recover the Msg.type set from either update form ===\n//\n// A Reducer's own keys ARE the Msg.type set. A Transitions table's keys are\n// state.type; its INNER keys are the Msg.type set (uniform across phases by\n// the mapped-type contract), so the first phase's inner keys are read. An\n// empty update (`M` is `never`) yields `[]`. Keyed on `formOf` — the withX\n// wrappers and the PBT `msgTypeKeys` all read through this one helper (#275).\nexport function msgKeysOf(machine: {\n update: object;\n __form?: UpdateForm;\n}): readonly string[] {\n const keys = Object.keys(machine.update);\n const firstKey = keys[0];\n if (firstKey === undefined) return [];\n if (formOf(machine) === \"reducer\") return keys;\n const firstValue = (machine.update as Record<string, unknown>)[firstKey];\n return Object.keys(firstValue as object);\n}\n\n// === Reducer<S, M, C>: record-of-handlers form of `update` ===\n//\n// Flat dispatch table keyed by `Msg.type`. Each cell is a pure transition for\n// a single Msg variant, narrowed via `Extract<M, { type: K }>`. The mapped type\n// is *load-bearing*: adding a Msg variant without a matching key in the\n// Reducer record is a compile error — no `absurd()` helper at call sites, no\n// silent fall-through, no default branch hiding impurity.\n//\n// Strengthens invariant 2 (pure transitions — the record form has no\n// fall-through default to hide impurity behind) and invariant 7 (identity is\n// explicit — the Msg variant set is load-bearing at the type level).\n//\n// `defineMachine` accepts the Reducer record form via overload. The runtime\n// dispatches via `update[msg.type](state, msg)`.\nexport type Reducer<S, M extends { type: string }, C extends Cmd> = {\n [K in M[\"type\"]]: (\n state: S,\n msg: Extract<M, { type: K }>,\n // `SyncReturn<S, C>` (not `readonly [S, readonly C[]]`) is the reentrancy\n // guard: a non-thenable return type, so an `async`/inline-`await`ing cell —\n // which returns `Promise<...>` — fails to compile at the cell. See the\n // `SyncReturn` doc above.\n ) => SyncReturn<S, C>;\n};\n\n// === Transitions<S, M, C>: table form of `update` for state-machine-shaped machines ===\n//\n// When `State` is itself a discriminated union (`State.type` is the active\n// phase), the table form makes every (state.type × msg.type) cell explicit at\n// the type level. Missing a cell — e.g. forgetting how `phase: \"settling\"`\n// handles `msg.type: \"tab_stepped\"` — fails to compile. No nested switch, no\n// fall-through, no `_ -> (state, [])` default branch hiding regressions.\n//\n// Each cell receives the narrowed `State` for its phase and the narrowed\n// `Msg` for its variant via two `Extract` lookups. Phantom-narrow at the\n// type level; pure data at runtime.\n//\n// `defineMachine` accepts a third `update` form for `Transitions<S, M, C>` —\n// the runtime dispatches via `update[state.type][msg.type](state, msg)`.\n//\n// Strengthens invariant 2 (table form has no fall-through default),\n// invariant 6 (runtime walks the table predictably, no hidden dispatch\n// fallback), and invariant 7 (both state.type and msg.type are load-bearing\n// at the type level).\nexport type Transitions<\n S extends { type: string },\n M extends { type: string },\n C extends Cmd,\n> = {\n [P in S[\"type\"]]: {\n [K in M[\"type\"]]: (\n state: Extract<S, { type: P }>,\n msg: Extract<M, { type: K }>,\n // Same reentrancy guard as `Reducer`: a transition cell that returns a\n // Promise (async / inline-await) is the suspended-blocking turn the canon\n // forbids, so its return is the non-thenable `SyncReturn<S, C>`.\n ) => SyncReturn<S, C>;\n };\n};\n\n// === Cmd: namespace for conditional Cmd emission ===\n//\n// Two recurring frictions in reducer cells:\n//\n// 1. \"Emit cmd X only when condition Y holds.\"\n// Hand-rolled: `cond ? [{ type: \"x\", ... }] : []`\n// With Cmd: `Cmd.when(cond, { type: \"x\", ... })`\n//\n// 2. \"Emit cmd X carrying a value that may be undefined; if undefined,\n// emit nothing.\"\n// Hand-rolled: `value !== undefined ? [{ type: \"x\", value }] : []`\n// With Cmd: `Cmd.whenDefined(value, (v) => ({ type: \"x\", value: v }))`\n//\n// Both forms return `readonly C[]` so they spread cleanly into the cmds\n// array returned by a Transitions cell:\n//\n// return [next, [\n// ...Cmd.when(state.tabId !== undefined, { type: \"detach_debugger\", tabId: state.tabId }),\n// ...Cmd.whenDefined(state.queueItemId, (id) => ({\n// type: \"queue:complete\", queueItemId: id, status: \"done\",\n// })),\n// ]];\n//\n// `Cmd` as a value namespace coexists with `Cmd<T>` as a type — TypeScript's\n// declaration merging puts them in different name spaces (type vs. value).\n// The reader sees `Cmd<...>` in type position and `Cmd.when(...)` in\n// expression position; no ambiguity at use sites.\n//\n// Why a namespace and not top-level `when` / `whenDefined`: `when` at module\n// scope reads as a generic conditional, but these helpers are specifically\n// for *Cmd emission* (return `readonly C[]`, the cmds-array contract of\n// every Transitions cell). The namespace pins that intent at the call site.\nexport const Cmd = {\n /**\n * The empty Cmd array. Typed `readonly never[]` so it's assignable to any\n * `readonly C[]` for any `C extends Cmd`. Use in `init` returns and\n * Transitions cells that emit zero effects:\n *\n * init: (loaded) => [loaded ?? initial, Cmd.none],\n * tick: (state) => [state, Cmd.none],\n *\n * Elm's `Cmd.none` analogue. Cultural signal alongside the runtime help:\n * `[state, Cmd.none]` reads as intent (\"this transition emits nothing\"),\n * `[state, []]` reads as \"empty array of what\".\n *\n * Frozen at runtime so a downstream consumer can't `.push()` into the\n * shared reference.\n */\n none: Object.freeze([]) as readonly never[],\n\n /**\n * Flat concat of cmd arrays. Use when a cell composes effects from\n * multiple conditional sources:\n *\n * return [next, Cmd.batch(\n * Cmd.whenDefined(state.queueItemId, (id) => ({ type: \"complete\", id })),\n * Cmd.when(state.windowId !== undefined, { type: \"close_window\", windowId }),\n * [{ type: \"detach_debugger\", tabId: state.tabId }],\n * )];\n *\n * `<const C>` keeps inline cmd literals' discriminants narrow (same\n * rationale as `when` / `whenDefined` above).\n */\n batch: <const C extends Cmd>(\n ...arrs: readonly (readonly C[])[]\n ): readonly C[] => {\n const out: C[] = [];\n for (const arr of arrs) out.push(...arr);\n return out;\n },\n\n /**\n * Emit `cmd` wrapped in a single-element array iff `cond` is true.\n * Otherwise return the empty array. Spreads cleanly into the cmds array\n * returned by a Transitions cell.\n *\n * `const C` (TypeScript 5.0+) keeps the inferred `type:` discriminator\n * literal narrow when called with an object literal — so `Cmd.when(b,\n * { type: \"x\", ... })` infers as `{ type: \"x\", ... }`, not `{ type:\n * string, ... }`, and stays assignable to a discriminated-union arm\n * without `as const` at the call site.\n */\n when: <const C extends Cmd>(cond: boolean, cmd: C): readonly C[] =>\n cond ? [cmd] : [],\n\n /**\n * If `value` is defined, call `build(value)` and emit the resulting cmd\n * wrapped in a single-element array. If `value` is `undefined`, return\n * the empty array. `value` is narrowed to `T` inside `build`.\n *\n * `const C` on the return type keeps the callback's object-literal\n * `type:` field narrow (see `when` above for the full rationale).\n */\n whenDefined: <T, const C extends Cmd>(\n value: T | undefined,\n build: (value: T) => C,\n ): readonly C[] => (value !== undefined ? [build(value)] : []),\n} as const;\n\n// === SubId: branded string for Sub identity ===\n//\n// Subs are reconciled by id on every transition (canon §2.5, invariant 7).\n// Before branding, `Sub.id` was a raw `string` — a typo at one call site and a\n// different typo at another would silently produce two distinct subs that\n// looked identical to a human reader. The brand makes id construction explicit\n// (`subId(\"...\")`) and catches accidental string-where-SubId at the type\n// level.\n//\n// The brand is structural: `string & { __brand: \"SubId\" }`. The `subId(s)`\n// constructor is the ONE permitted cast in the substrate — every other call\n// site must go through it.\nexport type SubId = string & { readonly __brand: \"SubId\" };\n\n/**\n * Construct a `SubId` from a string. Use this everywhere a Sub literal is\n * built — including ids derived from runtime data (`subId(\\`ws:${auditId}\\`)`).\n * The brand is structural, not nominal, so dynamic ids are permitted; the\n * constructor's job is to make the identity decision explicit at every call\n * site so the type system can catch accidental raw-string drift.\n *\n * Strengthens invariant 7 (identity is explicit).\n */\nexport function subId(s: string): SubId {\n return s as SubId;\n}\n\n// === Sub: tagged-union, continuous source of msgs; stable id used for diff/reconcile ===\nexport type Sub<T extends string = string> = { id: SubId; type: T };\n\n// === Port<T>: typed escape hatch for \"data leaving the runtime\" ===\n//\n// A Port is a named, typed channel that Cmd handlers can `emit` to via the\n// augmented `ctx.emit(port, value)`. Subscribers attach via\n// `runtime.subscribePort(port, listener)` and receive every emitted value\n// synchronously (same fanout discipline as `runtime.observe`).\n//\n// Why Ports are a substrate primitive, distinct from State and Observe:\n// - **State** is \"the world as the program sees it.\" Folding outgoing\n// announcements into State turns ephemeral signals into persisted facts —\n// the classic anti-pattern that motivated this primitive.\n// - **Observe** sees every transition `(msg, state)`. That's the right channel\n// for devtools and logging, but it forces every consumer to filter the\n// entire firehose for a single signal.\n// - **Ports** are typed and selective: one channel per concept, subscribers\n// only see what the handler chose to emit. Mirrors Elm's outgoing-port\n// semantics — a typed declaration with `port` keyword whose values flow\n// out of the program to the host.\n//\n// Port identity is **by reference** — the returned object IS the identity.\n// Name is metadata for debugging. To prevent the \"two modules definePort the\n// same name expecting to share a channel, silently get distinct ports\" class\n// of bug, `definePort` asserts the name has not been seen in this process —\n// the symmetric runtime check to `SubId` (canon §2.12, invariant 7). Each\n// definePort call must use a unique name; if two modules need the same port,\n// one module exports it and the other imports it.\nexport interface Port<T> {\n readonly __brand: \"port\";\n readonly name: string;\n // Phantom field — never assigned, never read at runtime. Carries `T` for\n // inference at `ctx.emit` and `subscribePort` call sites. Using `?` so\n // `definePort` can produce a Port without constructing a value of `T`.\n readonly __t?: T;\n}\n\n/**\n * Augmentation injected onto `ctx` inside Cmd handlers. Handlers receive\n * `ctx & PortEmitter` so they can call `ctx.emit(port, value)` synchronously.\n * Subscribers registered via `runtime.subscribePort(port, listener)` receive\n * the value immediately.\n *\n * Emitting to a port with no subscribers is a no-op (does not throw).\n */\nexport interface PortEmitter {\n emit<T>(port: Port<T>, value: T): void;\n}\n\n// === NoCtx: the context-free marker ===\n//\n// A handler, Sub, or machine that reads NOTHING from `ctx` says so by using\n// `NoCtx` for its Ctx slot. This is the DELIBERATE absence of context — not\n// the accidental `unknown` looseness that erodes a boundary (see issue #64).\n//\n// `unknown` at a Ctx seam is ambiguous: it can mean \"I intentionally need no\n// context\" OR \"I gave up tightening this type.\" `NoCtx` resolves that\n// ambiguity at the type level. A reader (and the next agent) sees `NoCtx` and\n// knows the context-free-ness is a choice the author made, not a hole.\n//\n// Shape: an empty readonly record. A `Ctx & PortEmitter` is-a `NoCtx`, so a\n// context-free handler still composes at a richer call site. It carries no\n// own fields, so the name's claim (\"reads nothing from ctx\") is what callers\n// read at the seam.\n//\n// Strengthens invariant 6 (no silent looseness — a context-free seam is named,\n// not inferred) and invariant 8 (the boundary is legible; `unknown` stays\n// reserved for genuine wire-edge erasure, not for \"didn't bother\").\nexport type NoCtx = Readonly<Record<never, never>>;\n\n/** Spelled-out alias for `NoCtx`, for sites that prefer the long name. */\nexport type ContextFree = NoCtx;\n\n// === Interpret<M, C, Ctx>: record-of-handlers form of `interpret` ===\n//\n// Flat dispatch table keyed by `Cmd.type`. Each cell receives the narrowed Cmd\n// and the runtime-augmented Ctx (`Ctx & PortEmitter`) and resolves to a\n// follow-up Msg or `void` (fire-and-forget). The mapped type makes a missing\n// handler a compile error — `defineMachine` cannot accept the dictionary until\n// every Cmd variant has one.\n//\n// Hoisted out of `Machine.interpret` so consumers can type a free-standing\n// handler dictionary with `Interpret<MyMsg, MyCmd, MyCtx>` instead of\n// re-declaring the mapped type at every effects module.\n//\n// Strengthens invariant 2 (the record form has no fall-through default to\n// hide impurity behind) and invariant 7 (identity is explicit — the Cmd\n// variant set is load-bearing at the type level).\nexport type Interpret<M extends { type: string }, C extends Cmd, Ctx> = {\n [K in C[\"type\"]]: (\n cmd: Extract<C, { type: K }>,\n ctx: Ctx & PortEmitter,\n // biome-ignore lint/suspicious/noConfusingVoidType: an interpret handler returns a follow-up Msg or nothing; `void` permits no-return bodies that `M | undefined` would reject\n ) => Promise<M | void>;\n};\n\n// === Subscribe<M, U, Ctx>: record-of-handlers form of `subscribe` ===\n//\n// Flat dispatch table keyed by `Sub.type`. Each cell receives the narrowed\n// Sub, the Ctx, and a `dispatch` to fire follow-up Msgs. Returns a cleanup\n// function the substrate calls when the Sub is reconciled out (state\n// transitioned away). The mapped type guarantees every Sub variant has a\n// handler at the type level; runtime dispatch is a single property lookup.\n//\n// Hoisted out of `Machine.subscribe` so consumers can type a free-standing\n// handler dictionary with `Subscribe<MyMsg, MySub, MyCtx>` instead of\n// re-declaring the mapped type at every subs module.\n//\n// Strengthens invariant 7 (identity is explicit — the Sub variant set is\n// load-bearing at the type level).\nexport type Subscribe<M extends { type: string }, U extends Sub, Ctx> = {\n [K in U[\"type\"]]: (\n sub: Extract<U, { type: K }>,\n ctx: Ctx,\n dispatch: (msg: M) => void,\n ) => () => void;\n};\n\n// === Machine: pure data, host-agnostic ===\n//\n// `update` is stored as a union of the two record forms — the runtime branches\n// on shape at dispatch time. The public `defineMachine` overloads enforce one\n// shape per call so consumers never see the union themselves.\n//\n// - Reducer form: `Reducer<S, M, C>` — flat record keyed by Msg.type;\n// exhaustiveness enforced by the mapped type.\n// - Transitions form: `Transitions<S, M, C>` — 2D table keyed by\n// `state.type` then `msg.type`; only available when `S extends { type:\n// string }`. Conditional in the union so machines without a discriminated\n// State don't widen to include this branch.\n//\n// `M` is constrained to `{ type: string }` because both record forms require\n// a string discriminant.\n//\n// `interpret` is conditionally optional: when `C` is `Cmd<never>` the\n// interpret map is keyed by `never`, so the only valid value is `{}`. Forcing\n// every cmdless machine to write `interpret: {} as never` is ceremony for a\n// shape the type already pins. The tuple-wrap (`[C] extends [Cmd<never>]`)\n// disables distributive conditional so a real cmd union (e.g.\n// `Cmd<\"a\"> | Cmd<\"b\">`) doesn't degrade to optional just because one arm\n// happens to be `Cmd<never>`. Same trick the `update` field uses.\nexport type Machine<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n> = {\n /**\n * Boot the runtime. Called once by `run(...)` with whatever `Store.load()`\n * returned: `null` on fresh boot, the persisted state on rehydrate.\n *\n * **Contract:** when `loaded !== null`, init MUST return `[loaded, []]` —\n * no Cmds. Init's rehydrate branch is the migration / parse boundary, not\n * the boot-effect hook. See Invariant 2 in `.patterns/tea/tea-invariants.md`.\n *\n * Boot effects routes:\n * - Stateless infrastructure → host module top, outside TEA.\n * - State-conditional resume → a `boot` Msg the host dispatches once\n * after `run(...)` returns.\n *\n * Violations are caught at runtime by `replay` (which throws with a\n * pointer to the alternatives).\n */\n init: (loaded: S | null, ctx: Ctx) => readonly [S, readonly C[]];\n update:\n | Reducer<S, M, C>\n // Wrap in tuple to disable distributive conditional behavior. Without\n // `[S]`, TS distributes the conditional across `S`'s union members,\n // producing `Transitions<A,...> | Transitions<B,...>` instead of the\n // desired `Transitions<A|B,...>` — the table form needs a single\n // mapping over the full union of state types, not separate tables per\n // member.\n | ([S] extends [{ type: string }] ? Transitions<S, M, C> : never);\n subscriptions?: (state: S) => readonly U[];\n subscribe?: Subscribe<M, U, Ctx>;\n /**\n * The update form (\"reducer\" | \"transitions\"), stamped non-enumerably by\n * `defineMachine` at construction (see `UpdateForm` / `formOf`). Optional in\n * the type so the structural `Machine` annotation form keeps accepting plain\n * object literals; readers go through `formOf`, which falls back to\n * `detectUpdateForm` when the tag is absent. Never written by hand.\n */\n readonly __form?: UpdateForm;\n} & ([C] extends [Cmd<never>]\n ? { interpret?: Interpret<M, C, Ctx> }\n : { interpret: Interpret<M, C, Ctx> });\n\n// === foldUpdates: the single internal fold `replay` and `foldMsgs` share ===\n//\n// Folds `machine.update` over `msgs` from `initialState`, dispatching each\n// Msg through `applyCell` — the same primitive `run` uses — so every fold site\n// agrees on the reducer-vs-transitions form by construction (no second copy of\n// the dispatch to drift). Returns the final state plus the Cmds the cells emitted\n// along the way; the caller keeps them (`replay`) or discards them (`foldMsgs`).\n//\n// Touches no `Store`, no `interpret` handler, and starts no subscription — it\n// only calls `update` cells. The two public folds differ only in how they\n// enter and what they return: `replay` enters via `init` and returns\n// `{ state, cmds, subs }`; `foldMsgs` enters from a base state and returns `S`.\nexport function foldUpdates<S, M extends { type: string }, C extends Cmd>(\n machine: { update: object; __form?: UpdateForm },\n initialState: S,\n msgs: readonly M[],\n): { state: S; cmds: C[] } {\n let state: S = initialState;\n const cmds: C[] = [];\n\n for (const msg of msgs) {\n if (__DEV__) deepFreeze(state);\n\n const result = applyCell<S, M, C>(machine, state, msg);\n\n if (__DEV__) assertPureResult(result, msg.type);\n\n const [next, emitted] = result;\n state = next;\n cmds.push(...emitted);\n }\n\n return { state, cmds };\n}\n\n// === foldMsgs: runtime-free client-prediction fold seam (ADR 0006, #211) ===\n//\n// Folds `machine.update` over an ordered `Msg[]` starting from a caller-supplied\n// `base` state and returns the resulting state ONLY. This is the client-side\n// replay primitive a prediction loop needs (the Gambetta/Valve\n// authoritative-server reconcile step): re-simulate a queue of un-acked inputs\n// on top of an authoritative snapshot —\n// `foldMsgs(machine, snapshot, pendingInputs)`.\n//\n// Distinct from `replay` (the test idiom), by design (ADR 0006):\n// - Enters from a direct `base` parameter, NOT via `init`/`loaded` — so\n// reconciliation correctness never depends on the machine author's `init`\n// rehydrate discipline. Takes no `ctx` (the fold calls `update` only).\n// - Returns just the final `S` — not `{ state, cmds, subs }`. During prediction\n// the inputs' effects were already sent to the server; re-emitting their Cmds\n// on the client would double-fire, and `subs` are a runtime concern. Returning\n// only `S` makes \"replay fires no effects\" structural, not caller discipline.\n// A caller that wants the emitted Cmds for assertions uses `replay`.\n//\n// Invokes no `Store`, no `interpret` handler, and starts no subscription — it\n// shares `replay`'s `foldUpdates` fold, which only calls `update` cells, and\n// reads the reducer-vs-transitions form via the same `formOf(machine)` reader\n// `run`/`replay` use, so it agrees with them by construction.\n//\n// Per ADR 0006 the runtime-free *guarantee* lives on a dedicated\n// `@demlik/tea/pure` subpath whose module graph never reaches `run`; that\n// subpath export + import-graph guard are #213's scope. Here `foldMsgs` ships\n// as a reachable public API from root; #213 formalizes the boundary.\nexport function foldMsgs<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n>(machine: Machine<S, M, C, U, Ctx>, base: S, msgs: readonly M[]): S {\n return foldUpdates<S, M, C>(machine, base, msgs).state;\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { createResilientCall } from './chunk-
|
|
1
|
+
import { createMonitoredRun } from './chunk-7W4LMPUW.js';
|
|
2
|
+
import { createLlmCall } from './chunk-PS23H6KQ.js';
|
|
3
|
+
import { createResilientCall } from './chunk-27N2SPTN.js';
|
|
4
4
|
import { MsgType } from './chunk-JELSZN25.js';
|
|
5
5
|
import { createFanOut, initFanOut } from './chunk-UV6UWGEO.js';
|
|
6
|
-
import { subscribeDeadline } from './chunk-
|
|
7
|
-
import { defineMachine } from './chunk-
|
|
6
|
+
import { subscribeDeadline } from './chunk-K7Q23EQ4.js';
|
|
7
|
+
import { defineMachine } from './chunk-MMH7CW5K.js';
|
|
8
8
|
|
|
9
9
|
// src/agent/index.ts
|
|
10
10
|
function isAgentTurn(value) {
|
|
@@ -502,5 +502,5 @@ function liftAgent(state, [slice, cmds]) {
|
|
|
502
502
|
}
|
|
503
503
|
|
|
504
504
|
export { COMPACTION_PURPOSE, agentBootMsg, agentEvents, agentTurnSchema, compactionSummarySchema, createAgent, isAgentTurn, isCompactionSummary, liftAgent, mergeInterpret, status };
|
|
505
|
-
//# sourceMappingURL=chunk-
|
|
506
|
-
//# sourceMappingURL=chunk-
|
|
505
|
+
//# sourceMappingURL=chunk-S3FQN4SL.js.map
|
|
506
|
+
//# sourceMappingURL=chunk-S3FQN4SL.js.map
|