@vielzeug/codex 2.0.2 → 2.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.
package/data/search.json CHANGED
@@ -202,7 +202,7 @@
202
202
  "docs": {
203
203
  "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]\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` adapts catalog operations to mcp.\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",
204
204
  "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 | sync | requires catalog and version |\n| `starthttphost` | loopback streamable http host | async | http remains local only |\n\n## package entry point\n\n| import | purpose |\n| | |\n| `@vielzeug/codex` | snapshot, catalog, mcp, and http apis |\n\n## snapshot\n\n### `loadsnapshot`\n\n```ts\nloadsnapshot(snapshotdirectory?: string): loadedsnapshot;\n```\n\nloads catalog/search metadata only. use `validatesnapshot()` during generation, integration tests, or explicit artifact verification; package chunks stay lazy at runtime.\n\n### `snapshotcatalog`\n\n```ts\nnew snapshotcatalog(snapshot: loadedsnapshot)\n```\n\nprovides package lookup, docs/source/example/signature access, deterministic search, and refine component lookup.\n\n## mcp\n\n### `createmcpserver`\n\n```ts\ncreatemcpserver(catalog: catalog, options: { version: string; debug?: boolean }): server;\n```\n\nregisters mcp tools as an adapter over `catalog`.\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. host accepts only loopback addresses.\n\n## types\n\n```ts\ninterface snapshotpointer {\n directory: 'snapshots/<immutable id>';\n}\n\n// dev snapshots use snapshotpointer; published snapshots are static directories.\ninterface snapshotmanifest {\n schemaversion: 1;\n catalog: 'catalog.json';\n search: 'search.json';\n contentdirectory: 'packages';\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",
205
- "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. no legacy sse endpoint, cors wildcard, or remote host mode exists.\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, createmcpserver, loadsnapshot } from '@vielzeug/codex';\nimport { stdioservertransport } from '@modelcontextprotocol/sdk/server/stdio.js';\n\nconst snapshot = loadsnapshot();\nconst catalog = new snapshotcatalog(snapshot);\nawait createmcpserver(catalog, { version: snapshot.manifest.version }).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 run `validatesnapshot()` in artifact verification paths, not normal server startup.\n keep http local. use stdio for normal client integration.\n run `pnpm test:unit` before `pnpm test:integration`.\n",
205
+ "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. no legacy sse endpoint, cors wildcard, or remote host mode exists.\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, createmcpserver, loadsnapshot } from '@vielzeug/codex';\nimport { stdioservertransport } from '@modelcontextprotocol/server/stdio';\n\nconst snapshot = loadsnapshot();\nconst catalog = new snapshotcatalog(snapshot);\nawait createmcpserver(catalog, { version: snapshot.manifest.version }).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 run `validatesnapshot()` in artifact verification paths, not normal server startup.\n keep http local. use stdio for normal client integration.\n run `pnpm test:unit` before `pnpm test:integration`.\n",
206
206
  "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"
207
207
  },
208
208
  "examples": [],
@@ -883,9 +883,9 @@
883
883
  "category": "state",
884
884
  "description": "framework agnostic signals, derived values, effects, scopes, async resources, and immutable state.",
