| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- import { pageMetadata } from "@/lib/page-metadata"
- export const metadata = pageMetadata("docs/api/devtools")
- # @json-render/devtools
- Framework-agnostic core for the json-render devtools — vanilla TS panel UI, event store, DOM picker, and stream tap utilities. Every framework-specific adapter package depends on this.
- Most users never import from this package directly. Pick the adapter that matches your renderer (`@json-render/devtools-react`, `@json-render/devtools-vue`, etc.) and drop the `<JsonRenderDevtools />` component into your app.
- See the [Devtools guide](/docs/devtools) for the drop-in walkthrough.
- ## Event Store
- ### createEventStore
- ```ts
- function createEventStore(options?: { bufferSize?: number }): EventStore
- interface EventStore {
- push: (event: DevtoolsEvent) => void;
- snapshot: () => DevtoolsEvent[];
- subscribe: (listener: () => void) => () => void;
- clear: () => void;
- size: () => number;
- }
- ```
- Ring-buffered pub/sub of `DevtoolsEvent`. Shared by every panel and every stream tap.
- ## Panel
- ### createPanel
- ```ts
- function createPanel(options: PanelOptions): PanelHandle
- interface PanelHandle {
- open: () => void;
- close: () => void;
- toggle: () => void;
- isOpen: () => boolean;
- refresh: () => void;
- destroy: () => void;
- }
- ```
- Mount the panel into a host document. Adapters call this internally.
- ### Panel tabs
- Each tab is a factory function that returns a `TabDef`:
- ```ts
- import {
- specTab,
- stateTab,
- actionsTab,
- streamTab,
- catalogTab,
- pickerTab,
- } from "@json-render/devtools";
- ```
- ## Stream Taps
- ### tapJsonRenderStream
- ```ts
- function tapJsonRenderStream(
- stream: ReadableStream<StreamChunk>,
- events: EventStore,
- ): ReadableStream<StreamChunk>
- ```
- Mirror the spec patches flowing through a `pipeJsonRender` transform into a devtools event store. Returns the original stream unchanged — the tap just forks a copy.
- ### tapYamlStream
- ```ts
- function tapYamlStream(
- stream: ReadableStream<StreamChunk>,
- events: EventStore,
- ): ReadableStream<StreamChunk>
- ```
- YAML equivalent of `tapJsonRenderStream`.
- ### scanMessageParts
- ```ts
- function scanMessageParts(
- parts: readonly DataPart[] | undefined,
- events: EventStore,
- seen: WeakSet<object>,
- ): void
- ```
- Client-side helper: scan an AI SDK message's `parts` array for spec data parts and push matching events into the store. Idempotent via `seen` — call it on every render of a chat UI.
- ## Picker
- ### startPicker
- ```ts
- function startPicker(options: PickerOptions): PickerSession | null
- interface PickerOptions {
- onPick: (key: string) => void;
- onCancel?: () => void;
- }
- ```
- Start a DOM picker session. Hovering paints an outline on any element carrying `data-jr-key`; clicking fires `onPick` with the spec key. Returns `null` in environments without a DOM.
- ### findElementByKey / highlightElement
- ```ts
- function findElementByKey(key: string): Element | null
- function highlightElement(key: string, durationMs?: number): void
- ```
- Look up the live DOM node for a spec element key, or briefly paint an outline around it.
- ## Types
- ### DevtoolsEvent
- ```ts
- type DevtoolsEvent =
- | { kind: "spec-changed"; at: number; spec: Spec }
- | { kind: "state-set"; at: number; path: string; prev: unknown; next: unknown }
- | { kind: "action-dispatched"; at: number; id: string; name: string; params?: unknown }
- | { kind: "action-settled"; at: number; id: string; ok: boolean; result?: unknown; error?: string; durationMs: number }
- | { kind: "stream-patch"; at: number; patch: JsonPatch; source: "json" | "yaml" }
- | { kind: "stream-text"; at: number; text: string }
- | { kind: "stream-usage"; at: number; usage: TokenUsage }
- | { kind: "stream-lifecycle"; at: number; phase: "start" | "end"; ok?: boolean };
- ```
- ### isProduction
- ```ts
- function isProduction(): boolean
- ```
- `true` when `process.env.NODE_ENV === "production"`. Adapters use this to short-circuit to a null render.
|