@vielzeug/codex 3.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +6 -0
  2. package/data/catalog.json +1984 -0
  3. package/data/llms-full.txt +31429 -0
  4. package/data/llms.txt +47 -0
  5. package/data/manifest.json +8 -0
  6. package/data/packages/arsenal.json +216 -0
  7. package/data/packages/assay.json +46 -0
  8. package/data/packages/clockwork.json +66 -0
  9. package/data/packages/codex.json +29 -0
  10. package/data/packages/coins.json +101 -0
  11. package/data/packages/conduit.json +68 -0
  12. package/data/packages/courier.json +55 -0
  13. package/data/packages/dnd.json +60 -0
  14. package/data/packages/familiar.json +17 -0
  15. package/data/packages/flux.json +94 -0
  16. package/data/packages/focus.json +38 -0
  17. package/data/packages/forge.json +60 -0
  18. package/data/packages/gesture.json +37 -0
  19. package/data/packages/herald.json +81 -0
  20. package/data/packages/illusionist.json +132 -0
  21. package/data/packages/keymap.json +51 -0
  22. package/data/packages/ledger.json +60 -0
  23. package/data/packages/lingua.json +70 -0
  24. package/data/packages/mesh.json +54 -0
  25. package/data/packages/necromancer.json +50 -0
  26. package/data/packages/orbit.json +99 -0
  27. package/data/packages/ore.json +65 -0
  28. package/data/packages/postmaster.json +49 -0
  29. package/data/packages/prism.json +66 -0
  30. package/data/packages/pulse.json +71 -0
  31. package/data/packages/refine.json +12 -0
  32. package/data/packages/ripple.json +88 -0
  33. package/data/packages/rune.json +78 -0
  34. package/data/packages/sandbox.json +26 -0
  35. package/data/packages/scout.json +63 -0
  36. package/data/packages/scroll.json +110 -0
  37. package/data/packages/sentinel.json +35 -0
  38. package/data/packages/sigil.json +49 -0
  39. package/data/packages/sourcerer.json +70 -0
  40. package/data/packages/spell.json +132 -0
  41. package/data/packages/tempo.json +81 -0
  42. package/data/packages/vault.json +93 -0
  43. package/data/packages/ward.json +80 -0
  44. package/data/packages/wayfinder.json +114 -0
  45. package/data/refine.json +12828 -0
  46. package/data/search.json +1582 -0
  47. package/dist/cli.js +32 -0
  48. package/dist/cli.js.map +1 -1
  49. package/dist/skills.d.ts +26 -0
  50. package/dist/skills.js +46 -0
  51. package/dist/skills.js.map +1 -0
  52. package/package.json +6 -6
  53. package/skills/vielzeug/SKILL.md +153 -0