885
885
  "docs": {
886
- "index": " \ntitle: ripple — reactive graphs\ndescription: framework agnostic signals, derived values, effects, scopes, async resources, and immutable state.\npackage: ripple\ncategory: state\nkeywords: [reactive, signals, computed, effects, graph, scope, batch, async]\nrelated: [ore, clockwork, ledger]\nexports: [createripple, signal, computed, effect, batch, createscope, createstore, resource, untrack, watch, isreactive]\nenvironments: [browser, node, ssr, deno]\n \n\n<! markdownlint disable md025 md033 md060 >\n\n<packagehero package=\"ripple\" />\n\n## why ripple?\n\nhand rolled reactive state spreads subscription, cleanup, and derived value rules across application code. ripple gives you one graph boundary with explicit disposal and fine grained dependencies while keeping rendering and routing outside the runtime.\n\n```ts\n// before\nlet count = 0;\nconst listeners = new set<() => void>();\n\nfunction setcount(next: number) {\n count = next;\n for (const listener of listeners) listener();\n}\n\n// after\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple();\nconst count = ripple.signal(0);\nconst doubled = ripple.computed(() => count.value * 2);\nconst stop = ripple.effect(() => console.log(doubled.value));\n\ncount.value = 1;\nstop.dispose();\nripple.dispose();\n```\n\n| feature | ripple | zustand | jotai |\n| | | | |\n| bundle size | <packageinfo package=\"ripple\" type=\"size\" /> | ~3.5 kb | ~7 kb |\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| framework agnostic | <ore icon name=\"check\" size=\"16\"></ore icon> | <ore icon name=\"check\" size=\"16\"></ore icon> | react first |\n| explicit graph lifetime | <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| fine grained derived values | <ore icon name=\"check\" size=\"16\"></ore icon> | selectors | atoms |\n\n<div class=\"decision callout\">\n\n**use ripple when** you need framework independent state with explicit graph lifetime and small composable primitives.\n\n**consider a framework store when** component bindings, server cache, or framework specific tooling matter more than portable reactive state.\n\n</div>\n\n## installation\n\n::: code group\n\n```sh [pnpm]\npnpm add @vielzeug/ripple\n```\n\n```sh [npm]\nnpm install @vielzeug/ripple\n```\n\n```sh [yarn]\nyarn add @vielzeug/ripple\n```\n\n:::\n\n## quick start\n\ncreate one graph, derive a value, observe it, then dispose resources when the graph lifetime ends.\n\n```ts\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple();\nconst count = ripple.signal(0);\nconst doubled = ripple.computed(() => count.value * 2);\nconst stop = ripple.effect(() => console.log(doubled.value));\n\nripple.batch(() => {\n count.value = 1;\n count.value = 2;\n});\n\nstop.dispose();\nripple.dispose();\n```\n\n## features\n\n<div class=\"features grid\">\n\n `createripple()` creates an isolated graph and lifetime boundary.\n `signal()` stores writable values with configurable equality.\n `computed()` derives lazy read only values.\n `effect()` reacts to dependency changes with cleanup support.\n `batch()` coalesces synchronous writes and notifications.\n `createscope()` groups owned reactive work.\n `watch()` observes one selected source transition.\n `resource()` loads async values with stale work cancellation.\n `createstore()` wraps explicit value replacement and updater functions.\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 [ore](/ore/) — uses ripple signals and effects for web component reactivity.\n [clockwork](/clockwork/) — exposes machine state through reactive ripple values.\n [ledger](/ledger/) — adds command based undo and redo beside ripple state.\n\n</div>\n\n<! markdownlint enable >\n",
887
- "api": " \ntitle: ripple — api reference\ndescription: complete reference for reactive graphs, signals, effects, scopes, watchers, resources, and stores.\n \n\n[[toc]]\n\n## api overview\n\n| symbol | purpose | execution mode | common gotcha |\n| | | | |\n| `createripple()` | create isolated graph | sync | dispose request/test/feature graphs |\n| `signal()` | create writable value | sync | default graph is process wide |\n| `computed()` | create lazy derived value | sync | keep derivation pure |\n| `effect()` | react to dependency reads | sync | dispose handle or return cleanup |\n| `batch()` | coalesce synchronous writes | sync | does not roll back writes |\n| `createscope()` | group owned reactive work | sync | call `run()` to activate it |\n| `untrack()` | read without tracking | sync | read still happens immediately |\n| `watch()` | observe selected output | sync | use `effect()` for broad reads |\n| `resource()` | load async source | async | read dependencies in source callback |\n| `createstore()` | hold replacement based state | sync | return replacement objects from updates |\n| `isreactive()` | test `readable` identity | sync | does not test arbitrary objects |\n\n## package entry point\n\n| import | purpose |\n| | |\n| `@vielzeug/ripple` | default graph apis, isolated graph factory, types, and errors |\n| `@vielzeug/ripple/watch` | `watch()` and `watchoptions` |\n| `@vielzeug/ripple/async` | `resource()`, `resource`, `asyncstate`, `resourceoptions` |\n| `@vielzeug/ripple/store` | `createstore()`, `store`, `storeoptions` |\n\n## graph creation\n\n### `createripple(options?)`\n\n```ts\nfunction createripple(options?: rippleoptions): ripple;\n```\n\ncreates one isolated reactive graph. factories on the returned object share scheduling, ownership, observer, and error boundaries.\n\n| parameter | type | description |\n| | | |\n| `options.onerror` | `(error, context) => void` | receives effect, cleanup, listener, or observer failures. |\n| `options.observer` | `reactiveobserver` | receives graph events. |\n\n**returns:** `ripple`.\n\n**example:**\n\n```ts\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple();\nconst count = ripple.signal(0);\nconst stop = ripple.effect(() => console.log(count.value));\n\nstop.dispose();\nripple.dispose();\n```\n\n \n\n### `isreactive(value)`\n\n```ts\nfunction isreactive<t>(value: t | readable<t>): value is readable<t>;\n```\n\ntests whether a value is a ripple readable node.\n\n**returns:** `true` for a `signal`, computed value, or other `readable` node.\n\n**example:**\n\n```ts\nimport { isreactive, signal } from '@vielzeug/ripple';\n\nconsole.log(isreactive(signal(0)));\n```\n\n## default graph functions\n\n### `signal(initial, options?)`\n\n```ts\nfunction signal<t>(initial: t, options?: signaloptions<t>): signal<t>;\n```\n\ncreates writable state on the default graph.\n\n**returns:** `signal<t>`.\n\n**example:**\n\n```ts\nimport { signal } from '@vielzeug/ripple';\n\nconst count = signal(0);\ncount.value += 1;\n```\n\n \n\n### `computed(derive, options?)`\n\n```ts\nfunction computed<t>(derive: () => t, options?: computedoptions<t>): readable<t>;\n```\n\ncreates a lazy read only value from reactive reads in `derive`.\n\n**returns:** `readable<t>`.\n\n**example:**\n\n```ts\nimport { computed, signal } from '@vielzeug/ripple';\n\nconst count = signal(2);\nconst doubled = computed(() => count.value * 2);\nconsole.log(doubled.value);\n```\n\n \n\n### `effect(callback, options?)`\n\n```ts\nfunction effect(callback: () => cleanup | void, options?: effectoptions): effecthandle;\n```\n\nruns immediately and reruns when its tracked reads change. a returned cleanup runs before the next callback or disposal.\n\n**returns:** `effecthandle`.\n\n**example:**\n\n```ts\nimport { effect, signal } from '@vielzeug/ripple';\n\nconst connected = signal(false);\nconst stop = effect(() => {\n if (!connected.value) return;\n\n return () => console.log('disconnect');\n});\n\nstop.dispose();\n```\n\n \n\n### `batch(fn)` and `untrack(fn)`\n\n```ts\nfunction batch<t>(fn: () => t): t;\nfunction untrack<t>(fn: () => t): t;\n```\n\n`batch()` defers effects and listeners until its callback returns. `untrack()` reads current state without adding dependencies to an enclosing effect.\n\n**returns:** the callback result.\n\n**example:**\n\n```ts\nimport { batch, signal, untrack } from '@vielzeug/ripple';\n\nconst first = signal('ada');\nconst last = signal('lovelace');\nconst locale = signal('en us');\n\nbatch(() => {\n first.value = 'grace';\n last.value = 'hopper';\n});\n\nconsole.log(untrack(() => locale.value));\n```\n\n \n\n### `createscope(name?)`\n\n```ts\nfunction createscope(name?: string): scope;\n```\n\ncreates a disposable ownership boundary. work created inside `scope.run()` belongs to that scope.\n\n**returns:** `scope`.\n\n**example:**\n\n```ts\nimport { createscope, effect, signal } from '@vielzeug/ripple';\n\nconst scope = createscope('panel');\nconst count = signal(0);\n\nscope.run(() => effect(() => console.log(count.value)));\nscope.dispose();\n```\n\n## watch, resources, and stores\n\n### `watch(source, callback, options?)`\n\n```ts\nfunction watch<t>(\n source: readable<t> | (() => t),\n callback: (value: t, previous: t | undefined) => void,\n options?: watchoptions<t>,\n): effecthandle;\n```\n\nobserves selected output changes using the default graph or a `ripple.watch()` method.\n\n**returns:** `effecthandle`.\n\n**example:**\n\n```ts\nimport { signal } from '@vielzeug/ripple';\nimport { watch } from '@vielzeug/ripple/watch';\n\nconst count = signal(0);\nconst stop = watch(count, (value, previous) => console.log(previous, value), { immediate: true });\nstop.dispose();\n```\n\n \n\n### `resource(source, loader, options?)`\n\n```ts\nfunction resource<source, value>(\n source: () => source,\n loader: (source: source, context: { readonly signal: abortsignal }) => promise<value>,\n options?: resourceoptions,\n): resource<value>;\n```\n\ntracks `source`, aborts stale loader work, and exposes `asyncstate<value>`.\n\n**returns:** `resource<value>`.\n\n**example:**\n\n```ts\nimport { resource, signal } from '@vielzeug/ripple/async';\n\nconst userid = signal('42');\nconst user = resource(() => userid.value, async (id) => ({ id }));\nuser.dispose();\n```\n\n \n\n### `createstore(initial, options?)`\n\n```ts\nfunction createstore<t>(initial: t, options?: storeoptions): store<t>;\n```\n\ncreates one writable value wrapper with explicit `set()` and `update()` operations.\n\n**returns:** `store<t>`.\n\n**example:**\n\n```ts\nimport { createstore } from '@vielzeug/ripple/store';\n\nconst user = createstore({ name: 'ada', visits: 0 });\nuser.update((value) => ({ ...value, visits: value.visits + 1 }));\n```\n\n## types\n\n```ts\ntype cleanup = () => void;\ntype equality<t> = (previous: t, next: t) => boolean;\ntype unsubscribe = () => void;\n\ntype signaloptions<t> = { equals?: equality<t>; name?: string };\ntype computedoptions<t> = { equals?: equality<t>; name?: string };\ntype effectoptions = { name?: string; scheduler?: 'microtask' | 'sync' };\ntype watchoptions<t> = { equals?: equality<t>; immediate?: boolean; name?: string; once?: boolean };\ntype resourceoptions = { name?: string };\ntype storeoptions = { name?: string };\n\ntype reactiveevent =\n | { readonly kind: 'compute'; readonly name?: string }\n | { readonly kind: 'effect'; readonly name?: string }\n | { readonly kind: 'write'; readonly name?: string; readonly next: unknown; readonly previous: unknown }\n | { readonly kind: 'dispose'; readonly name?: string; readonly node: 'effect' | 'scope' };\n\ntype reactiveobserver = (event: reactiveevent) => void;\ntype reactiveerrorcontext = { readonly kind: 'cleanup' | 'effect' | 'listener' | 'observer'; readonly name?: string };\ntype rippleoptions = { observer?: reactiveobserver; onerror?: (error: unknown, context: reactiveerrorcontext) => void };\n\ntype asyncstate<t> =\n | { readonly previous?: t; readonly status: 'pending' }\n | { readonly status: 'success'; readonly value: t }\n | { readonly error: unknown; readonly previous?: t; readonly status: 'error' };\n\ninterface readable<t> {\n readonly name?: string;\n peek(): t;\n subscribe(listener: () => void): unsubscribe;\n readonly value: t;\n}\n\ninterface signal<t> extends readable<t> { value: t }\ninterface disposable { dispose(): void; readonly disposed: boolean; readonly disposalsignal: abortsignal; [symbol.dispose](): void }\ntype effecthandle = disposable;\ninterface scope extends disposable { run<t>(fn: () => t): t }\n\ninterface resource<t> extends readable<asyncstate<t>>, disposable { reload(): void }\ninterface store<t> extends readable<t> { set(value: t): void; update(updater: (value: t) => t): void }\n\ninterface ripple {\n batch<t>(fn: () => t): t;\n computed<t>(derive: () => t, options?: computedoptions<t>): readable<t>;\n createscope(name?: string): scope;\n createstore<t>(initial: t, options?: storeoptions): store<t>;\n dispose(): void;\n effect(callback: () => cleanup | void, options?: effectoptions): effecthandle;\n resource<source, value>(source: () => source, loader: (source: source, context: { readonly signal: abortsignal }) => promise<value>, options?: resourceoptions): resource<value>;\n signal<t>(initial: t, options?: signaloptions<t>): signal<t>;\n untrack<t>(fn: () => t): t;\n watch<t>(source: readable<t> | (() => t), callback: (value: t, previous: t | undefined) => void, options?: watchoptions<t>): effecthandle;\n}\n```\n\n## errors\n\n| error | trigger | notable properties |\n| | | |\n| `rippleerror` | base ripple error | `rippleerror.is(error)` narrows unknown values. |\n| `ripplecomputedcycleerror` | computed dependency reads itself through a cycle | extends `rippleerror`. |\n| `rippledisposedscopeerror` | `scope.run()` after scope disposal | extends `rippleerror`. |\n| `rippleinfinitelooperror` | effect flush exceeds graph iteration limit | extends `rippleerror`. |\n",
888
- "usage": " \ntitle: ripple — usage guide\ndescription: build reactive state with one explicit graph boundary.\n \n\n[[toc]]\n\n## basic usage\n\nuse top level functions when one application lifetime graph is sufficient. read a signal inside an effect to make that read reactive.\n\n```ts\nimport { computed, effect, signal } from '@vielzeug/ripple';\n\nconst count = signal(0);\nconst label = computed(() => `count: ${count.value}`);\nconst stop = effect(() => console.log(label.value));\n\ncount.value = 1;\nstop.dispose();\n```\n\n## isolated graphs\n\nuse `createripple()` for tests, ssr requests, embedded applications, or independently disposable features. never mix reactive values from separate graphs.\n\n```ts\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple({\n onerror(error, context) {\n console.log(context.kind, error);\n },\n});\n\nconst count = ripple.signal(0);\nconst stop = ripple.effect(() => console.log(count.value));\n\nstop.dispose();\nripple.dispose();\n```\n\n## derived values and batches\n\nuse `computed()` for pure derivation. use `untrack()` when a current read must not become an effect dependency. use `batch()` for related synchronous writes.\n\n```ts\nconst first = ripple.signal('ada');\nconst last = ripple.signal('lovelace');\nconst locale = ripple.signal('en us');\nconst name = ripple.computed(() => `${first.value} ${last.value}`);\n\nripple.effect(() => {\n console.log({ locale: ripple.untrack(() => locale.value), name: name.value });\n});\n\nripple.batch(() => {\n first.value = 'grace';\n last.value = 'hopper';\n});\n```\n\n## ownership with scopes\n\ncreate a scope when a group of effects or derived values shares one lifetime. dispose the scope when its feature ends.\n\n```ts\nconst scope = ripple.createscope('panel');\nconst count = ripple.signal(0);\n\nscope.run(() => {\n ripple.effect(() => console.log(`panel count: ${count.value}`));\n});\n\ncount.value = 1;\nscope.dispose();\n```\n\n## watch selected values\n\nuse `watch()` for one selected output. use `effect()` when every reactive read in the callback should be a dependency.\n\n```ts\nconst stopwatch = ripple.watch(\n () => `${first.value} ${last.value}`,\n (value, previous) => console.log({ previous, value }),\n { immediate: true },\n);\n\nstopwatch.dispose();\n```\n\n## async data\n\n`resource()` captures source dependencies synchronously and passes a cancellation signal to the loader.\n\n```ts\nconst userid = ripple.signal('42');\nconst user = ripple.resource(\n () => userid.value,\n async (id, { signal }) => {\n const response = await fetch(`/users/${id}`, { signal });\n if (!response.ok) throw new error(`request failed: ${response.status}`);\n\n return response.json() as promise<{ id: string; name: string }>;\n },\n);\n\nif (user.value.status === 'success') console.log(user.value.value.name);\nuser.dispose();\n```\n\n## object state\n\n`createstore()` holds one value and exposes `set()` and `update()`. return replacement objects from `update()` when object consumers depend on immutable updates.\n\n```ts\nconst cart = ripple.createstore({ items: 0, label: 'empty' });\nconst items = ripple.computed(() => cart.value.items);\n\ncart.update((state) => ({ ...state, items: state.items + 1 }));\ncart.set({ items: 3, label: 'ready' });\n\nconsole.log(items.value);\n```\n\n## testing\n\ncreate an isolated graph per test. disposal prevents effects and resource work from leaking into later tests.\n\n```ts\nimport { expect, test } from 'vitest';\nimport { createripple } from '@vielzeug/ripple';\n\ntest('derives a doubled count', () => {\n const ripple = createripple();\n const count = ripple.signal(2);\n const doubled = ripple.computed(() => count.value * 2);\n\n expect(doubled.value).tobe(4);\n ripple.dispose();\n});\n```\n\n## framework integration\n\nuse signals and effects with any renderer. dispose component owned effects when the component unmounts.\n\n::: code group\n\n```ts [react]\nimport { useeffect, usestate } from 'react';\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple();\nconst count = ripple.signal(0);\n\nexport function counter() {\n const [, rerender] = usestate(0);\n\n useeffect(() => {\n const stop = ripple.effect(() => {\n void count.value;\n rerender((revision) => revision + 1);\n });\n\n return () => stop.dispose();\n }, []);\n\n return <button onclick={() => (count.value += 1)}>{count.value}</button>;\n}\n```\n\n```ts [vue 3]\nimport { onunmounted, ref } from 'vue';\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple();\nconst count = ripple.signal(0);\nconst revision = ref(0);\nconst stop = ripple.effect(() => {\n void count.value;\n revision.value++;\n});\n\nonunmounted(() => stop.dispose());\n```\n\n```ts [svelte]\n<script lang=\"ts\">\n import { ondestroy } from 'svelte';\n import { createripple } from '@vielzeug/ripple';\n\n const ripple = createripple();\n const count = ripple.signal(0);\n let revision = 0;\n const stop = ripple.effect(() => {\n void count.value;\n revision++;\n });\n\n ondestroy(() => stop.dispose());\n</script>\n\n<button on:click={() => (count.value += 1)}>{count.value}</button>\n```\n\n:::\n\n## working with other vielzeug libraries\n\nore uses ripple for component reactivity. clockwork actors expose framework neutral snapshots; bridge actor subscriptions into a ripple signal. ledger adds undo/redo commands around state changes without replacing graph.\n\n```ts\nimport { createripple } from '@vielzeug/ripple';\nimport { definemachine } from '@vielzeug/clockwork';\n\nconst ripple = createripple();\nconst actor = definemachine<record<string, never>, { type: 'start' }>()({\n initial: 'idle',\n states: { active: {}, idle: { on: { start: { target: 'active' } } } },\n}).createactor();\n\nconst snapshot = ripple.signal(actor.snapshot);\nconst stop = actor.subscribe((next) => (snapshot.value = next));\nconst status = ripple.computed(() => snapshot.value.state);\nconsole.log(status.value);\n\nstop();\nactor.dispose();\nripple.dispose();\n```\n\n## best practices\n\n create one graph per ownership boundary.\n keep computed callbacks pure.\n return cleanup from effects.\n dispose request, test, and feature graphs.\n batch related synchronous writes.\n use `watch()` only for selected source transitions.\n read dependencies in a resource source, not its loader.\n route background failures through `onerror`.\n",
886
+ "index": " \ntitle: ripple — reactive graphs\ndescription: framework agnostic signals, derived values, effects, scopes, async resources, and immutable state.\npackage: ripple\ncategory: state\nkeywords: [reactive, signals, computed, effects, graph, scope, batch, async]\nrelated: [ore, clockwork, ledger]\nexports: [createripple, signal, computed, effect, batch, createscope, untrack, isreactive]\nenvironments: [browser, node, ssr, deno]\n \n\n<! markdownlint disable md025 md033 md060 >\n\n<packagehero package=\"ripple\" />\n\n## why ripple?\n\nhand rolled reactive state spreads subscription, cleanup, and derived value rules across application code. ripple gives you one graph boundary with explicit disposal and fine grained dependencies while keeping rendering and routing outside the runtime.\n\n```ts\n// before\nlet count = 0;\nconst listeners = new set<() => void>();\n\nfunction setcount(next: number) {\n count = next;\n for (const listener of listeners) listener();\n}\n\n// after\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple();\nconst count = ripple.signal(0);\nconst doubled = ripple.computed(() => count.value * 2);\nconst stop = ripple.effect(() => console.log(doubled.value));\n\ncount.value = 1;\nstop.dispose();\nripple.dispose();\n```\n\n| feature | ripple | zustand | jotai |\n| | | | |\n| bundle size | <packageinfo package=\"ripple\" type=\"size\" /> | ~3.5 kb | ~7 kb |\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| framework agnostic | <ore icon name=\"check\" size=\"16\"></ore icon> | <ore icon name=\"check\" size=\"16\"></ore icon> | react first |\n| explicit graph lifetime | <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| fine grained derived values | <ore icon name=\"check\" size=\"16\"></ore icon> | selectors | atoms |\n\n<div class=\"decision callout\">\n\n**use ripple when** you need framework independent state with explicit graph lifetime and small composable primitives.\n\n**consider a framework store when** component bindings, server cache, or framework specific tooling matter more than portable reactive state.\n\n</div>\n\n## installation\n\n::: code group\n\n```sh [pnpm]\npnpm add @vielzeug/ripple\n```\n\n```sh [npm]\nnpm install @vielzeug/ripple\n```\n\n```sh [yarn]\nyarn add @vielzeug/ripple\n```\n\n:::\n\n## quick start\n\ncreate one graph, derive a value, observe it, then dispose resources when the graph lifetime ends.\n\n```ts\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple();\nconst count = ripple.signal(0);\nconst doubled = ripple.computed(() => count.value * 2);\nconst stop = ripple.effect(() => console.log(doubled.value));\n\nripple.batch(() => {\n count.value = 1;\n count.value = 2;\n});\n\nstop.dispose();\nripple.dispose();\n```\n\n## features\n\n<div class=\"features grid\">\n\n `createripple()` creates an isolated graph and lifetime boundary.\n `signal()` stores writable values with configurable equality.\n `computed()` derives lazy read only values.\n `effect()` reacts to dependency changes with cleanup support.\n `batch()` coalesces synchronous writes and notifications.\n `createscope()` groups owned reactive work.\n `watch()` observes one selected source transition.\n `resource()` loads async values with stale work cancellation.\n `createstore()` wraps explicit value replacement and updater functions.\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 [ore](/ore/) — uses ripple signals and effects for web component reactivity.\n [clockwork](/clockwork/) — exposes machine state through reactive ripple values.\n [ledger](/ledger/) — adds command based undo and redo beside ripple state.\n\n</div>\n\n<! markdownlint enable >\n",
887
+ "api": " \ntitle: ripple — api reference\ndescription: complete reference for reactive graphs, signals, effects, scopes, watchers, resources, and stores.\n \n\n[[toc]]\n\n## api overview\n\n| symbol | purpose | execution mode | common gotcha |\n| | | | |\n| `createripple()` | create isolated graph | sync | disposal is terminal; create a new graph instead of reusing it |\n| `signal()` | create writable value | sync | default graph is process wide |\n| `computed()` | create lazy derived value | sync | keep derivation pure |\n| `effect()` | react to dependency reads | sync | dispose handle or return cleanup |\n| `batch()` | coalesce synchronous writes | sync | does not roll back writes |\n| `createscope()` | group owned reactive work | sync | call `run()` to activate it |\n| `untrack()` | read without tracking | sync | read still happens immediately |\n| `watch()` | observe selected output | sync | use `effect()` for broad reads |\n| `resource()` | load async source | async | read dependencies in source callback |\n| `createstore()` | hold replacement based state | sync | return replacement objects from updates |\n| `isreactive()` | test `readable` identity | sync | does not test arbitrary objects |\n\n## package entry point\n\n| import | purpose |\n| | |\n| `@vielzeug/ripple` | default graph apis, isolated graph factory, types, and errors |\n| `@vielzeug/ripple/watch` | `watch()` and `watchoptions` |\n| `@vielzeug/ripple/async` | `resource()`, `resource`, `asyncstate`, `resourceoptions` |\n| `@vielzeug/ripple/store` | `createstore()`, `store`, `storeoptions` |\n\n## graph creation\n\n### `createripple(options?)`\n\n```ts\nfunction createripple(options?: rippleoptions): ripple;\n```\n\ncreates one isolated reactive graph. factories on the returned object share scheduling, ownership, observer, and error boundaries. `dispose()` is terminal: `ripple.disposed` becomes `true`, existing owned work is disposed, and creating more graph work throws `rippledisposedruntimeerror`. create a new graph for a new lifetime.\n\n| parameter | type | description |\n| | | |\n| `options.onerror` | `(error, context) => void` | receives effect, cleanup, listener, or observer failures. |\n| `options.observer` | `reactiveobserver` | receives graph events. |\n\n**returns:** `ripple`.\n\n**example:**\n\n```ts\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple();\nconst count = ripple.signal(0);\nconst stop = ripple.effect(() => console.log(count.value));\n\nstop.dispose();\nripple.dispose();\n```\n\n \n\n### `isreactive(value)`\n\n```ts\nfunction isreactive<t>(value: t | readable<t>): value is readable<t>;\n```\n\ntests whether a value is a ripple readable node.\n\n**returns:** `true` for a `signal`, computed value, or other `readable` node.\n\n**example:**\n\n```ts\nimport { isreactive, signal } from '@vielzeug/ripple';\n\nconsole.log(isreactive(signal(0)));\n```\n\n## default graph functions\n\n### `signal(initial, options?)`\n\n```ts\nfunction signal<t>(initial: t, options?: signaloptions<t>): signal<t>;\n```\n\ncreates writable state on the default graph.\n\n**returns:** `signal<t>`.\n\n**example:**\n\n```ts\nimport { signal } from '@vielzeug/ripple';\n\nconst count = signal(0);\ncount.value += 1;\n```\n\n \n\n### `computed(derive, options?)`\n\n```ts\nfunction computed<t>(derive: () => t, options?: computedoptions<t>): readable<t>;\n```\n\ncreates a lazy read only value from reactive reads in `derive`.\n\n**returns:** `readable<t>`.\n\n**example:**\n\n```ts\nimport { computed, signal } from '@vielzeug/ripple';\n\nconst count = signal(2);\nconst doubled = computed(() => count.value * 2);\nconsole.log(doubled.value);\n```\n\n \n\n### `effect(callback, options?)`\n\n```ts\nfunction effect(callback: () => cleanup | void, options?: effectoptions): effecthandle;\n```\n\nruns immediately and reruns when its tracked reads change. a returned cleanup runs before the next callback or disposal.\n\n**returns:** `effecthandle`.\n\n**example:**\n\n```ts\nimport { effect, signal } from '@vielzeug/ripple';\n\nconst connected = signal(false);\nconst stop = effect(() => {\n if (!connected.value) return;\n\n return () => console.log('disconnect');\n});\n\nstop.dispose();\n```\n\n \n\n### `batch(fn)` and `untrack(fn)`\n\n```ts\nfunction batch<t>(fn: () => t): t;\nfunction untrack<t>(fn: () => t): t;\n```\n\n`batch()` defers effects and listeners until its callback returns. `untrack()` reads current state without adding dependencies to an enclosing effect.\n\n**returns:** the callback result.\n\n**example:**\n\n```ts\nimport { batch, signal, untrack } from '@vielzeug/ripple';\n\nconst first = signal('ada');\nconst last = signal('lovelace');\nconst locale = signal('en us');\n\nbatch(() => {\n first.value = 'grace';\n last.value = 'hopper';\n});\n\nconsole.log(untrack(() => locale.value));\n```\n\n \n\n### `createscope(name?)`\n\n```ts\nfunction createscope(name?: string): scope;\n```\n\ncreates a disposable ownership boundary. work created inside `scope.run()` belongs to that scope.\n\n**returns:** `scope`.\n\n**example:**\n\n```ts\nimport { createscope, effect, signal } from '@vielzeug/ripple';\n\nconst scope = createscope('panel');\nconst count = signal(0);\n\nscope.run(() => effect(() => console.log(count.value)));\nscope.dispose();\n```\n\n## watch, resources, and stores\n\n### `watch(source, callback, options?)`\n\n```ts\nfunction watch<t>(\n source: readable<t> | (() => t),\n callback: (value: t, previous: t | undefined) => void,\n options?: watchoptions<t>,\n): effecthandle;\n```\n\nobserves selected output changes using the default graph or a `ripple.watch()` method.\n\n**returns:** `effecthandle`.\n\n**example:**\n\n```ts\nimport { signal } from '@vielzeug/ripple';\nimport { watch } from '@vielzeug/ripple/watch';\n\nconst count = signal(0);\nconst stop = watch(count, (value, previous) => console.log(previous, value), { immediate: true });\nstop.dispose();\n```\n\n \n\n### `resource(source, loader, options?)`\n\n```ts\nfunction resource<source, value>(\n source: () => source,\n loader: (source: source, context: { readonly signal: abortsignal }) => promise<value>,\n options?: resourceoptions,\n): resource<value>;\n```\n\ntracks `source`, aborts stale loader work, and exposes `asyncstate<value>`. source and loader failures become `status: 'error'` state; handle them from `resource.value` rather than `rippleoptions.onerror`, which is reserved for runtime callback, cleanup, listener, and observer failures.\n\n**returns:** `resource<value>`.\n\n**example:**\n\n```ts\nimport { signal } from '@vielzeug/ripple';\nimport { resource } from '@vielzeug/ripple/async';\n\nconst userid = signal('42');\nconst user = resource(() => userid.value, async (id) => ({ id }));\n\nif (user.value.status === 'error') console.error(user.value.error);\nuser.dispose();\n```\n\n \n\n### `createstore(initial, options?)`\n\n```ts\nfunction createstore<t>(initial: t, options?: storeoptions): store<t>;\n```\n\ncreates one writable value wrapper with explicit `set()` and `update()` operations.\n\n**returns:** `store<t>`.\n\n**example:**\n\n```ts\nimport { createstore } from '@vielzeug/ripple/store';\n\nconst user = createstore({ name: 'ada', visits: 0 });\nuser.update((value) => ({ ...value, visits: value.visits + 1 }));\n```\n\n## types\n\n```ts\ntype cleanup = () => void;\ntype equality<t> = (previous: t, next: t) => boolean;\ntype unsubscribe = () => void;\n\ntype signaloptions<t> = { equals?: equality<t>; name?: string };\ntype computedoptions<t> = { equals?: equality<t>; name?: string };\ntype effectoptions = { name?: string; scheduler?: 'microtask' | 'sync' };\ntype watchoptions<t> = { equals?: equality<t>; immediate?: boolean; name?: string; once?: boolean };\ntype resourceoptions = { name?: string };\ntype storeoptions = { name?: string };\n\ntype reactiveevent =\n | { readonly kind: 'compute'; readonly name?: string }\n | { readonly kind: 'effect'; readonly name?: string }\n | { readonly kind: 'write'; readonly name?: string; readonly next: unknown; readonly previous: unknown }\n | { readonly kind: 'dispose'; readonly name?: string; readonly node: 'effect' | 'scope' };\n\ntype reactiveobserver = (event: reactiveevent) => void;\ntype reactiveerrorcontext = { readonly kind: 'cleanup' | 'effect' | 'listener' | 'observer'; readonly name?: string };\ntype rippleoptions = { observer?: reactiveobserver; onerror?: (error: unknown, context: reactiveerrorcontext) => void };\n\ntype asyncstate<t> =\n | { readonly previous?: t; readonly status: 'pending' }\n | { readonly status: 'success'; readonly value: t }\n | { readonly error: unknown; readonly previous?: t; readonly status: 'error' };\n\ninterface readable<t> {\n readonly name?: string;\n peek(): t;\n subscribe(listener: () => void): unsubscribe;\n readonly value: t;\n}\n\ninterface signal<t> extends readable<t> { value: t }\ninterface disposable { dispose(): void; readonly disposed: boolean; readonly disposalsignal: abortsignal; [symbol.dispose](): void }\ntype effecthandle = disposable;\ninterface scope extends disposable { run<t>(fn: () => t): t }\n\ninterface resource<t> extends readable<asyncstate<t>>, disposable { reload(): void }\ninterface store<t> extends readable<t> { set(value: t): void; update(updater: (value: t) => t): void }\n\ninterface ripple {\n batch<t>(fn: () => t): t;\n computed<t>(derive: () => t, options?: computedoptions<t>): readable<t>;\n createscope(name?: string): scope;\n createstore<t>(initial: t, options?: storeoptions): store<t>;\n dispose(): void;\n readonly disposed: boolean;\n effect(callback: () => cleanup | void, options?: effectoptions): effecthandle;\n resource<source, value>(source: () => source, loader: (source: source, context: { readonly signal: abortsignal }) => promise<value>, options?: resourceoptions): resource<value>;\n signal<t>(initial: t, options?: signaloptions<t>): signal<t>;\n untrack<t>(fn: () => t): t;\n watch<t>(source: readable<t> | (() => t), callback: (value: t, previous: t | undefined) => void, options?: watchoptions<t>): effecthandle;\n}\n```\n\n## errors\n\n| error | trigger | notable properties |\n| | | |\n| `rippleerror` | base ripple error | `rippleerror.is(error)` narrows unknown values. |\n| `ripplecomputedcycleerror` | computed dependency reads itself through a cycle | extends `rippleerror`. |\n| `rippledisposedruntimeerror` | factory or execution api used after `ripple.dispose()` | extends `rippleerror`. |\n| `rippledisposedscopeerror` | `scope.run()` after scope disposal | extends `rippleerror`. |\n| `rippleinfinitelooperror` | effect flush exceeds graph iteration limit | extends `rippleerror`. |\n",
888
+ "usage": " \ntitle: ripple — usage guide\ndescription: build reactive state with one explicit graph boundary.\n \n\n[[toc]]\n\n## basic usage\n\nuse top level functions when one application lifetime graph is sufficient. read a signal inside an effect to make that read reactive.\n\n```ts\nimport { computed, effect, signal } from '@vielzeug/ripple';\n\nconst count = signal(0);\nconst label = computed(() => `count: ${count.value}`);\nconst stop = effect(() => console.log(label.value));\n\ncount.value = 1;\nstop.dispose();\n```\n\n## isolated graphs\n\nuse `createripple()` for tests, ssr requests, embedded applications, or independently disposable features. never mix reactive values from separate graphs.\n\n```ts\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple({\n onerror(error, context) {\n console.log(context.kind, error);\n },\n});\n\nconst count = ripple.signal(0);\nconst stop = ripple.effect(() => console.log(count.value));\n\nstop.dispose();\nripple.dispose();\n```\n\n## derived values and batches\n\nuse `computed()` for pure derivation. use `untrack()` when a current read must not become an effect dependency. use `batch()` for related synchronous writes.\n\n```ts\nconst first = ripple.signal('ada');\nconst last = ripple.signal('lovelace');\nconst locale = ripple.signal('en us');\nconst name = ripple.computed(() => `${first.value} ${last.value}`);\n\nripple.effect(() => {\n console.log({ locale: ripple.untrack(() => locale.value), name: name.value });\n});\n\nripple.batch(() => {\n first.value = 'grace';\n last.value = 'hopper';\n});\n```\n\n## ownership with scopes\n\ncreate a scope when a group of effects or derived values shares one lifetime. dispose the scope when its feature ends.\n\n```ts\nconst scope = ripple.createscope('panel');\nconst count = ripple.signal(0);\n\nscope.run(() => {\n ripple.effect(() => console.log(`panel count: ${count.value}`));\n});\n\ncount.value = 1;\nscope.dispose();\n```\n\n## watch selected values\n\nuse `watch()` for one selected output. use `effect()` when every reactive read in the callback should be a dependency.\n\n```ts\nconst stopwatch = ripple.watch(\n () => `${first.value} ${last.value}`,\n (value, previous) => console.log({ previous, value }),\n { immediate: true },\n);\n\nstopwatch.dispose();\n```\n\n## async data\n\n`resource()` captures source dependencies synchronously and passes a cancellation signal to the loader.\n\n```ts\nconst userid = ripple.signal('42');\nconst user = ripple.resource(\n () => userid.value,\n async (id, { signal }) => {\n const response = await fetch(`/users/${id}`, { signal });\n if (!response.ok) throw new error(`request failed: ${response.status}`);\n\n return response.json() as promise<{ id: string; name: string }>;\n },\n);\n\nif (user.value.status === 'success') console.log(user.value.value.name);\nif (user.value.status === 'error') console.error(user.value.error);\nuser.dispose();\n```\n\n## object state\n\n`createstore()` holds one value and exposes `set()` and `update()`. return replacement objects from `update()` when object consumers depend on immutable updates.\n\n```ts\nconst cart = ripple.createstore({ items: 0, label: 'empty' });\nconst items = ripple.computed(() => cart.value.items);\n\ncart.update((state) => ({ ...state, items: state.items + 1 }));\ncart.set({ items: 3, label: 'ready' });\n\nconsole.log(items.value);\n```\n\n## testing\n\ncreate an isolated graph per test. disposal prevents effects and resource work from leaking into later tests.\n\n```ts\nimport { expect, test } from 'vitest';\nimport { createripple } from '@vielzeug/ripple';\n\ntest('derives a doubled count', () => {\n const ripple = createripple();\n const count = ripple.signal(2);\n const doubled = ripple.computed(() => count.value * 2);\n\n expect(doubled.value).tobe(4);\n ripple.dispose();\n});\n```\n\n## framework integration\n\nuse signals and effects with any renderer. dispose component owned effects when the component unmounts.\n\n::: code group\n\n```ts [react]\nimport { useeffect, usestate } from 'react';\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple();\nconst count = ripple.signal(0);\n\nexport function counter() {\n const [, rerender] = usestate(0);\n\n useeffect(() => {\n const stop = ripple.effect(() => {\n void count.value;\n rerender((revision) => revision + 1);\n });\n\n return () => stop.dispose();\n }, []);\n\n return <button onclick={() => (count.value += 1)}>{count.value}</button>;\n}\n```\n\n```ts [vue 3]\nimport { onunmounted, ref } from 'vue';\nimport { createripple } from '@vielzeug/ripple';\n\nconst ripple = createripple();\nconst count = ripple.signal(0);\nconst revision = ref(0);\nconst stop = ripple.effect(() => {\n void count.value;\n revision.value++;\n});\n\nonunmounted(() => stop.dispose());\n```\n\n```ts [svelte]\n<script lang=\"ts\">\n import { ondestroy } from 'svelte';\n import { createripple } from '@vielzeug/ripple';\n\n const ripple = createripple();\n const count = ripple.signal(0);\n let revision = 0;\n const stop = ripple.effect(() => {\n void count.value;\n revision++;\n });\n\n ondestroy(() => stop.dispose());\n</script>\n\n<button on:click={() => (count.value += 1)}>{count.value}</button>\n```\n\n:::\n\n## working with other vielzeug libraries\n\nore uses ripple for component reactivity. clockwork actors expose framework neutral snapshots; bridge actor subscriptions into a ripple signal. ledger adds undo/redo commands around state changes without replacing graph.\n\n```ts\nimport { createripple } from '@vielzeug/ripple';\nimport { definemachine } from '@vielzeug/clockwork';\n\nconst ripple = createripple();\nconst actor = definemachine<record<string, never>, { type: 'start' }>()({\n initial: 'idle',\n states: { active: {}, idle: { on: { start: { target: 'active' } } } },\n}).createactor();\n\nconst snapshot = ripple.signal(actor.snapshot);\nconst stop = actor.subscribe((next) => (snapshot.value = next));\nconst status = ripple.computed(() => snapshot.value.state);\nconsole.log(status.value);\n\nstop();\nactor.dispose();\nripple.dispose();\n```\n\n## best practices\n\n create one graph per ownership boundary.\n keep computed callbacks pure.\n return cleanup from effects.\n dispose request, test, and feature graphs.\n batch related synchronous writes.\n use `watch()` only for selected source transitions.\n read dependencies in a resource source, not its loader.\n use `onerror` for runtime callback, cleanup, listener, and observer failures; handle resource source and loader failures through `resource.value.status === 'error'`.\n",
889
889
  "examples": " \ntitle: ripple — examples\ndescription: practical ripple recipes.\n \n\n## examples\n\n [reactive counter](./examples/reactive counter.md)\n [batch and untrack](./examples/batch and untrack.md)\n [scope ownership](./examples/scope ownership.md)\n [watch selected value](./examples/watch selected value.md)\n [replacement based store](./examples/immutable store.md)\n [isolated graph](./examples/isolated runtime.md)\n [async resource](./examples/async resource.md)\n"
890
890
  },
