@wotnak/json-render-react 0.0.0-pr.slots.9c5563f

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 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/contexts/state.tsx","../src/contexts/visibility.tsx","../src/contexts/actions.tsx","../src/contexts/validation.tsx","../src/contexts/repeat-scope.tsx","../src/schema.ts","../src/renderer.tsx","../src/hooks.ts"],"sourcesContent":["// Contexts\nexport {\n StateProvider,\n useStateStore,\n useStateValue,\n useStateBinding,\n type StateContextValue,\n type StateProviderProps,\n} from \"./contexts/state\";\n\nexport {\n VisibilityProvider,\n useVisibility,\n useIsVisible,\n type VisibilityContextValue,\n type VisibilityProviderProps,\n} from \"./contexts/visibility\";\n\nexport {\n ActionProvider,\n useActions,\n useAction,\n ConfirmDialog,\n type ActionContextValue,\n type ActionProviderProps,\n type PendingConfirmation,\n type ConfirmDialogProps,\n} from \"./contexts/actions\";\n\nexport {\n ValidationProvider,\n useValidation,\n useFieldValidation,\n type ValidationContextValue,\n type ValidationProviderProps,\n type FieldValidationState,\n} from \"./contexts/validation\";\n\nexport {\n RepeatScopeProvider,\n useRepeatScope,\n type RepeatScopeValue,\n} from \"./contexts/repeat-scope\";\n\n// Schema (React's spec format)\nexport {\n schema,\n type ReactSchema,\n type ReactSpec,\n // Backward compatibility\n elementTreeSchema,\n type ElementTreeSchema,\n type ElementTreeSpec,\n} from \"./schema\";\n\n// Core types (re-exported for convenience)\nexport type { Spec } from \"@json-render/core\";\n\n// Catalog-aware types for React\nexport type {\n SetState,\n StateModel,\n ComponentContext,\n ComponentFn,\n Components,\n ActionFn,\n Actions,\n} from \"./catalog-types\";\n\n// Renderer\nexport {\n // Registry\n defineRegistry,\n type DefineRegistryResult,\n // createRenderer (higher-level, includes providers)\n createRenderer,\n type CreateRendererProps,\n type ComponentMap,\n // Low-level\n Renderer,\n JSONUIProvider,\n type ComponentRenderProps,\n type ComponentRenderer,\n type ComponentRegistry,\n type RendererProps,\n type JSONUIProviderProps,\n} from \"./renderer\";\n\n// Hooks\nexport {\n useUIStream,\n useChatUI,\n useBoundProp,\n flatToTree,\n buildSpecFromParts,\n getTextFromParts,\n useJsonRenderMessage,\n type UseUIStreamOptions,\n type UseUIStreamReturn,\n type UseChatUIOptions,\n type UseChatUIReturn,\n type ChatMessage,\n type DataPart,\n type TokenUsage,\n} from \"./hooks\";\n","\"use client\";\n\nimport React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useMemo,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\";\nimport { getByPath, setByPath, type StateModel } from \"@json-render/core\";\n\n/**\n * State context value\n */\nexport interface StateContextValue {\n /** The current state model */\n state: StateModel;\n /** Get a value by path */\n get: (path: string) => unknown;\n /** Set a value by path */\n set: (path: string, value: unknown) => void;\n /** Update multiple values at once */\n update: (updates: Record<string, unknown>) => void;\n}\n\nconst StateContext = createContext<StateContextValue | null>(null);\n\n/**\n * Props for StateProvider\n */\nexport interface StateProviderProps {\n /** Initial state model */\n initialState?: StateModel;\n /** Callback when state changes */\n onStateChange?: (path: string, value: unknown) => void;\n children: ReactNode;\n}\n\n/**\n * Provider for state model context\n */\nexport function StateProvider({\n initialState = {},\n onStateChange,\n children,\n}: StateProviderProps) {\n const [state, setStateInternal] = useState<StateModel>(initialState);\n\n // Keep a ref to the latest state so `get` doesn't change on every update.\n const stateRef = useRef(state);\n stateRef.current = state;\n\n // Track the serialized initialState to detect actual value changes (not just reference changes)\n const initialStateJsonRef = useRef<string>(JSON.stringify(initialState));\n\n // Sync external state changes with internal state - only when values actually change\n useEffect(() => {\n const newJson = JSON.stringify(initialState);\n if (newJson !== initialStateJsonRef.current) {\n initialStateJsonRef.current = newJson;\n if (initialState && Object.keys(initialState).length > 0) {\n setStateInternal((prev) => ({ ...prev, ...initialState }));\n }\n }\n }, [initialState]);\n\n // `get` uses a ref so it never changes identity — consumers that only\n // need `get` won't re-render on every state change.\n const get = useCallback(\n (path: string) => getByPath(stateRef.current, path),\n [],\n );\n\n const set = useCallback(\n (path: string, value: unknown) => {\n setStateInternal((prev) => {\n const next = { ...prev };\n setByPath(next, path, value);\n return next;\n });\n // Side effect after the state update\n onStateChange?.(path, value);\n },\n [onStateChange],\n );\n\n const update = useCallback(\n (updates: Record<string, unknown>) => {\n const entries = Object.entries(updates);\n setStateInternal((prev) => {\n const next = { ...prev };\n for (const [path, value] of entries) {\n setByPath(next, path, value);\n }\n return next;\n });\n // Side effects after the state update\n for (const [path, value] of entries) {\n onStateChange?.(path, value);\n }\n },\n [onStateChange],\n );\n\n const value = useMemo<StateContextValue>(\n () => ({\n state,\n get,\n set,\n update,\n }),\n [state, get, set, update],\n );\n\n return (\n <StateContext.Provider value={value}>{children}</StateContext.Provider>\n );\n}\n\n/**\n * Hook to access the state context\n */\nexport function useStateStore(): StateContextValue {\n const ctx = useContext(StateContext);\n if (!ctx) {\n throw new Error(\"useStateStore must be used within a StateProvider\");\n }\n return ctx;\n}\n\n/**\n * Hook to get a value from the state model\n */\nexport function useStateValue<T>(path: string): T | undefined {\n const { state } = useStateStore();\n return getByPath(state, path) as T | undefined;\n}\n\n/**\n * Hook to get and set a value from the state model (like useState).\n *\n * @deprecated Use {@link useBoundProp} with `$bindState` expressions instead.\n * `useStateBinding` takes a raw state path string, while `useBoundProp` works\n * with the renderer's `bindings` map and supports both `$bindState` and\n * `$bindItem` expressions.\n */\nexport function useStateBinding<T>(\n path: string,\n): [T | undefined, (value: T) => void] {\n const { state, set } = useStateStore();\n const value = getByPath(state, path) as T | undefined;\n const setValue = useCallback(\n (newValue: T) => set(path, newValue),\n [path, set],\n );\n return [value, setValue];\n}\n","\"use client\";\n\nimport React, {\n createContext,\n useContext,\n useMemo,\n type ReactNode,\n} from \"react\";\nimport {\n evaluateVisibility,\n type VisibilityCondition,\n type VisibilityContext as CoreVisibilityContext,\n} from \"@json-render/core\";\nimport { useStateStore } from \"./state\";\n\n/**\n * Visibility context value\n */\nexport interface VisibilityContextValue {\n /** Evaluate a visibility condition */\n isVisible: (condition: VisibilityCondition | undefined) => boolean;\n /** The underlying visibility context */\n ctx: CoreVisibilityContext;\n}\n\nconst VisibilityContext = createContext<VisibilityContextValue | null>(null);\n\n/**\n * Props for VisibilityProvider\n */\nexport interface VisibilityProviderProps {\n children: ReactNode;\n}\n\n/**\n * Provider for visibility evaluation\n */\nexport function VisibilityProvider({ children }: VisibilityProviderProps) {\n const { state } = useStateStore();\n\n const ctx: CoreVisibilityContext = useMemo(\n () => ({\n stateModel: state,\n }),\n [state],\n );\n\n const isVisible = useMemo(\n () => (condition: VisibilityCondition | undefined) =>\n evaluateVisibility(condition, ctx),\n [ctx],\n );\n\n const value = useMemo<VisibilityContextValue>(\n () => ({ isVisible, ctx }),\n [isVisible, ctx],\n );\n\n return (\n <VisibilityContext.Provider value={value}>\n {children}\n </VisibilityContext.Provider>\n );\n}\n\n/**\n * Hook to access visibility evaluation\n */\nexport function useVisibility(): VisibilityContextValue {\n const ctx = useContext(VisibilityContext);\n if (!ctx) {\n throw new Error(\"useVisibility must be used within a VisibilityProvider\");\n }\n return ctx;\n}\n\n/**\n * Hook to check if a condition is visible\n */\nexport function useIsVisible(\n condition: VisibilityCondition | undefined,\n): boolean {\n const { isVisible } = useVisibility();\n return isVisible(condition);\n}\n","\"use client\";\n\nimport React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useMemo,\n useRef,\n type ReactNode,\n} from \"react\";\nimport {\n resolveAction,\n executeAction,\n type ActionBinding,\n type ActionHandler,\n type ActionConfirm,\n type ResolvedAction,\n} from \"@json-render/core\";\nimport { useStateStore } from \"./state\";\n\n/**\n * Generate a unique ID for use with the \"$id\" token.\n * Combines a timestamp with a random suffix for uniqueness.\n */\nlet idCounter = 0;\nfunction generateUniqueId(): string {\n idCounter += 1;\n return `${Date.now()}-${idCounter}`;\n}\n\n/**\n * Deep-resolve dynamic value references within an object.\n *\n * Supported tokens:\n * - `{ $state: \"/statePath\" }` - read a value from state\n * - `\"$id\"` (string) or `{ \"$id\": true }` - generate a unique ID\n *\n * This allows pushState values to contain references to current state\n * and auto-generated IDs.\n */\nfunction deepResolveValue(\n value: unknown,\n get: (path: string) => unknown,\n): unknown {\n if (value === null || value === undefined) return value;\n\n // \"$id\" string token -> generate unique ID\n if (value === \"$id\") {\n return generateUniqueId();\n }\n\n if (typeof value === \"object\" && !Array.isArray(value)) {\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj);\n\n // { $state: \"/foo\" } -> read from state\n if (keys.length === 1 && typeof obj.$state === \"string\") {\n return get(obj.$state as string);\n }\n\n // { \"$id\": true } -> generate unique ID (single-key object)\n if (keys.length === 1 && \"$id\" in obj) {\n return generateUniqueId();\n }\n }\n\n // Recurse into arrays\n if (Array.isArray(value)) {\n return value.map((item) => deepResolveValue(item, get));\n }\n\n // Recurse into plain objects\n if (typeof value === \"object\") {\n const resolved: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n resolved[key] = deepResolveValue(val, get);\n }\n return resolved;\n }\n\n return value;\n}\n\n/**\n * Pending confirmation state\n */\nexport interface PendingConfirmation {\n /** The resolved action */\n action: ResolvedAction;\n /** The action handler */\n handler: ActionHandler;\n /** Resolve callback */\n resolve: () => void;\n /** Reject callback */\n reject: () => void;\n}\n\n/**\n * Action context value\n */\nexport interface ActionContextValue {\n /** Registered action handlers */\n handlers: Record<string, ActionHandler>;\n /** Currently loading action names */\n loadingActions: Set<string>;\n /** Pending confirmation dialog */\n pendingConfirmation: PendingConfirmation | null;\n /** Execute an action binding */\n execute: (binding: ActionBinding) => Promise<void>;\n /** Confirm the pending action */\n confirm: () => void;\n /** Cancel the pending action */\n cancel: () => void;\n /** Register an action handler */\n registerHandler: (name: string, handler: ActionHandler) => void;\n}\n\nconst ActionContext = createContext<ActionContextValue | null>(null);\n\n/**\n * Props for ActionProvider\n */\nexport interface ActionProviderProps {\n /** Initial action handlers */\n handlers?: Record<string, ActionHandler>;\n /** Navigation function */\n navigate?: (path: string) => void;\n children: ReactNode;\n}\n\n/**\n * Provider for action execution\n */\nexport function ActionProvider({\n handlers: initialHandlers = {},\n navigate,\n children,\n}: ActionProviderProps) {\n const { state, get, set } = useStateStore();\n // Keep a ref to the latest state so `execute` doesn't change on every\n // state update — preventing the entire action context from churning.\n const stateRef = useRef(state);\n stateRef.current = state;\n\n const [handlers, setHandlers] =\n useState<Record<string, ActionHandler>>(initialHandlers);\n const [loadingActions, setLoadingActions] = useState<Set<string>>(new Set());\n const [pendingConfirmation, setPendingConfirmation] =\n useState<PendingConfirmation | null>(null);\n\n const registerHandler = useCallback(\n (name: string, handler: ActionHandler) => {\n setHandlers((prev) => ({ ...prev, [name]: handler }));\n },\n [],\n );\n\n const execute = useCallback(\n async (binding: ActionBinding) => {\n const resolved = resolveAction(binding, stateRef.current);\n\n // Built-in: setState updates the StateProvider state directly\n if (resolved.action === \"setState\" && resolved.params) {\n const statePath = resolved.params.statePath as string;\n const value = resolved.params.value;\n if (statePath) {\n set(statePath, value);\n }\n return;\n }\n\n // Built-in: pushState appends an item to an array in state.\n // Supports dynamic values inside the value object via { $state: \"/...\" } syntax.\n if (resolved.action === \"pushState\" && resolved.params) {\n const statePath = resolved.params.statePath as string;\n const rawValue = resolved.params.value;\n if (statePath) {\n const resolvedValue = deepResolveValue(rawValue, get);\n const arr = (get(statePath) as unknown[] | undefined) ?? [];\n set(statePath, [...arr, resolvedValue]);\n // Optionally clear a state path after pushing (e.g. clear the input)\n const clearStatePath = resolved.params.clearStatePath as\n | string\n | undefined;\n if (clearStatePath) {\n set(clearStatePath, \"\");\n }\n }\n return;\n }\n\n // Built-in: removeState removes an item from an array in state by index.\n if (resolved.action === \"removeState\" && resolved.params) {\n const statePath = resolved.params.statePath as string;\n const index = resolved.params.index as number;\n if (statePath !== undefined && index !== undefined) {\n const arr = (get(statePath) as unknown[] | undefined) ?? [];\n set(\n statePath,\n arr.filter((_, i) => i !== index),\n );\n }\n return;\n }\n\n // Built-in: push navigates to a new screen by updating state.\n // Pushes the current screen onto /navStack and sets /currentScreen.\n if (resolved.action === \"push\" && resolved.params) {\n const screen = resolved.params.screen as string;\n if (screen) {\n const currentScreen = get(\"/currentScreen\") as string | undefined;\n const navStack = (get(\"/navStack\") as string[] | undefined) ?? [];\n if (currentScreen) {\n set(\"/navStack\", [...navStack, currentScreen]);\n } else {\n // No current screen set yet -- push a sentinel so pop returns here\n set(\"/navStack\", [...navStack, \"\"]);\n }\n set(\"/currentScreen\", screen);\n }\n return;\n }\n\n // Built-in: pop navigates back to the previous screen.\n // Pops the last entry from /navStack and restores /currentScreen.\n if (resolved.action === \"pop\") {\n const navStack = (get(\"/navStack\") as string[] | undefined) ?? [];\n if (navStack.length > 0) {\n const previousScreen = navStack[navStack.length - 1];\n set(\"/navStack\", navStack.slice(0, -1));\n if (previousScreen) {\n set(\"/currentScreen\", previousScreen);\n } else {\n // Sentinel empty string = clear currentScreen (return to default)\n set(\"/currentScreen\", undefined);\n }\n }\n return;\n }\n\n const handler = handlers[resolved.action];\n\n if (!handler) {\n console.warn(`No handler registered for action: ${resolved.action}`);\n return;\n }\n\n // If confirmation is required, show dialog\n if (resolved.confirm) {\n return new Promise<void>((resolve, reject) => {\n setPendingConfirmation({\n action: resolved,\n handler,\n resolve: () => {\n setPendingConfirmation(null);\n resolve();\n },\n reject: () => {\n setPendingConfirmation(null);\n reject(new Error(\"Action cancelled\"));\n },\n });\n }).then(async () => {\n setLoadingActions((prev) => new Set(prev).add(resolved.action));\n try {\n await executeAction({\n action: resolved,\n handler,\n setState: set,\n navigate,\n executeAction: async (name) => {\n const subBinding: ActionBinding = { action: name };\n await execute(subBinding);\n },\n });\n } finally {\n setLoadingActions((prev) => {\n const next = new Set(prev);\n next.delete(resolved.action);\n return next;\n });\n }\n });\n }\n\n // Execute immediately\n setLoadingActions((prev) => new Set(prev).add(resolved.action));\n try {\n await executeAction({\n action: resolved,\n handler,\n setState: set,\n navigate,\n executeAction: async (name) => {\n const subBinding: ActionBinding = { action: name };\n await execute(subBinding);\n },\n });\n } finally {\n setLoadingActions((prev) => {\n const next = new Set(prev);\n next.delete(resolved.action);\n return next;\n });\n }\n },\n [handlers, get, set, navigate],\n );\n\n const confirm = useCallback(() => {\n pendingConfirmation?.resolve();\n }, [pendingConfirmation]);\n\n const cancel = useCallback(() => {\n pendingConfirmation?.reject();\n }, [pendingConfirmation]);\n\n const value = useMemo<ActionContextValue>(\n () => ({\n handlers,\n loadingActions,\n pendingConfirmation,\n execute,\n confirm,\n cancel,\n registerHandler,\n }),\n [\n handlers,\n loadingActions,\n pendingConfirmation,\n execute,\n confirm,\n cancel,\n registerHandler,\n ],\n );\n\n return (\n <ActionContext.Provider value={value}>{children}</ActionContext.Provider>\n );\n}\n\n/**\n * Hook to access action context\n */\nexport function useActions(): ActionContextValue {\n const ctx = useContext(ActionContext);\n if (!ctx) {\n throw new Error(\"useActions must be used within an ActionProvider\");\n }\n return ctx;\n}\n\n/**\n * Hook to execute an action binding\n */\nexport function useAction(binding: ActionBinding): {\n execute: () => Promise<void>;\n isLoading: boolean;\n} {\n const { execute, loadingActions } = useActions();\n const isLoading = loadingActions.has(binding.action);\n\n const executeAction = useCallback(() => execute(binding), [execute, binding]);\n\n return { execute: executeAction, isLoading };\n}\n\n/**\n * Props for ConfirmDialog component\n */\nexport interface ConfirmDialogProps {\n /** The confirmation config */\n confirm: ActionConfirm;\n /** Called when confirmed */\n onConfirm: () => void;\n /** Called when cancelled */\n onCancel: () => void;\n}\n\n/**\n * Default confirmation dialog component\n */\nexport function ConfirmDialog({\n confirm,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n const isDanger = confirm.variant === \"danger\";\n\n return (\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 50,\n }}\n onClick={onCancel}\n >\n <div\n style={{\n backgroundColor: \"white\",\n borderRadius: \"8px\",\n padding: \"24px\",\n maxWidth: \"400px\",\n width: \"100%\",\n boxShadow: \"0 20px 25px -5px rgba(0, 0, 0, 0.1)\",\n }}\n onClick={(e) => e.stopPropagation()}\n >\n <h3\n style={{\n margin: \"0 0 8px 0\",\n fontSize: \"18px\",\n fontWeight: 600,\n }}\n >\n {confirm.title}\n </h3>\n <p\n style={{\n margin: \"0 0 24px 0\",\n color: \"#6b7280\",\n }}\n >\n {confirm.message}\n </p>\n <div\n style={{\n display: \"flex\",\n gap: \"12px\",\n justifyContent: \"flex-end\",\n }}\n >\n <button\n onClick={onCancel}\n style={{\n padding: \"8px 16px\",\n borderRadius: \"6px\",\n border: \"1px solid #d1d5db\",\n backgroundColor: \"white\",\n cursor: \"pointer\",\n }}\n >\n {confirm.cancelLabel ?? \"Cancel\"}\n </button>\n <button\n onClick={onConfirm}\n style={{\n padding: \"8px 16px\",\n borderRadius: \"6px\",\n border: \"none\",\n backgroundColor: isDanger ? \"#dc2626\" : \"#3b82f6\",\n color: \"white\",\n cursor: \"pointer\",\n }}\n >\n {confirm.confirmLabel ?? \"Confirm\"}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useMemo,\n useRef,\n type ReactNode,\n} from \"react\";\nimport {\n runValidation,\n type ValidationConfig,\n type ValidationFunction,\n type ValidationResult,\n} from \"@json-render/core\";\nimport { useStateStore } from \"./state\";\n\n/**\n * Field validation state\n */\nexport interface FieldValidationState {\n /** Whether the field has been touched */\n touched: boolean;\n /** Whether the field has been validated */\n validated: boolean;\n /** Validation result */\n result: ValidationResult | null;\n}\n\n/**\n * Validation context value\n */\nexport interface ValidationContextValue {\n /** Custom validation functions from catalog */\n customFunctions: Record<string, ValidationFunction>;\n /** Validation state by field path */\n fieldStates: Record<string, FieldValidationState>;\n /** Validate a field */\n validate: (path: string, config: ValidationConfig) => ValidationResult;\n /** Mark field as touched */\n touch: (path: string) => void;\n /** Clear validation for a field */\n clear: (path: string) => void;\n /** Validate all fields */\n validateAll: () => boolean;\n /** Register field config */\n registerField: (path: string, config: ValidationConfig) => void;\n}\n\nconst ValidationContext = createContext<ValidationContextValue | null>(null);\n\n/**\n * Props for ValidationProvider\n */\nexport interface ValidationProviderProps {\n /** Custom validation functions from catalog */\n customFunctions?: Record<string, ValidationFunction>;\n children: ReactNode;\n}\n\n/**\n * Compare two DynamicValue args records shallowly.\n * Values are primitives or { $state: string }, so shallow comparison suffices.\n */\nfunction dynamicArgsEqual(\n a: Record<string, unknown> | undefined,\n b: Record<string, unknown> | undefined,\n): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n const va = a[key];\n const vb = b[key];\n if (va === vb) continue;\n // Handle { $state: string } objects\n if (\n typeof va === \"object\" &&\n va !== null &&\n typeof vb === \"object\" &&\n vb !== null\n ) {\n const sa = (va as Record<string, unknown>).$state;\n const sb = (vb as Record<string, unknown>).$state;\n if (typeof sa === \"string\" && sa === sb) continue;\n }\n return false;\n }\n return true;\n}\n\n/**\n * Structural equality check for ValidationConfig.\n */\nfunction validationConfigEqual(\n a: ValidationConfig,\n b: ValidationConfig,\n): boolean {\n if (a === b) return true;\n\n // Compare validateOn\n if (a.validateOn !== b.validateOn) return false;\n\n // Compare checks arrays\n const ac = a.checks ?? [];\n const bc = b.checks ?? [];\n if (ac.length !== bc.length) return false;\n\n for (let i = 0; i < ac.length; i++) {\n const ca = ac[i]!;\n const cb = bc[i]!;\n if (ca.type !== cb.type) return false;\n if (ca.message !== cb.message) return false;\n if (!dynamicArgsEqual(ca.args, cb.args)) return false;\n }\n\n return true;\n}\n\n/**\n * Provider for validation\n */\nexport function ValidationProvider({\n customFunctions = {},\n children,\n}: ValidationProviderProps) {\n const { state } = useStateStore();\n // Keep a ref to the latest state so `validate` doesn't change on every\n // state update — preventing the entire validation context from churning.\n const stateRef = useRef(state);\n stateRef.current = state;\n\n const [fieldStates, setFieldStates] = useState<\n Record<string, FieldValidationState>\n >({});\n const [fieldConfigs, setFieldConfigs] = useState<\n Record<string, ValidationConfig>\n >({});\n\n const registerField = useCallback(\n (path: string, config: ValidationConfig) => {\n setFieldConfigs((prev) => {\n const existing = prev[path];\n // Bail out (return same reference) if config is unchanged to avoid\n // infinite re-render loops when callers pass a fresh object each render.\n if (existing && validationConfigEqual(existing, config)) {\n return prev;\n }\n return { ...prev, [path]: config };\n });\n },\n [],\n );\n\n const validate = useCallback(\n (path: string, config: ValidationConfig): ValidationResult => {\n // Walk the nested state object using JSON Pointer segments\n const currentState = stateRef.current;\n const segments = path.split(\"/\").filter(Boolean);\n let value: unknown = currentState;\n for (const seg of segments) {\n if (value != null && typeof value === \"object\") {\n value = (value as Record<string, unknown>)[seg];\n } else {\n value = undefined;\n break;\n }\n }\n const result = runValidation(config, {\n value,\n stateModel: currentState,\n customFunctions,\n });\n\n setFieldStates((prev) => ({\n ...prev,\n [path]: {\n touched: prev[path]?.touched ?? true,\n validated: true,\n result,\n },\n }));\n\n return result;\n },\n [customFunctions],\n );\n\n const touch = useCallback((path: string) => {\n setFieldStates((prev) => ({\n ...prev,\n [path]: {\n ...prev[path],\n touched: true,\n validated: prev[path]?.validated ?? false,\n result: prev[path]?.result ?? null,\n },\n }));\n }, []);\n\n const clear = useCallback((path: string) => {\n setFieldStates((prev) => {\n const { [path]: _, ...rest } = prev;\n return rest;\n });\n }, []);\n\n const validateAll = useCallback(() => {\n let allValid = true;\n\n for (const [path, config] of Object.entries(fieldConfigs)) {\n const result = validate(path, config);\n if (!result.valid) {\n allValid = false;\n }\n }\n\n return allValid;\n }, [fieldConfigs, validate]);\n\n const value = useMemo<ValidationContextValue>(\n () => ({\n customFunctions,\n fieldStates,\n validate,\n touch,\n clear,\n validateAll,\n registerField,\n }),\n [\n customFunctions,\n fieldStates,\n validate,\n touch,\n clear,\n validateAll,\n registerField,\n ],\n );\n\n return (\n <ValidationContext.Provider value={value}>\n {children}\n </ValidationContext.Provider>\n );\n}\n\n/**\n * Hook to access validation context\n */\nexport function useValidation(): ValidationContextValue {\n const ctx = useContext(ValidationContext);\n if (!ctx) {\n throw new Error(\"useValidation must be used within a ValidationProvider\");\n }\n return ctx;\n}\n\n/**\n * Hook to get validation state for a field\n */\nexport function useFieldValidation(\n path: string,\n config?: ValidationConfig,\n): {\n state: FieldValidationState;\n validate: () => ValidationResult;\n touch: () => void;\n clear: () => void;\n errors: string[];\n isValid: boolean;\n} {\n const {\n fieldStates,\n validate: validateField,\n touch: touchField,\n clear: clearField,\n registerField,\n } = useValidation();\n\n // Register field on mount\n React.useEffect(() => {\n if (path && config) {\n registerField(path, config);\n }\n }, [path, config, registerField]);\n\n const state = fieldStates[path] ?? {\n touched: false,\n validated: false,\n result: null,\n };\n\n const validate = useCallback(\n () => validateField(path, config ?? { checks: [] }),\n [path, config, validateField],\n );\n\n const touch = useCallback(() => touchField(path), [path, touchField]);\n const clear = useCallback(() => clearField(path), [path, clearField]);\n\n return {\n state,\n validate,\n touch,\n clear,\n errors: state.result?.errors ?? [],\n isValid: state.result?.valid ?? true,\n };\n}\n","\"use client\";\n\nimport React, { createContext, useContext, type ReactNode } from \"react\";\n\n/**\n * Repeat scope value provided to child elements inside a repeated element.\n */\nexport interface RepeatScopeValue {\n /** The current array item object */\n item: unknown;\n /** Index of the current item in the array */\n index: number;\n /** Absolute state path to the current array item (e.g. \"/todos/0\") — used for statePath two-way binding */\n basePath: string;\n}\n\nconst RepeatScopeContext = createContext<RepeatScopeValue | null>(null);\n\n/**\n * Provides repeat scope to child elements so $item and $index expressions resolve correctly.\n */\nexport function RepeatScopeProvider({\n item,\n index,\n basePath,\n children,\n}: RepeatScopeValue & { children: ReactNode }) {\n return (\n <RepeatScopeContext.Provider value={{ item, index, basePath }}>\n {children}\n </RepeatScopeContext.Provider>\n );\n}\n\n/**\n * Read the current repeat scope (or null if not inside a repeated element).\n */\nexport function useRepeatScope(): RepeatScopeValue | null {\n return useContext(RepeatScopeContext);\n}\n","import { defineSchema } from \"@json-render/core\";\n\n/**\n * The schema for @json-render/react\n *\n * Defines:\n * - Spec: A flat tree of elements with keys, types, props, and children references\n * - Catalog: Components with props schemas, and optional actions\n */\nexport const schema = defineSchema(\n (s) => ({\n // What the AI-generated SPEC looks like\n spec: s.object({\n /** Root element key */\n root: s.string(),\n /** Flat map of elements by key */\n elements: s.record(\n s.object({\n /** Component type from catalog */\n type: s.ref(\"catalog.components\"),\n /** Component props */\n props: s.propsOf(\"catalog.components\"),\n /** Child element keys (flat reference) - maps to the 'default' slot */\n children: s.array(s.string()),\n /** Named slots - maps slot names to arrays of child element keys */\n slots: s.record(s.array(s.string())),\n /** Visibility condition */\n visible: s.any(),\n }),\n ),\n }),\n\n // What the CATALOG must provide\n catalog: s.object({\n /** Component definitions */\n components: s.map({\n /** Zod schema for component props */\n props: s.zod(),\n /** Slots for this component. Use ['default'] for children, or named slots like ['header', 'footer'] */\n slots: s.array(s.string()),\n /** Description for AI generation hints */\n description: s.string(),\n /** Example prop values used in prompt examples (auto-generated from Zod schema if omitted) */\n example: s.any(),\n }),\n /** Action definitions (optional) */\n actions: s.map({\n /** Zod schema for action params */\n params: s.zod(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n }),\n }),\n {\n defaultRules: [\n // Element integrity\n \"CRITICAL INTEGRITY CHECK: Before outputting ANY element that references children, you MUST have already output (or will output) each child as its own element. If an element has children: ['a', 'b'], then elements 'a' and 'b' MUST exist. A missing child element causes that entire branch of the UI to be invisible.\",\n \"SELF-CHECK: After generating all elements, mentally walk the tree from root. Every key in every children array must resolve to a defined element. If you find a gap, output the missing element immediately.\",\n\n // Named slots\n 'Components may declare named slots in their catalog definition (e.g., slots: [\"header\", \"footer\"]). Example: {\"type\":\"Layout\",\"props\":{},\"slots\":{\"header\":[\"h1\"],\"footer\":[\"f1\"]},\"children\":[\"main1\"]}. Verify slot names exist in the component\\'s catalog definition and all referenced child element keys exist.',\n\n // Field placement\n 'CRITICAL: The \"visible\" field goes on the ELEMENT object, NOT inside \"props\". Correct: {\"type\":\"<ComponentName>\",\"props\":{},\"visible\":{\"$state\":\"/tab\",\"eq\":\"home\"},\"children\":[...]}.',\n 'CRITICAL: The \"on\" field goes on the ELEMENT object, NOT inside \"props\". Use on.press, on.change, on.submit etc. NEVER put action/actionParams inside props.',\n\n // State and data\n \"When the user asks for a UI that displays data (e.g. blog posts, products, users), ALWAYS include a state field with realistic sample data. The state field is a top-level field on the spec (sibling of root/elements).\",\n 'When building repeating content backed by a state array (e.g. posts, products, items), use the \"repeat\" field on a container element. Example: { \"type\": \"<ContainerComponent>\", \"props\": {}, \"repeat\": { \"statePath\": \"/posts\", \"key\": \"id\" }, \"children\": [\"post-card\"] }. Replace <ContainerComponent> with an appropriate component from the AVAILABLE COMPONENTS list. Inside repeated children, use { \"$item\": \"field\" } to read a field from the current item, and { \"$index\": true } for the current array index. For two-way binding to an item field use { \"$bindItem\": \"completed\" }. Do NOT hardcode individual elements for each array item.',\n\n // Design quality\n \"Design with visual hierarchy: use container components to group content, heading components for section titles, proper spacing, and status indicators. ONLY use components from the AVAILABLE COMPONENTS list.\",\n \"For data-rich UIs, use multi-column layout components if available. For forms and single-column content, use vertical layout components. ONLY use components from the AVAILABLE COMPONENTS list.\",\n \"Always include realistic, professional-looking sample data. For blogs include 3-4 posts with varied titles, authors, dates, categories. For products include names, prices, images. Never leave data empty.\",\n ],\n },\n);\n\n/**\n * Type for the React schema\n */\nexport type ReactSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type ReactSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n\n// Backward compatibility aliases\n/** @deprecated Use `schema` instead */\nexport const elementTreeSchema = schema;\n/** @deprecated Use `ReactSchema` instead */\nexport type ElementTreeSchema = ReactSchema;\n/** @deprecated Use `ReactSpec` instead */\nexport type ElementTreeSpec<T> = ReactSpec<T>;\n","\"use client\";\n\nimport React, {\n type ComponentType,\n type ErrorInfo,\n type ReactNode,\n useCallback,\n useMemo,\n} from \"react\";\nimport type {\n UIElement,\n Spec,\n ActionBinding,\n Catalog,\n SchemaDefinition,\n} from \"@json-render/core\";\nimport {\n resolveElementProps,\n resolveBindings,\n resolveActionParam,\n evaluateVisibility,\n getByPath,\n type PropResolutionContext,\n type VisibilityContext as CoreVisibilityContext,\n} from \"@json-render/core\";\nimport type {\n Components,\n Actions,\n ActionFn,\n SetState,\n StateModel,\n} from \"./catalog-types\";\nimport { useIsVisible, useVisibility } from \"./contexts/visibility\";\nimport { useActions } from \"./contexts/actions\";\nimport { useStateStore } from \"./contexts/state\";\nimport { StateProvider } from \"./contexts/state\";\nimport { VisibilityProvider } from \"./contexts/visibility\";\nimport { ActionProvider } from \"./contexts/actions\";\nimport { ValidationProvider } from \"./contexts/validation\";\nimport { ConfirmDialog } from \"./contexts/actions\";\nimport { RepeatScopeProvider, useRepeatScope } from \"./contexts/repeat-scope\";\n\n/**\n * Props passed to component renderers\n */\nexport interface ComponentRenderProps<P = Record<string, unknown>> {\n /** The element being rendered */\n element: UIElement<string, P>;\n /** Rendered children (default slot) */\n children?: ReactNode;\n /** Named slots - maps slot names to rendered children */\n slots?: Record<string, ReactNode>;\n /** Emit a named event. The renderer resolves the event to action binding(s) from the element's `on` field. Always provided by the renderer. */\n emit: (event: string) => void;\n /**\n * Two-way binding paths resolved from `$bindState` / `$bindItem` expressions.\n * Maps prop name → absolute state path for write-back.\n * Only present when at least one prop uses `{ $bindState: \"...\" }` or `{ $bindItem: \"...\" }`.\n */\n bindings?: Record<string, string>;\n /** Whether the parent is loading */\n loading?: boolean;\n}\n\n/**\n * Component renderer type\n */\nexport type ComponentRenderer<P = Record<string, unknown>> = ComponentType<\n ComponentRenderProps<P>\n>;\n\n/**\n * Helper function to attach metadata (used for slot validation) to a registry.\n * Metadata is stored as a non-enumerable __metadata__ property at runtime,\n * but not included in the type definition to avoid index signature conflicts.\n * @internal\n */\nexport function attachRegistryMetadata(\n registry: ComponentRegistry,\n metadata: { components: Record<string, { slots?: string[] }> },\n): void {\n Object.defineProperty(registry, \"__metadata__\", {\n value: metadata,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n}\n\n/**\n * Registry of component renderers\n */\nexport type ComponentRegistry = Record<string, ComponentRenderer<any>>;\n\n/**\n * Props for the Renderer component\n */\nexport interface RendererProps {\n /** The UI spec to render */\n spec: Spec | null;\n /** Component registry */\n registry: ComponentRegistry;\n /** Whether the spec is currently loading/streaming */\n loading?: boolean;\n /** Fallback component for unknown types */\n fallback?: ComponentRenderer;\n}\n\n// ---------------------------------------------------------------------------\n// ElementErrorBoundary – catches rendering errors in individual elements so\n// a single bad component never crashes the whole page.\n// ---------------------------------------------------------------------------\n\ninterface ElementErrorBoundaryProps {\n elementType: string;\n children: ReactNode;\n}\n\ninterface ElementErrorBoundaryState {\n hasError: boolean;\n}\n\nclass ElementErrorBoundary extends React.Component<\n ElementErrorBoundaryProps,\n ElementErrorBoundaryState\n> {\n constructor(props: ElementErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ElementErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n console.error(\n `[json-render] Rendering error in <${this.props.elementType}>:`,\n error,\n info.componentStack,\n );\n }\n\n render() {\n if (this.state.hasError) {\n // Render nothing – the element silently disappears rather than\n // crashing the entire application.\n return null;\n }\n return this.props.children;\n }\n}\n\ninterface ElementRendererProps {\n element: UIElement;\n spec: Spec;\n registry: ComponentRegistry;\n loading?: boolean;\n fallback?: ComponentRenderer;\n}\n\n/**\n * Element renderer component.\n * Memoized to prevent re-rendering all repeat children when state changes.\n */\nconst ElementRenderer = React.memo(function ElementRenderer({\n element,\n spec,\n registry,\n loading,\n fallback,\n}: ElementRendererProps) {\n const repeatScope = useRepeatScope();\n const { ctx } = useVisibility();\n const { execute } = useActions();\n\n // Build context with repeat scope (used for both visibility and props)\n const fullCtx: PropResolutionContext = useMemo(\n () =>\n repeatScope\n ? {\n ...ctx,\n repeatItem: repeatScope.item,\n repeatIndex: repeatScope.index,\n repeatBasePath: repeatScope.basePath,\n }\n : ctx,\n [ctx, repeatScope],\n );\n\n // Evaluate visibility (now supports $item/$index inside repeat scopes)\n const isVisible =\n element.visible === undefined\n ? true\n : evaluateVisibility(element.visible, fullCtx);\n\n // Create emit function that resolves events to action bindings.\n // Must be called before any early return to satisfy Rules of Hooks.\n const onBindings = element.on;\n const emit = useCallback(\n (eventName: string) => {\n const binding = onBindings?.[eventName];\n if (!binding) return;\n const actionBindings = Array.isArray(binding) ? binding : [binding];\n for (const b of actionBindings) {\n if (!b.params) {\n execute(b);\n continue;\n }\n // Resolve all action params via resolveActionParam which handles\n // $item (→ absolute state path), $index (→ number), $state, $cond, and literals.\n const resolved: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(b.params)) {\n resolved[key] = resolveActionParam(val, fullCtx);\n }\n execute({ ...b, params: resolved });\n }\n },\n [onBindings, execute, fullCtx],\n );\n\n // Don't render if not visible\n if (!isVisible) {\n return null;\n }\n\n // Resolve $bindState/$bindItem expressions → bindings map (prop name → state path)\n const rawProps = element.props as Record<string, unknown>;\n const elementBindings = resolveBindings(rawProps, fullCtx);\n\n // Resolve dynamic prop expressions ($state, $item, $index, $bindState, $bindItem, $cond/$then/$else)\n const resolvedProps = resolveElementProps(rawProps, fullCtx);\n\n const resolvedElement =\n resolvedProps !== element.props\n ? { ...element, props: resolvedProps }\n : element;\n\n // Get the component renderer\n const Component = registry[resolvedElement.type] ?? fallback;\n\n if (!Component) {\n console.warn(`No renderer for component type: ${resolvedElement.type}`);\n return null;\n }\n\n // Validate slots\n const registryMetadata = (registry as any).__metadata__;\n if (resolvedElement.slots && registryMetadata) {\n const componentMeta = registryMetadata.components[resolvedElement.type];\n if (componentMeta?.slots) {\n const declaredSlots = new Set(componentMeta.slots);\n for (const slotName of Object.keys(resolvedElement.slots)) {\n if (slotName === \"default\") {\n console.warn(\n `[json-render] Component \"${resolvedElement.type}\" uses slots.default. ` +\n `Use the \"children\" field instead for default slot content.`,\n );\n } else if (!declaredSlots.has(slotName)) {\n console.warn(\n `[json-render] Unknown slot \"${slotName}\" on component \"${resolvedElement.type}\". ` +\n `Available slots: ${componentMeta.slots.join(\", \")}`,\n );\n }\n }\n }\n }\n\n // ---- Render children (with repeat support) and named slots ----\n const renderChildKeys = (childKeys: string[], slotName?: string) => {\n return childKeys.map((childKey) => {\n const childElement = spec.elements[childKey];\n if (!childElement) {\n if (!loading) {\n const location = slotName\n ? `in slot \"${slotName}\" of \"${resolvedElement.type}\"`\n : `as child of \"${resolvedElement.type}\"`;\n console.warn(\n `[json-render] Missing element \"${childKey}\" referenced ${location}. This element will not render.`,\n );\n }\n return null;\n }\n return (\n <ElementRenderer\n key={childKey}\n element={childElement}\n spec={spec}\n registry={registry}\n loading={loading}\n fallback={fallback}\n />\n );\n });\n };\n\n const children = resolvedElement.repeat ? (\n <RepeatChildren\n element={resolvedElement}\n spec={spec}\n registry={registry}\n loading={loading}\n fallback={fallback}\n />\n ) : resolvedElement.children ? (\n renderChildKeys(resolvedElement.children)\n ) : undefined;\n\n const slots = resolvedElement.slots\n ? Object.fromEntries(\n Object.entries(resolvedElement.slots).map(([slotName, childKeys]) => [\n slotName,\n renderChildKeys(childKeys, slotName),\n ]),\n )\n : undefined;\n\n return (\n <ElementErrorBoundary elementType={resolvedElement.type}>\n <Component\n element={resolvedElement}\n emit={emit}\n bindings={elementBindings}\n loading={loading}\n slots={slots}\n >\n {children}\n </Component>\n </ElementErrorBoundary>\n );\n});\n\n// ---------------------------------------------------------------------------\n// RepeatChildren -- renders child elements once per item in a state array.\n// Used when an element has a `repeat` field.\n// ---------------------------------------------------------------------------\n\nfunction RepeatChildren({\n element,\n spec,\n registry,\n loading,\n fallback,\n}: {\n element: UIElement;\n spec: Spec;\n registry: ComponentRegistry;\n loading?: boolean;\n fallback?: ComponentRenderer;\n}) {\n const { state } = useStateStore();\n const repeat = element.repeat!;\n const statePath = repeat.statePath;\n\n const items = (getByPath(state, statePath) as unknown[] | undefined) ?? [];\n\n return (\n <>\n {items.map((itemValue, index) => {\n // Use a stable key: prefer key field, fall back to index\n const key =\n repeat.key && typeof itemValue === \"object\" && itemValue !== null\n ? String(\n (itemValue as Record<string, unknown>)[repeat.key] ?? index,\n )\n : String(index);\n\n return (\n <RepeatScopeProvider\n key={key}\n item={itemValue}\n index={index}\n basePath={`${statePath}/${index}`}\n >\n {element.children?.map((childKey) => {\n const childElement = spec.elements[childKey];\n if (!childElement) {\n if (!loading) {\n console.warn(\n `[json-render] Missing element \"${childKey}\" referenced as child of \"${element.type}\" (repeat). This element will not render.`,\n );\n }\n return null;\n }\n return (\n <ElementRenderer\n key={childKey}\n element={childElement}\n spec={spec}\n registry={registry}\n loading={loading}\n fallback={fallback}\n />\n );\n })}\n </RepeatScopeProvider>\n );\n })}\n </>\n );\n}\n\n/**\n * Main renderer component\n */\nexport function Renderer({ spec, registry, loading, fallback }: RendererProps) {\n if (!spec || !spec.root) {\n return null;\n }\n\n const rootElement = spec.elements[spec.root];\n if (!rootElement) {\n return null;\n }\n\n return (\n <ElementRenderer\n element={rootElement}\n spec={spec}\n registry={registry}\n loading={loading}\n fallback={fallback}\n />\n );\n}\n\n/**\n * Props for JSONUIProvider\n */\nexport interface JSONUIProviderProps {\n /** Component registry */\n registry: ComponentRegistry;\n /** Initial state model */\n initialState?: Record<string, unknown>;\n /** Action handlers */\n handlers?: Record<\n string,\n (params: Record<string, unknown>) => Promise<unknown> | unknown\n >;\n /** Navigation function */\n navigate?: (path: string) => void;\n /** Custom validation functions */\n validationFunctions?: Record<\n string,\n (value: unknown, args?: Record<string, unknown>) => boolean\n >;\n /** Callback when state changes */\n onStateChange?: (path: string, value: unknown) => void;\n children: ReactNode;\n}\n\n/**\n * Combined provider for all JSONUI contexts\n */\nexport function JSONUIProvider({\n registry,\n initialState,\n handlers,\n navigate,\n validationFunctions,\n onStateChange,\n children,\n}: JSONUIProviderProps) {\n return (\n <StateProvider initialState={initialState} onStateChange={onStateChange}>\n <VisibilityProvider>\n <ActionProvider handlers={handlers} navigate={navigate}>\n <ValidationProvider customFunctions={validationFunctions}>\n {children}\n <ConfirmationDialogManager />\n </ValidationProvider>\n </ActionProvider>\n </VisibilityProvider>\n </StateProvider>\n );\n}\n\n/**\n * Renders the confirmation dialog when needed\n */\nfunction ConfirmationDialogManager() {\n const { pendingConfirmation, confirm, cancel } = useActions();\n\n if (!pendingConfirmation?.action.confirm) {\n return null;\n }\n\n return (\n <ConfirmDialog\n confirm={pendingConfirmation.action.confirm}\n onConfirm={confirm}\n onCancel={cancel}\n />\n );\n}\n\n// ============================================================================\n// defineRegistry\n// ============================================================================\n\n/**\n * Result returned by defineRegistry\n */\nexport interface DefineRegistryResult {\n /** Component registry for `<Renderer registry={...} />` */\n registry: ComponentRegistry;\n /**\n * Create ActionProvider-compatible handlers.\n * Accepts getter functions so handlers always read the latest state/setState\n * (e.g. from React refs).\n */\n handlers: (\n getSetState: () => SetState | undefined,\n getState: () => StateModel,\n ) => Record<string, (params: Record<string, unknown>) => Promise<void>>;\n /**\n * Execute an action by name imperatively\n * (for use outside the React tree, e.g. initial state loading).\n */\n executeAction: (\n actionName: string,\n params: Record<string, unknown> | undefined,\n setState: SetState,\n state?: StateModel,\n ) => Promise<void>;\n}\n\n/**\n * Create a registry from a catalog with components and/or actions.\n *\n * @example\n * ```tsx\n * // Components only\n * const { registry } = defineRegistry(catalog, {\n * components: {\n * Card: ({ props, children }) => (\n * <div className=\"card\">{props.title}{children}</div>\n * ),\n * },\n * });\n *\n * // Actions only\n * const { handlers, executeAction } = defineRegistry(catalog, {\n * actions: {\n * viewCustomers: async (params, setState) => { ... },\n * },\n * });\n *\n * // Both\n * const { registry, handlers, executeAction } = defineRegistry(catalog, {\n * components: { ... },\n * actions: { ... },\n * });\n * ```\n */\nexport function defineRegistry<C extends Catalog>(\n catalog: C,\n options: {\n components?: Components<C>;\n actions?: Actions<C>;\n },\n): DefineRegistryResult {\n // Build component registry\n const registry: ComponentRegistry = {};\n if (options.components) {\n for (const [name, componentFn] of Object.entries(options.components)) {\n registry[name] = ({\n element,\n children,\n slots,\n emit,\n bindings,\n loading,\n }: ComponentRenderProps) => {\n return (componentFn as DefineRegistryComponentFn)({\n props: element.props,\n children,\n slots,\n emit,\n bindings,\n loading,\n });\n };\n }\n }\n\n // Attach metadata from catalog for slot validation\n const catalogData = catalog.data as {\n components?: Record<string, { slots?: string[] }>;\n };\n if (catalogData.components) {\n attachRegistryMetadata(registry, {\n components: Object.fromEntries(\n Object.entries(catalogData.components).map(([name, def]) => [\n name,\n { slots: def.slots },\n ]),\n ),\n });\n }\n\n // Build action helpers\n const actionMap = options.actions\n ? (Object.entries(options.actions) as Array<\n [string, DefineRegistryActionFn]\n >)\n : [];\n\n const handlers = (\n getSetState: () => SetState | undefined,\n getState: () => StateModel,\n ): Record<string, (params: Record<string, unknown>) => Promise<void>> => {\n const result: Record<\n string,\n (params: Record<string, unknown>) => Promise<void>\n > = {};\n for (const [name, actionFn] of actionMap) {\n result[name] = async (params) => {\n const setState = getSetState();\n const state = getState();\n if (setState) {\n await actionFn(params, setState, state);\n }\n };\n }\n return result;\n };\n\n const executeAction = async (\n actionName: string,\n params: Record<string, unknown> | undefined,\n setState: SetState,\n state: StateModel = {},\n ): Promise<void> => {\n const entry = actionMap.find(([name]) => name === actionName);\n if (entry) {\n await entry[1](params, setState, state);\n } else {\n console.warn(`Unknown action: ${actionName}`);\n }\n };\n\n return { registry, handlers, executeAction };\n}\n\n/** @internal */\ntype DefineRegistryComponentFn = (ctx: {\n props: unknown;\n children?: React.ReactNode;\n slots?: Record<string, React.ReactNode>;\n emit: (event: string) => void;\n bindings?: Record<string, string>;\n loading?: boolean;\n}) => React.ReactNode;\n\n/** @internal */\ntype DefineRegistryActionFn = (\n params: Record<string, unknown> | undefined,\n setState: SetState,\n state: StateModel,\n) => Promise<void>;\n\n// ============================================================================\n// NEW API\n// ============================================================================\n\n/**\n * Props for renderers created with createRenderer\n */\nexport interface CreateRendererProps {\n /** The spec to render (AI-generated JSON) */\n spec: Spec | null;\n /** State context for dynamic values */\n state?: Record<string, unknown>;\n /** Action handler */\n onAction?: (actionName: string, params?: Record<string, unknown>) => void;\n /** Callback when state changes (e.g., from form inputs) */\n onStateChange?: (path: string, value: unknown) => void;\n /** Whether the spec is currently loading/streaming */\n loading?: boolean;\n /** Fallback component for unknown types */\n fallback?: ComponentRenderer;\n}\n\n/**\n * Component map type - maps component names to React components\n */\nexport type ComponentMap<\n TComponents extends Record<string, { props: unknown }>,\n> = {\n [K in keyof TComponents]: ComponentType<\n ComponentRenderProps<\n TComponents[K][\"props\"] extends { _output: infer O }\n ? O\n : Record<string, unknown>\n >\n >;\n};\n\n/**\n * Create a renderer from a catalog\n *\n * @example\n * ```typescript\n * const DashboardRenderer = createRenderer(dashboardCatalog, {\n * Card: ({ element, children }) => <div className=\"card\">{children}</div>,\n * Metric: ({ element }) => <span>{element.props.value}</span>,\n * });\n *\n * // Usage\n * <DashboardRenderer spec={aiGeneratedSpec} state={state} />\n * ```\n */\nexport function createRenderer<\n TDef extends SchemaDefinition,\n TCatalog extends { components: Record<string, { props: unknown }> },\n>(\n catalog: Catalog<TDef, TCatalog>,\n components: ComponentMap<TCatalog[\"components\"]>,\n): ComponentType<CreateRendererProps> {\n // Convert component map to registry\n const registry: ComponentRegistry =\n components as unknown as ComponentRegistry;\n\n // Return the renderer component\n return function CatalogRenderer({\n spec,\n state,\n onAction,\n onStateChange,\n loading,\n fallback,\n }: CreateRendererProps) {\n // Wrap onAction with a Proxy so any action name routes to the callback\n const actionHandlers = onAction\n ? new Proxy(\n {} as Record<\n string,\n (params: Record<string, unknown>) => void | Promise<void>\n >,\n {\n get: (_target, prop: string) => {\n return (params: Record<string, unknown>) =>\n onAction(prop, params);\n },\n has: () => true,\n },\n )\n : undefined;\n\n return (\n <StateProvider initialState={state} onStateChange={onStateChange}>\n <VisibilityProvider>\n <ActionProvider handlers={actionHandlers}>\n <ValidationProvider>\n <Renderer\n spec={spec}\n registry={registry}\n loading={loading}\n fallback={fallback}\n />\n <ConfirmationDialogManager />\n </ValidationProvider>\n </ActionProvider>\n </VisibilityProvider>\n </StateProvider>\n );\n };\n}\n","\"use client\";\n\nimport { useState, useCallback, useRef, useEffect } from \"react\";\nimport type {\n Spec,\n UIElement,\n FlatElement,\n JsonPatch,\n SpecDataPart,\n} from \"@json-render/core\";\nimport {\n setByPath,\n getByPath,\n addByPath,\n removeByPath,\n createMixedStreamParser,\n applySpecPatch,\n nestedToFlat,\n SPEC_DATA_PART_TYPE,\n} from \"@json-render/core\";\n\n/**\n * Token usage metadata from AI generation\n */\nexport interface TokenUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\n/**\n * Parse result for a single line -- either a patch or usage metadata\n */\ntype ParsedLine =\n | { type: \"patch\"; patch: JsonPatch }\n | { type: \"usage\"; usage: TokenUsage }\n | null;\n\n/**\n * Parse a single JSON line (patch or metadata)\n */\nfunction parseLine(line: string): ParsedLine {\n try {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"//\")) {\n return null;\n }\n const parsed = JSON.parse(trimmed);\n\n // Check for usage metadata\n if (parsed.__meta === \"usage\") {\n return {\n type: \"usage\",\n usage: {\n promptTokens: parsed.promptTokens ?? 0,\n completionTokens: parsed.completionTokens ?? 0,\n totalTokens: parsed.totalTokens ?? 0,\n },\n };\n }\n\n return { type: \"patch\", patch: parsed as JsonPatch };\n } catch {\n return null;\n }\n}\n\n/**\n * Set a value at a spec path (for add/replace operations).\n */\nfunction setSpecValue(newSpec: Spec, path: string, value: unknown): void {\n if (path === \"/root\") {\n newSpec.root = value as string;\n return;\n }\n\n if (path === \"/state\") {\n newSpec.state = value as Record<string, unknown>;\n return;\n }\n\n if (path.startsWith(\"/state/\")) {\n if (!newSpec.state) newSpec.state = {};\n const statePath = path.slice(\"/state\".length); // e.g. \"/posts\"\n setByPath(newSpec.state as Record<string, unknown>, statePath, value);\n return;\n }\n\n if (path.startsWith(\"/elements/\")) {\n const pathParts = path.slice(\"/elements/\".length).split(\"/\");\n const elementKey = pathParts[0];\n if (!elementKey) return;\n\n if (pathParts.length === 1) {\n newSpec.elements[elementKey] = value as UIElement;\n } else {\n const element = newSpec.elements[elementKey];\n if (element) {\n const propPath = \"/\" + pathParts.slice(1).join(\"/\");\n const newElement = { ...element };\n setByPath(\n newElement as unknown as Record<string, unknown>,\n propPath,\n value,\n );\n newSpec.elements[elementKey] = newElement;\n }\n }\n }\n}\n\n/**\n * Remove a value at a spec path.\n */\nfunction removeSpecValue(newSpec: Spec, path: string): void {\n if (path === \"/state\") {\n delete newSpec.state;\n return;\n }\n\n if (path.startsWith(\"/state/\") && newSpec.state) {\n const statePath = path.slice(\"/state\".length);\n removeByPath(newSpec.state as Record<string, unknown>, statePath);\n return;\n }\n\n if (path.startsWith(\"/elements/\")) {\n const pathParts = path.slice(\"/elements/\".length).split(\"/\");\n const elementKey = pathParts[0];\n if (!elementKey) return;\n\n if (pathParts.length === 1) {\n const { [elementKey]: _, ...rest } = newSpec.elements;\n newSpec.elements = rest;\n } else {\n const element = newSpec.elements[elementKey];\n if (element) {\n const propPath = \"/\" + pathParts.slice(1).join(\"/\");\n const newElement = { ...element };\n removeByPath(\n newElement as unknown as Record<string, unknown>,\n propPath,\n );\n newSpec.elements[elementKey] = newElement;\n }\n }\n }\n}\n\n/**\n * Get a value at a spec path.\n */\nfunction getSpecValue(spec: Spec, path: string): unknown {\n if (path === \"/root\") return spec.root;\n if (path === \"/state\") return spec.state;\n if (path.startsWith(\"/state/\") && spec.state) {\n const statePath = path.slice(\"/state\".length);\n return getByPath(spec.state as Record<string, unknown>, statePath);\n }\n return getByPath(spec as unknown as Record<string, unknown>, path);\n}\n\n/**\n * Apply an RFC 6902 JSON patch to the current spec.\n * Supports add, remove, replace, move, copy, and test operations.\n */\nfunction applyPatch(spec: Spec, patch: JsonPatch): Spec {\n const newSpec = {\n ...spec,\n elements: { ...spec.elements },\n ...(spec.state ? { state: { ...spec.state } } : {}),\n };\n\n switch (patch.op) {\n case \"add\":\n case \"replace\": {\n setSpecValue(newSpec, patch.path, patch.value);\n break;\n }\n case \"remove\": {\n removeSpecValue(newSpec, patch.path);\n break;\n }\n case \"move\": {\n if (!patch.from) break;\n const moveValue = getSpecValue(newSpec, patch.from);\n removeSpecValue(newSpec, patch.from);\n setSpecValue(newSpec, patch.path, moveValue);\n break;\n }\n case \"copy\": {\n if (!patch.from) break;\n const copyValue = getSpecValue(newSpec, patch.from);\n setSpecValue(newSpec, patch.path, copyValue);\n break;\n }\n case \"test\": {\n // test is a no-op for rendering purposes (validation only)\n break;\n }\n }\n\n return newSpec;\n}\n\n/**\n * Options for useUIStream\n */\nexport interface UseUIStreamOptions {\n /** API endpoint */\n api: string;\n /** Callback when complete */\n onComplete?: (spec: Spec) => void;\n /** Callback on error */\n onError?: (error: Error) => void;\n}\n\n/**\n * Return type for useUIStream\n */\nexport interface UseUIStreamReturn {\n /** Current UI spec */\n spec: Spec | null;\n /** Whether currently streaming */\n isStreaming: boolean;\n /** Error if any */\n error: Error | null;\n /** Token usage from the last generation */\n usage: TokenUsage | null;\n /** Raw JSONL lines received from the stream (JSON patch lines) */\n rawLines: string[];\n /** Send a prompt to generate UI */\n send: (prompt: string, context?: Record<string, unknown>) => Promise<void>;\n /** Clear the current spec */\n clear: () => void;\n}\n\n/**\n * Hook for streaming UI generation\n */\nexport function useUIStream({\n api,\n onComplete,\n onError,\n}: UseUIStreamOptions): UseUIStreamReturn {\n const [spec, setSpec] = useState<Spec | null>(null);\n const [isStreaming, setIsStreaming] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [usage, setUsage] = useState<TokenUsage | null>(null);\n const [rawLines, setRawLines] = useState<string[]>([]);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n // Keep refs to callbacks so `send` doesn't recreate when consumers\n // pass inline arrow functions.\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n const clear = useCallback(() => {\n setSpec(null);\n setError(null);\n }, []);\n\n const send = useCallback(\n async (prompt: string, context?: Record<string, unknown>) => {\n // Abort any existing request\n abortControllerRef.current?.abort();\n abortControllerRef.current = new AbortController();\n\n setIsStreaming(true);\n setError(null);\n setUsage(null);\n setRawLines([]);\n\n // Start with previous spec if provided, otherwise empty spec\n const previousSpec = context?.previousSpec as Spec | undefined;\n let currentSpec: Spec =\n previousSpec && previousSpec.root\n ? { ...previousSpec, elements: { ...previousSpec.elements } }\n : { root: \"\", elements: {} };\n setSpec(currentSpec);\n\n try {\n const response = await fetch(api, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n prompt,\n context,\n currentSpec,\n }),\n signal: abortControllerRef.current.signal,\n });\n\n if (!response.ok) {\n // Try to parse JSON error response for better error messages\n let errorMessage = `HTTP error: ${response.status}`;\n try {\n const errorData = await response.json();\n if (errorData.message) {\n errorMessage = errorData.message;\n } else if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch {\n // Ignore JSON parsing errors, use default message\n }\n throw new Error(errorMessage);\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"No response body\");\n }\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete lines\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const result = parseLine(trimmed);\n if (!result) continue;\n if (result.type === \"usage\") {\n setUsage(result.usage);\n } else {\n setRawLines((prev) => [...prev, trimmed]);\n currentSpec = applyPatch(currentSpec, result.patch);\n setSpec({ ...currentSpec });\n }\n }\n }\n\n // Process any remaining buffer\n if (buffer.trim()) {\n const trimmed = buffer.trim();\n const result = parseLine(trimmed);\n if (result) {\n if (result.type === \"usage\") {\n setUsage(result.usage);\n } else {\n setRawLines((prev) => [...prev, trimmed]);\n currentSpec = applyPatch(currentSpec, result.patch);\n setSpec({ ...currentSpec });\n }\n }\n }\n\n onCompleteRef.current?.(currentSpec);\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n return;\n }\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n } finally {\n setIsStreaming(false);\n }\n },\n [api],\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n };\n }, []);\n\n return {\n spec,\n isStreaming,\n error,\n usage,\n rawLines,\n send,\n clear,\n };\n}\n\n/**\n * Convert a flat element list to a Spec.\n * Input elements use key/parentKey to establish identity and relationships.\n * Output spec uses the map-based format where key is the map entry key\n * and parent-child relationships are expressed through children arrays.\n */\nexport function flatToTree(elements: FlatElement[]): Spec {\n const elementMap: Record<string, UIElement> = {};\n let root = \"\";\n\n // First pass: add all elements to map\n for (const element of elements) {\n elementMap[element.key] = {\n type: element.type,\n props: element.props,\n children: [],\n visible: element.visible,\n };\n }\n\n // Second pass: build parent-child relationships\n for (const element of elements) {\n if (element.parentKey) {\n const parent = elementMap[element.parentKey];\n if (parent) {\n if (!parent.children) {\n parent.children = [];\n }\n parent.children.push(element.key);\n }\n } else {\n root = element.key;\n }\n }\n\n return { root, elements: elementMap };\n}\n\n// =============================================================================\n// useBoundProp — Two-way binding helper for $bindState/$bindItem expressions\n// =============================================================================\n\n/**\n * Hook for two-way bound props. Returns `[value, setValue]` where:\n *\n * - `value` is the already-resolved prop value (passed through from render props)\n * - `setValue` writes back to the bound state path (no-op if not bound)\n *\n * Designed to work with the `bindings` map that the renderer provides when\n * a prop uses `{ $bindState: \"/path\" }` or `{ $bindItem: \"field\" }`.\n *\n * @example\n * ```tsx\n * import { useBoundProp } from \"@json-render/react\";\n *\n * const Input: ComponentRenderer = ({ props, bindings }) => {\n * const [value, setValue] = useBoundProp<string>(props.value, bindings?.value);\n * return <input value={value ?? \"\"} onChange={(e) => setValue(e.target.value)} />;\n * };\n * ```\n */\nexport function useBoundProp<T>(\n propValue: T | undefined,\n bindingPath: string | undefined,\n): [T | undefined, (value: T) => void] {\n // Import useStateStore lazily to avoid circular dependency issues.\n // The hook is always called inside a StateProvider so this is safe.\n const { set } = useStateStoreFromContext();\n const setValue = useCallback(\n (value: T) => {\n if (bindingPath) set(bindingPath, value);\n },\n [bindingPath, set],\n );\n return [propValue, setValue];\n}\n\n// Re-export useStateStore access for useBoundProp without circular import\nimport { useStateStore as useStateStoreFromContext } from \"./contexts/state\";\n\n// =============================================================================\n// buildSpecFromParts — Derive Spec from AI SDK data parts\n// =============================================================================\n\n/**\n * A single part from the AI SDK's `message.parts` array. This is a minimal\n * structural type so that library helpers do not depend on the AI SDK.\n * Fields are optional because different part types carry different data:\n * - Text parts have `text`\n * - Data parts have `data`\n */\nexport interface DataPart {\n type: string;\n text?: string;\n data?: unknown;\n}\n\n/**\n * Build a `Spec` by replaying all spec data parts from a message's\n * parts array. Returns `null` if no spec data parts are present.\n *\n * This function is designed to work with the AI SDK's `UIMessage.parts` array.\n * It picks out parts whose `type` is {@link SPEC_DATA_PART_TYPE} and processes them based\n * on the payload's `type` discriminator:\n *\n * - `\"patch\"`: Applies the JSON Patch operation incrementally via `applySpecPatch`.\n * - `\"flat\"`: Replaces the spec with the complete flat spec.\n * - `\"nested\"`: Assigns the nested spec directly (future: nested-to-flat conversion).\n *\n * The function has no AI SDK dependency — it operates on a generic array of\n * `{ type: string; data: unknown }` objects.\n *\n * @example\n * ```tsx\n * const spec = buildSpecFromParts(message.parts);\n * if (spec) {\n * return <MyRenderer spec={spec} />;\n * }\n * ```\n */\n/**\n * Type guard that validates a data part payload looks like a valid\n * {@link SpecDataPart} before we cast it. Returns `false` (and the\n * part is silently skipped) for malformed payloads.\n */\nfunction isSpecDataPart(data: unknown): data is SpecDataPart {\n if (typeof data !== \"object\" || data === null) return false;\n const obj = data as Record<string, unknown>;\n switch (obj.type) {\n case \"patch\":\n return typeof obj.patch === \"object\" && obj.patch !== null;\n case \"flat\":\n case \"nested\":\n return typeof obj.spec === \"object\" && obj.spec !== null;\n default:\n return false;\n }\n}\n\nexport function buildSpecFromParts(parts: DataPart[]): Spec | null {\n const spec: Spec = { root: \"\", elements: {} };\n let hasSpec = false;\n\n for (const part of parts) {\n if (part.type === SPEC_DATA_PART_TYPE) {\n if (!isSpecDataPart(part.data)) continue;\n const payload = part.data;\n if (payload.type === \"patch\") {\n hasSpec = true;\n applySpecPatch(spec, payload.patch);\n } else if (payload.type === \"flat\") {\n hasSpec = true;\n Object.assign(spec, payload.spec);\n } else if (payload.type === \"nested\") {\n hasSpec = true;\n const flat = nestedToFlat(payload.spec);\n Object.assign(spec, flat);\n }\n }\n }\n\n return hasSpec ? spec : null;\n}\n\n/**\n * Extract and join all text content from a message's parts array.\n *\n * Filters for parts with `type === \"text\"`, trims each one, and joins them\n * with double newlines so that text from separate agent steps renders as\n * distinct paragraphs in markdown.\n *\n * Has no AI SDK dependency — operates on a generic `DataPart[]`.\n *\n * @example\n * ```tsx\n * const text = getTextFromParts(message.parts);\n * if (text) {\n * return <Streamdown>{text}</Streamdown>;\n * }\n * ```\n */\nexport function getTextFromParts(parts: DataPart[]): string {\n return parts\n .filter(\n (p): p is DataPart & { text: string } =>\n p.type === \"text\" && typeof p.text === \"string\",\n )\n .map((p) => p.text.trim())\n .filter(Boolean)\n .join(\"\\n\\n\");\n}\n\n// =============================================================================\n// useJsonRenderMessage — extract spec + text from message parts\n// =============================================================================\n\n/**\n * Hook that extracts both the json-render spec and text content from a\n * message's parts array. Combines `buildSpecFromParts` and `getTextFromParts`\n * into a single call with memoized results.\n *\n * **Memoization behavior:** Results are recomputed only when the `parts` array\n * reference changes **and** either the length differs or the last element is a\n * different object. This is optimized for the typical AI SDK streaming pattern\n * where parts are appended incrementally. Mid-array edits (e.g. replacing an\n * earlier part without appending) may not trigger recomputation. If you need to\n * force a recompute after such edits, pass a new array reference with a\n * different last element.\n *\n * @example\n * ```tsx\n * import { useJsonRenderMessage } from \"@json-render/react\";\n *\n * function MessageBubble({ message }) {\n * const { spec, text, hasSpec } = useJsonRenderMessage(message.parts);\n *\n * return (\n * <div>\n * {text && <Markdown>{text}</Markdown>}\n * {hasSpec && <MyRenderer spec={spec} />}\n * </div>\n * );\n * }\n * ```\n */\nexport function useJsonRenderMessage(parts: DataPart[]) {\n const prevPartsRef = useRef<DataPart[]>([]);\n const prevResultRef = useRef<{ spec: Spec | null; text: string }>({\n spec: null,\n text: \"\",\n });\n\n // Recompute only when parts actually change (by length + last element identity).\n // AI SDK typically appends to the parts array during streaming, so checking\n // length and the last element covers both \"new array reference with same\n // content\" (no recompute) and \"new part appended\" (recompute).\n const partsChanged =\n parts !== prevPartsRef.current &&\n (parts.length !== prevPartsRef.current.length ||\n parts[parts.length - 1] !==\n prevPartsRef.current[prevPartsRef.current.length - 1]);\n\n if (partsChanged || prevPartsRef.current.length === 0) {\n prevPartsRef.current = parts;\n prevResultRef.current = {\n spec: buildSpecFromParts(parts),\n text: getTextFromParts(parts),\n };\n }\n\n const { spec, text } = prevResultRef.current;\n const hasSpec = spec !== null && Object.keys(spec.elements || {}).length > 0;\n return { spec, text, hasSpec };\n}\n\n// =============================================================================\n// useChatUI — Chat + GenUI hook\n// =============================================================================\n\n/**\n * A single message in the chat, which may contain text, a rendered UI spec, or both.\n */\nexport interface ChatMessage {\n /** Unique message ID */\n id: string;\n /** Who sent this message */\n role: \"user\" | \"assistant\";\n /** Text content (conversational prose) */\n text: string;\n /** json-render Spec built from JSONL patches (null if no UI was generated) */\n spec: Spec | null;\n}\n\n/**\n * Options for useChatUI\n */\nexport interface UseChatUIOptions {\n /** API endpoint that accepts `{ messages: Array<{ role, content }> }` and returns a text stream */\n api: string;\n /** Callback when streaming completes for a message */\n onComplete?: (message: ChatMessage) => void;\n /** Callback on error */\n onError?: (error: Error) => void;\n}\n\n/**\n * Return type for useChatUI\n */\nexport interface UseChatUIReturn {\n /** All messages in the conversation */\n messages: ChatMessage[];\n /** Whether currently streaming an assistant response */\n isStreaming: boolean;\n /** Error from the last request, if any */\n error: Error | null;\n /** Send a user message */\n send: (text: string) => Promise<void>;\n /** Clear all messages and reset the conversation */\n clear: () => void;\n}\n\nlet chatMessageIdCounter = 0;\nfunction generateChatId(): string {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.randomUUID === \"function\"\n ) {\n return crypto.randomUUID();\n }\n chatMessageIdCounter += 1;\n return `msg-${Date.now()}-${chatMessageIdCounter}`;\n}\n\n/**\n * Hook for chat + GenUI experiences.\n *\n * Manages a multi-turn conversation where each assistant message can contain\n * both conversational text and a json-render UI spec. The hook sends the full\n * message history to the API endpoint, reads the streamed response, and\n * separates text lines from JSONL patch lines using `createMixedStreamParser`.\n *\n * @example\n * ```tsx\n * const { messages, isStreaming, send, clear } = useChatUI({\n * api: \"/api/chat\",\n * });\n *\n * // Send a message\n * await send(\"Compare weather in NYC and Tokyo\");\n *\n * // Render messages\n * {messages.map((msg) => (\n * <div key={msg.id}>\n * {msg.text && <p>{msg.text}</p>}\n * {msg.spec && <MyRenderer spec={msg.spec} />}\n * </div>\n * ))}\n * ```\n */\nexport function useChatUI({\n api,\n onComplete,\n onError,\n}: UseChatUIOptions): UseChatUIReturn {\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [isStreaming, setIsStreaming] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n // Keep a ref to the latest messages so `send` always reads the\n // current history, avoiding stale closure issues.\n const messagesRef = useRef(messages);\n messagesRef.current = messages;\n // Keep refs to callbacks so `send` doesn't recreate when consumers\n // pass inline arrow functions.\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n const clear = useCallback(() => {\n setMessages([]);\n setError(null);\n }, []);\n\n const send = useCallback(\n async (text: string) => {\n if (!text.trim()) return;\n\n // Abort any existing request\n abortControllerRef.current?.abort();\n abortControllerRef.current = new AbortController();\n\n const userMessage: ChatMessage = {\n id: generateChatId(),\n role: \"user\",\n text: text.trim(),\n spec: null,\n };\n\n const assistantId = generateChatId();\n const assistantMessage: ChatMessage = {\n id: assistantId,\n role: \"assistant\",\n text: \"\",\n spec: null,\n };\n\n // Append user message and empty assistant placeholder\n setMessages((prev) => [...prev, userMessage, assistantMessage]);\n setIsStreaming(true);\n setError(null);\n\n // Build messages array for the API (full conversation history + new message).\n // Read from ref to always get the latest messages (avoids stale closure).\n const historyForApi = [\n ...messagesRef.current.map((m) => ({\n role: m.role,\n content: m.text,\n })),\n { role: \"user\" as const, content: text.trim() },\n ];\n\n // Mutable state for accumulating the assistant response\n let accumulatedText = \"\";\n let currentSpec: Spec = { root: \"\", elements: {} };\n let hasSpec = false;\n\n try {\n const response = await fetch(api, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ messages: historyForApi }),\n signal: abortControllerRef.current.signal,\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP error: ${response.status}`;\n try {\n const errorData = await response.json();\n if (errorData.message) {\n errorMessage = errorData.message;\n } else if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch {\n // Ignore JSON parsing errors\n }\n throw new Error(errorMessage);\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"No response body\");\n }\n\n const decoder = new TextDecoder();\n\n // Use createMixedStreamParser to classify lines\n const parser = createMixedStreamParser({\n onPatch(patch) {\n hasSpec = true;\n applySpecPatch(currentSpec, patch);\n setMessages((prev) =>\n prev.map((m) =>\n m.id === assistantId\n ? {\n ...m,\n spec: {\n root: currentSpec.root,\n elements: { ...currentSpec.elements },\n ...(currentSpec.state\n ? { state: { ...currentSpec.state } }\n : {}),\n },\n }\n : m,\n ),\n );\n },\n onText(line) {\n accumulatedText += (accumulatedText ? \"\\n\" : \"\") + line;\n setMessages((prev) =>\n prev.map((m) =>\n m.id === assistantId ? { ...m, text: accumulatedText } : m,\n ),\n );\n },\n });\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n parser.push(decoder.decode(value, { stream: true }));\n }\n parser.flush();\n\n // Build final message for onComplete callback\n const finalMessage: ChatMessage = {\n id: assistantId,\n role: \"assistant\",\n text: accumulatedText,\n spec: hasSpec\n ? {\n root: currentSpec.root,\n elements: { ...currentSpec.elements },\n ...(currentSpec.state\n ? { state: { ...currentSpec.state } }\n : {}),\n }\n : null,\n };\n onCompleteRef.current?.(finalMessage);\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n return;\n }\n const resolvedError =\n err instanceof Error ? err : new Error(String(err));\n setError(resolvedError);\n // Remove empty assistant message on error\n setMessages((prev) =>\n prev.filter((m) => m.id !== assistantId || m.text.length > 0),\n );\n onErrorRef.current?.(resolvedError);\n } finally {\n setIsStreaming(false);\n }\n },\n [api],\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n };\n }, []);\n\n return {\n messages,\n isStreaming,\n error,\n send,\n clear,\n };\n}\n"],"mappings":"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","names":["value","import_react","import_core","import_jsx_runtime","import_react","import_core","import_jsx_runtime","value","executeAction","import_react","import_core","import_jsx_runtime","value","React","import_react","import_jsx_runtime","import_core","import_react","import_core","import_jsx_runtime","React","ElementRenderer","executeAction","import_react","import_core","error"]}