@json-render/core 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,738 +1,7 @@
1
+ import { S as StateModel, V as VisibilityCondition, a as StateCondition, A as AndCondition, O as OrCondition, D as DynamicValue, b as Spec } from './store-utils-DHnkfKAT.mjs';
2
+ export { Y as Action, X as ActionBinding, a4 as ActionBindingSchema, Z as ActionConfirm, a6 as ActionConfirmSchema, a1 as ActionDefinition, a3 as ActionExecutionContext, a0 as ActionHandler, $ as ActionOnError, a8 as ActionOnErrorSchema, _ as ActionOnSuccess, a7 as ActionOnSuccessSchema, a5 as ActionSchema, C as ComponentSchema, e as DynamicBoolean, r as DynamicBooleanSchema, d as DynamicNumber, q as DynamicNumberSchema, c as DynamicString, p as DynamicStringSchema, o as DynamicValueSchema, F as FlatElement, f as IndexCondition, I as ItemCondition, J as JsonPatch, M as MixedStreamCallbacks, l as MixedStreamParser, P as PatchOp, a2 as ResolvedAction, Q as SPEC_DATA_PART, R as SPEC_DATA_PART_TYPE, g as SingleCondition, n as SpecDataPart, k as SpecStreamCompiler, j as SpecStreamLine, h as StateStore, T as StoreAdapterConfig, m as StreamChunk, U as UIElement, i as ValidationMode, ad as action, ac as actionBinding, v as addByPath, B as applySpecPatch, z as applySpecStreamPatch, G as compileSpecStream, L as createJsonRenderTransform, K as createMixedStreamParser, H as createSpecStreamCompiler, W as createStateStore, aa as executeAction, x as findFormValue, t as getByPath, ab as interpolateString, E as nestedToFlat, y as parseSpecStreamLine, N as pipeJsonRender, w as removeByPath, a9 as resolveAction, s as resolveDynamicValue, u as setByPath } from './store-utils-DHnkfKAT.mjs';
1
3
  import { z } from 'zod';
2
4
 
