@json-render/vue 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.
@@ -0,0 +1,885 @@
1
+ import * as vue from 'vue';
2
+ import { PropType, ShallowRef, ComputedRef, VNode, Ref, Component } from 'vue';
3
+ import { StateStore, StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, Spec, FlatElement, SchemaDefinition, ComputedFunction, UIElement } from '@json-render/core';
4
+ export { ComputedFunction, Spec, StateModel, StateStore, createStateStore } from '@json-render/core';
5
+ export { VueSchema, VueSpec, schema } from './schema.mjs';
6
+
7
+ /**
8
+ * State context value
9
+ */
10
+ interface StateContextValue {
11
+ /** Reactive state snapshot — use state.value in reactive contexts */
12
+ state: ShallowRef<StateModel>;
13
+ /** Get a value by path */
14
+ get: (path: string) => unknown;
15
+ /** Set a value by path */
16
+ set: (path: string, value: unknown) => void;
17
+ /** Update multiple values at once */
18
+ update: (updates: Record<string, unknown>) => void;
19
+ /** Return the live state snapshot from the underlying store (not through Vue reactivity). */
20
+ getSnapshot: () => StateModel;
21
+ }
22
+ /**
23
+ * Props for StateProvider
24
+ */
25
+ interface StateProviderProps {
26
+ /**
27
+ * External store that owns the state. When provided, the provider operates
28
+ * in **controlled mode** — `initialState` and `onStateChange` are ignored
29
+ * and the store is the single source of truth.
30
+ */
31
+ store?: StateStore;
32
+ /** Initial state model (used only in uncontrolled mode) */
33
+ initialState?: StateModel;
34
+ /**
35
+ * Callback when state changes (used only in uncontrolled mode).
36
+ * Called once per `set` or `update` with all changed entries.
37
+ */
38
+ onStateChange?: (changes: Array<{
39
+ path: string;
40
+ value: unknown;
41
+ }>) => void;
42
+ }
43
+ /**
44
+ * Provider for state model context.
45
+ *
46
+ * Supports two modes:
47
+ * - **Controlled**: pass a `store` prop (e.g. backed by Redux / Zustand).
48
+ * - **Uncontrolled** (default): omit `store` and optionally pass
49
+ * `initialState` / `onStateChange`.
50
+ */
51
+ declare const StateProvider: vue.DefineComponent<vue.ExtractPropTypes<{
52
+ store: {
53
+ type: PropType<StateStore>;
54
+ default: undefined;
55
+ };
56
+ initialState: {
57
+ type: PropType<StateModel>;
58
+ default: undefined;
59
+ };
60
+ onStateChange: {
61
+ type: PropType<(changes: Array<{
62
+ path: string;
63
+ value: unknown;
64
+ }>) => void>;
65
+ default: undefined;
66
+ };
67
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
68
+ [key: string]: any;
69
+ }>[] | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
70
+ store: {
71
+ type: PropType<StateStore>;
72
+ default: undefined;
73
+ };
74
+ initialState: {
75
+ type: PropType<StateModel>;
76
+ default: undefined;
77
+ };
78
+ onStateChange: {
79
+ type: PropType<(changes: Array<{
80
+ path: string;
81
+ value: unknown;
82
+ }>) => void>;
83
+ default: undefined;
84
+ };
85
+ }>> & Readonly<{}>, {
86
+ store: StateStore;
87
+ initialState: StateModel;
88
+ onStateChange: (changes: Array<{
89
+ path: string;
90
+ value: unknown;
91
+ }>) => void;
92
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
93
+ /**
94
+ * Composable to access the state context
95
+ */
96
+ declare function useStateStore(): StateContextValue;
97
+ /**
98
+ * Composable to get a value from the state model (reactive)
99
+ */
100
+ declare function useStateValue<T>(path: string): ComputedRef<T | undefined>;
101
+ /**
102
+ * Composable to get and set a value from the state model by path.
103
+ *
104
+ * This is the path-based variant for use in arbitrary composables. For
105
+ * registry components that receive `bindings` from the renderer, prefer
106
+ * `useBoundProp` which reads the already-resolved prop value and writes back
107
+ * to the bound path.
108
+ */
109
+ declare function useStateBinding<T>(path: string): [ComputedRef<T | undefined>, (value: T) => void];
110
+
111
+ /**
112
+ * Visibility context value
113
+ */
114
+ interface VisibilityContextValue {
115
+ /** Evaluate a visibility condition */
116
+ isVisible: (condition: VisibilityCondition | undefined) => boolean;
117
+ /** The underlying visibility context (reactive) */
118
+ ctx: ComputedRef<VisibilityContext>;
119
+ }
120
+ /**
121
+ * Provider for visibility evaluation
122
+ */
123
+ declare const VisibilityProvider: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
124
+ [key: string]: any;
125
+ }>[] | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
126
+ /**
127
+ * Composable to access visibility evaluation
128
+ */
129
+ declare function useVisibility(): VisibilityContextValue;
130
+ /**
131
+ * Composable to check if a condition is visible. Returns a reactive
132
+ * `ComputedRef<boolean>` so the result updates whenever state changes.
133
+ */
134
+ declare function useIsVisible(condition: VisibilityCondition | undefined): ComputedRef<boolean>;
135
+
136
+ /**
137
+ * Pending confirmation state
138
+ */
139
+ interface PendingConfirmation {
140
+ action: ResolvedAction;
141
+ handler: ActionHandler;
142
+ resolve: () => void;
143
+ reject: () => void;
144
+ }
145
+ /**
146
+ * Action context value
147
+ */
148
+ interface ActionContextValue {
149
+ handlers: Record<string, ActionHandler>;
150
+ loadingActions: Set<string>;
151
+ pendingConfirmation: PendingConfirmation | null;
152
+ execute: (binding: ActionBinding) => Promise<void>;
153
+ confirm: () => void;
154
+ cancel: () => void;
155
+ registerHandler: (name: string, handler: ActionHandler) => void;
156
+ }
157
+ interface ActionProviderProps {
158
+ handlers?: Record<string, ActionHandler>;
159
+ navigate?: (path: string) => void;
160
+ }
161
+ /**
162
+ * Provider for action execution
163
+ */
164
+ declare const ActionProvider: vue.DefineComponent<vue.ExtractPropTypes<{
165
+ handlers: {
166
+ type: PropType<Record<string, ActionHandler>>;
167
+ default: () => {};
168
+ };
169
+ navigate: {
170
+ type: PropType<(path: string) => void>;
171
+ default: undefined;
172
+ };
173
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
174
+ [key: string]: any;
175
+ }>[] | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
176
+ handlers: {
177
+ type: PropType<Record<string, ActionHandler>>;
178
+ default: () => {};
179
+ };
180
+ navigate: {
181
+ type: PropType<(path: string) => void>;
182
+ default: undefined;
183
+ };
184
+ }>> & Readonly<{}>, {
185
+ handlers: Record<string, ActionHandler>;
186
+ navigate: (path: string) => void;
187
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
188
+ /**
189
+ * Composable to access action context
190
+ */
191
+ declare function useActions(): ActionContextValue;
192
+ /**
193
+ * Composable to execute an action binding
194
+ */
195
+ declare function useAction(binding: ActionBinding): {
196
+ execute: () => Promise<void>;
197
+ isLoading: ComputedRef<boolean>;
198
+ };
199
+ /**
200
+ * Props for ConfirmDialog component
201
+ */
202
+ interface ConfirmDialogProps {
203
+ confirm: ActionConfirm;
204
+ onConfirm: () => void;
205
+ onCancel: () => void;
206
+ }
207
+ /**
208
+ * Default confirmation dialog component
209
+ */
210
+ declare const ConfirmDialog: vue.DefineComponent<vue.ExtractPropTypes<{
211
+ confirm: {
212
+ type: PropType<ActionConfirm>;
213
+ required: true;
214
+ };
215
+ onConfirm: {
216
+ type: PropType<() => void>;
217
+ required: true;
218
+ };
219
+ onCancel: {
220
+ type: PropType<() => void>;
221
+ required: true;
222
+ };
223
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
224
+ [key: string]: any;
225
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
226
+ confirm: {
227
+ type: PropType<ActionConfirm>;
228
+ required: true;
229
+ };
230
+ onConfirm: {
231
+ type: PropType<() => void>;
232
+ required: true;
233
+ };
234
+ onCancel: {
235
+ type: PropType<() => void>;
236
+ required: true;
237
+ };
238
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
239
+
240
+ /**
241
+ * Field validation state
242
+ */
243
+ interface FieldValidationState {
244
+ touched: boolean;
245
+ validated: boolean;
246
+ result: ValidationResult | null;
247
+ }
248
+ /**
249
+ * Validation context value
250
+ */
251
+ interface ValidationContextValue {
252
+ customFunctions: Record<string, ValidationFunction>;
253
+ fieldStates: Record<string, FieldValidationState>;
254
+ validate: (path: string, config: ValidationConfig) => ValidationResult;
255
+ touch: (path: string) => void;
256
+ clear: (path: string) => void;
257
+ validateAll: () => boolean;
258
+ registerField: (path: string, config: ValidationConfig) => void;
259
+ }
260
+ interface ValidationProviderProps {
261
+ customFunctions?: Record<string, ValidationFunction>;
262
+ }
263
+ /**
264
+ * Provider for validation
265
+ */
266
+ declare const ValidationProvider: vue.DefineComponent<vue.ExtractPropTypes<{
267
+ customFunctions: {
268
+ type: PropType<Record<string, ValidationFunction>>;
269
+ default: () => {};
270
+ };
271
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
272
+ [key: string]: any;
273
+ }>[] | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
274
+ customFunctions: {
275
+ type: PropType<Record<string, ValidationFunction>>;
276
+ default: () => {};
277
+ };
278
+ }>> & Readonly<{}>, {
279
+ customFunctions: Record<string, ValidationFunction>;
280
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
281
+ /**
282
+ * Composable to access validation context (or null if not inside a ValidationProvider).
283
+ * Useful for components that optionally participate in form validation.
284
+ */
285
+ declare function useOptionalValidation(): ValidationContextValue | null;
286
+ /**
287
+ * Composable to access validation context
288
+ */
289
+ declare function useValidation(): ValidationContextValue;
290
+ /**
291
+ * Composable to get validation state for a field
292
+ */
293
+ declare function useFieldValidation(path: string, config?: ValidationConfig): {
294
+ state: ComputedRef<FieldValidationState>;
295
+ validate: () => ValidationResult;
296
+ touch: () => void;
297
+ clear: () => void;
298
+ errors: ComputedRef<string[]>;
299
+ isValid: ComputedRef<boolean>;
300
+ };
301
+
302
+ /**
303
+ * Repeat scope value provided to child elements inside a repeated element.
304
+ */
305
+ interface RepeatScopeValue {
306
+ /** The current array item object */
307
+ item: unknown;
308
+ /** Index of the current item in the array */
309
+ index: number;
310
+ /** Absolute state path to the current array item (e.g. "/todos/0") — used for statePath two-way binding */
311
+ basePath: string;
312
+ }
313
+ /**
314
+ * Provides repeat scope to child elements so $item and $index expressions resolve correctly.
315
+ */
316
+ declare const RepeatScopeProvider: vue.DefineComponent<vue.ExtractPropTypes<{
317
+ item: {
318
+ required: true;
319
+ };
320
+ index: {
321
+ type: NumberConstructor;
322
+ required: true;
323
+ };
324
+ basePath: {
325
+ type: PropType<string>;
326
+ required: true;
327
+ };
328
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
329
+ [key: string]: any;
330
+ }>[] | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
331
+ item: {
332
+ required: true;
333
+ };
334
+ index: {
335
+ type: NumberConstructor;
336
+ required: true;
337
+ };
338
+ basePath: {
339
+ type: PropType<string>;
340
+ required: true;
341
+ };
342
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
343
+ /**
344
+ * Read the current repeat scope (or null if not inside a repeated element).
345
+ */
346
+ declare function useRepeatScope(): RepeatScopeValue | null;
347
+
348
+ /**
349
+ * State setter function for updating application state
350
+ */
351
+ type SetState = (updater: (prev: Record<string, unknown>) => Record<string, unknown>) => void;
352
+ /**
353
+ * Handle returned by the `on()` function for a specific event.
354
+ * Provides metadata about the event binding and a method to fire it.
355
+ *
356
+ * @example
357
+ * ```ts
358
+ * const press = on("press");
359
+ * if (press.shouldPreventDefault) e.preventDefault();
360
+ * press.emit();
361
+ * ```
362
+ */
363
+ interface EventHandle {
364
+ /** Fire the event (resolve action bindings) */
365
+ emit: () => void;
366
+ /** Whether any binding requested preventDefault */
367
+ shouldPreventDefault: boolean;
368
+ /** Whether any handler is bound to this event */
369
+ bound: boolean;
370
+ }
371
+ /**
372
+ * Catalog-agnostic base type for component render function arguments.
373
+ * Use this when building reusable component libraries that are not tied to a specific catalog.
374
+ *
375
+ * @example
376
+ * ```ts
377
+ * const Card = ({ props, children }: BaseComponentProps<{ title?: string }>) =>
378
+ * h('div', null, [props.title, children])
379
+ * ```
380
+ */
381
+ interface BaseComponentProps<P = Record<string, unknown>> {
382
+ props: P;
383
+ /** Rendered children (from the default slot) */
384
+ children?: VNode | VNode[];
385
+ /** Simple event emitter (shorthand). Fires the event and returns void. */
386
+ emit: (event: string) => void;
387
+ /** Get an event handle with metadata. Use when you need shouldPreventDefault or bound checks. */
388
+ on: (event: string) => EventHandle;
389
+ /**
390
+ * Two-way binding paths resolved from `$bindState` / `$bindItem` expressions.
391
+ * Maps prop name → absolute state path for write-back.
392
+ */
393
+ bindings?: Record<string, string>;
394
+ loading?: boolean;
395
+ }
396
+ /**
397
+ * Context passed to component render functions
398
+ * @example
399
+ * const Button: ComponentFn<typeof catalog, 'Button'> = (ctx) => {
400
+ * return h('button', { onClick: () => ctx.emit("press") }, ctx.props.label)
401
+ * }
402
+ */
403
+ interface ComponentContext<C extends Catalog, K extends keyof InferCatalogComponents<C>> extends BaseComponentProps<InferComponentProps<C, K>> {
404
+ }
405
+ /**
406
+ * Component render function type for Vue
407
+ * @example
408
+ * const Button: ComponentFn<typeof catalog, 'Button'> = ({ props, emit }) =>
409
+ * h('button', { onClick: () => emit("press") }, props.label)
410
+ */
411
+ type ComponentFn<C extends Catalog, K extends keyof InferCatalogComponents<C>> = (ctx: ComponentContext<C, K>) => VNode | VNode[] | null | string;
412
+ /**
413
+ * Registry of all component render functions for a catalog
414
+ * @example
415
+ * const components: Components<typeof myCatalog> = {
416
+ * Button: ({ props }) => h('button', null, props.label),
417
+ * Input: ({ props }) => h('input', { placeholder: props.placeholder }),
418
+ * };
419
+ */
420
+ type Components<C extends Catalog> = {
421
+ [K in keyof InferCatalogComponents<C>]: ComponentFn<C, K>;
422
+ };
423
+ /**
424
+ * Action handler function type
425
+ * @example
426
+ * const viewCustomers: ActionFn<typeof catalog, 'viewCustomers'> = async (params, setState) => {
427
+ * const data = await fetch('/api/customers');
428
+ * setState(prev => ({ ...prev, customers: data }));
429
+ * };
430
+ */
431
+ type ActionFn<C extends Catalog, K extends keyof InferCatalogActions<C>> = (params: InferActionParams<C, K> | undefined, setState: SetState, state: StateModel) => Promise<void>;
432
+ /**
433
+ * Registry of all action handlers for a catalog
434
+ * @example
435
+ * const actions: Actions<typeof myCatalog> = {
436
+ * viewCustomers: async (params, setState) => { ... },
437
+ * createCustomer: async (params, setState) => { ... },
438
+ * };
439
+ */
440
+ type Actions<C extends Catalog> = {
441
+ [K in keyof InferCatalogActions<C>]: ActionFn<C, K>;
442
+ };
443
+ /**
444
+ * True when the catalog declares at least one action, false otherwise.
445
+ * Used by defineRegistry to conditionally require the `actions` field.
446
+ */
447
+ type CatalogHasActions<C extends Catalog> = [
448
+ InferCatalogActions<C>
449
+ ] extends [never] ? false : [keyof InferCatalogActions<C>] extends [never] ? false : true;
450
+
451
+ /**
452
+ * Token usage metadata from AI generation
453
+ */
454
+ interface TokenUsage {
455
+ promptTokens: number;
456
+ completionTokens: number;
457
+ totalTokens: number;
458
+ }
459
+ /**
460
+ * Options for useUIStream
461
+ */
462
+ interface UseUIStreamOptions {
463
+ /** API endpoint */
464
+ api: string;
465
+ /** Callback when complete */
466
+ onComplete?: (spec: Spec) => void;
467
+ /** Callback on error */
468
+ onError?: (error: Error) => void;
469
+ }
470
+ /**
471
+ * Return type for useUIStream
472
+ */
473
+ interface UseUIStreamReturn {
474
+ /** Current UI spec */
475
+ spec: Ref<Spec | null>;
476
+ /** Whether currently streaming */
477
+ isStreaming: Ref<boolean>;
478
+ /** Error if any */
479
+ error: Ref<Error | null>;
480
+ /** Token usage from the last generation */
481
+ usage: Ref<TokenUsage | null>;
482
+ /** Raw JSONL lines received from the stream (JSON patch lines) */
483
+ rawLines: Ref<string[]>;
484
+ /** Send a prompt to generate UI */
485
+ send: (prompt: string, context?: Record<string, unknown>) => Promise<void>;
486
+ /** Clear the current spec */
487
+ clear: () => void;
488
+ }
489
+ /**
490
+ * Composable for streaming UI generation
491
+ */
492
+ declare function useUIStream({ api, onComplete, onError, }: UseUIStreamOptions): UseUIStreamReturn;
493
+ /**
494
+ * Convert a flat element list to a Spec.
495
+ * Input elements use key/parentKey to establish identity and relationships.
496
+ * Output spec uses the map-based format where key is the map entry key
497
+ * and parent-child relationships are expressed through children arrays.
498
+ */
499
+ declare function flatToTree(elements: FlatElement[]): Spec;
500
+ /**
501
+ * Composable for two-way bound props. Returns `[value, setValue]` where:
502
+ *
503
+ * - `value` is the already-resolved prop value (passed through from render props)
504
+ * - `setValue` writes back to the bound state path (no-op if not bound)
505
+ *
506
+ * Designed to work with the `bindings` map that the renderer provides when
507
+ * a prop uses `{ $bindState: "/path" }` or `{ $bindItem: "field" }`.
508
+ *
509
+ * @example
510
+ * ```ts
511
+ * import { useBoundProp } from "@json-render/vue";
512
+ *
513
+ * const Input: ComponentFn<AppCatalog, "Input"> = ({ props, bindings }) => {
514
+ * const [value, setValue] = useBoundProp<string>(props.value as string, bindings?.value);
515
+ * return h("input", { value: value ?? "", onInput: (e) => setValue(e.target.value) });
516
+ * };
517
+ * ```
518
+ */
519
+ declare function useBoundProp<T>(propValue: T | undefined, bindingPath: string | undefined): [T | undefined, (value: T) => void];
520
+ /**
521
+ * A single part from the AI SDK's `message.parts` array. This is a minimal
522
+ * structural type so that library helpers do not depend on the AI SDK.
523
+ * Fields are optional because different part types carry different data:
524
+ * - Text parts have `text`
525
+ * - Data parts have `data`
526
+ */
527
+ interface DataPart {
528
+ type: string;
529
+ text?: string;
530
+ data?: unknown;
531
+ }
532
+ /**
533
+ * Build a `Spec` by replaying all spec data parts from a message's
534
+ * parts array. Returns `null` if no spec data parts are present.
535
+ *
536
+ * Works with the AI SDK's `UIMessage.parts` array. Picks out parts whose
537
+ * `type` is `SPEC_DATA_PART_TYPE` and processes them based on the payload's
538
+ * `type` discriminator: `"patch"`, `"flat"`, or `"nested"`.
539
+ */
540
+ declare function buildSpecFromParts(parts: DataPart[]): Spec | null;
541
+ /**
542
+ * Extract and join all text content from a message's parts array.
543
+ *
544
+ * Filters for parts with `type === "text"`, trims each one, and joins them
545
+ * with double newlines so that text from separate agent steps renders as
546
+ * distinct paragraphs in markdown.
547
+ */
548
+ declare function getTextFromParts(parts: DataPart[]): string;
549
+ /**
550
+ * Composable that extracts both the json-render spec and text content from a
551
+ * message's parts array. Accepts a plain `DataPart[]` or a `Ref<DataPart[]>`
552
+ * for reactive use in streaming scenarios.
553
+ *
554
+ * Returns `ComputedRef`s that recompute whenever `parts` changes.
555
+ *
556
+ * @example
557
+ * ```ts
558
+ * import { useJsonRenderMessage } from "@json-render/vue";
559
+ *
560
+ * const { spec, text, hasSpec } = useJsonRenderMessage(message.parts);
561
+ * ```
562
+ */
563
+ declare function useJsonRenderMessage(parts: DataPart[] | Ref<DataPart[]>): {
564
+ spec: ComputedRef<Spec | null>;
565
+ text: ComputedRef<string>;
566
+ hasSpec: ComputedRef<boolean>;
567
+ };
568
+ /**
569
+ * A single message in the chat, which may contain text, a rendered UI spec, or both.
570
+ */
571
+ interface ChatMessage {
572
+ /** Unique message ID */
573
+ id: string;
574
+ /** Who sent this message */
575
+ role: "user" | "assistant";
576
+ /** Text content (conversational prose) */
577
+ text: string;
578
+ /** json-render Spec built from JSONL patches (null if no UI was generated) */
579
+ spec: Spec | null;
580
+ }
581
+ /**
582
+ * Options for useChatUI
583
+ */
584
+ interface UseChatUIOptions {
585
+ /** API endpoint that accepts `{ messages: Array<{ role, content }> }` and returns a text stream */
586
+ api: string;
587
+ /** Callback when streaming completes for a message */
588
+ onComplete?: (message: ChatMessage) => void;
589
+ /** Callback on error */
590
+ onError?: (error: Error) => void;
591
+ }
592
+ /**
593
+ * Return type for useChatUI
594
+ */
595
+ interface UseChatUIReturn {
596
+ /** All messages in the conversation */
597
+ messages: Ref<ChatMessage[]>;
598
+ /** Whether currently streaming an assistant response */
599
+ isStreaming: Ref<boolean>;
600
+ /** Error from the last request, if any */
601
+ error: Ref<Error | null>;
602
+ /** Send a user message */
603
+ send: (text: string) => Promise<void>;
604
+ /** Clear all messages and reset the conversation */
605
+ clear: () => void;
606
+ }
607
+ /**
608
+ * Composable for chat + GenUI experiences.
609
+ *
610
+ * Manages a multi-turn conversation where each assistant message can contain
611
+ * both conversational text and a json-render UI spec. Sends the full message
612
+ * history to the API endpoint, reads the streamed response, and separates
613
+ * text lines from JSONL patch lines using `createMixedStreamParser`.
614
+ *
615
+ * @example
616
+ * ```ts
617
+ * const { messages, isStreaming, send, clear } = useChatUI({ api: "/api/chat" });
618
+ *
619
+ * await send("Compare weather in NYC and Tokyo");
620
+ * ```
621
+ */
622
+ declare function useChatUI({ api, onComplete, onError, }: UseChatUIOptions): UseChatUIReturn;
623
+
624
+ /**
625
+ * Props passed to component renderers
626
+ */
627
+ interface ComponentRenderProps<P = Record<string, unknown>> {
628
+ /** The element being rendered */
629
+ element: UIElement<string, P>;
630
+ /** Emit a named event */
631
+ emit: (event: string) => void;
632
+ /** Get an event handle with metadata */
633
+ on: (event: string) => EventHandle;
634
+ /**
635
+ * Two-way binding paths resolved from `$bindState` / `$bindItem` expressions.
636
+ * Maps prop name → absolute state path for write-back.
637
+ */
638
+ bindings?: Record<string, string>;
639
+ /** Whether the parent is loading */
640
+ loading?: boolean;
641
+ }
642
+ /**
643
+ * Registry of component renderers (Vue component definitions)
644
+ */
645
+ type ComponentRegistry = Record<string, Component>;
646
+ /**
647
+ * Props for the Renderer component
648
+ */
649
+ interface RendererProps {
650
+ spec: Spec | null;
651
+ registry: ComponentRegistry;
652
+ loading?: boolean;
653
+ fallback?: Component;
654
+ }
655
+ /**
656
+ * Main renderer component
657
+ */
658
+ declare const Renderer: vue.DefineComponent<vue.ExtractPropTypes<{
659
+ spec: {
660
+ type: PropType<Spec | null>;
661
+ default: null;
662
+ };
663
+ registry: {
664
+ type: PropType<ComponentRegistry>;
665
+ required: true;
666
+ };
667
+ loading: {
668
+ type: BooleanConstructor;
669
+ default: undefined;
670
+ };
671
+ fallback: {
672
+ type: PropType<Component>;
673
+ default: undefined;
674
+ };
675
+ }>, () => VNode<vue.RendererNode, vue.RendererElement, {
676
+ [key: string]: any;
677
+ }> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
678
+ spec: {
679
+ type: PropType<Spec | null>;
680
+ default: null;
681
+ };
682
+ registry: {
683
+ type: PropType<ComponentRegistry>;
684
+ required: true;
685
+ };
686
+ loading: {
687
+ type: BooleanConstructor;
688
+ default: undefined;
689
+ };
690
+ fallback: {
691
+ type: PropType<Component>;
692
+ default: undefined;
693
+ };
694
+ }>> & Readonly<{}>, {
695
+ spec: Spec | null;
696
+ loading: boolean;
697
+ fallback: Component;
698
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
699
+ /**
700
+ * Props for JSONUIProvider
701
+ */
702
+ interface JSONUIProviderProps {
703
+ registry: ComponentRegistry;
704
+ store?: StateStore;
705
+ initialState?: Record<string, unknown>;
706
+ handlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
707
+ navigate?: (path: string) => void;
708
+ validationFunctions?: Record<string, (value: unknown, args?: Record<string, unknown>) => boolean>;
709
+ /** Named functions for `$computed` expressions in props */
710
+ functions?: Record<string, ComputedFunction>;
711
+ onStateChange?: (changes: Array<{
712
+ path: string;
713
+ value: unknown;
714
+ }>) => void;
715
+ }
716
+ /**
717
+ * Combined provider for all JSONUI contexts
718
+ */
719
+ declare const JSONUIProvider: vue.DefineComponent<vue.ExtractPropTypes<{
720
+ registry: {
721
+ type: PropType<ComponentRegistry>;
722
+ required: true;
723
+ };
724
+ store: {
725
+ type: PropType<StateStore>;
726
+ default: undefined;
727
+ };
728
+ initialState: {
729
+ type: PropType<Record<string, unknown>>;
730
+ default: undefined;
731
+ };
732
+ handlers: {
733
+ type: PropType<Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>>;
734
+ default: undefined;
735
+ };
736
+ navigate: {
737
+ type: PropType<(path: string) => void>;
738
+ default: undefined;
739
+ };
740
+ validationFunctions: {
741
+ type: PropType<Record<string, (value: unknown, args?: Record<string, unknown>) => boolean>>;
742
+ default: undefined;
743
+ };
744
+ functions: {
745
+ type: PropType<Record<string, ComputedFunction>>;
746
+ default: undefined;
747
+ };
748
+ onStateChange: {
749
+ type: PropType<(changes: Array<{
750
+ path: string;
751
+ value: unknown;
752
+ }>) => void>;
753
+ default: undefined;
754
+ };
755
+ }>, () => VNode<vue.RendererNode, vue.RendererElement, {
756
+ [key: string]: any;
757
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
758
+ registry: {
759
+ type: PropType<ComponentRegistry>;
760
+ required: true;
761
+ };
762
+ store: {
763
+ type: PropType<StateStore>;
764
+ default: undefined;
765
+ };
766
+ initialState: {
767
+ type: PropType<Record<string, unknown>>;
768
+ default: undefined;
769
+ };
770
+ handlers: {
771
+ type: PropType<Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>>;
772
+ default: undefined;
773
+ };
774
+ navigate: {
775
+ type: PropType<(path: string) => void>;
776
+ default: undefined;
777
+ };
778
+ validationFunctions: {
779
+ type: PropType<Record<string, (value: unknown, args?: Record<string, unknown>) => boolean>>;
780
+ default: undefined;
781
+ };
782
+ functions: {
783
+ type: PropType<Record<string, ComputedFunction>>;
784
+ default: undefined;
785
+ };
786
+ onStateChange: {
787
+ type: PropType<(changes: Array<{
788
+ path: string;
789
+ value: unknown;
790
+ }>) => void>;
791
+ default: undefined;
792
+ };
793
+ }>> & Readonly<{}>, {
794
+ store: StateStore;
795
+ initialState: Record<string, unknown>;
796
+ onStateChange: (changes: Array<{
797
+ path: string;
798
+ value: unknown;
799
+ }>) => void;
800
+ handlers: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
801
+ navigate: (path: string) => void;
802
+ functions: Record<string, ComputedFunction>;
803
+ validationFunctions: Record<string, (value: unknown, args?: Record<string, unknown>) => boolean>;
804
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
805
+ /**
806
+ * Result returned by defineRegistry
807
+ */
808
+ interface DefineRegistryResult {
809
+ registry: ComponentRegistry;
810
+ handlers: (getSetState: () => SetState | undefined, getState: () => StateModel) => Record<string, (params: Record<string, unknown>) => Promise<void>>;
811
+ executeAction: (actionName: string, params: Record<string, unknown> | undefined, setState: SetState, state?: StateModel) => Promise<void>;
812
+ }
813
+ type DefineRegistryOptions<C extends Catalog> = {
814
+ components?: Components<C>;
815
+ } & (CatalogHasActions<C> extends true ? {
816
+ actions: Actions<C>;
817
+ } : {
818
+ actions?: Actions<C>;
819
+ });
820
+ /**
821
+ * Create a registry from a catalog with components and/or actions.
822
+ *
823
+ * @example
824
+ * ```ts
825
+ * // Components only
826
+ * const { registry } = defineRegistry(catalog, {
827
+ * components: {
828
+ * Card: ({ props, children }) => h('div', { class: 'card' }, [props.title, children]),
829
+ * },
830
+ * });
831
+ *
832
+ * // Both
833
+ * const { registry, handlers, executeAction } = defineRegistry(catalog, {
834
+ * components: { ... },
835
+ * actions: { ... },
836
+ * });
837
+ * ```
838
+ */
839
+ declare function defineRegistry<C extends Catalog>(_catalog: C, options: DefineRegistryOptions<C>): DefineRegistryResult;
840
+ /**
841
+ * Props for renderers created with createRenderer
842
+ */
843
+ interface CreateRendererProps {
844
+ spec: Spec | null;
845
+ store?: StateStore;
846
+ state?: Record<string, unknown>;
847
+ onAction?: (actionName: string, params?: Record<string, unknown>) => void;
848
+ onStateChange?: (changes: Array<{
849
+ path: string;
850
+ value: unknown;
851
+ }>) => void;
852
+ /** Named functions for `$computed` expressions in props */
853
+ functions?: Record<string, ComputedFunction>;
854
+ loading?: boolean;
855
+ fallback?: Component;
856
+ }
857
+ /**
858
+ * Component map type — maps component names to Vue components
859
+ */
860
+ type ComponentMap<TComponents extends Record<string, {
861
+ props: unknown;
862
+ }>> = {
863
+ [K in keyof TComponents]: Component;
864
+ };
865
+ /**
866
+ * Create a renderer from a catalog
867
+ *
868
+ * @example
869
+ * ```typescript
870
+ * const DashboardRenderer = createRenderer(dashboardCatalog, {
871
+ * Card: ({ props, children }) => h('div', { class: 'card' }, children),
872
+ * Metric: ({ props }) => h('span', null, props.value),
873
+ * });
874
+ *
875
+ * // Usage in template
876
+ * <DashboardRenderer :spec="aiGeneratedSpec" :state="state" />
877
+ * ```
878
+ */
879
+ declare function createRenderer<TDef extends SchemaDefinition, TCatalog extends {
880
+ components: Record<string, {
881
+ props: unknown;
882
+ }>;
883
+ }>(catalog: Catalog<TDef, TCatalog>, components: ComponentMap<TCatalog["components"]>): Component;
884
+
885
+ export { type ActionContextValue, type ActionFn, ActionProvider, type ActionProviderProps, type Actions, type BaseComponentProps, type ChatMessage, type ComponentContext, type ComponentFn, type ComponentMap, type ComponentRegistry, type ComponentRenderProps, type Components, ConfirmDialog, type ConfirmDialogProps, type CreateRendererProps, type DataPart, type DefineRegistryResult, type EventHandle, type FieldValidationState, JSONUIProvider, type JSONUIProviderProps, type PendingConfirmation, Renderer, type RendererProps, RepeatScopeProvider, type RepeatScopeValue, type SetState, type StateContextValue, StateProvider, type StateProviderProps, type TokenUsage, type UseChatUIOptions, type UseChatUIReturn, type UseUIStreamOptions, type UseUIStreamReturn, type ValidationContextValue, ValidationProvider, type ValidationProviderProps, type VisibilityContextValue, VisibilityProvider, buildSpecFromParts, createRenderer, defineRegistry, flatToTree, getTextFromParts, useAction, useActions, useBoundProp, useChatUI, useFieldValidation, useIsVisible, useJsonRenderMessage, useOptionalValidation, useRepeatScope, useStateBinding, useStateStore, useStateValue, useUIStream, useValidation, useVisibility };