@@ -0,0 +1,66 @@
1
+ {
2
+ "apiSource": "export { ClockworkError, type ClockworkErrorCode } from './errors.js';\nexport { defineMachine } from './interpret.js';\nexport type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';\n",
3
+ "docs": {
4
+ "index": "---\ntitle: Clockwork — Typed finite state machines for TypeScript\ndescription: Framework-neutral typed state machines with pure transitions, actor-owned runtime work, timers, invokes, and explicit effects.\npackage: clockwork\ncategory: state\nkeywords: [state-machine, finite-state, typed, actor, async-tasks]\nrelated: [herald, ripple, ward]\nexports: [defineMachine, ClockworkError, Machine, Actor, MachineConfig, MachineSnapshot]\nenvironments: [browser, node, ssr, deno]\n---\n\n<!-- markdownlint-disable MD025 MD033 MD060 -->\n\n<PackageHero package=\"clockwork\" />\n\n## Why Clockwork?\n\nApplication workflows often mix state changes with timers, requests, rendering, and cleanup. Clockwork keeps transition logic pure while each disposable actor owns runtime work. You can test state decisions without starting effects or invokes.\n\n```ts\nimport { defineMachine } from '@vielzeug/clockwork';\n\n// Before\nif (status === 'idle') status = 'loading';\nfetchItems().then((items) => {\n status = 'ready';\n data = items;\n});\n\n// After\ntype Event = { type: 'FETCH' } | { items: string[]; type: 'DONE' };\nconst machine = defineMachine<{ items: string[] }, Event>()({\n context: { items: [] },\n initial: 'idle',\n states: {\n idle: { on: { FETCH: { target: 'loading' } } },\n loading: {\n invoke: [{\n src: ({ signal }) => fetch('/api/items', { signal }).then((response) => response.json() as Promise<string[]>),\n onDone: ({ result }) => ({ items: result, type: 'DONE' }),\n }],\n on: { DONE: { reduce: ({ event }) => ({ items: event.items }), target: 'ready' } },\n },\n ready: {},\n },\n});\n```\n\n| Feature | Clockwork | XState | Zustand |\n| --- | --- | --- | --- |\n| Bundle size | <PackageInfo package=\"clockwork\" type=\"size\" /> | Larger actor/statechart runtime | Smaller store runtime |\n| Zero dependencies | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"check\" size=\"16\"></ore-icon> |\n| Pure transition API | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"triangle-alert\" size=\"16\"></ore-icon> Statechart-focused | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n| Owned cancellation | <ore-icon name=\"check\" size=\"16\"></ore-icon> Actor disposal | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n| Framework coupling | <ore-icon name=\"check\" size=\"16\"></ore-icon> None | <ore-icon name=\"check\" size=\"16\"></ore-icon> None | <ore-icon name=\"check\" size=\"16\"></ore-icon> None |\n\n<div class=\"decision-callout\">\n\n**Use Clockwork when** your feature has explicit workflow states, cancellable work, or effects that must run after a state commit.\n\n**Consider XState when** you need statecharts, visual tooling, or its broader actor ecosystem.\n\n</div>\n\n## Installation\n\n::: code-group\n\n```sh [pnpm]\npnpm add @vielzeug/clockwork\n```\n\n```sh [npm]\nnpm install @vielzeug/clockwork\n```\n\n```sh [yarn]\nyarn add @vielzeug/clockwork\n```\n\n:::\n\n## Quick Start\n\nDefine the context and event union, create an actor, observe its snapshot, then dispose it when its owner ends.\n\n```ts\nimport { defineMachine } from '@vielzeug/clockwork';\n\ntype Event = { type: 'DEC' } | { type: 'INC' };\n\nconst counter = defineMachine<{ count: number }, Event>()({\n context: { count: 0 },\n initial: 'idle',\n states: {\n idle: {\n on: {\n DEC: { reduce: ({ context }) => ({ count: context.count - 1 }), target: 'idle' },\n INC: { reduce: ({ context }) => ({ count: context.count + 1 }), target: 'idle' },\n },\n },\n },\n});\n\nusing actor = counter.createActor();\nactor.subscribe((snapshot) => console.log(snapshot));\nactor.send({ type: 'INC' });\n// { context: { count: 1 }, state: 'idle' }\n```\n\n## Features\n\n<div class=\"features-grid\">\n\n- **`defineMachine()`** — validates and compiles one flat machine definition.\n- **`machine.transition()`** — evaluates a transition without actor runtime work.\n- **`machine.createActor()`** — creates isolated, disposable runtime ownership.\n- **`reduce`** — returns a replacement context from a transition.\n- **`effects`** — run after commit and stable subscriber notification.\n- **`invoke`** — runs cancellable asynchronous work on state entry.\n- **`after`** — schedules cancellable delayed transitions.\n- **`actor.snapshot`** — exposes the current shallow-frozen state/context value.\n\n</div>\n\n## Documentation\n\n<div class=\"doc-links\">\n\n- [Usage Guide](./usage.md)\n- [API Reference](./api.md)\n- [Examples](./examples.md)\n- [Migration Guide](./migration.md)\n\n</div>\n\n## See Also\n\n<div class=\"see-also\">\n\n- [Herald](/herald/) — publish events between independent actors without coupling machine definitions.\n- [Ripple](/ripple/) — bridge actor snapshots into a reactive graph when you need fine-grained rendering.\n- [Ward](/ward/) — call authorization predicates from transition guards.\n\n</div>\n\n<!-- markdownlint-enable MD025 MD033 MD060 -->\n",
5
+ "api": "---\ntitle: Clockwork — API Reference\ndescription: Reference for Clockwork machine definitions, actors, and types.\n---\n\n[[toc]]\n\n## API Overview\n\n| Symbol | Purpose | Execution mode | Common gotcha |\n| --- | --- | --- | --- |\n| `defineMachine()` | Compile a typed flat machine definition | Sync | Call the generic factory before supplying the definition |\n| `Machine.transition()` | Resolve a pure next snapshot | Sync | Does not run effects, invokes, or timers |\n| `Machine.createActor()` | Create a runtime owner | Sync | Fresh and restored actors have different entry behavior |\n| `Actor.send()` | Dispatch an event | Sync | Returns `void`; re-entrant events queue internally |\n| `Actor.subscribe()` | Observe committed snapshots | Sync | Observes only; it does not trace sends or errors |\n| `ClockworkError` | Report definition and snapshot validation failures | Sync | Use `code`, not message text |\n\n## Package Entry Points\n\n| Import | Purpose |\n| --- | --- |\n| `@vielzeug/clockwork` | Machine compiler, actor runtime, errors, and types |\n\n## Exported Surface\n\nCallback parameter types are inferred for inline definitions. Clockwork also exports reusable callback, transition, state-node, actor-option, result, and error-context types for shared helpers.\n\n| Primary export | Kind |\n| --- | --- |\n| `defineMachine` | Function |\n| `Machine` | Type |\n| `Actor` | Type |\n| `MachineSnapshot` | Type |\n| `MachineConfig` | Type |\n| `ClockworkError` | Class |\n\nAdditional exported types: `ActorErrorContext`, `ActorOptions`, `After`, `Effect`, `EffectArgs`, `EventByType`, `EventType`, `Guard`, `Invoke`, `InvokeArgs`, `MachineEvent`, `Reducer`, `StateNode`, `Transition`, `TransitionInput`, and `TransitionResult`.\n\n## Core Functions\n\n### `defineMachine()`\n\n```ts\nfunction defineMachine<\n Context extends Record<string, unknown> = Record<string, never>,\n Event extends MachineEvent = MachineEvent,\n>(): <State extends string>(definition: MachineConfig<State, Context, Event>) => Machine<State, Context, Event>;\n```\n\nReturns a factory that validates and compiles a typed flat machine definition. Definitions and their structural entries must be ordinary or null-prototype records, not arrays or class instances. Context follows the same record rule; omit it only when the context type has no keys. Compilation snapshots invoke and transition callback references.\n\nThe curried signature is required so TypeScript can infer `State` from the `states` object while you explicitly provide `Context` and `Event`. TypeScript does not support partial type argument inference, so the state-key union cannot be inferred in a single non-curried call when the context and event generics are explicit.\n\n**Returns:** A definition function that returns `Machine`.\n\n**Example:**\n\n```ts\nimport { defineMachine } from '@vielzeug/clockwork';\n\ntype Event = { type: 'START' };\n\nconst machine = defineMachine<Record<string, never>, Event>()({\n initial: 'idle',\n states: { idle: { on: { START: { target: 'running' } } }, running: {} },\n});\n```\n\nThrows `ClockworkError` when a definition has an invalid context, initial state, target, transition, effect, invoke, or timer delay.\n\n---\n\n### `Actor.subscribe()`\n\n```ts\nsubscribe(listener: (snapshot: MachineSnapshot<State, Context>) => void): () => void;\n```\n\nSubscribes to future committed actor snapshots. It does not run immediately; read `actor.snapshot` for the initial value. Returns an unsubscribe function. Subscriber failures are reported through `onError` without stopping remaining subscribers, declared effects, or the actor.\n\n**Example:**\n\n```ts\nimport { defineMachine } from '@vielzeug/clockwork';\n\nconst machine = defineMachine<Record<string, never>, { type: 'NEXT' }>()({\n initial: 'idle',\n states: { idle: { on: { NEXT: { target: 'idle' } } } },\n});\n\nconst actor = machine.createActor();\nconst stop = actor.subscribe((snapshot) => console.debug(snapshot));\nactor.send({ type: 'NEXT' });\nstop();\nactor.dispose();\n```\n\n## Machine Methods\n\n### `machine.transition()`\n\n```ts\ntransition(\n snapshot: MachineSnapshot<State, Context>,\n event: Event,\n): TransitionResult<State, Context>;\n```\n\nResolves a snapshot for one user event without actor runtime work.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `snapshot` | `MachineSnapshot<State, Context>` | Input state and context |\n| `event` | `Event` | User event to evaluate |\n\n**Returns:** A `TransitionResult` with `transition` or `ignored` type.\n\n**Example:**\n\n```ts\nconst result = machine.transition(machine.initialSnapshot, { type: 'START' });\n```\n\n---\n\n### `machine.can()`\n\n```ts\ncan(snapshot: MachineSnapshot<State, Context>, event: Event): boolean;\n```\n\nReturns whether a transition exists and its guard passes.\n\n**Returns:** `true` when the supplied snapshot accepts the event.\n\n---\n\n### `machine.createActor()`\n\n```ts\ncreateActor(options?: ActorOptions<State, Context, Event>): Actor<State, Context, Event>;\n```\n\nCreates an independent actor for event dispatch, timers, invokes, effects, subscriptions, and disposal. A fresh actor starts the initial state's entry effects and resources. An actor restored with `options.snapshot` starts only the restored state's resources: invokes and timers, not entry effects.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `options.snapshot` | `MachineSnapshot<State, Context>` | Optional restored actor snapshot |\n| `options.maxTransitions` | `number` | Positive queued-transition limit for one synchronous flush |\n| `options.onError` | `(error, context) => void` | Side-channel observation callback for runtime failures |\n\n**Returns:** Disposable `Actor`.\n\n**Example:**\n\n```ts\nconst actor = machine.createActor({\n onError(error, { phase, state }) {\n console.error(phase, state, error);\n },\n snapshot: { context: {}, state: 'idle' },\n});\n```\n\n## Actor Methods\n\n### `actor.send()`\n\n```ts\nsend(event: Event): void;\n```\n\nDispatches a user event to the current actor state. Events sent while the actor is processing queue and flush synchronously; sends to a disposed actor are ignored. For active actors, malformed events without a string `type` log a development warning and are ignored. Valid but unhandled event types are ignored without a warning. Use `actor.snapshot` after sending to read the current snapshot.\n\n**Returns:** Nothing.\n\n---\n\n### `actor.can()`\n\n```ts\ncan(event: Event): boolean;\n```\n\nReturns whether the current actor snapshot accepts an event. A guard failure is reported as a fatal transition error, disposes the actor, and returns `false`. Returns `false` after disposal.\n\n**Returns:** Boolean transition availability.\n\n---\n\n### `actor.subscribe()`\n\n```ts\nsubscribe(listener: (snapshot: MachineSnapshot<State, Context>) => void): () => void;\n```\n\nRegisters a listener for committed snapshots. The listener does not run immediately.\n\n**Returns:** An unsubscribe function.\n\n---\n\n### `actor.dispose()`\n\n```ts\ndispose(): void;\n[Symbol.dispose](): void;\n```\n\nCancels timers and invokes, clears queued events and listeners, and aborts `disposalSignal`.\n\n**Returns:** Nothing. Idempotent.\n\n## Error Handling Policy\n\nMachine-execution failures are fail-stop: guard, reducer, effect, invoke, timer, and queued-transition-limit failures dispose the actor. Subscriber failures are observational: Clockwork reports them, continues the stable subscriber snapshot and declared effects, and keeps the actor active.\n\nThe optional `onError` callback receives the error and its phase/state context but cannot control disposition. Errors thrown by this observer are swallowed so error reporting cannot change synchronous, timer, or invoke behavior.\n\n```ts\ntype ActorErrorContext<State, Event> = {\n readonly event?: Event;\n readonly phase: 'effect' | 'invoke' | 'subscriber' | 'transition';\n readonly state: State;\n};\n```\n\nSubscriber iteration uses a stable snapshot: listeners added during notification begin with the next transition.\n\n## Types\n\n### `MachineSnapshot<State, Context>`\n\n```ts\ntype MachineSnapshot<State extends string, Context extends Record<string, unknown>> = {\n readonly context: Readonly<Context>;\n readonly state: State;\n};\n```\n\nClockwork shallow-clones and freezes each snapshot and its context record. Nested context values remain caller-owned and are not deep-frozen.\n\n### `MachineConfig<State, Context, Event>`\n\n```ts\ntype MachineConfig<State extends string, Context extends Record<string, unknown>, Event extends MachineEvent> =\n (keyof Context extends never ? { readonly context?: Context } : { readonly context: Context }) & {\n readonly initial: State;\n readonly states: Record<State, StateNode<State, Context, Event>>;\n };\n```\n\nA flat machine definition. State nodes cannot contain child states. The `StateNode`, `Transition`, `After`, `Invoke`, `Effect`, `Guard`, and `Reducer` shapes are inferred inline and exported for reusable helpers. `After.delay` must be finite and between 0 and 2,147,483,647 milliseconds; delayed guards and reducers receive `event: undefined`.\n\n### `Actor<State, Context, Event>`\n\n```ts\ntype Actor<State extends string, Context extends Record<string, unknown>, Event extends MachineEvent> = {\n [Symbol.dispose](): void;\n can(event: Event): boolean;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n send(event: Event): void;\n readonly snapshot: MachineSnapshot<State, Context>;\n subscribe(listener: (snapshot: MachineSnapshot<State, Context>) => void): () => void;\n};\n```\n\nAn actor's `snapshot` is the current plain readonly snapshot.\n\n### `Machine<State, Context, Event>`\n\n```ts\ntype Machine<State extends string, Context extends Record<string, unknown>, Event extends MachineEvent> = {\n can(snapshot: MachineSnapshot<State, Context>, event: Event): boolean;\n createActor(options?: ActorOptions<State, Context, Event>): Actor<State, Context, Event>;\n readonly initialSnapshot: MachineSnapshot<State, Context>;\n transition(snapshot: MachineSnapshot<State, Context>, event: Event): TransitionResult<State, Context>;\n};\n```\n\nA compiled, reusable machine. Its transition lookup is map-based, so unknown or poison event names such as `__proto__` are safely ignored when no transition exists.\n\n## Errors\n\n### `ClockworkError`\n\n`ClockworkError` reports invalid definitions, contexts, snapshots, and actor transition limits. It has `code`, `details`, and standard `Error` fields. Use `instanceof ClockworkError` to narrow an unknown error.\n\n```ts\nif (error instanceof ClockworkError) {\n console.error(error.code, error.details);\n}\n```\n",
6
+ "usage": "---\ntitle: Clockwork — Usage Guide\ndescription: Build deterministic state machines with pure transitions and actor-owned runtime work.\n---\n\n[[toc]]\n\n## Basic Usage\n\nCall `defineMachine<Context, Event>()` first to bind context and event types; the returned definition function infers state labels from `states`. Context is optional only when its type has no keys. Create one actor for each independently owned workflow.\n\n```ts\nimport { defineMachine } from '@vielzeug/clockwork';\n\ntype Event = { type: 'TOGGLE' };\n\nconst machine = defineMachine<Record<string, never>, Event>()({\n initial: 'on',\n states: {\n off: { on: { TOGGLE: { target: 'on' } } },\n on: { on: { TOGGLE: { target: 'off' } } },\n },\n});\n\nconst actor = machine.createActor();\nactor.send({ type: 'TOGGLE' });\nconsole.log(actor.snapshot.state); // 'off'\nactor.dispose();\n```\n\nDispose actors when a feature, request, or test ends. You can use `using` when the surrounding runtime supports `Symbol.dispose`.\n\n```ts\nusing actor = machine.createActor();\nactor.send({ type: 'TOGGLE' });\n```\n\n## Context reducers\n\nA reducer receives readonly context and returns the next context. Clockwork shallow-clones and freezes each snapshot and context record; nested values are not deep-cloned, so make explicit nested replacements.\n\n```ts\ntype Event = { type: 'DEC' } | { type: 'INC' } | { type: 'RESET' };\n\nconst counter = defineMachine<{ count: number }, Event>()({\n context: { count: 0 },\n initial: 'idle',\n states: {\n idle: {\n on: {\n DEC: { reduce: ({ context }) => ({ count: context.count - 1 }), target: 'idle' },\n INC: { reduce: ({ context }) => ({ count: context.count + 1 }), target: 'idle' },\n RESET: { reduce: () => ({ count: 0 }), target: 'idle' },\n },\n },\n },\n});\n```\n\nKeep reducers pure. Make nested copies yourself when nested data changes.\n\n```ts\nSAVE: {\n reduce: ({ context, event }) => ({\n ...context,\n profile: { ...context.profile, name: event.name },\n }),\n target: 'editing',\n}\n```\n\n## Guards\n\nGuards decide whether a transition can run. They receive readonly context and the matching event. For several choices, use an ordered array; the first passing guard wins.\n\n```ts\nPAY: [\n {\n guard: ({ context }) => context.balance >= context.total,\n reduce: ({ context }) => ({ ...context, balance: context.balance - context.total }),\n target: 'success',\n },\n { target: 'insufficientFunds' },\n]\n```\n\nCall `actor.can(event)` for the current actor snapshot or `machine.can(snapshot, event)` for an arbitrary snapshot.\n\n## Pure transitions\n\n`machine.transition()` enables isolated unit tests and decision UIs. It returns the unchanged snapshot with `type: 'ignored'` when no transition matches; it does not expose or run effects.\n\n```ts\nconst result = counter.transition(\n { context: { count: 3 }, state: 'idle' },\n { type: 'INC' },\n);\n\nif (result.type === 'transition') {\n console.log(result.snapshot.context.count); // 4\n}\n```\n\n## Effects\n\nEntry, exit, and transition effects run only through an actor. The actor commits, establishes target-state timers and invokes, notifies a stable subscriber snapshot, then runs exit, transition, and entry effects. Subscriber failures are reported but cannot skip declared effects. Effects cannot change context; send a regular event for another state change.\n\n```ts\ntype WorkflowEvent = { type: 'SUBMIT' };\nconst workflow = defineMachine<{ orderId: string }, WorkflowEvent>()({\n context: { orderId: '' },\n initial: 'draft',\n states: {\n draft: {\n on: {\n SUBMIT: {\n effects: [({ context }) => console.debug('submitted', context)],\n target: 'submitted',\n },\n },\n },\n submitted: { entry: [({ context }) => console.log(`Submitted ${context.orderId}`)] },\n },\n});\n```\n\nEffects receive `context`, the triggering `event` (or `undefined` for initial entry), actor `send`, and the actor lifetime `signal`.\n\n## Async invokes\n\nInvokes start on state entry. `src` gets readonly entry context, the triggering event or `undefined`, and an `AbortSignal`. `onDone` or `onError` map settlement to ordinary events. All invokes are cancelled when the actor exits the state or disposes.\n\n```ts\ntype LoadEvent =\n | { type: 'FETCH' }\n | { items: string[]; type: 'SUCCESS' }\n | { message: string; type: 'FAILURE' }\n | { type: 'RETRY' };\n\nconst loader = defineMachine<{ error: string; items: string[] }, LoadEvent>()({\n context: { error: '', items: [] },\n initial: 'idle',\n states: {\n idle: { on: { FETCH: { target: 'loading' } } },\n loading: {\n invoke: [{\n src: async ({ signal }) => {\n const response = await fetch('/api/items', { signal });\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n return response.json() as Promise<string[]>;\n },\n onDone: ({ result }) => ({ items: result, type: 'SUCCESS' }),\n onError: ({ error }) => ({ message: String(error), type: 'FAILURE' }),\n }],\n on: {\n FAILURE: { reduce: ({ event }) => ({ error: event.message, items: [] }), target: 'error' },\n SUCCESS: { reduce: ({ event }) => ({ error: '', items: event.items }), target: 'ready' },\n },\n },\n ready: {},\n error: { on: { RETRY: { target: 'loading' } } },\n },\n});\n```\n\n## Delayed transitions\n\n`after` starts timers on state entry and cancels them on exit or disposal. Delay must be finite and between 0 and 2,147,483,647 milliseconds. Guards and reducers receive `event: undefined`; a user event with `type: '$after'` remains a normal user event.\n\n```ts\ntype NotificationEvent = { type: 'DISMISS' } | { message: string; type: 'SHOW' };\nconst notification = defineMachine<{ message: string }, NotificationEvent>()({\n context: { message: '' },\n initial: 'hidden',\n states: {\n hidden: { on: { SHOW: { reduce: ({ event }) => ({ message: event.message }), target: 'visible' } } },\n visible: {\n after: [{ delay: 5_000, target: 'hidden' }],\n on: { DISMISS: { target: 'hidden' } },\n },\n },\n});\n```\n\n## Snapshot observation and persistence\n\n`actor.snapshot` is the current shallow-frozen `MachineSnapshot`; read it directly rather than calling a snapshot method. Use `subscribe()` to integrate a state library or persist future committed snapshots. Fresh actors run their initial entry effects and resources; restored actors start only the restored state's invokes and timers, not its entry effects.\n\n```ts\nconst stored = sessionStorage.getItem('wizard');\nconst actor = machine.createActor({\n snapshot: stored ? JSON.parse(stored) : undefined,\n});\n\nconst stopSaving = actor.subscribe((snapshot) => {\n sessionStorage.setItem('wizard', JSON.stringify(snapshot));\n});\n\nconsole.log(actor.snapshot);\nstopSaving();\nactor.dispose();\n```\n\nValidate untrusted persisted data before passing it to `createActor()`. Clockwork validates the restored state name but cannot validate application-specific context fields.\n\n## Error handling\n\nGuard, reducer, effect, invoke, timer, and transition-limit failures dispose the actor. Subscriber failures are reported but do not dispose the actor or interrupt remaining subscribers and declared effects.\n\nUse `onError` to observe either class without controlling disposition. The callback receives the error and its `phase` and `state`; callback failures are swallowed so observation cannot alter actor behavior.\n\n```ts\nconst actor = machine.createActor({\n onError(error, { event, phase, state }) {\n console.error({ error, event, phase, state });\n },\n});\n```\n\nFor fatal machine failures, the observer runs before disposal. Without `onError`, fatal failures dispose silently.\n\n## Debugging\n\nUse `actor.subscribe()` to observe committed snapshots during development. It observes snapshots only; it does not trace dispatched events or runtime errors.\n\n```ts\nconst actor = machine.createActor();\nconst stop = actor.subscribe((snapshot) => console.debug(snapshot));\nactor.send({ type: 'NEXT' });\nstop();\nactor.dispose();\n```\n\nFor richer inspection, route snapshots to application devtools. Clockwork intentionally has no internal trace buffer.\n\n## Flat state maps\n\nClockwork has flat state IDs. Prefer explicit states such as `editingDraft` and `editingSaving`, or compose several actors when domains have independent lifecycles.\n\n## SSR\n\nReuse a compiled machine definition, but create and dispose an actor per request. Never share an actor across concurrent requests.\n\n## Testing\n\nTest deterministic state behavior through `machine.transition()`. Create actors only for timers, invokes, effects, queueing, subscriptions, or disposal behavior.\n\n```ts\nimport { expect, test } from 'vitest';\n\ntest('increments without an actor', () => {\n const result = counter.transition(\n { context: { count: 2 }, state: 'idle' },\n { type: 'INC' },\n );\n\n expect(result).toMatchObject({\n snapshot: { context: { count: 3 }, state: 'idle' },\n type: 'transition',\n });\n});\n```\n\n## Framework Integration\n\nBridge the current actor snapshot into renderer state through one subscription. Dispose that subscription with component lifecycle.\n\n::: code-group\n\n```ts [React]\nimport { useSyncExternalStore } from 'react';\n\nfunction useActor<Value>(actor: { readonly snapshot: Value; subscribe(listener: (snapshot: Value) => void): () => void }) {\n return useSyncExternalStore(\n (notify) => actor.subscribe(() => notify()),\n () => actor.snapshot,\n () => actor.snapshot,\n );\n}\n```\n\n```ts [Vue 3]\nimport { onUnmounted, shallowRef } from 'vue';\n\nconst snapshot = shallowRef(actor.snapshot);\nconst stop = actor.subscribe((next) => (snapshot.value = next));\nonUnmounted(stop);\n```\n\n```ts [Svelte]\nimport { onDestroy } from 'svelte';\n\nlet snapshot = actor.snapshot;\nconst stop = actor.subscribe((next) => (snapshot = next));\nonDestroy(stop);\n```\n\n:::\n\n## Working with Other Vielzeug Libraries\n\nUse Herald when separate actors exchange application events. Bridge Clockwork snapshots into Ripple only at a UI or application boundary.\n\n```ts\nimport { createBus } from '@vielzeug/herald';\n\nconst bus = createBus<{ REFRESH: void }>();\nbus.on('REFRESH', () => actor.send({ type: 'FETCH' }));\n```\n\n## Best Practices\n\n- Define context and event unions with `defineMachine<Context, Event>()`.\n- Return replacement context from reducers; do not rely on runtime copying or freezing.\n- Keep guards and reducers pure.\n- Use actors for effects, timers, invokes, subscriptions, and cancellation.\n- Read the current snapshot from `actor.snapshot`, not a wrapper value.\n- Validate persisted context before restoring a snapshot.\n- Dispose every actor at its ownership boundary.\n- Route runtime failures through the `onError` observer for logging and diagnostics.\n",
7
+ "examples": "---\ntitle: Clockwork — Examples\ndescription: Practical state machine patterns with pure transitions and actors.\n---\n\n- [Counter with Reset](./examples/counter-with-reset.md)\n- [Form Validation](./examples/form-validation.md)\n- [Auto-Dismiss Notification](./examples/auto-dismiss-notification.md)\n- [Model Nested Workflows with Flat States](./examples/hierarchical-states.md)\n- [Pure Transition Testing](./examples/unit-testing.md)\n- [Auth Flow with Guards](./examples/auth-flow.md)\n- [Data Fetching with Error Recovery](./examples/data-fetching.md)\n- [Fetch with Retry](./examples/fetch-retry.md)\n- [Paginated Data Loading](./examples/paginated-data-loading.md)\n- [Media Player](./examples/media-player.md)\n- [Persisted Wizard](./examples/persisted-wizard.md)\n- [Multi-Step Wizard with Routing](./examples/wizard-with-routing.md)\n- [Shopping Cart Checkout](./examples/checkout.md)\n- [Permission-Based Access Control](./examples/permission-based-access.md)\n- [Event Boundaries](./examples/middleware-pipeline.md)\n- [Multi-Machine Coordination](./examples/multi-machine-coordination.md)\n- [Debugging Transitions](./examples/debugging-transitions.md)\n"
8
+ },
9
+ "examples": [
10
+ {
11
+ "id": "after-transitions",
12
+ "code": "import { defineMachine } from '@vielzeug/clockwork'\n\n// Timers begin on entry and cancel automatically on exit or disposal.\nconst machine = defineMachine()({\n context: { message: '' },\n initial: 'hidden',\n states: {\n hidden: {\n on: {\n SHOW: {\n reduce: ({ event }) => ({ message: event.message }),\n target: 'visible',\n },\n },\n },\n visible: {\n after: [{ delay: 500, target: 'hidden' }],\n on: { DISMISS: { target: 'hidden' } },\n },\n },\n})\n\nconst actor = machine.createActor()\nactor.send({ type: 'SHOW', message: 'Saved' })\nconsole.log('Visible:', actor.snapshot)\nsetTimeout(() => console.log('After timer:', actor.snapshot), 700)",
13
+ "name": "Delayed Transitions"
14
+ },
15
+ {
16
+ "id": "async-invokes",
17
+ "code": "import { defineMachine } from '@vielzeug/clockwork'\n\n// Invokes get an AbortSignal and send regular events when settled.\nconst machine = defineMachine()({\n context: { error: '', user: null },\n initial: 'idle',\n states: {\n idle: { on: { FETCH: { target: 'loading' } } },\n loading: {\n invoke: [{\n src: async ({ signal }) => {\n await new Promise((resolve, reject) => {\n const timer = setTimeout(resolve, 250)\n signal.addEventListener('abort', () => { clearTimeout(timer); reject(new Error('aborted')) })\n })\n return { name: 'Alice' }\n },\n onDone: ({ result }) => ({ type: 'DONE', user: result }),\n onError: ({ error }) => ({ type: 'FAILED', message: String(error) }),\n }],\n on: {\n DONE: { reduce: ({ event }) => ({ error: '', user: event.user }), target: 'ready' },\n FAILED: { reduce: ({ event }) => ({ error: event.message, user: null }), target: 'error' },\n },\n },\n ready: {},\n error: {},\n },\n})\n\nconst actor = machine.createActor()\nactor.send({ type: 'FETCH' })\nconsole.log('Loading:', actor.snapshot)\nsetTimeout(() => console.log('Resolved:', actor.snapshot), 400)",
18
+ "name": "Async Invokes"
19
+ },
20
+ {
21
+ "id": "basic-machine",
22
+ "code": "import { defineMachine } from '@vielzeug/clockwork'\n\n// Compile one machine, then create an independent actor.\nconst machine = defineMachine()({\n context: { cycles: 0 },\n initial: 'red',\n states: {\n red: { on: { NEXT: { target: 'green' } } },\n green: { on: { NEXT: { target: 'yellow' } } },\n yellow: {\n on: {\n NEXT: {\n reduce: ({ context }) => ({ cycles: context.cycles + 1 }),\n target: 'red',\n },\n },\n },\n },\n})\n\nconst actor = machine.createActor()\nconsole.log('Initial:', actor.snapshot)\nactor.send({ type: 'NEXT' })\nactor.send({ type: 'NEXT' })\nactor.send({ type: 'NEXT' })\nconsole.log('After cycle:', actor.snapshot)\nconsole.log('Can continue?', actor.can({ type: 'NEXT' }))",
23
+ "name": "Basic State Machine"
24
+ },
25
+ {
26
+ "id": "entry-exit-actions",
27
+ "code": "import { defineMachine } from '@vielzeug/clockwork'\n\nconst log = (message) => console.log(message)\n\n// Effects run after the actor commits and notifies subscribers.\nconst machine = defineMachine()({\n context: { reconnects: 0 },\n initial: 'disconnected',\n states: {\n disconnected: {\n entry: [() => log('[disconnected] socket closed')],\n on: { CONNECT: { target: 'connected' } },\n },\n connected: {\n entry: [({ context }) => log('[connected] reconnects: ' + context.reconnects)],\n exit: [() => log('[connected] socket closing')],\n on: {\n DISCONNECT: { target: 'disconnected' },\n ERROR: {\n reduce: ({ context }) => ({ reconnects: context.reconnects + 1 }),\n target: 'disconnected',\n },\n },\n },\n },\n})\n\nconst actor = machine.createActor()\nactor.subscribe((snapshot) => console.log('Committed:', snapshot))\nactor.send({ type: 'CONNECT' })\nactor.send({ type: 'ERROR' })",
28
+ "name": "Post-commit Effects"
29
+ },
30
+ {
31
+ "id": "guards-and-reducers",
32
+ "code": "import { defineMachine } from '@vielzeug/clockwork'\n\nconst SECRET_KEY = 'vielzeug'\n\n// Guards select a transition. Reducers return replacement context.\nconst machine = defineMachine()({\n context: { accessAttempts: 0 },\n initial: 'locked',\n states: {\n locked: {\n on: {\n UNLOCK: [\n {\n guard: ({ event }) => event.key === SECRET_KEY,\n reduce: () => ({ accessAttempts: 0 }),\n target: 'unlocked',\n },\n {\n reduce: ({ context }) => ({ accessAttempts: context.accessAttempts + 1 }),\n target: 'locked',\n },\n ],\n },\n },\n unlocked: { on: { LOCK: { target: 'locked' } } },\n },\n})\n\nconst actor = machine.createActor()\nactor.send({ type: 'UNLOCK', key: 'wrong' })\nconsole.log('Wrong key:', actor.snapshot)\nactor.send({ type: 'UNLOCK', key: SECRET_KEY })\nconsole.log('Correct key:', actor.snapshot)",
33
+ "name": "Guards & Reducers"
34
+ },
35
+ {
36
+ "id": "pure-transitions-and-errors",
37
+ "code": "import { ClockworkError, defineMachine } from '@vielzeug/clockwork'\n\nconst machine = defineMachine()({\n context: { role: 'guest' },\n initial: 'locked',\n states: {\n locked: {\n on: {\n UNLOCK: {\n guard: ({ context }) => context.role === 'admin',\n target: 'unlocked',\n },\n },\n },\n unlocked: { on: { LOCK: { target: 'locked' } } },\n },\n})\n\n// Pure transition: no actor, effects, or mutation.\nconst result = machine.transition(\n { context: { role: 'guest' }, state: 'locked' },\n { type: 'UNLOCK' },\n)\nconsole.log('Guest result:', result.type)\n\nfor (const definition of [\n { initial: 'missing', states: { idle: {} } },\n { context: [], initial: 'idle', states: { idle: {} } },\n]) {\n try {\n defineMachine()(definition)\n } catch (error) {\n if (error instanceof ClockworkError) {\n console.log('Validation code:', error.code)\n console.log('Details:', error.details)\n }\n }\n}",
38
+ "name": "Pure Transitions & Errors"
39
+ }
40
+ ],
41
+ "typeSignatures": {
42
+ "ClockworkError": "export { ClockworkError, type ClockworkErrorCode } from './errors.js';",
43
+ "ClockworkErrorCode": "export { ClockworkError, type ClockworkErrorCode } from './errors.js';",
44
+ "defineMachine": "export { defineMachine } from './interpret.js';",
45
+ "Actor": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
46
+ "ActorErrorContext": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
47
+ "ActorOptions": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
48
+ "After": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
49
+ "Effect": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
50
+ "EffectArgs": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
51
+ "EventByType": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
52
+ "EventType": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
53
+ "Guard": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
54
+ "Invoke": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
55
+ "InvokeArgs": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
56
+ "Machine": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
57
+ "MachineConfig": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
58
+ "MachineEvent": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
59
+ "MachineSnapshot": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
60
+ "Reducer": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
61
+ "StateNode": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
62
+ "Transition": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
63
+ "TransitionInput": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
64
+ "TransitionResult": "export type {\n Actor,\n ActorErrorContext,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';"
65
+ }
66
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "apiSource": "/**\n * `@vielzeug/codex` — supported public contract.\n *\n * Exposes the generic catalog, snapshot loader, errors, and server hosts. Snapshot\n * parser internals live behind `@vielzeug/codex/advanced`; Refine catalog types and\n * tools live behind `@vielzeug/codex/refine`.\n */\nexport { StdioServerTransport } from '@modelcontextprotocol/server/stdio';\nexport { type Catalog, CatalogError, type SearchHit, SnapshotCatalog } from './catalog.js';\nexport { CodexError } from './errors.js';\nexport { type HttpHost, type HttpHostOptions, startHttpHost } from './http.js';\nexport { createMcpServer } from './server.js';\nexport { type LoadedSnapshot, loadSnapshot } from './snapshot.js';\nexport type {\n DocPage,\n Example,\n PackageContent,\n PackageMeta,\n SnapshotManifest,\n} from './types.js';\n",
3
+ "docs": {
4
+ "index": "---\ntitle: Codex\ndescription: Local MCP access to Vielzeug documentation and package metadata.\npackage: codex\ncategory: AI\nkeywords: [mcp, docs, ai]\nrelated: [refine]\nexports: [loadSnapshot, SnapshotCatalog, createMcpServer, startHttpHost, StdioServerTransport, CatalogError, CodexError]\nenvironments: [node]\n---\n\n<PackageHero package=\"codex\" />\n\n## Why Codex?\n\nCodex exposes current Vielzeug catalog data through MCP without scanning source at request time.\n\n## Installation\n\n```sh\npnpm add @vielzeug/codex\n```\n\n## Quick Start\n\n```sh\nnpx -y @vielzeug/codex\n```\n\n## Features\n\n- `loadSnapshot` validates chunked snapshot metadata.\n- `SnapshotCatalog` loads package content only when requested.\n- `createMcpServer` registers generic package tools; `/refine` adds component tools explicitly.\n- Root, `/advanced`, and `/refine` entry points publish TypeScript declarations.\n- `startHttpHost` enforces loopback binding plus localhost Host and Origin validation.\n\n## Documentation\n\n- [Usage](./usage.md)\n- [API](./api.md)\n- [Examples](./examples.md)\n- [Migration Guide](./migration.md)\n\n## See Also\n\n- [Refine](../refine/) provides component metadata bundled by Codex.\n",
5
+ "api": "---\ntitle: Codex API\ndescription: Snapshot, catalog, MCP server, and local HTTP host APIs.\n---\n\n[[toc]]\n\n## API Overview\n\n| Symbol | Purpose | Execution mode | Common gotcha |\n| --- | --- | --- | --- |\n| `loadSnapshot` | Read validated snapshot metadata | Sync | Content chunks load lazily |\n| `SnapshotCatalog` | Query package corpus | Sync | Construct from loaded snapshot |\n| `createMcpServer` | MCP adapter factory (generic tools) | Sync | Requires catalog and version |\n| `startHttpHost` | Loopback Streamable HTTP host | Async | HTTP remains local-only |\n| `registerRefineTools` | Opt-in Refine tool registration | Sync | Import from `@vielzeug/codex/refine` |\n| `parsePointer` / `parseManifest` / `parseCatalog` / `parseContent` / `parseSearch` | Pure snapshot parsers | Sync | Import from `@vielzeug/codex/advanced`; throw `CodexError` on malformed input |\n\n## Package Entry Points\n\n| Import | Purpose |\n| --- | --- |\n| `@vielzeug/codex` | `Catalog`, `SnapshotCatalog`, `loadSnapshot`, MCP server, and HTTP host |\n| `@vielzeug/codex/advanced` | Snapshot parser internals and raw snapshot types |\n| `@vielzeug/codex/refine` | Opt-in Refine component tools (`registerRefineTools`) |\n\n## Snapshot\n\n### `loadSnapshot`\n\n```ts\nloadSnapshot(snapshotRoot?: string, options?: { validateContents?: boolean }): LoadedSnapshot;\n```\n\nLoads catalog/search metadata and Refine metadata. `snapshotRoot` defaults to bundled `data/`. Package content chunks stay lazy unless `validateContents: true`; `validateSnapshot()` from `/advanced` is the full-validation shortcut.\n\n### `SnapshotCatalog`\n\n```ts\nnew SnapshotCatalog(snapshot: LoadedSnapshot)\n```\n\nProvides generic package lookup, docs/source/example/signature access, and deterministic search. Use `SnapshotRefineCatalog` from `/refine` when component methods are needed.\n\n---\n\n### Snapshot parsers (`@vielzeug/codex/advanced`)\n\n```ts\nvalidateSnapshot(snapshotRoot?: string): void;\nloadSnapshotDirectory(directory: string, options?: { validateContents?: boolean }): LoadedSnapshot;\nparsePointer(value: unknown): SnapshotPointer;\nparseManifest(value: unknown): SnapshotManifest;\nparseCatalog(value: unknown): CatalogFile;\nparseContent(value: unknown, slug: string): PackageContent;\nparseSearch(value: unknown, catalog: CatalogFile): SearchRecord[];\nparseRefine(value: unknown): CemDeclaration[];\n```\n\nPure validation parsers used by `loadSnapshot`. Each throws `CodexError` on malformed input. `validateSnapshot` loads and validates every package content chunk — use during generation, integration tests, or explicit artifact verification.\n\n## MCP\n\n### `createMcpServer`\n\n```ts\ncreateMcpServer(catalog: Catalog, options: { version: string; debug?: boolean }): Server;\n```\n\nRegisters generic package tools over `Catalog`. Refine tools are opt-in through `/refine`. The root also re-exports `StdioServerTransport` for connecting the server without a second package import.\n\n## Refine tools (`@vielzeug/codex/refine`)\n\n### `SnapshotRefineCatalog`\n\n```ts\nnew SnapshotRefineCatalog(snapshot: LoadedSnapshot)\n```\n\nExtends `SnapshotCatalog` with `getComponent()` and `listComponents()`.\n\n### `registerRefineTools`\n\n```ts\nregisterRefineTools(server: Server, catalog: RefineCatalog, debug?: boolean): void;\n```\n\nUpgrades a server created by `createMcpServer()` with the combined generic and `refine-*` tool set. `refineTools` is exported as a readonly registry.\n\n## HTTP\n\n### `startHttpHost`\n\n```ts\nstartHttpHost(options: HttpHostOptions): Promise<HttpHost>;\n```\n\nStarts Streamable HTTP on `127.0.0.1` by default. Runtime validation accepts only `127.0.0.1` or `::1`; every request must also pass localhost Host and Origin checks. `configureServer` runs once for each lazily created MCP request server and is not called during host startup.\n\n## Types\n\n```ts\ninterface SnapshotPointer {\n directory: string;\n}\n\ninterface SnapshotManifest {\n catalog: 'catalog.json';\n contentDirectory: 'packages';\n refine: 'refine.json' | null;\n schemaVersion: typeof SNAPSHOT_SCHEMA_VERSION;\n search: 'search.json';\n version: string;\n}\n```\n\nDev snapshots use `SnapshotPointer` (via `current.json`); published snapshots are static directories.\n\n```ts\ninterface LoadedSnapshot {\n catalog: CatalogFile;\n contentDirectory: string;\n manifest: SnapshotManifest;\n refineComponents: CemDeclaration[];\n search: SearchRecord[];\n}\n```\n\n```ts\ninterface CatalogFile {\n packages: PackageMeta[];\n version: string;\n}\n\ninterface SearchRecord {\n category: string;\n description: string;\n docs: Partial<Record<DocPage, string>>;\n examples: Array<{ id: string; text: string }>;\n exports: string;\n keywords: string;\n name: string;\n related: string;\n slug: string;\n source: string | null;\n}\n\ninterface PackageMeta {\n availableDocPages: DocPage[];\n category: string;\n description: string;\n exampleIds: string[];\n exports: string[];\n hasSource: boolean;\n keywords: string[];\n name: string;\n related: string[];\n slug: string;\n version: string;\n}\n\ninterface PackageContent {\n apiSource: string | null;\n docs: Partial<Record<DocPage, string>>;\n examples: Example[];\n typeSignatures: Record<string, string>;\n}\n\ninterface Example {\n code: string;\n id: string;\n name: string;\n}\n```\n\n```ts\ninterface Catalog {\n getContent(slug: string): PackageContent;\n getDocs(slug: string, page: DocPage): string;\n getExample(slug: string, exampleId: string): Example;\n getPackage(slug: string): PackageMeta;\n getSource(slug: string): string;\n getTypeSignature(slug: string, symbol: string): string;\n listExamples(slug: string): Array<Pick<Example, 'id' | 'name'>>;\n listPackages(): PackageMeta[];\n search(query: string): SearchHit[];\n}\n\ninterface RefineCatalog extends Catalog {\n getComponent(tagName: string): CemDeclaration;\n listComponents(): CemDeclaration[];\n}\n\ninterface SearchHit {\n matchedExamples?: string[];\n matchedIn: Array<'docs' | 'examples' | 'exports' | 'keywords' | 'metadata' | 'related' | 'source'>;\n matchedPages?: DocPage[];\n name: string;\n slug: string;\n}\n```\n\n```ts\ninterface HttpHost {\n readonly disposalSignal: AbortSignal;\n dispose(): Promise<void>;\n readonly disposed: boolean;\n readonly host: string;\n readonly port: number;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\ninterface HttpHostOptions {\n catalog: Catalog;\n configureServer?: (server: Server) => void;\n debug?: boolean;\n host?: '127.0.0.1' | '::1';\n port: number;\n version: string;\n}\n```\n\n```ts\nconst DOC_PAGES = ['index', 'api', 'usage', 'examples'] as const;\ntype DocPage = (typeof DOC_PAGES)[number];\n\nconst SNAPSHOT_SCHEMA_VERSION = 1 as const;\n```\n\n`DOC_PAGES`, `SNAPSHOT_SCHEMA_VERSION`, and raw snapshot types are exported from `/advanced`. CEM types and `RefineCatalog` are exported from `/refine`.\n\n```ts\ninterface CemDeclaration {\n attributes?: CemAttribute[];\n cssParts?: CemCssPart[];\n cssProperties?: CemCssProperty[];\n description?: string;\n events?: CemEvent[];\n members?: CemMember[];\n name?: string;\n slots?: CemSlot[];\n superclass?: { name: string; package?: string };\n tagName?: string;\n [key: string]: unknown;\n}\n\ninterface CemAttribute {\n default?: string;\n description?: string;\n fieldName?: string;\n name: string;\n type?: { text: string };\n}\n\ninterface CemCssPart {\n description?: string;\n name: string;\n}\n\ninterface CemCssProperty {\n default?: string;\n description?: string;\n name: string;\n}\n\ninterface CemEvent {\n description?: string;\n name: string;\n type?: { text: string };\n}\n\ninterface CemMember {\n description?: string;\n kind?: 'field' | 'method';\n name: string;\n type?: { text: string };\n}\n\ninterface CemSlot {\n description?: string;\n name: string;\n}\n```\n\n## Errors\n\n`CodexError` signals malformed snapshots or host failures. `CatalogError` adds `INVALID_ARG`, `NOT_FOUND`, or `UNAVAILABLE` for expected tool failures.\n",
6
+ "usage": "---\ntitle: Codex — Usage Guide\ndescription: Install, connect, develop, and debug the Vielzeug MCP server.\n---\n\n[[toc]]\n\n## Basic Usage\n\nRun local stdio server:\n\n```sh\nnpx -y @vielzeug/codex\n```\n\nUse shipped `mcp-setup.json` for machine-readable generic configuration. Client-specific configuration must use its documented MCP format.\n\n## HTTP Mode\n\nHTTP uses Streamable HTTP and binds loopback only:\n\n```sh\nnpx -y @vielzeug/codex --port=3100\ncurl http://127.0.0.1:3100/health\n```\n\nResponse includes snapshot version. Runtime bind validation and Host/Origin allowlists restrict access to localhost; no remote host mode exists. Programmatic `configureServer` hooks run once per MCP request server, not at host startup. Dispose the host asynchronously and observe `disposed` or `disposalSignal` when coordinating shutdown.\n\n## Agent Skill\n\nCodex ships a `vielzeug` agent skill — a `SKILL.md` that tells an AI agent working in *your* project to discover packages through the MCP tools instead of guessing, to use the owning `@vielzeug/*` package instead of hand-rolling, and to build UI from Refine components, tokens, and theme whenever `@vielzeug/refine` is installed. Install it into the project:\n\n```sh\nnpx -y @vielzeug/codex skills install\nnpx -y @vielzeug/codex skills install --target=.claude/skills\nnpx -y @vielzeug/codex skills install --force # overwrite an existing copy\n```\n\nWithout `--target`, the first existing directory among `.agents/skills`, `.github/skills`, and `.claude/skills` is used; when none exists, `.agents/skills` is created. The command refuses to overwrite an installed skill unless `--force` is passed. Rerun after upgrading codex to pick up the current package list, which is generated from the published manifests. The skill pairs with the MCP server: its lookups (`get-docs`, `refine-get-component`, `refine-validate-usage`, …) assume codex is connected, and it documents `node_modules` fallbacks for when it is not.\n\n## Local Development\n\nRequires Node 22+ and root setup:\n\n```sh\npnpm setup\ncd packages/codex\npnpm test:unit\npnpm test:integration\npnpm dev\n```\n\n`test:unit` uses fixtures only. `test:integration` regenerates a current snapshot then checks real monorepo inputs.\n\n`pnpm dev` watches documentation and package inputs, atomically publishes snapshots, then restarts server when snapshot changes.\n\n## Debugging\n\n```sh\npnpm dev\nnode src/cli.ts --port=3100 --debug\ncurl http://127.0.0.1:3100/health\n```\n\n`--debug` logs tool durations and expected catalog errors to stderr. Build `@vielzeug/refine` before generating snapshot when component metadata changes.\n\n## Programmatic Usage\n\n```ts\nimport { SnapshotCatalog, StdioServerTransport, createMcpServer, loadSnapshot } from '@vielzeug/codex';\n\nconst snapshot = loadSnapshot();\nconst catalog = new SnapshotCatalog(snapshot);\nawait createMcpServer(catalog, { version: snapshot.manifest.version }).connect(new StdioServerTransport());\n```\n\nTo include Refine component tools, upgrade the server with the `@vielzeug/codex/refine` subpath:\n\n```ts\nimport { StdioServerTransport, createMcpServer, loadSnapshot } from '@vielzeug/codex';\nimport { SnapshotRefineCatalog, registerRefineTools } from '@vielzeug/codex/refine';\n\nconst snapshot = loadSnapshot();\nconst catalog = new SnapshotRefineCatalog(snapshot);\nconst server = createMcpServer(catalog, { version: snapshot.manifest.version });\nregisterRefineTools(server, catalog);\nawait server.connect(new StdioServerTransport());\n```\n\n## Best Practices\n\n- Use `search-packages` for capability discovery before loading broad source.\n- Use `get-type-signature` before loading full source.\n- Published package snapshots are static directories; local dev snapshots are immutable generations selected by `.dev/current.json`.\n- Import `validateSnapshot()` from `/advanced` for artifact verification; normal startup keeps package chunks lazy.\n- Treat `configureServer` as a per-request factory hook and avoid process-global side effects.\n- Keep HTTP local. Use stdio for normal client integration.\n- Run `pnpm test:unit` before `pnpm test:integration`.\n",
7
+ "examples": "---\ntitle: Codex — Examples\ndescription: Practical MCP tool-call examples for package discovery, docs lookup, and Refine component queries.\n---\n\n## Examples\n\n- [Listing Packages](./examples/listing-packages.md)\n- [Searching Packages](./examples/searching-packages.md)\n- [Package Metadata](./examples/package-metadata.md)\n- [Reading Docs](./examples/reading-docs.md)\n- [Running REPL Examples](./examples/running-repl-examples.md)\n- [Looking Up Components](./examples/looking-up-components.md)\n- [Inspector](./examples/inspector.md)\n"
8
+ },
9
+ "examples": [],
10
+ "typeSignatures": {
11
+ "StdioServerTransport": "export { StdioServerTransport } from '@modelcontextprotocol/server/stdio';",
12
+ "Catalog": "export { type Catalog, CatalogError, type SearchHit, SnapshotCatalog } from './catalog.js';",
13
+ "CatalogError": "export { type Catalog, CatalogError, type SearchHit, SnapshotCatalog } from './catalog.js';",
14
+ "SearchHit": "export { type Catalog, CatalogError, type SearchHit, SnapshotCatalog } from './catalog.js';",
15
+ "SnapshotCatalog": "export { type Catalog, CatalogError, type SearchHit, SnapshotCatalog } from './catalog.js';",
16
+ "CodexError": "export { CodexError } from './errors.js';",
17
+ "HttpHost": "export { type HttpHost, type HttpHostOptions, startHttpHost } from './http.js';",
18
+ "HttpHostOptions": "export { type HttpHost, type HttpHostOptions, startHttpHost } from './http.js';",
19
+ "startHttpHost": "export { type HttpHost, type HttpHostOptions, startHttpHost } from './http.js';",
20
+ "createMcpServer": "export { createMcpServer } from './server.js';",
21
+ "LoadedSnapshot": "export { type LoadedSnapshot, loadSnapshot } from './snapshot.js';",
22
+ "loadSnapshot": "export { type LoadedSnapshot, loadSnapshot } from './snapshot.js';",
23
+ "DocPage": "export type {\n DocPage,\n Example,\n PackageContent,\n PackageMeta,\n SnapshotManifest,\n} from './types.js';",
24
+ "Example": "export type {\n DocPage,\n Example,\n PackageContent,\n PackageMeta,\n SnapshotManifest,\n} from './types.js';",
25
+ "PackageContent": "export type {\n DocPage,\n Example,\n PackageContent,\n PackageMeta,\n SnapshotManifest,\n} from './types.js';",
26
+ "PackageMeta": "export type {\n DocPage,\n Example,\n PackageContent,\n PackageMeta,\n SnapshotManifest,\n} from './types.js';",
27
+ "SnapshotManifest": "export type {\n DocPage,\n Example,\n PackageContent,\n PackageMeta,\n SnapshotManifest,\n} from './types.js';"
28
+ }
29
+ }
@@ -0,0 +1,101 @@
1
+ {
2
+ "apiSource": "export { allocate, sum } from './aggregate';\nexport { BHD, currency, EUR, GBP, isCurrency, JPY, KRW, KWD, USD } from './currency';\nexport type { CoinsErrorCode } from './errors';\nexport { CoinsError, CurrencyMismatchError, InvalidCurrencyError } from './errors';\nexport { exchange, exchangeRate, isExchangeRate } from './exchange';\nexport { format, formatParts } from './format';\nexport {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';\nexport { toJSON } from './serialization';\nexport type {\n Currency,\n CurrencyCode,\n Decimal,\n ExchangeRate,\n FormatOptions,\n Money,\n MoneyFormatPart,\n MoneyJSON,\n RoundingMode,\n} from './types';\n",
3
+ "docs": {
4
+ "index": "---\ntitle: Coins — Exact Money for TypeScript\ndescription: Exact bigint monetary arithmetic with explicit currency definitions, decimal strings, allocation, exchange, formatting, and JSON boundaries.\npackage: coins\ncategory: finance\nkeywords: [money, currency, bigint, decimal, exchange, formatting]\nexports: [USD, EUR, GBP, JPY, KRW, BHD, KWD, money, decodeMoney, isMoney, currency, isCurrency, add, subtract, multiply, divide, compare, clamp, abs, negate, round, toDecimal, sum, allocate, exchangeRate, isExchangeRate, exchange, format, formatParts, toJSON]\nrelated: [vault, courier, spell]\nenvironments: [browser, node, ssr, deno]\n---\n\n<!-- markdownlint-disable MD025 MD033 MD060 -->\n\n<PackageHero package=\"coins\" />\n\n## Why Coins?\n\nCoins keeps monetary values in bigint minor units, but makes units explicit at construction. Currency scale comes from deterministic definitions; `Intl` formats a known value without deciding its arithmetic representation.\n\n```ts\n// Before\nconst total = (19.99 + 7.25) * 1.08;\n\n// After\nimport { USD, add, money, multiply } from '@vielzeug/coins';\n\nconst total = multiply(add(money('19.99', USD), money('7.25', USD)), '1.08');\n```\n\n| Feature | Coins | decimal.js | Dinero.js |\n| --- | --- | --- | --- |\n| Bundle size | <PackageInfo package=\"coins\" type=\"size\" /> | External dependency | External dependency |\n| Bigint minor units | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"check\" size=\"16\"></ore-icon> |\n| Explicit currency scale | <ore-icon name=\"check\" size=\"16\"></ore-icon> | App-defined | Partial |\n| Exact allocation | <ore-icon name=\"check\" size=\"16\"></ore-icon> | Manual | <ore-icon name=\"check\" size=\"16\"></ore-icon> |\n| Zero dependencies | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n\n<div class=\"decision-callout\">\n\n**Use Coins when** application values represent real money and every rounding boundary must be visible.\n\n**Consider native numbers when** values are estimates, analytics, or display-only approximations.\n\n</div>\n\n## Installation\n\n::: code-group\n\n```sh [pnpm]\npnpm add @vielzeug/coins\n```\n\n```sh [npm]\nnpm install @vielzeug/coins\n```\n\n```sh [yarn]\nyarn add @vielzeug/coins\n```\n\n:::\n\n## Quick Start\n\n```ts\nimport { USD, add, format, money, multiply } from '@vielzeug/coins';\n\nconst subtotal = add(money('12.50', USD), money('7.25', USD));\nconst total = multiply(subtotal, '1.08', { rounding: 'halfEven' });\n\nconsole.log(format(total));\n```\n\n## Features\n\n<div class=\"features-grid\">\n\n- **`money`**: one constructor for decimal and explicit minor-unit values\n- **`currency`**: resolve seven canonical built-ins, or create a local custom definition\n- **`add`**: exact same-currency arithmetic\n- **`allocate`**: split every minor unit without loss\n- **`exchange`**: typed source and target currency conversion\n- **`format`**: locale presentation for bigint values\n- **`decodeMoney`**: validate and re-canonicalize persisted, transported, or cross-realm values\n\n</div>\n\n## Documentation\n\n<div class=\"doc-links\">\n\n- [Usage Guide](./usage.md)\n- [API Reference](./api.md)\n- [Examples](./examples.md)\n- [Migration Guide](./migration.md)\n\n</div>\n\n## See Also\n\n<div class=\"see-also\">\n\n- [Vault](/vault/) — persist validated money JSON.\n- [Courier](/courier/) — retrieve exchange-rate data.\n- [Spell](/spell/) — validate external monetary payloads.\n\n</div>\n\n<!-- markdownlint-enable MD025 MD033 MD060 -->\n",
5
+ "api": "---\ntitle: Coins — API Reference\ndescription: Exact money, currency definitions, exchange, formatting, serialization, and errors.\n---\n\n[[toc]]\n\n## API Overview\n\n| Symbol | Purpose | Execution | Common gotcha |\n| --- | --- | --- | --- |\n| `money` | Construct validated money | Sync | Bigint requires `{ unit: 'minor' }` |\n| `currency` | Resolve built-in or construct custom | Sync | Unknown codes throw |\n| `add` / `subtract` | Combine matching currencies | Sync | Mismatches throw |\n| `multiply` / `divide` | Exact decimal scaling | Sync | Use decimal strings |\n| `sum` | Aggregate with inferred currency | Sync | Empty iterable requires `{ currency }` |\n| `allocate` | Split without losing minor units | Sync | Weights must be non-negative |\n| `clamp` | Bound to min/max range | Sync | Min must not exceed max |\n| `exchange` | Convert through an exact rate | Sync | Rate source must match value currency |\n| `format` | Present money with `Intl` | Sync | Formatting does not define currency scale |\n| `toJSON` / `decodeMoney` | Cross serialization or realm boundary | Sync | Persisted amount uses minor units |\n\n## Package Entry Point\n\n| Import | Purpose |\n| --- | --- |\n| `@vielzeug/coins` | Complete public Coins API |\n\n## Construction\n\n### `currency(code)` / `currency({ code, minorUnit })`\n\n```ts\nfunction currency<C extends string>(code: C): Currency<C>;\nfunction currency<C extends string>(definition: { code: C; minorUnit: number }): Currency<C>;\n```\n\nResolves one of the seven built-ins—`USD`, `EUR`, `GBP`, `JPY`, `KRW`, `BHD`, or `KWD`—or constructs an immutable custom currency. Custom currencies are local values with no global registry. Code must be exactly three uppercase letters; `minorUnit` must be an integer from 0 to 6. Arithmetic compares currency definitions by reference.\n\n```ts\ncurrency('USD');\ncurrency({ code: 'PTS', minorUnit: 0 });\n```\n\n### `isCurrency(value)`\n\n```ts\nfunction isCurrency(value: unknown): value is Currency;\n```\n\nType guard for canonical currency values (built-in or constructed via `currency()`).\n\n### `money(amount, currency, options?)`\n\n```ts\nfunction money<C extends Currency>(amount: string, currency: C, options?: { rounding?: RoundingMode }): Money<C>;\nfunction money<C extends Currency>(amount: bigint, currency: C, options: { unit: 'minor' }): Money<C>;\n```\n\n```ts\nmoney('19.99', USD);\nmoney(1999n, USD, { unit: 'minor' });\n```\n\nDecimal strings that exceed the currency's precision require a `rounding` mode. Inputs use plain base-10 syntax without exponent, leading plus, or whitespace; input length is capped at 1,000 characters and normalized fractional precision at 100 places. Bigint amounts require `{ unit: 'minor' }`.\n\n### `decodeMoney(value, options?)`\n\n```ts\nfunction decodeMoney(value: unknown, options?: { currency?: (code: string) => Currency }): Money;\n```\n\nValidates untrusted or cross-realm data and returns canonical money. Plain bigint input must have exactly `amount` and canonical `currency`; JSON must have exactly `amount`, currency code, and `unit: 'minor'`. Serialized amounts are bounded to 1,000 characters. A custom resolver must return a canonical currency whose code matches the envelope.\n\n### `isMoney(value)`\n\n```ts\nfunction isMoney(value: unknown): value is Money;\n```\n\nType guard for canonical Coins money values. Checks identity against the internal canonical set — forged frozen objects do not pass.\n\n## Arithmetic\n\n```ts\nfunction add<C extends Currency>(left: Money<C>, right: Money<NoInfer<C>>): Money<C>;\nfunction subtract<C extends Currency>(left: Money<C>, right: Money<NoInfer<C>>): Money<C>;\nfunction multiply<C extends Currency>(value: Money<C>, factor: string, options?: { rounding?: RoundingMode }): Money<C>;\nfunction divide<C extends Currency>(value: Money<C>, divisor: string, options?: { rounding?: RoundingMode }): Money<C>;\nfunction compare<C extends Currency>(left: Money<C>, right: Money<NoInfer<C>>): -1 | 0 | 1;\nfunction clamp<C extends Currency>(\n value: Money<C>,\n options: { max: Money<NoInfer<C>>; min: Money<NoInfer<C>> },\n): Money<C>;\nfunction abs<C extends Currency>(value: Money<C>): Money<C>;\nfunction negate<C extends Currency>(value: Money<C>): Money<C>;\nfunction round<C extends Currency>(\n value: Money<C>,\n options: { fractionDigits: number; rounding?: RoundingMode },\n): Money<C>;\nfunction toDecimal(value: Money): string;\n```\n\n`factor` and `divisor` are plain decimal strings; exponent notation, whitespace, and a leading plus are invalid. Matching currency identity is required for binary operations. `round()` requires integer `fractionDigits` from 0 through the currency's `minorUnit`. Scaling and rounding default to `halfAwayFromZero`.\n\n## Aggregation\n\n```ts\nfunction sum<C extends Currency>(values: readonly Money<C>[]): Money<C>;\nfunction sum<C extends Currency>(values: Iterable<Money<C>>, options: { currency: C }): Money<C>;\nfunction allocate<C extends Currency>(value: Money<C>, count: number): Money<C>[];\nfunction allocate<C extends Currency>(value: Money<C>, weights: readonly string[]): Money<C>[];\n```\n\n`sum()` infers currency from non-empty values. An empty iterable requires a canonical `{ currency }` and returns canonical zero. `allocate()` accepts a positive integer count or dense, non-empty, non-negative decimal-string weights with a positive total. Either form is limited to 100,000 output parts. It distributes remainders by largest fractional share, breaks ties by input order, and preserves the exact signed minor-unit total.\n\n## Exchange\n\n```ts\nfunction exchangeRate<From extends Currency, To extends Currency>({\n from,\n to,\n value,\n}: {\n from: From;\n to: To;\n value: string;\n}): ExchangeRate<From, To>;\n\nfunction exchange<From extends Currency, To extends Currency>(\n value: Money<From>,\n rate: ExchangeRate<From, To>,\n options?: { rounding?: RoundingMode },\n): Money<To>;\n```\n\n```ts\nconst rate = exchangeRate({ from: USD, to: EUR, value: '0.9234' });\nexchange(money('100.00', USD), rate);\n```\n\nRates are exact positive decimal strings. The money currency must be the same canonical instance as `rate.from`. Conversion defaults to `halfAwayFromZero` rounding.\n\n### `isExchangeRate(value)`\n\n```ts\nfunction isExchangeRate(value: unknown): value is ExchangeRate;\n```\n\nType guard for canonical exchange rates created by `exchangeRate()`. Checks identity against the internal canonical set — forged frozen objects do not pass.\n\n## Formatting\n\n```ts\nfunction format(value: Money, options?: FormatOptions): string;\nfunction formatParts(value: Money, options?: FormatOptions): MoneyFormatPart[];\n```\n\nDefaults are locale `en-US`, style `symbol`, and the currency's minor-unit digits. Either fraction bound may be supplied independently; the omitted bound adjusts to remain compatible. Explicit bounds must satisfy `0 ≤ minimum ≤ maximum ≤ 20`. Exact decimal strings and mapped rounding modes are passed to `Intl.NumberFormat`, preserving locale digits, currency-name pluralization, and rounded negative signs. `formatParts()` keeps locale grouping inside its `integer` part.\n\n## Serialization\n\n```ts\nfunction toJSON(value: Money): MoneyJSON;\nfunction decodeMoney(value: unknown, options?: { currency?: (code: string) => Currency }): Money;\n```\n\n`toJSON()` produces exactly `{ amount, currency, unit: 'minor' }`. `amount` is a canonical integer string of at most 1,000 characters: no decimal point, exponent, leading plus, leading zero, whitespace, or negative zero. `decodeMoney()` resolves built-ins with `currency()` by default; custom codes require a resolver returning the same encoded code.\n\n## Types\n\n```ts\ntype CurrencyCode<C extends string = string> = C & { readonly [currencyBrand]: C };\n\ntype Currency<C extends string = string> = Readonly<{\n code: CurrencyCode<C>;\n minorUnit: number;\n}>;\n\ntype Decimal = Readonly<{\n readonly [decimalBrand]: true;\n denominator: bigint;\n numerator: bigint;\n}>;\n\ntype Money<C extends Currency = Currency> = Readonly<{\n amount: bigint;\n currency: C;\n readonly [moneyBrand]: C;\n}>;\n\ntype ExchangeRate<From extends Currency = Currency, To extends Currency = Currency> = Readonly<{\n from: From;\n to: To;\n value: Decimal;\n}>;\n\ntype FormatOptions = Readonly<{\n locale?: string;\n maximumFractionDigits?: number;\n minimumFractionDigits?: number;\n rounding?: RoundingMode;\n style?: 'code' | 'name' | 'narrowSymbol' | 'symbol';\n}>;\n\ntype MoneyFormatPart = Readonly<{\n type: 'currency' | 'decimal' | 'fraction' | 'integer' | 'literal' | 'minusSign' | 'plusSign';\n value: string;\n}>;\n\ntype MoneyJSON = Readonly<{\n amount: string;\n currency: string;\n unit: 'minor';\n}>;\n\ntype RoundingMode = 'awayFromZero' | 'ceil' | 'floor' | 'halfAwayFromZero' | 'halfEven' | 'towardZero';\n```\n\n`CurrencyCode`, `Decimal`, and `Money` carry phantom brand symbols that prevent unbranded values from being assigned where canonical values are required. `ExchangeRate.value` exposes a normalized exact `Decimal` numerator and denominator.\n\n| Rounding mode | Behavior |\n| --- | --- |\n| `awayFromZero` | Always increase a non-exact magnitude |\n| `ceil` | Toward positive infinity |\n| `floor` | Toward negative infinity |\n| `halfAwayFromZero` | Nearest; midpoint away from zero |\n| `halfEven` | Nearest; midpoint to an even retained unit |\n| `towardZero` | Truncate toward zero |\n\n## Errors\n\n```ts\ntype CoinsErrorCode =\n | 'CURRENCY_MISMATCH'\n | 'DIVISION_BY_ZERO'\n | 'FORMAT_ERROR'\n | 'INVALID_ALLOCATION'\n | 'INVALID_CURRENCY'\n | 'INVALID_DECIMAL'\n | 'INVALID_EXCHANGE_RATE'\n | 'INVALID_MONEY'\n | 'INVALID_RANGE'\n | 'INVALID_ROUNDING';\n```\n\nEvery Coins failure extends `CoinsError` and exposes `code`.\n\n```ts\nclass CoinsError extends Error {\n readonly code: CoinsErrorCode;\n}\n\nclass CurrencyMismatchError extends CoinsError {\n readonly expected: string;\n readonly received: string;\n}\n\nclass InvalidCurrencyError extends CoinsError {\n readonly value: unknown;\n}\n```\n\n`CurrencyMismatchError` and `InvalidCurrencyError` are specialized `CoinsError` subclasses. Use `instanceof CoinsError` to narrow any value to the Coins error hierarchy.\n",
6
+ "usage": "---\ntitle: Coins — Usage Guide\ndescription: Construct exact money, aggregate values, convert currencies, and format results with Coins.\n---\n\n[[toc]]\n\n## Basic Usage\n\nConstruct decimal values with a currency definition. Coins stores minor units internally and never accepts implicit floating-point input.\n\n```ts\nimport { USD, add, money, toDecimal } from '@vielzeug/coins';\n\nconst subtotal = add(money('12.50', USD), money('7.25', USD));\n\nconsole.log(toDecimal(subtotal)); // '19.75'\n```\n\nUse bigint only when data is already in minor units:\n\n```ts\nimport { USD, money } from '@vielzeug/coins';\n\nconst cents = money(1999n, USD, { unit: 'minor' });\n```\n\n## Define Currencies\n\nCoins exports seven built-in definitions: `USD`, `EUR`, `GBP`, `JPY`, `KRW`, `BHD`, and `KWD`. Construct other ISO or business currencies explicitly. Custom definitions are local canonical values; share one instance because arithmetic compares currencies by reference.\n\n```ts\nimport { EUR, USD, currency, money } from '@vielzeug/coins';\n\nconst rewards = currency({ code: 'PTS', minorUnit: 0 });\n\nmoney('10.00', USD);\nmoney('10.00', EUR);\nmoney('500', rewards);\n```\n\n## Apply Exact Arithmetic\n\nPass plain decimal strings to scaling operations; exponent notation, signs such as `+1`, whitespace, and numeric inputs are rejected. `multiply()`, `divide()`, `exchange()`, `round()`, and visible formatting default to `halfAwayFromZero`; pass a named mode when accounting policy requires another rule.\n\n```ts\nimport { USD, divide, money, multiply, round, toDecimal } from '@vielzeug/coins';\n\nconst subtotal = money('19.99', USD);\nconst taxed = multiply(subtotal, '1.08', { rounding: 'halfEven' });\n\n// Extra currency precision must name its rounding policy.\nconst roundedInput = money('19.999', USD, { rounding: 'halfAwayFromZero' });\nconst split = divide(taxed, '3', { rounding: 'floor' });\nconst displayed = round(taxed, { fractionDigits: 0, rounding: 'halfAwayFromZero' });\n\nconsole.log(toDecimal(split), toDecimal(displayed));\n```\n\n## Aggregate and Allocate\n\n`sum()` infers currency from non-empty values. Pass a canonical `{ currency }` for possibly empty iterables. `allocate()` preserves every minor unit, distributes remainders by largest fractional share with stable index ties, and applies the same allocation symmetrically to negative values. Counts and dense weight arrays are limited to 100,000 shares.\n\n```ts\nimport { USD, allocate, money, sum, toDecimal } from '@vielzeug/coins';\n\nconst total = sum([money('10.00', USD), money('5.00', USD)]);\nconst zero = sum([], { currency: USD });\nconst weighted = allocate(money('10.00', USD), ['1', '2', '1']);\nconst even = allocate(money(5n, USD, { unit: 'minor' }), 2);\n\nconsole.log(toDecimal(total));\nconsole.log(weighted.map(toDecimal));\nconsole.log(even.map((value) => value.amount)); // [3n, 2n]\n```\n\n## Convert Currency\n\nCreate a typed rate from currency definitions and a strictly positive exact decimal string.\n\n```ts\nimport { EUR, USD, exchange, exchangeRate, format, money } from '@vielzeug/coins';\n\nconst usdToEur = exchangeRate({ from: USD, to: EUR, value: '0.9234' });\nconst euros = exchange(money('100.00', USD), usdToEur, { rounding: 'halfEven' });\n\nconsole.log(format(euros, { locale: 'de-DE' }));\n```\n\n## Format Money\n\nFormat only at presentation boundaries. Coins keeps bigint arithmetic exact and uses `Intl.NumberFormat` only to obtain locale and currency layout.\n\n```ts\nimport { EUR, format, formatParts, money } from '@vielzeug/coins';\n\nconst value = money('1234.56', EUR);\nconsole.log(format(value, { locale: 'de-DE', style: 'code' }));\nconsole.log(formatParts(value, { maximumFractionDigits: 1, rounding: 'halfEven' }));\n```\n\nEither fraction bound may be supplied independently; the omitted bound adjusts to remain compatible. Explicit values must satisfy `0 ≤ minimumFractionDigits ≤ maximumFractionDigits ≤ 20`. Formatting passes the exact decimal string and rounding mode to `Intl`, including locale digits, currency-name pluralization, and rounded negative signs. It never mutates money.\n\n## Serialize Money\n\nUse `toJSON()` and `decodeMoney()` at storage, transport, worker, and realm boundaries. Decoding validates the envelope and returns a new canonical `Money` value.\n\n```ts\nimport { USD, currency, decodeMoney, money, toJSON } from '@vielzeug/coins';\n\nconst encoded = toJSON(money('19.99', USD));\nconst restored = decodeMoney(encoded);\n\nconst TOK = currency({ code: 'TOK', minorUnit: 2 });\nconst customEncoded = toJSON(money('1.00', TOK));\nconst custom = decodeMoney(customEncoded, {\n currency: (code) => (code === 'TOK' ? TOK : currency(code)),\n});\n```\n\n`MoneyJSON.amount` is a canonical integer string of at most 1,000 characters in minor units: no decimal point, exponent, leading plus, leading zero, whitespace, or negative zero. Built-in codes resolve automatically; custom codes require a resolver.\n\n`decodeMoney()` also accepts exactly `{ amount: bigint, currency: Currency }` when the currency is canonical. Custom resolvers must return the same code encoded in JSON. Use `isMoney()` only to test values already created or decoded in the current realm.\n\n## Handle Errors\n\nUse `CoinsError.code` for stable recovery branches.\n\n```ts\nimport { CoinsError, USD, money } from '@vielzeug/coins';\n\ntry {\n money('19.999', USD);\n} catch (error) {\n if (error instanceof CoinsError && error.code === 'INVALID_MONEY') {\n console.log('Over-precise decimal requires a rounding mode.');\n }\n}\n```\n\n## Best Practices\n\n- Use decimal strings for exact external inputs.\n- Use bigint only with `{ unit: 'minor' }`.\n- Pass named rounding options for division, scaling, and exchange.\n- Export each custom currency from one module and reuse that canonical instance.\n- Use `sum(values)` for non-empty collections; `sum(values, { currency })` for possibly empty ones.\n- Serialize with `toJSON()` and validate or re-canonicalize with `decodeMoney()`.\n- Format only at presentation boundaries.\n",
7
+ "examples": "---\ntitle: Coins — Examples\ndescription: Practical examples and recipes for @vielzeug/coins.\n---\n\n## Examples\n\n- [Formatting](./examples/formatting.md)\n- [Exchange Rate Conversion](./examples/exchange.md)\n- [Allocation](./examples/allocation.md)\n- [Serialization](./examples/serialization.md)\n"
8
+ },
9
+ "examples": [
10
+ {
11
+ "id": "allocation-basic",
12
+ "code": "import { USD, allocate, money, sum, toDecimal } from '@vielzeug/coins'\n\nconst weighted = allocate(money('10.00', USD), ['1', '2', '1'])\nconst even = allocate(money(5n, USD, { unit: 'minor' }), 2)\n\nconsole.log(weighted.map(toDecimal))\nconsole.log(toDecimal(sum(weighted)))\nconsole.log(even.map(value => value.amount))",
13
+ "name": "allocate - Preserve every minor unit"
14
+ },
15
+ {
16
+ "id": "arithmetic-basic",
17
+ "code": "import { USD, add, divide, money, multiply, subtract, toDecimal } from '@vielzeug/coins'\n\nconst subtotal = add(money('12.50', USD), money('7.25', USD))\nconst taxed = multiply(subtotal, '1.08', { rounding: 'halfEven' })\nconst split = divide(taxed, '3', { rounding: 'floor' })\n\nconsole.log(toDecimal(subtract(subtotal, money('1.00', USD))) )\nconsole.log(toDecimal(taxed))\nconsole.log(toDecimal(split))",
18
+ "name": "Arithmetic - Exact decimal scaling"
19
+ },
20
+ {
21
+ "id": "errors-basic",
22
+ "code": "import { CoinsError, USD, money } from '@vielzeug/coins'\n\ntry {\n money('19.999', USD)\n} catch (error) {\n if (error instanceof CoinsError) {\n console.log(error.code)\n console.log(error.message)\n }\n}",
23
+ "name": "Errors - Stable codes"
24
+ },
25
+ {
26
+ "id": "exchange-basic",
27
+ "code": "import { EUR, USD, exchange, exchangeRate, format, money } from '@vielzeug/coins'\n\nconst usdToEur = exchangeRate({ from: USD, to: EUR, value: '0.9234' })\nconst euros = exchange(money('100.00', USD), usdToEur, { rounding: 'halfEven' })\n\nconsole.log(format(euros, { locale: 'de-DE' }))",
28
+ "name": "exchange - Exact currency conversion"
29
+ },
30
+ {
31
+ "id": "format-basic",
32
+ "code": "import { EUR, USD, format, formatParts, money } from '@vielzeug/coins'\n\nconst value = money('1234.56', USD)\n\nconsole.log(format(value))\nconsole.log(format(money('1234.56', EUR), { locale: 'de-DE' }))\nconsole.log(formatParts(value))",
33
+ "name": "format - Locale presentation"
34
+ },
35
+ {
36
+ "id": "money-basic",
37
+ "code": "import { USD, money, toDecimal, toJSON } from '@vielzeug/coins'\n\nconst price = money('19.99', USD)\nconst stored = money(1999n, USD, { unit: 'minor' })\n\nconsole.log(toDecimal(price))\nconsole.log(stored.amount)\nconsole.log(toJSON(price))",
38
+ "name": "money - Decimal and minor-unit construction"
39
+ },
40
+ {
41
+ "id": "rounding-basic",
42
+ "code": "import { USD, money, round, toDecimal } from '@vielzeug/coins'\n\nconst value = money('1.55', USD)\n\nconsole.log(toDecimal(round(value, { fractionDigits: 1, rounding: 'halfEven' })))\nconsole.log(toDecimal(round(value, { fractionDigits: 1, rounding: 'towardZero' })))",
43
+ "name": "round - Explicit rounding policy"
44
+ },
45
+ {
46
+ "id": "serialization-basic",
47
+ "code": "import { USD, money, decodeMoney, toJSON } from '@vielzeug/coins'\n\nconst encoded = toJSON(money('19.99', USD))\nconst restored = decodeMoney(encoded)\n\nconsole.log(encoded)\nconsole.log(restored.amount, restored.currency.code)",
48
+ "name": "Serialization - Validate JSON boundaries"
49
+ },
50
+ {
51
+ "id": "utilities-basic",
52
+ "code": "import { currency, isCurrency, isMoney, money } from '@vielzeug/coins'\n\nconst points = currency({ code: 'PTS', minorUnit: 0 })\nconst balance = money('250', points)\n\nconsole.log(currency('USD').minorUnit)\nconsole.log(isCurrency(points))\nconsole.log(isMoney(balance))",
53
+ "name": "Currency definitions and validation"
54
+ }
55
+ ],
56
+ "typeSignatures": {
57
+ "allocate": "export { allocate, sum } from './aggregate';",
58
+ "sum": "export { allocate, sum } from './aggregate';",
59
+ "BHD": "export { BHD, currency, EUR, GBP, isCurrency, JPY, KRW, KWD, USD } from './currency';",
60
+ "currency": "export { BHD, currency, EUR, GBP, isCurrency, JPY, KRW, KWD, USD } from './currency';",
61
+ "EUR": "export { BHD, currency, EUR, GBP, isCurrency, JPY, KRW, KWD, USD } from './currency';",
62
+ "GBP": "export { BHD, currency, EUR, GBP, isCurrency, JPY, KRW, KWD, USD } from './currency';",
63
+ "isCurrency": "export { BHD, currency, EUR, GBP, isCurrency, JPY, KRW, KWD, USD } from './currency';",
64
+ "JPY": "export { BHD, currency, EUR, GBP, isCurrency, JPY, KRW, KWD, USD } from './currency';",
65
+ "KRW": "export { BHD, currency, EUR, GBP, isCurrency, JPY, KRW, KWD, USD } from './currency';",
66
+ "KWD": "export { BHD, currency, EUR, GBP, isCurrency, JPY, KRW, KWD, USD } from './currency';",
67
+ "USD": "export { BHD, currency, EUR, GBP, isCurrency, JPY, KRW, KWD, USD } from './currency';",
68
+ "CoinsErrorCode": "export type { CoinsErrorCode } from './errors';",
69
+ "CoinsError": "export { CoinsError, CurrencyMismatchError, InvalidCurrencyError } from './errors';",
70
+ "CurrencyMismatchError": "export { CoinsError, CurrencyMismatchError, InvalidCurrencyError } from './errors';",
71
+ "InvalidCurrencyError": "export { CoinsError, CurrencyMismatchError, InvalidCurrencyError } from './errors';",
72
+ "exchange": "export { exchange, exchangeRate, isExchangeRate } from './exchange';",
73
+ "exchangeRate": "export { exchange, exchangeRate, isExchangeRate } from './exchange';",
74
+ "isExchangeRate": "export { exchange, exchangeRate, isExchangeRate } from './exchange';",
75
+ "format": "export { format, formatParts } from './format';",
76
+ "formatParts": "export { format, formatParts } from './format';",
77
+ "abs": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
78
+ "add": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
79
+ "clamp": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
80
+ "compare": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
81
+ "decodeMoney": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
82
+ "divide": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
83
+ "isMoney": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
84
+ "money": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
85
+ "multiply": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
86
+ "negate": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
87
+ "round": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
88
+ "subtract": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
89
+ "toDecimal": "export {\n abs,\n add,\n clamp,\n compare,\n decodeMoney,\n divide,\n isMoney,\n money,\n multiply,\n negate,\n round,\n subtract,\n toDecimal,\n} from './money';",
90
+ "toJSON": "export { toJSON } from './serialization';",
91
+ "Currency": "export type {\n Currency,\n CurrencyCode,\n Decimal,\n ExchangeRate,\n FormatOptions,\n Money,\n MoneyFormatPart,\n MoneyJSON,\n RoundingMode,\n} from './types';",
92
+ "CurrencyCode": "export type {\n Currency,\n CurrencyCode,\n Decimal,\n ExchangeRate,\n FormatOptions,\n Money,\n MoneyFormatPart,\n MoneyJSON,\n RoundingMode,\n} from './types';",
93
+ "Decimal": "export type {\n Currency,\n CurrencyCode,\n Decimal,\n ExchangeRate,\n FormatOptions,\n Money,\n MoneyFormatPart,\n MoneyJSON,\n RoundingMode,\n} from './types';",
94
+ "ExchangeRate": "export type {\n Currency,\n CurrencyCode,\n Decimal,\n ExchangeRate,\n FormatOptions,\n Money,\n MoneyFormatPart,\n MoneyJSON,\n RoundingMode,\n} from './types';",
95
+ "FormatOptions": "export type {\n Currency,\n CurrencyCode,\n Decimal,\n ExchangeRate,\n FormatOptions,\n Money,\n MoneyFormatPart,\n MoneyJSON,\n RoundingMode,\n} from './types';",
96
+ "Money": "export type {\n Currency,\n CurrencyCode,\n Decimal,\n ExchangeRate,\n FormatOptions,\n Money,\n MoneyFormatPart,\n MoneyJSON,\n RoundingMode,\n} from './types';",
97
+ "MoneyFormatPart": "export type {\n Currency,\n CurrencyCode,\n Decimal,\n ExchangeRate,\n FormatOptions,\n Money,\n MoneyFormatPart,\n MoneyJSON,\n RoundingMode,\n} from './types';",
98
+ "MoneyJSON": "export type {\n Currency,\n CurrencyCode,\n Decimal,\n ExchangeRate,\n FormatOptions,\n Money,\n MoneyFormatPart,\n MoneyJSON,\n RoundingMode,\n} from './types';",
99
+ "RoundingMode": "export type {\n Currency,\n CurrencyCode,\n Decimal,\n ExchangeRate,\n FormatOptions,\n Money,\n MoneyFormatPart,\n MoneyJSON,\n RoundingMode,\n} from './types';"
100
+ }
101
+ }
@@ -0,0 +1,68 @@
1
+ {
2
+ "apiSource": "export { createContainer } from './container.js';\nexport {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';\nexport type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';\nexport { disposalSignalToken, factoryProvider, scope, token, valueProvider } from './types.js';\n",
3
+ "docs": {
4
+ "index": "---\ntitle: Conduit — Dependency Injection for TypeScript\ndescription: Dependency-first asynchronous dependency injection with typed tokens, lifecycle scopes, startup validation, and deterministic disposal.\npackage: conduit\ncategory: infrastructure\nkeywords: [dependency injection, container, token, lifecycle, scope]\nexports: [createContainer, valueProvider, factoryProvider, disposalSignalToken, token, scope]\nrelated: [courier, vault, rune]\nenvironments: [browser, node, ssr, deno]\n---\n\n<!-- markdownlint-disable MD025 MD033 MD060 -->\n\n<PackageHero package=\"conduit\" />\n\n## Why Conduit?\n\nConduit makes service wiring explicit. Typed builders create immutable providers, static graphs are validated at construction, and dependency tuples drive creation and disposal. Resolve one root token or a typed composition map.\n\n```ts\n// Before\nconst service = createService(createApi(config), logger);\n\n// After\nconst container = createContainer([\n valueProvider(Config, config),\n factoryProvider(Api, [Config], (config) => createApi(config)),\n factoryProvider(Service, [Api, Logger], (api, logger) => createService(api, logger)),\n]);\nconst services = await container.resolve({ service: Service });\n```\n\n| Feature | Conduit | Inversify | tsyringe |\n| --- | --- | --- | --- |\n| Dependencies | Explicit token tuples | Decorators/runtime metadata | Decorators/runtime metadata |\n| Async factories | <ore-icon name=\"check\" size=\"16\"></ore-icon> | Partial | Partial |\n| Lifecycle scopes | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"check\" size=\"16\"></ore-icon> |\n| Runtime dependencies | 0 | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n\n<div class=\"decision-callout\">\n\n**Use Conduit when** application services need explicit wiring and owned lifecycle cleanup.\n\n**Consider direct imports when** dependencies are static, small, and need no replacement or disposal boundary.\n\n</div>\n\n## Installation\n\n::: code-group\n\n```sh [pnpm]\npnpm add @vielzeug/conduit\n```\n\n```sh [npm]\nnpm install @vielzeug/conduit\n```\n\n```sh [yarn]\nyarn add @vielzeug/conduit\n```\n\n:::\n\n## Quick Start\n\n```ts\nimport { createContainer, factoryProvider, token, valueProvider } from '@vielzeug/conduit';\n\nconst Config = token<{ baseUrl: string }>('Config');\nconst Client = token<{ url: string }>('Client');\n\nconst container = createContainer([\n valueProvider(Config, { baseUrl: '/api' }),\n factoryProvider(Client, [Config], (config) => ({ url: `${config.baseUrl}/users` })),\n]);\n\nconst services = await container.resolve({ client: Client });\nconsole.log(services.client);\nawait container.dispose();\n```\n\n## Features\n\n<div class=\"features-grid\">\n\n- **`token`**: typed dependency identity\n- **`valueProvider` / `factoryProvider`**: token-safe immutable registrations\n- **`createContainer`**: validated provider graph\n- **`resolve`**: direct service or typed composition map\n- **`scope`**: explicit request and job ownership\n- **`dispose`**: in-flight-safe resource cleanup\n\n</div>\n\n## Documentation\n\n<div class=\"doc-links\">\n\n- [Usage Guide](./usage.md)\n- [API Reference](./api.md)\n- [Examples](./examples.md)\n- [Migration Guide](./migration.md)\n\n</div>\n\n## See Also\n\n<div class=\"see-also\">\n\n- [Courier](/courier/) — inject HTTP clients into application services.\n- [Vault](/vault/) — inject persistence adapters with scoped ownership.\n- [Rune](/rune/) — provide application logging services.\n\n</div>\n\n<!-- markdownlint-enable MD025 MD033 MD060 -->\n",
5
+ "api": "---\ntitle: Conduit — API Reference\ndescription: Reference for Conduit tokens, immutable provider arrays, dependency-first factories, scopes, composition-root resolution, and lifecycle disposal.\n---\n\n[[toc]]\n\n## API Overview\n\n| Symbol | Purpose | Mode | Common gotcha |\n| --- | --- | --- | --- |\n| `token` | Create typed dependency identity | Sync | Same description does not mean same token |\n| `scope` | Create named lifecycle identity | Sync | Must match factory lifetime |\n| `createContainer` | Build root container from an immutable provider array | Sync | Validates the full graph at construction |\n| `valueProvider` / `factoryProvider` | Build type-safe immutable registrations | Sync | Prefer over unannotated object literals |\n| `Provider` | Value or factory registration type | Sync | One local registration per token |\n| `has` | Check registration visibility | Sync | Walks parent containers |\n| `resolve` | Resolve one token or typed composition-root map | Async | Undeclared map tokens fail at resolution |\n| `createScope` | Create child owner | Sync | Named scope required for scoped factories |\n| `dispose` | Release owned resources | Async | May throw `ConduitDisposeError` after cleanup attempts |\n\n## Package Entry Point\n\n| Import | Purpose |\n| --- | --- |\n| `@vielzeug/conduit` | Complete Conduit API |\n\n## Tokens and Scopes\n\n```ts\ntoken<T>(description: string): Token<T>\nscope(name: string): ScopeToken\n```\n\nTokens and scopes are unique symbols. Descriptions exist only for diagnostics. `disposalSignalToken` is a built-in `Token<AbortSignal>` that resolves to the owning root, transient-requesting container, or named scope signal.\n\n## Container\n\n```ts\ncreateContainer(providers: readonly Provider[], options?: { name?: string }): Container\n```\n\n`providers` is an immutable array of value and factory providers. Construction validates the entire graph — duplicate tokens, missing dependencies, circular factory tuples, and singletons depending on scoped factories all fail fast.\n\n### Providers\n\n```ts\ntype Provider<T, Dependencies> = ValueProvider<T> | FactoryProvider<T, Dependencies>;\n\nvalueProvider<T>(token: Token<T>, value: T, options?: ValueOptions<T>): ValueProvider<T>;\nfactoryProvider<T, Dependencies>(\n token: Token<T>,\n dependencies: Dependencies,\n factory: (...values: InferTokens<Dependencies>) => Promise<T> | T,\n options?: FactoryOptions<T>,\n): FactoryProvider<T, Dependencies>;\n```\n\nUse builders for token-driven value and dependency inference:\n\n```ts\nvalueProvider(Config, { baseUrl: '/api' }, { dispose: (value) => value.close() });\nfactoryProvider(Service, [Api, Logger], (api, logger) => createService(api, logger), {\n lifetime: 'singleton',\n dispose: (value) => value.dispose(),\n});\n```\n\nExplicit `ValueProvider<T>` and `FactoryProvider<T, Dependencies>` annotations remain available for reusable provider declarations. Avoid unannotated provider object literals because TypeScript cannot contextually infer one factory parameter from another object property.\n\n`dependencies` is copied at construction and drives creation, validation, cycle detection, and teardown order. Factories may return a value or promise.\n\n`lifetime` accepts `'singleton'` (default), `'transient'`, or a `ScopeToken`. Singletons cannot capture transient or scoped factories. Named-scope factories may depend on singletons, transients, or factories in the same named scope.\n\n```ts\ntype FactoryProvider<T, Dependencies> = {\n token: Token<T>;\n dependencies: Dependencies;\n factory: (...values: InferTokens<Dependencies>) => Promise<T> | T;\n dispose?: (value: T) => void | Promise<void>;\n lifetime?: 'singleton' | 'transient' | ScopeToken;\n};\n```\n\n### has\n\n```ts\ncontainer.has(token): boolean\n```\n\nChecks local and parent registrations without creating a factory result.\n\n### resolve\n\n```ts\ncontainer.resolve(token: Token<T>): Promise<T>\ncontainer.resolve(map: ServiceMap): Promise<InferServices<typeof map>>\n```\n\nResolves one typed token or a service object at a composition root. Map keys are defined as own properties, including `__proto__`, without changing the result prototype. Missing top-level tokens fail during resolution.\n\n```ts\nconst services = await container.resolve({ client: Client, config: Config });\n```\n\nSingleton resolutions deduplicate concurrent callers and cache successful values. A rejected creation attempt is evicted so a later resolution can retry.\n\n### createScope\n\n```ts\ncontainer.createScope(\n scope?: ScopeToken,\n options?: { name?: string; providers?: readonly Provider[] },\n): Container\n```\n\nA matching scope owns resources registered with its `ScopeToken` lifetime. Immutable local providers may shadow parent registrations for request or test overrides. Disposing a parent also disposes active children.\n\n### dispose\n\n```ts\ncontainer.dispose(): Promise<void>\ncontainer.disposalSignal: AbortSignal\ncontainer.disposed: boolean\n```\n\nDisposal blocks new work, aborts `disposalSignal`, disposes active child scopes, waits for complete in-flight creation and late-result cleanup, then disposes owned resources in reverse creation order. Cleanup failures are aggregated in the readonly `ConduitDisposeError.errors` array.\n\n## Types\n\n```ts\ntype Token<T = unknown> = symbol;\ntype ScopeToken = symbol;\ntype Lifetime = 'singleton' | 'transient' | ScopeToken;\n\ntype InferTokens<T extends readonly Token<unknown>[]> = {\n [K in keyof T]: T[K] extends Token<infer Value> ? Value : never;\n};\n\ntype ServiceMap = { readonly [key: string]: Token<unknown> };\n\ntype InferServices<M extends ServiceMap> = {\n readonly [K in keyof M]: M[K] extends Token<infer Value> ? Value : never;\n};\n\ninterface Container {\n createScope(scope?: ScopeToken, options?: { name?: string; providers?: readonly Provider[] }): Container;\n readonly disposalSignal: AbortSignal;\n dispose(): Promise<void>;\n readonly disposed: boolean;\n has<T>(token: Token<T>): boolean;\n readonly name: string;\n resolve<T>(token: Token<T>): Promise<T>;\n resolve<M extends ServiceMap>(map: M): Promise<InferServices<M>>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n## Errors\n\n- `ConduitError` — base class; use `instanceof ConduitError` to narrow package errors.\n- `ConduitProviderNotFoundError` — dependency has no registration.\n- `ConduitCircularDependencyError` — static factory tuple graph contains a cycle.\n- `ConduitDuplicateRegistrationError` — token registered twice in one container.\n- `ConduitScopedResolutionError` — scoped factory resolved without matching scope, or a singleton depends on a scoped factory.\n- `ConduitDisposedError` — operation attempted after disposal began.\n- `ConduitDisposeError` — one or more cleanup hooks failed.\n",
6
+ "usage": "---\ntitle: Conduit — Usage Guide\ndescription: Register an immutable provider array, resolve a typed service object at composition roots, create scopes, and dispose owned resources.\n---\n\n[[toc]]\n\n## Basic Usage\n\nCreate tokens once, build a container from an immutable provider array, then resolve a typed service object at your composition root.\n\n```ts\nimport { createContainer, factoryProvider, token, valueProvider } from '@vielzeug/conduit';\n\nconst Config = token<{ baseUrl: string }>('Config');\nconst Client = token<{ url: string }>('Client');\n\nconst container = createContainer([\n valueProvider(Config, { baseUrl: '/api' }),\n factoryProvider(Client, [Config], (config) => ({ url: `${config.baseUrl}/users` })),\n]);\n\nconst services = await container.resolve({ config: Config, client: Client });\nconsole.log(services.client);\nawait container.dispose();\n```\n\n## Define Dependencies\n\nFactory `dependencies` tuples are authoritative. Conduit resolves tuple values in order, validates every edge at construction, and disposes created services in reverse dependency order.\n\n```ts\nconst Logger = token<{ info(message: string): void }>('Logger');\nconst Api = token<{ get(path: string): Promise<unknown> }>('Api');\nconst Service = token<{ load(): Promise<unknown> }>('Service');\n\nconst container = createContainer([\n valueProvider(Logger, { info: (message) => console.log(message) }),\n factoryProvider(Api, [], () => ({ get: async (path: string) => fetch(path) })),\n factoryProvider(Service, [Api, Logger], (api, logger) => ({\n async load() {\n logger.info('Loading data');\n return api.get('/data');\n },\n })),\n]);\n```\n\n## Choose Lifetimes\n\nFactories are singletons by default and cached on the registering container. Concurrent singleton resolutions share one in-flight attempt; a rejected attempt is evicted for retry. Use `'transient'` for one value per resolution or a `ScopeToken` for request, job, or test ownership. Singletons cannot depend on transient or scoped factories, and one named scope cannot depend on another.\n\n```ts\nimport { createContainer, factoryProvider, scope, token } from '@vielzeug/conduit';\n\nconst Request = scope('request');\nconst Session = token<{ id: string }>('Session');\n\nconst root = createContainer([\n factoryProvider(Session, [], () => ({ id: crypto.randomUUID() }), { lifetime: Request }),\n]);\n```\n\nFactory dependency tuples are copied at construction, so later caller mutation cannot change Conduit's graph. Add `disposalSignalToken` to a factory tuple when work must observe its owning container or scope cancellation.\n\n## Create Named Scopes\n\nUse a scope token when a resource belongs to a request, job, or test lifecycle. Pass immutable local providers through `createScope()` options to override parent registrations.\n\n```ts\nconst TraceId = token<string>('TraceId');\nconst request = root.createScope(Request, {\n providers: [valueProvider(TraceId, 'request-trace')],\n});\nconst services = await request.resolve({ session: Session });\nawait request.dispose();\nawait root.dispose();\n```\n\nResolving `Session` from `root` throws `ConduitScopedResolutionError` because no matching scope owns it.\n\n## Resolve at Composition Roots\n\nResolve a map at composition roots to receive an explicitly typed service object. Direct `resolve(token)` remains available for one root service and focused tests; avoid scattering service-locator calls through application code.\n\n```ts\nconst client = await container.resolve(Client);\nconst services = await container.resolve({ client: Client, config: Config });\n// Both results are fully typed.\n```\n\n## Dispose Resources\n\n`dispose()` rejects new work, aborts `disposalSignal`, disposes child scopes, waits for in-flight creation, then releases services in reverse creation order. A factory that finishes after disposal starts is immediately cleaned up and its resolver receives `ConduitDisposedError`.\n\n```ts\nawait container.dispose();\n```\n\n`ConduitDisposeError.errors` contains every cleanup failure after Conduit attempts all hooks, including cleanup from in-flight factories and child scopes.\n\n## Testing\n\nBuild a container per test with explicit values for external dependencies. Because the provider array is immutable and validated at construction, a misconfigured test container fails immediately.\n\n```ts\nconst Clock = token<{ now(): number }>('Clock');\nconst Service = token<{ timestamp: number }>('Service');\n\nconst container = createContainer([\n valueProvider(Clock, { now: () => 123 }),\n factoryProvider(Service, [Clock], (clock) => ({ timestamp: clock.now() })),\n]);\n\nconst services = await container.resolve({ service: Service });\nexpect(services.service).toEqual({ timestamp: 123 });\nawait container.dispose();\n```\n\n## Best Practices\n\n- Create tokens at module scope.\n- Use `valueProvider()` and `factoryProvider()` so tokens, values, dependencies, and disposers remain type-safe.\n- Declare every factory dependency in its tuple.\n- Keep factories focused on one service.\n- Use scopes for request/job-owned resources.\n- Resolve once at a composition root; pass the typed service object downstream.\n- Dispose every scope and root container.\n- Keep optional application fallback policy outside Conduit.\n- Use `await using container = createContainer([...])` when lexical async disposal fits application lifetime.\n",
7
+ "examples": "---\ntitle: Conduit — Examples\ndescription: Immutable provider array recipes.\n---\n\n## Examples\n\n- [Basic setup](./examples/basic-setup.md)\n- [Static async providers](./examples/async-providers.md)\n- [Singleton lifetime](./examples/lifetimes.md)\n- [Named scopes](./examples/named-scopes.md)\n- [Disposal lifecycle](./examples/dispose-lifecycle.md)\n- [Startup validation](./examples/startup-hardening.md)\n"
8
+ },
9
+ "examples": [
10
+ {
11
+ "id": "basic-container",
12
+ "code": "import { createContainer, factoryProvider, token, valueProvider } from '@vielzeug/conduit'\n\nconst Config = token<{ baseUrl: string }>('Config')\nconst Client = token<{ url: string }>('Client')\n\nconst container = createContainer([\n valueProvider(Config, { baseUrl: '/api' }),\n factoryProvider(Client, [Config], config => ({ url: config.baseUrl + '/users' })),\n])\n\nconst services = await container.resolve({ client: Client })\nconsole.log(services.client)\nawait container.dispose()",
13
+ "name": "Immutable provider array"
14
+ },
15
+ {
16
+ "id": "dispose-lifecycle",
17
+ "code": "import { createContainer, factoryProvider, token } from '@vielzeug/conduit'\n\nconst Database = token('Database')\nconst Service = token('Service')\nconst order = []\n\nconst container = createContainer([\n factoryProvider(Database, [], () => ({ close() {} }), { dispose: () => { order.push('database') } }),\n factoryProvider(Service, [Database], database => ({ database }), { dispose: () => { order.push('service') } }),\n])\n\nawait container.resolve({ service: Service })\nawait container.dispose()\nconsole.log(order)",
18
+ "name": "Reverse dependency disposal"
19
+ },
20
+ {
21
+ "id": "lifetimes",
22
+ "code": "import { createContainer, factoryProvider, token } from '@vielzeug/conduit'\n\nconst Singleton = token('Singleton')\n\nconst container = createContainer([\n factoryProvider(Singleton, [], () => ({ id: crypto.randomUUID() })),\n])\n\nconst services = await container.resolve({ a: Singleton, b: Singleton })\nconsole.log(services.a === services.b)\nawait container.dispose()",
23
+ "name": "Singleton lifetime caching"
24
+ },
25
+ {
26
+ "id": "scoped-execution",
27
+ "code": "import { createContainer, factoryProvider, scope, token } from '@vielzeug/conduit'\n\nconst Request = scope('request')\nconst Session = token('Session')\n\nconst root = createContainer([\n factoryProvider(Session, [], () => ({ id: crypto.randomUUID() }), { lifetime: Request }),\n])\n\nconst request = root.createScope(Request)\nconst services = await request.resolve({ session: Session })\nconsole.log(services.session)\nawait request.dispose()\nawait root.dispose()",
28
+ "name": "Named scope ownership"
29
+ },
30
+ {
31
+ "id": "testing",
32
+ "code": "import { createContainer, factoryProvider, token, valueProvider } from '@vielzeug/conduit'\n\nconst Clock = token<{ now(): number }>('Clock')\nconst Service = token<{ timestamp: number }>('Service')\n\nconst container = createContainer([\n valueProvider(Clock, { now: () => 123 }),\n factoryProvider(Service, [Clock], clock => ({ timestamp: clock.now() })),\n])\n\nconst services = await container.resolve({ service: Service })\nconsole.log(services.service)\nawait container.dispose()",
33
+ "name": "Replace dependencies in tests"
34
+ },
35
+ {
36
+ "id": "validate",
37
+ "code": "import { createContainer, factoryProvider, token } from '@vielzeug/conduit'\n\nconst Api = token('Api')\nconst Service = token('Service')\n\ntry {\n createContainer([\n factoryProvider(Service, [Api], api => ({ api })),\n ])\n} catch (error) {\n console.log(error.message)\n}",
38
+ "name": "Fail-fast startup validation"
39
+ }
40
+ ],
41
+ "typeSignatures": {
42
+ "createContainer": "export { createContainer } from './container.js';",
43
+ "ConduitCircularDependencyError": "export {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';",
44
+ "ConduitDisposedError": "export {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';",
45
+ "ConduitDisposeError": "export {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';",
46
+ "ConduitDuplicateRegistrationError": "export {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';",
47
+ "ConduitError": "export {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';",
48
+ "ConduitProviderNotFoundError": "export {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';",
49
+ "ConduitScopedResolutionError": "export {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';",
50
+ "Container": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
51
+ "FactoryOptions": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
52
+ "FactoryProvider": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
53
+ "InferServices": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
54
+ "InferTokens": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
55
+ "Lifetime": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
56
+ "Provider": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
57
+ "ScopeToken": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
58
+ "ServiceMap": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
59
+ "Token": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
60
+ "ValueOptions": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
61
+ "ValueProvider": "export type {\n Container,\n FactoryOptions,\n FactoryProvider,\n InferServices,\n InferTokens,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueOptions,\n ValueProvider,\n} from './types.js';",
62
+ "disposalSignalToken": "export { disposalSignalToken, factoryProvider, scope, token, valueProvider } from './types.js';",
63
+ "factoryProvider": "export { disposalSignalToken, factoryProvider, scope, token, valueProvider } from './types.js';",
64
+ "scope": "export { disposalSignalToken, factoryProvider, scope, token, valueProvider } from './types.js';",
65
+ "token": "export { disposalSignalToken, factoryProvider, scope, token, valueProvider } from './types.js';",
66
+ "valueProvider": "export { disposalSignalToken, factoryProvider, scope, token, valueProvider } from './types.js';"
67
+ }
68
+ }