3
- /**
4
- * Confirmation dialog configuration
5
- */
6
- interface ActionConfirm {
7
- title: string;
8
- message: string;
9
- confirmLabel?: string;
10
- cancelLabel?: string;
11
- variant?: "default" | "danger";
12
- }
13
- /**
14
- * Action success handler
15
- */
16
- type ActionOnSuccess = {
17
- navigate: string;
18
- } | {
19
- set: Record<string, unknown>;
20
- } | {
21
- action: string;
22
- };
23
- /**
24
- * Action error handler
25
- */
26
- type ActionOnError = {
27
- set: Record<string, unknown>;
28
- } | {
29
- action: string;
30
- };
31
- /**
32
- * Action binding — maps an event to an action invocation.
33
- *
34
- * Used inside the `on` field of a UIElement:
35
- * ```json
36
- * { "on": { "press": { "action": "setState", "params": { "statePath": "/x", "value": 1 } } } }
37
- * ```
38
- */
39
- interface ActionBinding {
40
- /** Action name (must be in catalog) */
41
- action: string;
42
- /** Parameters to pass to the action handler */
43
- params?: Record<string, DynamicValue>;
44
- /** Confirmation dialog before execution */
45
- confirm?: ActionConfirm;
46
- /** Handler after successful execution */
47
- onSuccess?: ActionOnSuccess;
48
- /** Handler after failed execution */
49
- onError?: ActionOnError;
50
- /** Whether to prevent default browser behavior (e.g. navigation on links) */
51
- preventDefault?: boolean;
52
- }
53
- /**
54
- * @deprecated Use ActionBinding instead
55
- */
56
- type Action = ActionBinding;
57
- /**
58
- * Schema for action confirmation
59
- */
60
- declare const ActionConfirmSchema: z.ZodObject<{
61
- title: z.ZodString;
62
- message: z.ZodString;
63
- confirmLabel: z.ZodOptional<z.ZodString>;
64
- cancelLabel: z.ZodOptional<z.ZodString>;
65
- variant: z.ZodOptional<z.ZodEnum<{
66
- default: "default";
67
- danger: "danger";
68
- }>>;
69
- }, z.core.$strip>;
70
- /**
71
- * Schema for success handlers
72
- */
73
- declare const ActionOnSuccessSchema: z.ZodUnion<readonly [z.ZodObject<{
74
- navigate: z.ZodString;
75
- }, z.core.$strip>, z.ZodObject<{
76
- set: z.ZodRecord<z.ZodString, z.ZodUnknown>;
77
- }, z.core.$strip>, z.ZodObject<{
78
- action: z.ZodString;
79
- }, z.core.$strip>]>;
80
- /**
81
- * Schema for error handlers
82
- */
83
- declare const ActionOnErrorSchema: z.ZodUnion<readonly [z.ZodObject<{
84
- set: z.ZodRecord<z.ZodString, z.ZodUnknown>;
85
- }, z.core.$strip>, z.ZodObject<{
86
- action: z.ZodString;
87
- }, z.core.$strip>]>;
88
- /**
89
- * Full action binding schema
90
- */
91
- declare const ActionBindingSchema: z.ZodObject<{
92
- action: z.ZodString;
93
- params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodObject<{
94
- $state: z.ZodString;
95
- }, z.core.$strip>]>>>;
96
- confirm: z.ZodOptional<z.ZodObject<{
97
- title: z.ZodString;
98
- message: z.ZodString;
99
- confirmLabel: z.ZodOptional<z.ZodString>;
100
- cancelLabel: z.ZodOptional<z.ZodString>;
101
- variant: z.ZodOptional<z.ZodEnum<{
102
- default: "default";
103
- danger: "danger";
104
- }>>;
105
- }, z.core.$strip>>;
106
- onSuccess: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
107
- navigate: z.ZodString;
108
- }, z.core.$strip>, z.ZodObject<{
109
- set: z.ZodRecord<z.ZodString, z.ZodUnknown>;
110
- }, z.core.$strip>, z.ZodObject<{
111
- action: z.ZodString;
112
- }, z.core.$strip>]>>;
113
- onError: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
114
- set: z.ZodRecord<z.ZodString, z.ZodUnknown>;
115
- }, z.core.$strip>, z.ZodObject<{
116
- action: z.ZodString;
117
- }, z.core.$strip>]>>;
118
- preventDefault: z.ZodOptional<z.ZodBoolean>;
119
- }, z.core.$strip>;
120
- /**
121
- * @deprecated Use ActionBindingSchema instead
122
- */
123
- declare const ActionSchema: z.ZodObject<{
124
- action: z.ZodString;
125
- params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodObject<{
126
- $state: z.ZodString;
127
- }, z.core.$strip>]>>>;
128
- confirm: z.ZodOptional<z.ZodObject<{
129
- title: z.ZodString;
130
- message: z.ZodString;
131
- confirmLabel: z.ZodOptional<z.ZodString>;
132
- cancelLabel: z.ZodOptional<z.ZodString>;
133
- variant: z.ZodOptional<z.ZodEnum<{
134
- default: "default";
135
- danger: "danger";
136
- }>>;
137
- }, z.core.$strip>>;
138
- onSuccess: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
139
- navigate: z.ZodString;
140
- }, z.core.$strip>, z.ZodObject<{
141
- set: z.ZodRecord<z.ZodString, z.ZodUnknown>;
142
- }, z.core.$strip>, z.ZodObject<{
143
- action: z.ZodString;
144
- }, z.core.$strip>]>>;
145
- onError: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
146
- set: z.ZodRecord<z.ZodString, z.ZodUnknown>;
147
- }, z.core.$strip>, z.ZodObject<{
148
- action: z.ZodString;
149
- }, z.core.$strip>]>>;
150
- preventDefault: z.ZodOptional<z.ZodBoolean>;
151
- }, z.core.$strip>;
152
- /**
153
- * Action handler function signature
154
- */
155
- type ActionHandler<TParams = Record<string, unknown>, TResult = unknown> = (params: TParams) => Promise<TResult> | TResult;
156
- /**
157
- * Action definition in catalog
158
- */
159
- interface ActionDefinition<TParams = Record<string, unknown>> {
160
- /** Zod schema for params validation */
161
- params?: z.ZodType<TParams>;
162
- /** Description for AI */
163
- description?: string;
164
- }
165
- /**
166
- * Resolved action with all dynamic values resolved
167
- */
168
- interface ResolvedAction {
169
- action: string;
170
- params: Record<string, unknown>;
171
- confirm?: ActionConfirm;
172
- onSuccess?: ActionOnSuccess;
173
- onError?: ActionOnError;
174
- }
175
- /**
176
- * Resolve all dynamic values in an action binding
177
- */
178
- declare function resolveAction(binding: ActionBinding, stateModel: StateModel): ResolvedAction;
179
- /**
180
- * Interpolate ${path} expressions in a string
181
- */
182
- declare function interpolateString(template: string, stateModel: StateModel): string;
183
- /**
184
- * Context for action execution
185
- */
186
- interface ActionExecutionContext {
187
- /** The resolved action */
188
- action: ResolvedAction;
189
- /** The action handler from the host */
190
- handler: ActionHandler;
191
- /** Function to update state model */
192
- setState: (path: string, value: unknown) => void;
193
- /** Function to navigate */
194
- navigate?: (path: string) => void;
195
- /** Function to execute another action */
196
- executeAction?: (name: string) => Promise<void>;
197
- }
198
- /**
199
- * Execute an action with all callbacks
200
- */
201
- declare function executeAction(ctx: ActionExecutionContext): Promise<void>;
202
- /**
203
- * Helper to create action bindings
204
- */
205
- declare const actionBinding: {
206
- /** Create a simple action binding */
207
- simple: (actionName: string, params?: Record<string, DynamicValue>) => ActionBinding;
208
- /** Create an action binding with confirmation */
209
- withConfirm: (actionName: string, confirm: ActionConfirm, params?: Record<string, DynamicValue>) => ActionBinding;
210
- /** Create an action binding with success handler */
211
- withSuccess: (actionName: string, onSuccess: ActionOnSuccess, params?: Record<string, DynamicValue>) => ActionBinding;
212
- };
213
- /**
214
- * @deprecated Use actionBinding instead
215
- */
216
- declare const action: {
217
- /** Create a simple action binding */
218
- simple: (actionName: string, params?: Record<string, DynamicValue>) => ActionBinding;
219
- /** Create an action binding with confirmation */
220
- withConfirm: (actionName: string, confirm: ActionConfirm, params?: Record<string, DynamicValue>) => ActionBinding;
221
- /** Create an action binding with success handler */
222
- withSuccess: (actionName: string, onSuccess: ActionOnSuccess, params?: Record<string, DynamicValue>) => ActionBinding;
223
- };
224
-
225
- /**
226
- * Dynamic value - can be a literal or a `{ $state }` reference to the state model.
227
- *
228
- * Used in action params and validation args where values can either be
229
- * hardcoded or resolved from state at runtime.
230
- */
231
- type DynamicValue<T = unknown> = T | {
232
- $state: string;
233
- };
234
- /**
235
- * Dynamic string value
236
- */
237
- type DynamicString = DynamicValue<string>;
238
- /**
239
- * Dynamic number value
240
- */
241
- type DynamicNumber = DynamicValue<number>;
242
- /**
243
- * Dynamic boolean value
244
- */
245
- type DynamicBoolean = DynamicValue<boolean>;
246
- /**
247
- * Zod schema for dynamic values
248
- */
249
- declare const DynamicValueSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodObject<{
250
- $state: z.ZodString;
251
- }, z.core.$strip>]>;
252
- declare const DynamicStringSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
253
- $state: z.ZodString;
254
- }, z.core.$strip>]>;
255
- declare const DynamicNumberSchema: z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
256
- $state: z.ZodString;
257
- }, z.core.$strip>]>;
258
- declare const DynamicBooleanSchema: z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
259
- $state: z.ZodString;
260
- }, z.core.$strip>]>;
261
- /**
262
- * Base UI element structure for v2
263
- */
264
- interface UIElement<T extends string = string, P = Record<string, unknown>> {
265
- /** Component type from the catalog */
266
- type: T;
267
- /** Component props */
268
- props: P;
269
- /** Child element keys (flat structure) */
270
- children?: string[];
271
- /** Visibility condition */
272
- visible?: VisibilityCondition;
273
- /** Event bindings — maps event names to action bindings */
274
- on?: Record<string, ActionBinding | ActionBinding[]>;
275
- /** Repeat children once per item in a state array */
276
- repeat?: {
277
- statePath: string;
278
- key?: string;
279
- };
280
- }
281
- /**
282
- * Element with key and parentKey for use with flatToTree.
283
- * When elements are in an array (not a keyed map), key and parentKey
284
- * are needed to establish identity and parent-child relationships.
285
- */
286
- interface FlatElement<T extends string = string, P = Record<string, unknown>> extends UIElement<T, P> {
287
- /** Unique key identifying this element */
288
- key: string;
289
- /** Parent element key (null for root) */
290
- parentKey?: string | null;
291
- }
292
- /**
293
- * Shared comparison operators for visibility conditions.
294
- *
295
- * Use at most ONE comparison operator per condition. If multiple are
296
- * provided, only the first matching one is evaluated (precedence:
297
- * eq > neq > gt > gte > lt > lte). With no operator, truthiness is checked.
298
- *
299
- * `not` inverts the final result of whichever operator (or truthiness
300
- * check) is used.
301
- */
302
- type ComparisonOperators = {
303
- eq?: unknown;
304
- neq?: unknown;
305
- gt?: number | {
306
- $state: string;
307
- };
308
- gte?: number | {
309
- $state: string;
310
- };
311
- lt?: number | {
312
- $state: string;
313
- };
314
- lte?: number | {
315
- $state: string;
316
- };
317
- not?: true;
318
- };
319
- /**
320
- * A single state-based condition.
321
- * Resolves `$state` to a value from the state model, then applies the operator.
322
- * Without an operator, checks truthiness.
323
- *
324
- * When `not` is `true`, the result of the entire condition is inverted.
325
- * For example `{ $state: "/count", gt: 5, not: true }` means "NOT greater than 5".
326
- */
327
- type StateCondition = {
328
- $state: string;
329
- } & ComparisonOperators;
330
- /**
331
- * A condition that resolves `$item` to a field on the current repeat item.
332
- * Only meaningful inside a `repeat` scope.
333
- *
334
- * Use `""` to reference the whole item, or `"field"` for a specific field.
335
- */
336
- type ItemCondition = {
337
- $item: string;
338
- } & ComparisonOperators;
339
- /**
340
- * A condition that resolves `$index` to the current repeat array index.
341
- * Only meaningful inside a `repeat` scope.
342
- */
343
- type IndexCondition = {
344
- $index: true;
345
- } & ComparisonOperators;
346
- /** A single visibility condition (state, item, or index). */
347
- type SingleCondition = StateCondition | ItemCondition | IndexCondition;
348
- /**
349
- * AND wrapper — all child conditions must be true.
350
- * This is the explicit form of the implicit array AND (`SingleCondition[]`).
351
- * Unlike the implicit form, `$and` supports nested `$or` and `$and` conditions.
352
- */
353
- type AndCondition = {
354
- $and: VisibilityCondition[];
355
- };
356
- /**
357
- * OR wrapper — at least one child condition must be true.
358
- */
359
- type OrCondition = {
360
- $or: VisibilityCondition[];
361
- };
362
- /**
363
- * Visibility condition types.
364
- * - `boolean` — always/never
365
- * - `SingleCondition` — single condition (`$state`, `$item`, or `$index`)
366
- * - `SingleCondition[]` — implicit AND (all must be true)
367
- * - `AndCondition` — `{ $and: [...] }`, explicit AND (all must be true)
368
- * - `OrCondition` — `{ $or: [...] }`, at least one must be true
369
- */
370
- type VisibilityCondition = boolean | SingleCondition | SingleCondition[] | AndCondition | OrCondition;
371
- /**
372
- * Flat UI tree structure (optimized for LLM generation)
373
- */
374
- interface Spec {
375
- /** Root element key */
376
- root: string;
377
- /** Flat map of elements by key */
378
- elements: Record<string, UIElement>;
379
- /** Optional initial state to seed the state model.
380
- * Components using statePath will read from / write to this state. */
381
- state?: Record<string, unknown>;
382
- }
383
- /**
384
- * State model type
385
- */
386
- type StateModel = Record<string, unknown>;
387
- /**
388
- * Component schema definition using Zod
389
- */
390
- type ComponentSchema = z.ZodType<Record<string, unknown>>;
391
- /**
392
- * Validation mode for catalog validation
393
- */
394
- type ValidationMode = "strict" | "warn" | "ignore";
395
- /**
396
- * JSON patch operation types (RFC 6902)
397
- */
398
- type PatchOp = "add" | "remove" | "replace" | "move" | "copy" | "test";
399
- /**
400
- * JSON patch operation (RFC 6902)
401
- */
402
- interface JsonPatch {
403
- op: PatchOp;
404
- path: string;
405
- /** Required for add, replace, test */
406
- value?: unknown;
407
- /** Required for move, copy (source location) */
408
- from?: string;
409
- }
410
- /**
411
- * Resolve a dynamic value against a state model
412
- */
413
- declare function resolveDynamicValue<T>(value: DynamicValue<T>, stateModel: StateModel): T | undefined;
414
- /**
415
- * Get a value from an object by JSON Pointer path (RFC 6901)
416
- */
417
- declare function getByPath(obj: unknown, path: string): unknown;
418
- /**
419
- * Set a value in an object by JSON Pointer path (RFC 6901).
420
- * Automatically creates arrays when the path segment is a numeric index.
421
- */
422
- declare function setByPath(obj: Record<string, unknown>, path: string, value: unknown): void;
423
- /**
424
- * Add a value per RFC 6902 "add" semantics.
425
- * For objects: create-or-replace the member.
426
- * For arrays: insert before the given index, or append if "-".
427
- */
428
- declare function addByPath(obj: Record<string, unknown>, path: string, value: unknown): void;
429
- /**
430
- * Remove a value per RFC 6902 "remove" semantics.
431
- * For objects: delete the property.
432
- * For arrays: splice out the element at the given index.
433
- */
434
- declare function removeByPath(obj: Record<string, unknown>, path: string): void;
435
- /**
436
- * Find a form value from params and/or state.
437
- * Useful in action handlers to locate form input values regardless of path format.
438
- *
439
- * Checks in order:
440
- * 1. Direct param key (if not a path reference)
441
- * 2. Param keys ending with the field name
442
- * 3. State keys ending with the field name (dot notation)
443
- * 4. State path using getByPath (slash notation)
444
- *
445
- * @example
446
- * // Find "name" from params or state
447
- * const name = findFormValue("name", params, state);
448
- *
449
- * // Will find from: params.name, params["form.name"], state["form.name"], or getByPath(state, "name")
450
- */
451
- declare function findFormValue(fieldName: string, params?: Record<string, unknown>, state?: Record<string, unknown>): unknown;
452
- /**
453
- * A SpecStream line - a single patch operation in the stream.
454
- */
455
- type SpecStreamLine = JsonPatch;
456
- /**
457
- * Parse a single SpecStream line into a patch operation.
458
- * Returns null if the line is invalid or empty.
459
- *
460
- * SpecStream is json-render's streaming format where each line is a JSON patch
461
- * operation that progressively builds up the final spec.
462
- */
463
- declare function parseSpecStreamLine(line: string): SpecStreamLine | null;
464
- /**
465
- * Apply a single RFC 6902 JSON Patch operation to an object.
466
- * Mutates the object in place.
467
- *
468
- * Supports all six RFC 6902 operations: add, remove, replace, move, copy, test.
469
- *
470
- * @throws {Error} If a "test" operation fails (value mismatch).
471
- */
472
- declare function applySpecStreamPatch<T extends Record<string, unknown>>(obj: T, patch: SpecStreamLine): T;
473
- /**
474
- * Apply a single RFC 6902 JSON Patch operation to a Spec.
475
- * Mutates the spec in place and returns it.
476
- *
477
- * This is a typed convenience wrapper around `applySpecStreamPatch` that
478
- * accepts a `Spec` directly without requiring a cast to `Record<string, unknown>`.
479
- *
480
- * Note: This mutates the spec. For React state updates, spread the result
481
- * to create a new reference: `setSpec({ ...applySpecPatch(spec, patch) })`.
482
- *
483
- * @example
484
- * let spec: Spec = { root: "", elements: {} };
485
- * applySpecPatch(spec, { op: "add", path: "/root", value: "main" });
486
- */
487
- declare function applySpecPatch(spec: Spec, patch: SpecStreamLine): Spec;
488
- /**
489
- * Convert a nested (tree-structured) spec into the flat `Spec` format used
490
- * by json-render renderers.
491
- *
492
- * In the nested format each node has inline `children` as an array of child
493
- * objects. This function walks the tree, assigns auto-generated keys
494
- * (`el-0`, `el-1`, ...), and produces a flat `{ root, elements, state }` spec.
495
- *
496
- * The top-level `state` field (if present on the root node) is hoisted to
497
- * `spec.state`.
498
- *
499
- * @example
500
- * ```ts
501
- * const nested = {
502
- * type: "Card",
503
- * props: { title: "Hello" },
504
- * children: [
505
- * { type: "Text", props: { content: "World" } },
506
- * ],
507
- * state: { count: 0 },
508
- * };
509
- * const spec = nestedToFlat(nested);
510
- * // {
511
- * // root: "el-0",
512
- * // elements: {
513
- * // "el-0": { type: "Card", props: { title: "Hello" }, children: ["el-1"] },
514
- * // "el-1": { type: "Text", props: { content: "World" }, children: [] },
515
- * // },
516
- * // state: { count: 0 },
517
- * // }
518
- * ```
519
- */
520
- declare function nestedToFlat(nested: Record<string, unknown>): Spec;
521
- /**
522
- * Compile a SpecStream string into a JSON object.
523
- * Each line should be a patch operation.
524
- *
525
- * @example
526
- * const stream = `{"op":"add","path":"/name","value":"Alice"}
527
- * {"op":"add","path":"/age","value":30}`;
528
- * const result = compileSpecStream(stream);
529
- * // { name: "Alice", age: 30 }
530
- */
531
- declare function compileSpecStream<T extends Record<string, unknown> = Record<string, unknown>>(stream: string, initial?: T): T;
532
- /**
533
- * Streaming SpecStream compiler.
534
- * Useful for processing SpecStream data as it streams in from AI.
535
- *
536
- * @example
537
- * const compiler = createSpecStreamCompiler<MySpec>();
538
- *
539
- * // As chunks arrive:
540
- * const { result, newPatches } = compiler.push(chunk);
541
- * if (newPatches.length > 0) {
542
- * updateUI(result);
543
- * }
544
- *
545
- * // When done:
546
- * const finalResult = compiler.getResult();
547
- */
548
- interface SpecStreamCompiler<T> {
549
- /** Push a chunk of text. Returns the current result and any new patches applied. */
550
- push(chunk: string): {
551
- result: T;
552
- newPatches: SpecStreamLine[];
553
- };
554
- /** Get the current compiled result */
555
- getResult(): T;
556
- /** Get all patches that have been applied */
557
- getPatches(): SpecStreamLine[];
558
- /** Reset the compiler to initial state */
559
- reset(initial?: Partial<T>): void;
560
- }
561
- /**
562
- * Create a streaming SpecStream compiler.
563
- *
564
- * SpecStream is json-render's streaming format. AI outputs patch operations
565
- * line by line, and this compiler progressively builds the final spec.
566
- *
567
- * @example
568
- * const compiler = createSpecStreamCompiler<TimelineSpec>();
569
- *
570
- * // Process streaming response
571
- * const reader = response.body.getReader();
572
- * while (true) {
573
- * const { done, value } = await reader.read();
574
- * if (done) break;
575
- *
576
- * const { result, newPatches } = compiler.push(decoder.decode(value));
577
- * if (newPatches.length > 0) {
578
- * setSpec(result); // Update UI with partial result
579
- * }
580
- * }
581
- */
582
- declare function createSpecStreamCompiler<T = Record<string, unknown>>(initial?: Partial<T>): SpecStreamCompiler<T>;
583
- /**
584
- * Callbacks for the mixed stream parser.
585
- */
586
- interface MixedStreamCallbacks {
587
- /** Called when a JSONL patch line is parsed */
588
- onPatch: (patch: SpecStreamLine) => void;
589
- /** Called when a text (non-JSONL) line is received */
590
- onText: (text: string) => void;
591
- }
592
- /**
593
- * A stateful parser for mixed streams that contain both text and JSONL patches.
594
- * Used in chat + GenUI scenarios where an LLM responds with conversational text
595
- * interleaved with json-render JSONL patch operations.
596
- */
597
- interface MixedStreamParser {
598
- /** Push a chunk of streamed data. Calls onPatch/onText for each complete line. */
599
- push(chunk: string): void;
600
- /** Flush any remaining buffered content. Call when the stream ends. */
601
- flush(): void;
602
- }
603
- /**
604
- * Create a parser for mixed text + JSONL streams.
605
- *
606
- * In chat + GenUI scenarios, an LLM streams a response that contains both
607
- * conversational text and json-render JSONL patch lines. This parser buffers
608
- * incoming chunks, splits them into lines, and classifies each line as either
609
- * a JSONL patch (via `parseSpecStreamLine`) or plain text.
610
- *
611
- * @example
612
- * const parser = createMixedStreamParser({
613
- * onText: (text) => appendToMessage(text),
614
- * onPatch: (patch) => applySpecPatch(spec, patch),
615
- * });
616
- *
617
- * // As chunks arrive from the stream:
618
- * for await (const chunk of stream) {
619
- * parser.push(chunk);
620
- * }
621
- * parser.flush();
622
- */
623
- declare function createMixedStreamParser(callbacks: MixedStreamCallbacks): MixedStreamParser;
624
- /**
625
- * Minimal chunk shape compatible with the AI SDK's `UIMessageChunk`.
626
- *
627
- * Defined here so that `@json-render/core` has no dependency on the `ai`
628
- * package. The discriminated union covers the three text-related chunk types
629
- * the transform inspects; all other chunk types pass through via the fallback.
630
- */
631
- type StreamChunk = {
632
- type: "text-start";
633
- id: string;
634
- [k: string]: unknown;
635
- } | {
636
- type: "text-delta";
637
- id: string;
638
- delta: string;
639
- [k: string]: unknown;
640
- } | {
641
- type: "text-end";
642
- id: string;
643
- [k: string]: unknown;
644
- } | {
645
- type: string;
646
- [k: string]: unknown;
647
- };
648
- /**
649
- * Creates a `TransformStream` that intercepts AI SDK UI message stream chunks
650
- * and classifies text content as either prose or json-render JSONL patches.
651
- *
652
- * Two classification modes:
653
- *
654
- * 1. **Fence mode** (preferred): Lines between ` ```spec ` and ` ``` ` are
655
- * parsed as JSONL patches. Fence delimiters are swallowed (not emitted).
656
- * 2. **Heuristic mode** (backward compat): Outside of fences, lines starting
657
- * with `{` are buffered and tested with `parseSpecStreamLine`. Valid patches
658
- * are emitted as {@link SPEC_DATA_PART_TYPE} parts; everything else is
659
- * flushed as text.
660
- *
661
- * Non-text chunks (tool events, step markers, etc.) are passed through unchanged.
662
- *
663
- * @example
664
- * ```ts
665
- * import { createJsonRenderTransform } from "@json-render/core";
666
- * import { createUIMessageStream, createUIMessageStreamResponse } from "ai";
667
- *
668
- * const stream = createUIMessageStream({
669
- * execute: async ({ writer }) => {
670
- * writer.merge(
671
- * result.toUIMessageStream().pipeThrough(createJsonRenderTransform()),
672
- * );
673
- * },
674
- * });
675
- * return createUIMessageStreamResponse({ stream });
676
- * ```
677
- */
678
- declare function createJsonRenderTransform(): TransformStream<StreamChunk, StreamChunk>;
679
- /**
680
- * The key registered in `AppDataParts` for json-render specs.
681
- * The AI SDK automatically prefixes this with `"data-"` on the wire,
682
- * so the actual stream chunk type is `"data-spec"` (see {@link SPEC_DATA_PART_TYPE}).
683
- *
684
- * @example
685
- * ```ts
686
- * import { SPEC_DATA_PART, type SpecDataPart } from "@json-render/core";
687
- * type AppDataParts = { [SPEC_DATA_PART]: SpecDataPart };
688
- * ```
689
- */
690
- declare const SPEC_DATA_PART: "spec";
691
- /**
692
- * The wire-format type string as it appears in stream chunks and message parts.
693
- * This is `"data-"` + {@link SPEC_DATA_PART} — i.e. `"data-spec"`.
694
- *
695
- * Use this constant when filtering message parts or enqueuing stream chunks.
696
- */
697
- declare const SPEC_DATA_PART_TYPE: "data-spec";
698
- /**
699
- * Discriminated union for the payload of a {@link SPEC_DATA_PART_TYPE} SSE part.
700
- *
701
- * - `"patch"`: A single RFC 6902 JSON Patch operation (streaming, progressive UI).
702
- * - `"flat"`: A complete flat spec with `root`, `elements`, and optional `state`.
703
- * - `"nested"`: A complete nested spec (tree structure — schema depends on catalog).
704
- */
705
- type SpecDataPart = {
706
- type: "patch";
707
- patch: JsonPatch;
708
- } | {
709
- type: "flat";
710
- spec: Spec;
711
- } | {
712
- type: "nested";
713
- spec: Record<string, unknown>;
714
- };
715
- /**
716
- * Convenience wrapper that pipes an AI SDK UI message stream through the
717
- * json-render transform, classifying text as prose or JSONL patches.
718
- *
719
- * Eliminates the need for manual `pipeThrough(createJsonRenderTransform())`
720
- * and the associated type cast.
721
- *
722
- * @example
723
- * ```ts
724
- * import { pipeJsonRender } from "@json-render/core";
725
- *
726
- * const stream = createUIMessageStream({
727
- * execute: async ({ writer }) => {
728
- * writer.merge(pipeJsonRender(result.toUIMessageStream()));
729
- * },
730
- * });
731
- * return createUIMessageStreamResponse({ stream });
732
- * ```
733
- */
734
- declare function pipeJsonRender<T = StreamChunk>(stream: ReadableStream<T>): ReadableStream<T>;
735
-
736
5
  /**
737
6
  * Visibility condition schema.
738
7
  *
@@ -1336,4 +605,4 @@ interface UserPromptOptions {
1336
605
  */