891
891
  "examples": [
@@ -918,12 +918,12 @@
918
918
  "text": "watch selected value import { createripple } from '@vielzeug/ripple'\n\n// watch receives selected value transitions, not every graph update.\nconst ripple = createripple()\nconst first = ripple.signal('ada')\nconst last = ripple.signal('lovelace')\nconst fullname = ripple.computed(() => first.value + ' ' + last.value)\n\nconst stop = ripple.watch(fullname, (value, previous) => {\n console.log({ previous, value })\n}, { immediate: true })\n\nfirst.value = 'grace'\nlast.value = 'hopper'\n\nstop.dispose()\nripple.dispose()"
919
919
  }
920
920
  ],
921
- "exports": "createripple signal computed effect batch createscope createstore resource untrack watch isreactive",
921
+ "exports": "createripple signal computed effect batch createscope untrack isreactive",
922
922
  "keywords": "reactive signals computed effects graph scope batch async",
923
923
  "name": "@vielzeug/ripple",
924
924
  "related": "ore clockwork ledger",
925
925
  "slug": "ripple",
926
- "source": "export type {\n cleanup,\n computedoptions,\n disposable,\n effecthandle,\n effectoptions,\n equality,\n reactiveerrorcontext,\n reactiveevent,\n reactiveobserver,\n readable,\n rippleoptions,\n scope,\n signal,\n signaloptions,\n unsubscribe,\n} from './types';\n\nexport { ripplecomputedcycleerror, rippledisposedscopeerror, rippleerror, rippleinfinitelooperror } from './errors';\nexport { isreactive } from './runtime';\n\nimport type {\n cleanup,\n computedoptions,\n effecthandle,\n effectoptions,\n readable,\n rippleoptions,\n scope,\n signal,\n signaloptions,\n} from './types';\n\nimport { createresource, type resource, type resourceoptions } from './_async';\nimport { createstore as createstorefactory, type store, type storeoptions } from './_store';\nimport { createwatch, type watchoptions } from './_watch';\nimport { reactiveruntime } from './runtime';\n\nexport interface ripple {\n batch<t>(fn: () => t): t;\n computed<t>(derive: () => t, options?: computedoptions<t>): readable<t>;\n createscope(name?: string): scope;\n createstore<t>(initial: t, options?: storeoptions): store<t>;\n dispose(): void;\n effect(callback: () => cleanup | void, options?: effectoptions): effecthandle;\n resource<source, value>(\n source: () => source,\n loader: (source: source, context: { readonly signal: abortsignal }) => promise<value>,\n options?: resourceoptions,\n ): resource<value>;\n signal<t>(initial: t, options?: signaloptions<t>): signal<t>;\n untrack<t>(fn: () => t): t;\n watch<t>(\n source: readable<t> | (() => t),\n callback: (value: t, previous: t | undefined) => void,\n options?: watchoptions<t>,\n ): effecthandle;\n}\n\n/** creates one complete reactive graph. all factories on the object share its runtime. */\nexport const createripple = (options?: rippleoptions): ripple => {\n const runtime = new reactiveruntime(options);\n const resource = createresource(runtime);\n const createstore = createstorefactory(runtime);\n\n return {\n batch: runtime.batch,\n computed: runtime.computed,\n createscope: runtime.createscope,\n createstore,\n dispose: () => runtime.dispose(),\n effect: runtime.effect,\n resource,\n signal: runtime.signal,\n untrack: runtime.untrack,\n watch: createwatch(runtime),\n };\n};\n\nconst defaultripple = createripple();\n\nexport const signal = defaultripple.signal;\nexport const computed = defaultripple.computed;\nexport const effect = defaultripple.effect;\nexport const batch = defaultripple.batch;\nexport const createscope = defaultripple.createscope;\nexport const createstore = defaultripple.createstore;\nexport const resource = defaultripple.resource;\nexport const untrack = defaultripple.untrack;\nexport const watch = defaultripple.watch;\n"
926
+ "source": "export type {\n cleanup,\n computedoptions,\n disposable,\n effecthandle,\n effectoptions,\n equality,\n reactiveerrorcontext,\n reactiveevent,\n reactiveobserver,\n readable,\n rippleoptions,\n scope,\n signal,\n signaloptions,\n unsubscribe,\n} from './types';\n\nexport {\n ripplecomputedcycleerror,\n rippledisposedruntimeerror,\n rippledisposedscopeerror,\n rippleerror,\n rippleinfinitelooperror,\n} from './errors';\nexport { isreactive } from './runtime';\n\nexport { createripple, type ripple } from './_default';\n\nimport { defaultripple } from './_default';\n\n// `resource`/`createstore`/`watch` are deliberately not re exported here they're reachable\n// only through their dedicated subpaths (`./async`, `./store`, `./watch`), so there's exactly\n// one canonical import path per primitive instead of two that resolve to the same binding.\nexport const signal = defaultripple.signal;\nexport const computed = defaultripple.computed;\nexport const effect = defaultripple.effect;\nexport const batch = defaultripple.batch;\nexport const createscope = defaultripple.createscope;\nexport const untrack = defaultripple.untrack;\n"
927
927
  },
