page.mdx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import { pageMetadata } from "@/lib/page-metadata"
  2. export const metadata = pageMetadata("docs/api/devtools")
  3. # @json-render/devtools
  4. 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.
  5. 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.
  6. See the [Devtools guide](/docs/devtools) for the drop-in walkthrough.
  7. ## Event Store
  8. ### createEventStore
  9. ```ts
  10. function createEventStore(options?: { bufferSize?: number }): EventStore
  11. interface EventStore {
  12. push: (event: DevtoolsEvent) => void;
  13. snapshot: () => DevtoolsEvent[];
  14. subscribe: (listener: () => void) => () => void;
  15. clear: () => void;
  16. size: () => number;
  17. }
  18. ```
  19. Ring-buffered pub/sub of `DevtoolsEvent`. Shared by every panel and every stream tap.
  20. ## Panel
  21. ### createPanel
  22. ```ts
  23. function createPanel(options: PanelOptions): PanelHandle
  24. interface PanelHandle {
  25. open: () => void;
  26. close: () => void;
  27. toggle: () => void;
  28. isOpen: () => boolean;
  29. refresh: () => void;
  30. destroy: () => void;
  31. }
  32. ```
  33. Mount the panel into a host document. Adapters call this internally.
  34. ### Panel tabs
  35. Each tab is a factory function that returns a `TabDef`:
  36. ```ts
  37. import {
  38. specTab,
  39. stateTab,
  40. actionsTab,
  41. streamTab,
  42. catalogTab,
  43. pickerTab,
  44. } from "@json-render/devtools";
  45. ```
  46. ## Stream Taps
  47. ### tapJsonRenderStream
  48. ```ts
  49. function tapJsonRenderStream(
  50. stream: ReadableStream<StreamChunk>,
  51. events: EventStore,
  52. ): ReadableStream<StreamChunk>
  53. ```
  54. 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.
  55. ### tapYamlStream
  56. ```ts
  57. function tapYamlStream(
  58. stream: ReadableStream<StreamChunk>,
  59. events: EventStore,
  60. ): ReadableStream<StreamChunk>
  61. ```
  62. YAML equivalent of `tapJsonRenderStream`.
  63. ### scanMessageParts
  64. ```ts
  65. function scanMessageParts(
  66. parts: readonly DataPart[] | undefined,
  67. events: EventStore,
  68. seen: WeakSet<object>,
  69. ): void
  70. ```
  71. 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.
  72. ## Picker
  73. ### startPicker
  74. ```ts
  75. function startPicker(options: PickerOptions): PickerSession | null
  76. interface PickerOptions {
  77. onPick: (key: string) => void;
  78. onCancel?: () => void;
  79. }
  80. ```
  81. 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.
  82. ### findElementByKey / highlightElement
  83. ```ts
  84. function findElementByKey(key: string): Element | null
  85. function highlightElement(key: string, durationMs?: number): void
  86. ```
  87. Look up the live DOM node for a spec element key, or briefly paint an outline around it.
  88. ## Types
  89. ### DevtoolsEvent
  90. ```ts
  91. type DevtoolsEvent =
  92. | { kind: "spec-changed"; at: number; spec: Spec }
  93. | { kind: "state-set"; at: number; path: string; prev: unknown; next: unknown }
  94. | { kind: "action-dispatched"; at: number; id: string; name: string; params?: unknown }
  95. | { kind: "action-settled"; at: number; id: string; ok: boolean; result?: unknown; error?: string; durationMs: number }
  96. | { kind: "stream-patch"; at: number; patch: JsonPatch; source: "json" | "yaml" }
  97. | { kind: "stream-text"; at: number; text: string }
  98. | { kind: "stream-usage"; at: number; usage: TokenUsage }
  99. | { kind: "stream-lifecycle"; at: number; phase: "start" | "end"; ok?: boolean };
  100. ```
  101. ### isProduction
  102. ```ts
  103. function isProduction(): boolean
  104. ```
  105. `true` when `process.env.NODE_ENV === "production"`. Adapters use this to short-circuit to a null render.