1337
606
  declare function buildUserPrompt(options: UserPromptOptions): string;
1338
607
 
1339
- export { type Action, type ActionBinding, ActionBindingSchema, type ActionConfirm, ActionConfirmSchema, type ActionDefinition, type ActionExecutionContext, type ActionHandler, type ActionOnError, ActionOnErrorSchema, type ActionOnSuccess, ActionOnSuccessSchema, ActionSchema, type AndCondition, type BuiltInAction, type Catalog, type ComponentSchema, type DynamicBoolean, DynamicBooleanSchema, type DynamicNumber, DynamicNumberSchema, type DynamicString, DynamicStringSchema, type DynamicValue, DynamicValueSchema, type FlatElement, type IndexCondition, type InferActionParams, type InferCatalogActions, type InferCatalogComponents, type InferCatalogInput, type InferComponentProps, type InferSpec, type ItemCondition, type JsonPatch, type MixedStreamCallbacks, type MixedStreamParser, type OrCondition, type PatchOp, type PromptContext, type PromptOptions, type PromptTemplate, type PropExpression, type PropResolutionContext, type ResolvedAction, SPEC_DATA_PART, SPEC_DATA_PART_TYPE, type Schema, type SchemaBuilder, type SchemaDefinition, type SchemaOptions, type SchemaType, type SingleCondition, type Spec, type SpecDataPart, type SpecIssue, type SpecIssueSeverity, type SpecStreamCompiler, type SpecStreamLine, type SpecValidationIssues, type SpecValidationResult, type StateCondition, type StateModel, type StreamChunk, type UIElement, type UserPromptOptions, type ValidateSpecOptions, type ValidationCheck, type ValidationCheckResult, ValidationCheckSchema, type ValidationConfig, ValidationConfigSchema, type ValidationContext, type ValidationFunction, type ValidationFunctionDefinition, type ValidationMode, type ValidationResult, type VisibilityCondition, VisibilityConditionSchema, type VisibilityContext, action, actionBinding, addByPath, applySpecPatch, applySpecStreamPatch, autoFixSpec, buildUserPrompt, builtInValidationFunctions, check, compileSpecStream, createJsonRenderTransform, createMixedStreamParser, createSpecStreamCompiler, defineCatalog, defineSchema, evaluateVisibility, executeAction, findFormValue, formatSpecIssues, getByPath, interpolateString, nestedToFlat, parseSpecStreamLine, pipeJsonRender, removeByPath, resolveAction, resolveActionParam, resolveBindings, resolveDynamicValue, resolveElementProps, resolvePropValue, runValidation, runValidationCheck, setByPath, validateSpec, visibility };
608
+ export { AndCondition, type BuiltInAction, type Catalog, DynamicValue, type InferActionParams, type InferCatalogActions, type InferCatalogComponents, type InferCatalogInput, type InferComponentProps, type InferSpec, OrCondition, type PromptContext, type PromptOptions, type PromptTemplate, type PropExpression, type PropResolutionContext, type Schema, type SchemaBuilder, type SchemaDefinition, type SchemaOptions, type SchemaType, Spec, type SpecIssue, type SpecIssueSeverity, type SpecValidationIssues, type SpecValidationResult, StateCondition, StateModel, type UserPromptOptions, type ValidateSpecOptions, type ValidationCheck, type ValidationCheckResult, ValidationCheckSchema, type ValidationConfig, ValidationConfigSchema, type ValidationContext, type ValidationFunction, type ValidationFunctionDefinition, type ValidationResult, VisibilityCondition, VisibilityConditionSchema, type VisibilityContext, autoFixSpec, buildUserPrompt, builtInValidationFunctions, check, defineCatalog, defineSchema, evaluateVisibility, formatSpecIssues, resolveActionParam, resolveBindings, resolveElementProps, resolvePropValue, runValidation, runValidationCheck, validateSpec, visibility };