928
928
  {
929
929
  "category": "logging",
package/dist/http.js CHANGED
@@ -49,8 +49,14 @@ export async function startHttpHost(options) {
49
49
  const host = options.host ?? '127.0.0.1';
50
50
  // Stateless by default (SEP-2575): a fresh server instance per request, matching the
51
51
  // spec's "any request can land on any instance" design — codex's tools carry no
52
- // per-connection state, so there's nothing a persistent instance would buy here.
53
- const handler = createMcpHandler(() => createMcpServer(options.catalog, { debug: options.debug, version: options.version }));
52
+ // per-connection state, so a persistent instance buys nothing beyond a small, negligible
53
+ // (13-tool catalog) reconstruction cost per request.
54
+ const factory = () => createMcpServer(options.catalog, { debug: options.debug, version: options.version });
55
+ // `createMcpHandler()`'s factory only runs lazily, on the first real request — call it once
56
+ // eagerly here so a broken catalog/registration setup fails `startHttpHost()` itself, before
57
+ // the port opens, matching the old eager `mcpServer.connect()` fail-fast guarantee.
58
+ factory();
59
+ const handler = createMcpHandler(factory);
54
60
  const httpServer = createServer((request, response) => {
55
61
  if (request.method === 'GET' && request.url === '/health') {
56
62
  response.writeHead(200, { 'content-type': 'application/json; charset=utf-8' });
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAuB,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,YAAY,EAAwE,MAAM,WAAW,CAAC;AAC/G,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAIhD,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAiB9C,SAAS,KAAK,CAAC,MAAkB;IAC/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,mBAAmB,EAAE,EAAE,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,OAAwB;IAC5C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAElC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,KAAK,MAAM,KAAK,IAAI,KAAK;gBAAE,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;;YAC3E,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC;IAEtE,OAAO,IAAI,OAAO,CAAC,UAAU,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,EAAE;QAChF,GAAG,CAAC,OAAO,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAmB,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACnF,OAAO;QACP,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;AACL,CAAC;AAED,uGAAuG;AACvG,KAAK,UAAU,eAAe,CAAC,WAAqB,EAAE,QAAwB;IAC5E,QAAQ,CAAC,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC;IAEzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,WAAW,CAAC,OAAO;QAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAElF,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QACtB,QAAQ,CAAC,GAAG,EAAE,CAAC;QAEf,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC/D,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAwB;IAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IACzC,qFAAqF;IACrF,gFAAgF;IAChF,iFAAiF;IACjF,MAAM,OAAO,GAAmB,gBAAgB,CAAC,GAAG,EAAE,CACpD,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CACrF,CAAC;IACF,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QACpD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC1D,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,iCAAiC,EAAE,CAAC,CAAC;YAC/E,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAEzE,OAAO;QACT,CAAC;QAED,OAAO;aACJ,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;aAC5B,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,eAAe,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;aAC7D,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxB,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;gBAC1B,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,iCAAiC,EAAE,CAAC,CAAC;gBAC/E,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC;YAChE,CAAC;iBAAM,IAAI,CAAC,QAAQ,CAAC,aAAa;gBAAE,QAAQ,CAAC,GAAG,EAAE,CAAC;YAEnD,GAAG,CAAC,mBAAmB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,OAAO,GAAG,KAAK,IAAmB,EAAE;QACxC,IAAI,QAAQ;YAAE,OAAO;QAErB,QAAQ,GAAG,IAAI,CAAC;QAEhB,IAAI,CAAC;YACH,IAAI,SAAS;gBAAE,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACjC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;gBACzC,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAChC,SAAS,GAAG,IAAI,CAAC;gBACjB,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,EAAE,CAAC;QAChB,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IAElF,GAAG,CAAC,2CAA2C,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC;IAEhE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC;AACjE,CAAC"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vielzeug/codex",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "description": "MCP server that exposes the vielzeug ecosystem to AI assistants — run locally over stdio or remotely over HTTP",
6
6
  "exports": {
@@ -18,7 +18,7 @@
18
18
  "node": ">=22"
19
19
  },
20
20
  "scripts": {
21
- "build": "tsc",
21
+ "build": "rm -rf dist && tsc",
22
22
  "dev": "node --experimental-strip-types ./scripts/dev.ts",
23
23
  "fix": "eslint --fix src",
24
24
  "gen:tool-docs": "node --experimental-strip-types ./scripts/generate-tool-docs.ts",
@@ -1,346 +0,0 @@
1
- import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
- import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
3
- import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
4
- import { dirname, resolve } from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
- import { afterEach, beforeAll, describe, expect, it } from 'vitest';
7
- import { loadData } from '../data.js';
8
- import { createServer } from '../server.js';
9
- import { SCHEMA_VERSION } from '../types.js';
10
- let data;
11
- const activeClients = [];
12
- const __dirname = dirname(fileURLToPath(import.meta.url));
13
- const dataFile = resolve(__dirname, '../../data/vielzeug-data.json');
14
- beforeAll(async () => {
15
- // Regenerate if missing or if loadData throws (e.g. schema version mismatch from stale file)
16
- const needsRegen = !existsSync(dataFile) ||
17
- (() => {
18
- try {
19
- loadData();
20
- return false;
21
- }
22
- catch {
23
- return true;
24
- }
25
- })();
26
- if (needsRegen) {
27
- // Import the generator function directly — faster than spawning a subprocess
28
- const { generateBundledData } = await import("../../scripts/generator.js");
29
- const { data: generated } = generateBundledData({ incremental: false });
30
- mkdirSync(dirname(dataFile), { recursive: true });
31
- writeFileSync(dataFile, `${JSON.stringify(generated, null, 2)}\n`, 'utf8');
32
- }
33
- data = loadData();
34
- });
35
- afterEach(async () => {
36
- const clients = activeClients.splice(0);
37
- for (const client of clients) {
38
- await client.close();
39
- }
40
- });
41
- async function createTestPair() {
42
- const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
43
- const server = createServer(data);
44
- await server.connect(serverTransport);
45
- const client = new Client({ name: 'test-client', version: '1.0.0' });
46
- await client.connect(clientTransport);
47
- activeClients.push(client);
48
- return { client, server };
49
- }
50
- function readText(result) {
51
- return result.content[0]?.text ?? '';
52
- }
53
- describe('vielzeug MCP server', () => {
54
- it('registers seven tools', async () => {
55
- const { client } = await createTestPair();
56
- const { tools } = await client.listTools();
57
- const names = tools.map((t) => t.name).sort();
58
- expect(names).toEqual([
59
- 'get-component',
60
- 'get-docs',
61
- 'get-package',
62
- 'get-source',
63
- 'list-components',
64
- 'list-packages',
65
- 'search-packages',
66
- ]);
67
- });
68
- it('get-docs page enum only includes doc pages, not source', async () => {
69
- const { client } = await createTestPair();
70
- const { tools } = await client.listTools();
71
- const tool = tools.find((t) => t.name === 'get-docs');
72
- expect(tool).toBeDefined();
73
- const schema = tool?.inputSchema;
74
- expect(schema.properties['page'].enum).toEqual(['index', 'api', 'usage', 'examples']);
75
- expect(schema.properties['page'].enum).not.toContain('source');
76
- expect(schema.required).toContain('packageSlug');
77
- });
78
- it('list-packages returns all packages without internal docs payload', async () => {
79
- const { client } = await createTestPair();
80
- const result = (await client.callTool({ arguments: {}, name: 'list-packages' }));
81
- const parsed = JSON.parse(readText(result));
82
- expect(Array.isArray(parsed)).toBe(true);
83
- expect(parsed.length).toBeGreaterThan(0);
84
- expect(parsed[0]).toHaveProperty('name');
85
- expect(parsed[0]).toHaveProperty('availableDocPages');
86
- expect(parsed[0]).toHaveProperty('hasSource');
87
- expect(parsed[0]).not.toHaveProperty('docs');
88
- expect(parsed[0]).not.toHaveProperty('apiSource');
89
- });
90
- it('get-package returns a single PackageMeta object', async () => {
91
- const { client } = await createTestPair();
92
- const result = (await client.callTool({
93
- arguments: { packageSlug: 'spell' },
94
- name: 'get-package',
95
- }));
96
- const parsed = JSON.parse(readText(result));
97
- expect(result.isError).not.toBe(true);
98
- expect(parsed['slug']).toBe('spell');
99
- expect(parsed).toHaveProperty('hasSource');
100
- expect(parsed).not.toHaveProperty('docs');
101
- });
102
- it('get-package with unknown slug returns an error', async () => {
103
- const { client } = await createTestPair();
104
- const result = (await client.callTool({
105
- arguments: { packageSlug: 'does-not-exist' },
106
- name: 'get-package',
107
- }));
108
- expect(result.isError).toBe(true);
109
- });
110
- it('get-docs reads a doc page', async () => {
111
- const { client } = await createTestPair();
112
- const result = (await client.callTool({
113
- arguments: { packageSlug: 'spell', page: 'api' },
114
- name: 'get-docs',
115
- }));
116
- expect(result.isError).not.toBe(true);
117
- expect(readText(result).length).toBeGreaterThan(0);
118
- });
119
- it('get-source returns the src/index.ts content', async () => {
120
- const { client } = await createTestPair();
121
- const result = (await client.callTool({
122
- arguments: { packageSlug: 'spell' },
123
- name: 'get-source',
124
- }));
125
- expect(result.isError).not.toBe(true);
126
- expect(readText(result)).toContain('export');
127
- });
128
- it('get-docs rejects source as a page value', async () => {
129
- const { client } = await createTestPair();
130
- const result = (await client.callTool({
131
- arguments: { packageSlug: 'spell', page: 'source' },
132
- name: 'get-docs',
133
- }));
134
- expect(result.isError).toBe(true);
135
- });
136
- it('get-source returns isError for a package with no source', async () => {
137
- // codex has no apiSource bundled (it's the MCP server itself, not a browser-accessible lib)
138
- const { client } = await createTestPair();
139
- const pkgMetas = JSON.parse(readText((await client.callTool({ arguments: {}, name: 'list-packages' }))));
140
- const noSourceSlug = pkgMetas.find((p) => !p.hasSource)?.slug;
141
- if (!noSourceSlug)
142
- return; // all packages have source — skip
143
- const result = (await client.callTool({
144
- arguments: { packageSlug: noSourceSlug },
145
- name: 'get-source',
146
- }));
147
- expect(result.isError).toBe(true);
148
- expect(readText(result)).toContain('no src/index.ts source');
149
- });
150
- it('search-packages results include a name field on each hit', async () => {
151
- const { client } = await createTestPair();
152
- const result = (await client.callTool({
153
- arguments: { query: 'signal' },
154
- name: 'search-packages',
155
- }));
156
- expect(result.isError).not.toBe(true);
157
- const hits = JSON.parse(readText(result));
158
- expect(hits.length).toBeGreaterThan(0);
159
- expect(typeof hits[0]?.['name']).toBe('string');
160
- expect((hits[0]?.['name']).length).toBeGreaterThan(0);
161
- });
162
- it('search-packages returns source in matchedIn when query matches apiSource', async () => {
163
- const { client } = await createTestPair();
164
- // 'createServer' is only in codex apiSource — a reliable source-only match
165
- const result = (await client.callTool({
166
- arguments: { query: 'createServer' },
167
- name: 'search-packages',
168
- }));
169
- expect(result.isError).not.toBe(true);
170
- const hits = JSON.parse(readText(result));
171
- const codexHit = hits.find((h) => h.slug === 'codex');
172
- // codex may or may not have apiSource in the snapshot — test defensively
173
- if (codexHit) {
174
- expect(codexHit.matchedIn).toContain('source');
175
- }
176
- });
177
- it('search-packages returns empty array for no matches', async () => {
178
- const { client } = await createTestPair();
179
- const result = (await client.callTool({
180
- arguments: { query: 'zzz_no_match_xyz_' },
181
- name: 'search-packages',
182
- }));
183
- expect(result.isError).not.toBe(true);
184
- expect(JSON.parse(readText(result))).toEqual([]);
185
- });
186
- it('search-packages results have matchedIn as an array and a numeric score', async () => {
187
- const { client } = await createTestPair();
188
- const result = (await client.callTool({
189
- arguments: { query: 'signal' },
190
- name: 'search-packages',
191
- }));
192
- expect(result.isError).not.toBe(true);
193
- const hits = JSON.parse(readText(result));
194
- expect(hits.length).toBeGreaterThan(0);
195
- expect(Array.isArray(hits[0]?.['matchedIn'])).toBe(true);
196
- expect(typeof hits[0]?.['score']).toBe('number');
197
- expect(hits[0]?.['score']).toBeGreaterThan(0);
198
- });
199
- it('search-packages scores name matches higher than description matches', async () => {
200
- // ripple matches by name — should score higher than a package that only matches in description
201
- const { client } = await createTestPair();
202
- const result = (await client.callTool({
203
- arguments: { query: 'ripple' },
204
- name: 'search-packages',
205
- }));
206
- expect(result.isError).not.toBe(true);
207
- const hits = JSON.parse(readText(result));
208
- const rippleHit = hits.find((h) => h.slug === 'ripple');
209
- if (rippleHit) {
210
- // name match weight (3.9) is highest in metadata tier
211
- expect(rippleHit.score).toBeGreaterThanOrEqual(3.9);
212
- }
213
- });
214
- it('list-components and get-component work when sigil metadata is available', async () => {
215
- const { client } = await createTestPair();
216
- const listResult = (await client.callTool({ arguments: {}, name: 'list-components' }));
217
- if (listResult.isError) {
218
- expect(readText(listResult)).toContain('Sigil component metadata is unavailable');
219
- return;
220
- }
221
- const tags = JSON.parse(readText(listResult));
222
- expect(Array.isArray(tags)).toBe(true);
223
- expect(tags.length).toBeGreaterThan(0);
224
- const firstTag = tags[0]?.tagName;
225
- expect(typeof firstTag).toBe('string');
226
- const componentResult = (await client.callTool({
227
- arguments: { tagName: firstTag },
228
- name: 'get-component',
229
- }));
230
- expect(componentResult.isError).not.toBe(true);
231
- expect(readText(componentResult)).toContain(firstTag);
232
- });
233
- it('get-docs defaults to index page when page is omitted', async () => {
234
- const { client } = await createTestPair();
235
- const withPage = (await client.callTool({
236
- arguments: { packageSlug: 'spell', page: 'index' },
237
- name: 'get-docs',
238
- }));
239
- const withoutPage = (await client.callTool({
240
- arguments: { packageSlug: 'spell' },
241
- name: 'get-docs',
242
- }));
243
- expect(withPage.isError).not.toBe(true);
244
- expect(withoutPage.isError).not.toBe(true);
245
- expect(readText(withoutPage)).toBe(readText(withPage));
246
- });
247
- it('get-docs error lists available pages when requested page is missing', async () => {
248
- const { client } = await createTestPair();
249
- const result = (await client.callTool({
250
- // 'source' is not a valid page enum value — triggers the enum-validation error
251
- arguments: { packageSlug: 'spell', page: 'source' },
252
- name: 'get-docs',
253
- }));
254
- expect(result.isError).toBe(true);
255
- expect(readText(result)).toMatch(/index|api|usage|examples/);
256
- });
257
- it('unknown tool returns MethodNotFound error', async () => {
258
- const { client } = await createTestPair();
259
- await expect(client.callTool({ arguments: {}, name: 'no-such-tool' })).rejects.toThrow();
260
- });
261
- it('get-docs returns error when page enum is valid but package lacks that page', async () => {
262
- // Use a synthetic data fixture with only index page — guarantees the missing-page path always runs
263
- const syntheticData = {
264
- packages: [
265
- {
266
- apiSource: null,
267
- availableDocPages: ['index'],
268
- category: '',
269
- components: [],
270
- description: 'test',
271
- docs: { index: '# Test' },
272
- exports: [],
273
- keywords: [],
274
- name: '@vielzeug/synthetic',
275
- related: [],
276
- slug: 'synthetic',
277
- version: '1.0.0',
278
- },
279
- ],
280
- schemaVersion: SCHEMA_VERSION,
281
- version: '0.0.0',
282
- };
283
- const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
284
- const srv = createServer(syntheticData);
285
- await srv.connect(serverTransport);
286
- const client = new Client({ name: 'test-missing-page', version: '1.0.0' });
287
- await client.connect(clientTransport);
288
- activeClients.push(client);
289
- const result = (await client.callTool({
290
- arguments: { packageSlug: 'synthetic', page: 'examples' },
291
- name: 'get-docs',
292
- }));
293
- expect(result.isError).toBe(true);
294
- expect(readText(result)).toMatch(/Available/);
295
- });
296
- it('list-components returns error when Sigil CEM is absent', async () => {
297
- const dataWithNoSigil = {
298
- ...data,
299
- packages: data.packages.map((p) => (p.slug === 'sigil' ? { ...p, components: [] } : p)),
300
- };
301
- const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
302
- const srv = createServer(dataWithNoSigil);
303
- await srv.connect(serverTransport);
304
- const client = new Client({ name: 'test-no-sigil-list', version: '1.0.0' });
305
- await client.connect(clientTransport);
306
- activeClients.push(client);
307
- const result = (await client.callTool({ arguments: {}, name: 'list-components' }));
308
- expect(result.isError).toBe(true);
309
- expect(readText(result)).toContain('unavailable');
310
- });
311
- it('get-component returns error when Sigil CEM is absent', async () => {
312
- // components: [] causes ToolContext.components to be null (tools.ts checks length > 0)
313
- const dataWithNoSigil = {
314
- ...data,
315
- packages: data.packages.map((p) => (p.slug === 'sigil' ? { ...p, components: [] } : p)),
316
- };
317
- const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
318
- const srv = createServer(dataWithNoSigil);
319
- await srv.connect(serverTransport);
320
- const client = new Client({ name: 'test-no-sigil', version: '1.0.0' });
321
- await client.connect(clientTransport);
322
- activeClients.push(client);
323
- const result = (await client.callTool({
324
- arguments: { tagName: 'sg-button' },
325
- name: 'get-component',
326
- }));
327
- expect(result.isError).toBe(true);
328
- expect(readText(result)).toContain('unavailable');
329
- });
330
- it('search-packages returns error when query exceeds 500 chars', async () => {
331
- const { client } = await createTestPair();
332
- const longQuery = 'a'.repeat(501);
333
- const result = (await client.callTool({
334
- arguments: { query: longQuery },
335
- name: 'search-packages',
336
- }));
337
- expect(result.isError).toBe(true);
338
- expect(readText(result)).toContain('500');
339
- });
340
- it('get-package requires packageSlug', async () => {
341
- const { client } = await createTestPair();
342
- const result = (await client.callTool({ arguments: {}, name: 'get-package' }));
343
- expect(result.isError).toBe(true);
344
- });
345
- });
346
- //# sourceMappingURL=server.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../src/__tests__/server.test.ts"],"names":[],"mappings":"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"}