@freesail/react
Advanced tools
| /** | ||
| * @fileoverview Freesail React Context | ||
| * | ||
| * Provides React context for Freesail state management. | ||
| */ | ||
| import type { SurfaceManager, A2UITransport, Surface, SurfaceId, ComponentId } from '@freesail/core'; | ||
| /** | ||
| * Freesail context value. | ||
| */ | ||
| export interface FreesailContextValue { | ||
| /** Surface manager instance */ | ||
| surfaceManager: SurfaceManager; | ||
| /** Transport instance (may be null if not connected) */ | ||
| transport: A2UITransport | null; | ||
| /** Send an action (v0.9 format) */ | ||
| sendAction: (surfaceId: SurfaceId, name: string, sourceComponentId: ComponentId, context: Record<string, unknown>) => Promise<void>; | ||
| /** Get a surface by ID */ | ||
| getSurface: (surfaceId: SurfaceId) => Surface | undefined; | ||
| /** Connection state */ | ||
| isConnected: boolean; | ||
| } | ||
| /** | ||
| * React context for Freesail. | ||
| */ | ||
| export declare const FreesailContext: import("react").Context<FreesailContextValue | null>; | ||
| /** | ||
| * Hook to access the Freesail context. | ||
| * Throws if used outside of a FreesailProvider. | ||
| */ | ||
| export declare function useFreesailContext(): FreesailContextValue; | ||
| //# sourceMappingURL=context.d.ts.map |
| {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,OAAO,EACP,SAAS,EACT,WAAW,EAEZ,MAAM,gBAAgB,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,+BAA+B;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,wDAAwD;IACxD,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,mCAAmC;IACnC,UAAU,EAAE,CACV,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,WAAW,EAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,0BAA0B;IAC1B,UAAU,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,GAAG,SAAS,CAAC;IAC1D,uBAAuB;IACvB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,sDAAmD,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,oBAAoB,CAMzD"} |
| /** | ||
| * @fileoverview Freesail React Context | ||
| * | ||
| * Provides React context for Freesail state management. | ||
| */ | ||
| import { createContext, useContext } from 'react'; | ||
| /** | ||
| * React context for Freesail. | ||
| */ | ||
| export const FreesailContext = createContext(null); | ||
| /** | ||
| * Hook to access the Freesail context. | ||
| * Throws if used outside of a FreesailProvider. | ||
| */ | ||
| export function useFreesailContext() { | ||
| const context = useContext(FreesailContext); | ||
| if (!context) { | ||
| throw new Error('useFreesailContext must be used within a FreesailProvider'); | ||
| } | ||
| return context; | ||
| } | ||
| //# sourceMappingURL=context.js.map |
| {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AA+BlD;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAA8B,IAAI,CAAC,CAAC;AAEhF;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["/**\n * @fileoverview Freesail React Context\n *\n * Provides React context for Freesail state management.\n */\n\nimport { createContext, useContext } from 'react';\nimport type {\n SurfaceManager,\n A2UITransport,\n Surface,\n SurfaceId,\n ComponentId,\n A2UIClientDataModel,\n} from '@freesail/core';\n\n/**\n * Freesail context value.\n */\nexport interface FreesailContextValue {\n /** Surface manager instance */\n surfaceManager: SurfaceManager;\n /** Transport instance (may be null if not connected) */\n transport: A2UITransport | null;\n /** Send an action (v0.9 format) */\n sendAction: (\n surfaceId: SurfaceId,\n name: string,\n sourceComponentId: ComponentId,\n context: Record<string, unknown>\n ) => Promise<void>;\n /** Get a surface by ID */\n getSurface: (surfaceId: SurfaceId) => Surface | undefined;\n /** Connection state */\n isConnected: boolean;\n}\n\n/**\n * React context for Freesail.\n */\nexport const FreesailContext = createContext<FreesailContextValue | null>(null);\n\n/**\n * Hook to access the Freesail context.\n * Throws if used outside of a FreesailProvider.\n */\nexport function useFreesailContext(): FreesailContextValue {\n const context = useContext(FreesailContext);\n if (!context) {\n throw new Error('useFreesailContext must be used within a FreesailProvider');\n }\n return context;\n}\n"]} |
| /** | ||
| * @fileoverview FreesailProvider Component | ||
| * | ||
| * The root provider component that manages Freesail connections | ||
| * and state for the React application. | ||
| */ | ||
| import { type ReactNode } from 'react'; | ||
| import { type TransportOptions, type CatalogId } from '@freesail/core'; | ||
| import type { CatalogDefinition } from './types.js'; | ||
| /** | ||
| * Props for FreesailProvider. | ||
| */ | ||
| export interface FreesailProviderProps { | ||
| /** Child components */ | ||
| children: ReactNode; | ||
| /** Base gateway URL (e.g. 'http://localhost:3001'). SSE and POST endpoints are derived automatically. */ | ||
| gateway: string; | ||
| /** List of supported catalog IDs */ | ||
| catalogs?: CatalogId[]; | ||
| /** | ||
| * Array of custom catalog definitions to register. | ||
| * Each definition bundles a namespace, schema, and component map. | ||
| * Components are auto-registered on mount. | ||
| */ | ||
| catalogDefinitions?: CatalogDefinition[]; | ||
| /** Additional transport options */ | ||
| transportOptions?: Partial<Omit<TransportOptions, 'gateway' | 'capabilities'>>; | ||
| /** Auto-connect on mount (default: true) */ | ||
| autoConnect?: boolean; | ||
| /** Callback when connection state changes */ | ||
| onConnectionChange?: (connected: boolean) => void; | ||
| /** Callback when an error occurs */ | ||
| onError?: (error: Error) => void; | ||
| } | ||
| /** | ||
| * Root provider component for Freesail. | ||
| * | ||
| * Manages the transport connection and surface state, | ||
| * making them available to all child components. | ||
| */ | ||
| export declare function FreesailProvider({ children, gateway, catalogs, catalogDefinitions, transportOptions, autoConnect, onConnectionChange, onError, }: FreesailProviderProps): import("react/jsx-runtime").JSX.Element; | ||
| //# sourceMappingURL=FreesailProvider.d.ts.map |
| {"version":3,"file":"FreesailProvider.d.ts","sourceRoot":"","sources":["../src/FreesailProvider.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAc,EAMZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAUL,KAAK,gBAAgB,EAGrB,KAAK,SAAS,EAGf,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,uBAAuB;IACvB,QAAQ,EAAE,SAAS,CAAC;IACpB,yGAAyG;IACzG,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;IACvB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACzC,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC;IAC/E,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,6CAA6C;IAC7C,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,oCAAoC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,OAAO,EACP,QAAa,EACb,kBAAuB,EACvB,gBAAgB,EAChB,WAAkB,EAClB,kBAAkB,EAClB,OAAO,GACR,EAAE,qBAAqB,2CA6NvB"} |
| import { jsx as _jsx } from "react/jsx-runtime"; | ||
| /** | ||
| * @fileoverview FreesailProvider Component | ||
| * | ||
| * The root provider component that manages Freesail connections | ||
| * and state for the React application. | ||
| */ | ||
| import { useState, useEffect, useCallback, useMemo, useRef, } from 'react'; | ||
| import { createSurfaceManager, createTransport, isCreateSurfaceMessage, isUpdateComponentsMessage, isUpdateDataModelMessage, isDeleteSurfaceMessage, isGetDataModelMessage, } from '@freesail/core'; | ||
| import { FreesailContext } from './context.js'; | ||
| import { registerCatalog } from './registry.js'; | ||
| /** | ||
| * Root provider component for Freesail. | ||
| * | ||
| * Manages the transport connection and surface state, | ||
| * making them available to all child components. | ||
| */ | ||
| export function FreesailProvider({ children, gateway, catalogs = [], catalogDefinitions = [], transportOptions, autoConnect = true, onConnectionChange, onError, }) { | ||
| const [surfaceManager] = useState(() => createSurfaceManager()); | ||
| const [transport, setTransport] = useState(null); | ||
| const [isConnected, setIsConnected] = useState(false); | ||
| // Track surfaces deleted by agent messages so we don't echo them back | ||
| const agentDeletedRef = useRef(new Set()); | ||
| // Refs for callbacks so the transport effect always uses current values | ||
| // without needing to be recreated when callbacks change | ||
| const onConnectionChangeRef = useRef(onConnectionChange); | ||
| const onErrorRef = useRef(onError); | ||
| const catalogDefinitionsRef = useRef(catalogDefinitions); | ||
| const autoConnectRef = useRef(autoConnect); | ||
| useEffect(() => { | ||
| onConnectionChangeRef.current = onConnectionChange; | ||
| onErrorRef.current = onError; | ||
| catalogDefinitionsRef.current = catalogDefinitions; | ||
| autoConnectRef.current = autoConnect; | ||
| }); | ||
| // Register custom catalog definitions | ||
| useEffect(() => { | ||
| for (const def of catalogDefinitions) { | ||
| registerCatalog(def.namespace, def.components, def.functions, def.schema); | ||
| } | ||
| }, [catalogDefinitions]); | ||
| // Merge explicit catalog IDs with catalog definition namespaces | ||
| const mergedCatalogs = useMemo(() => { | ||
| const definitionIds = catalogDefinitions.map((d) => d.namespace); | ||
| const combined = [...catalogs, ...definitionIds]; | ||
| return Array.from(new Set(combined)); | ||
| }, [catalogs, catalogDefinitions]); | ||
| // Build capabilities from catalogs | ||
| const capabilities = useMemo(() => { | ||
| if (mergedCatalogs.length === 0) | ||
| return undefined; | ||
| return { catalogs: mergedCatalogs }; | ||
| }, [mergedCatalogs]); | ||
| // Initialize transport | ||
| useEffect(() => { | ||
| const newTransport = createTransport({ | ||
| gateway, | ||
| capabilities, | ||
| ...transportOptions, | ||
| }); | ||
| // Handle incoming messages | ||
| newTransport.on('message', (message) => { | ||
| if (isGetDataModelMessage(message)) { | ||
| const { surfaceId } = message.getDataModel; | ||
| const dataModel = surfaceManager.getDataModel(surfaceId); | ||
| newTransport.sendAction(surfaceId, '__get_data_model_response', '__system', { current_data_model: dataModel ?? {} }); | ||
| return; | ||
| } | ||
| handleMessage(message, surfaceManager, agentDeletedRef.current); | ||
| }); | ||
| // Notify agent when a surface is deleted client-side (e.g. disconnect cleanup) | ||
| const unsubSurfaceDeleted = surfaceManager.on('surfaceDeleted', (surfaceId) => { | ||
| if (agentDeletedRef.current.delete(surfaceId)) { | ||
| // Agent-initiated delete — don't echo back | ||
| return; | ||
| } | ||
| // Client-initiated delete — notify the agent | ||
| newTransport.sendAction(surfaceId, 'surface_deleted', '__system', { surfaceId, reason: 'client' }); | ||
| }); | ||
| // When a surface has no components after the orphan timeout, | ||
| // send a reminder action so the agent can decide to delete it. | ||
| const unsubOrphan = surfaceManager.on('surfaceOrphan', (surfaceId) => { | ||
| newTransport.sendAction(surfaceId, 'surface_cleanup_reminder', '__system', { surfaceId, message: `Surface ${String(surfaceId)} has no components. Delete it if no longer needed. Ignore this message if you plan to use the surface.` }); | ||
| }); | ||
| // When orphan components are detected, remind the agent to wire them up | ||
| const unsubOrphanComponents = surfaceManager.on('orphanComponents', (surfaceId, componentIds) => { | ||
| newTransport.sendAction(surfaceId, 'orphan_components_reminder', '__system', { | ||
| surfaceId, | ||
| componentIds, | ||
| message: `These components in surface '${String(surfaceId)}' are not reachable from root and won't render: ${componentIds.join(', ')}. Did you forget to wire them to a parent component? Please update the parent to include them, or ignore if this was intentional.`, | ||
| }); | ||
| }); | ||
| // Handle connection state changes | ||
| newTransport.on('stateChange', (state) => { | ||
| const connected = state === 'connected'; | ||
| setIsConnected(connected); | ||
| if (state === 'disconnected') { | ||
| // Clear all surfaces when connection is lost | ||
| surfaceManager.clearSurfaces(); | ||
| } | ||
| onConnectionChangeRef.current?.(connected); | ||
| }); | ||
| // When session starts, register catalog schemas with the gateway | ||
| newTransport.on('sessionStart', (_sessionId) => { | ||
| const defs = catalogDefinitionsRef.current; | ||
| if (defs.length > 0) { | ||
| const schemas = defs | ||
| .map((def) => def.schema) | ||
| .filter((s) => s && Object.keys(s).length > 0); | ||
| if (schemas.length > 0) { | ||
| newTransport.registerCatalogs(schemas).then((ok) => { | ||
| if (ok) { | ||
| console.log('[Freesail] Catalogs registered with gateway'); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| }); | ||
| // Handle errors | ||
| newTransport.on('error', (error) => { | ||
| console.error('[Freesail] Transport error:', error); | ||
| onErrorRef.current?.(error); | ||
| }); | ||
| setTransport(newTransport); | ||
| // Auto-connect if enabled | ||
| if (autoConnectRef.current) { | ||
| newTransport.connect(); | ||
| } | ||
| // Cleanup | ||
| return () => { | ||
| unsubSurfaceDeleted(); | ||
| unsubOrphan(); | ||
| unsubOrphanComponents(); | ||
| newTransport.disconnect(); | ||
| surfaceManager.dispose(); | ||
| }; | ||
| }, [gateway]); // Only recreate if gateway URL changes | ||
| // Send action callback (v0.9 format) | ||
| const sendAction = useCallback(async (surfaceId, name, sourceComponentId, context) => { | ||
| if (!transport) { | ||
| console.warn('[Freesail] Cannot send action: transport not initialized'); | ||
| return; | ||
| } | ||
| // Send only the data model of the surface that triggered the action. | ||
| let dataModel; | ||
| if (surfaceManager.shouldSendDataModel(surfaceId)) { | ||
| const model = surfaceManager.getDataModel(surfaceId); | ||
| if (model && Object.keys(model).length > 0) { | ||
| // Filter out __-prefixed paths (client-only internal state) | ||
| const filtered = {}; | ||
| for (const [key, value] of Object.entries(model)) { | ||
| if (!key.startsWith('__')) { | ||
| filtered[key] = value; | ||
| } | ||
| } | ||
| if (Object.keys(filtered).length > 0) { | ||
| dataModel = { surfaceId, dataModel: filtered }; | ||
| } | ||
| } | ||
| } | ||
| await transport.sendAction(surfaceId, name, sourceComponentId, context, dataModel); | ||
| }, [transport, surfaceManager]); | ||
| // Get surface callback | ||
| const getSurface = useCallback((surfaceId) => surfaceManager.getSurface(surfaceId), [surfaceManager]); | ||
| // Context value | ||
| const contextValue = useMemo(() => ({ | ||
| surfaceManager, | ||
| transport, | ||
| sendAction, | ||
| getSurface, | ||
| isConnected, | ||
| }), [surfaceManager, transport, sendAction, getSurface, isConnected]); | ||
| return (_jsx(FreesailContext.Provider, { value: contextValue, children: children })); | ||
| } | ||
| // ============================================================================= | ||
| // Message Handler | ||
| // ============================================================================= | ||
| function handleMessage(message, manager, agentDeleted) { | ||
| if (isCreateSurfaceMessage(message)) { | ||
| const { surfaceId, catalogId, sendDataModel } = message.createSurface; | ||
| manager.createSurface({ surfaceId, catalogId, sendDataModel }); | ||
| } | ||
| else if (isUpdateComponentsMessage(message)) { | ||
| const { surfaceId, components } = message.updateComponents; | ||
| manager.updateComponents(surfaceId, components); | ||
| } | ||
| else if (isUpdateDataModelMessage(message)) { | ||
| const { surfaceId, path, value } = message.updateDataModel; | ||
| manager.updateDataModel(surfaceId, path, value); | ||
| } | ||
| else if (isDeleteSurfaceMessage(message)) { | ||
| const { surfaceId } = message.deleteSurface; | ||
| agentDeleted.add(surfaceId); | ||
| manager.deleteSurface(surfaceId); | ||
| } | ||
| } | ||
| //# sourceMappingURL=FreesailProvider.js.map |
| {"version":3,"file":"FreesailProvider.js","sourceRoot":"","sources":["../src/FreesailProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview FreesailProvider Component\n *\n * The root provider component that manages Freesail connections\n * and state for the React application.\n */\n\nimport React, {\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport {\n createSurfaceManager,\n createTransport,\n isCreateSurfaceMessage,\n isUpdateComponentsMessage,\n isUpdateDataModelMessage,\n isDeleteSurfaceMessage,\n isGetDataModelMessage,\n type SurfaceManager,\n type A2UITransport,\n type TransportOptions,\n type SurfaceId,\n type ComponentId,\n type CatalogId,\n type DownstreamMessage,\n type A2UIClientCapabilities,\n} from '@freesail/core';\nimport { FreesailContext, type FreesailContextValue } from './context.js';\nimport { registerCatalog, type FreesailComponent } from './registry.js';\nimport type { CatalogDefinition } from './types.js';\n\n/**\n * Props for FreesailProvider.\n */\nexport interface FreesailProviderProps {\n /** Child components */\n children: ReactNode;\n /** Base gateway URL (e.g. 'http://localhost:3001'). SSE and POST endpoints are derived automatically. */\n gateway: string;\n /** List of supported catalog IDs */\n catalogs?: CatalogId[];\n /**\n * Array of custom catalog definitions to register.\n * Each definition bundles a namespace, schema, and component map.\n * Components are auto-registered on mount.\n */\n catalogDefinitions?: CatalogDefinition[];\n /** Additional transport options */\n transportOptions?: Partial<Omit<TransportOptions, 'gateway' | 'capabilities'>>;\n /** Auto-connect on mount (default: true) */\n autoConnect?: boolean;\n /** Callback when connection state changes */\n onConnectionChange?: (connected: boolean) => void;\n /** Callback when an error occurs */\n onError?: (error: Error) => void;\n}\n\n/**\n * Root provider component for Freesail.\n *\n * Manages the transport connection and surface state,\n * making them available to all child components.\n */\nexport function FreesailProvider({\n children,\n gateway,\n catalogs = [],\n catalogDefinitions = [],\n transportOptions,\n autoConnect = true,\n onConnectionChange,\n onError,\n}: FreesailProviderProps) {\n const [surfaceManager] = useState<SurfaceManager>(() => createSurfaceManager());\n const [transport, setTransport] = useState<A2UITransport | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n // Track surfaces deleted by agent messages so we don't echo them back\n const agentDeletedRef = useRef<Set<string>>(new Set());\n // Refs for callbacks so the transport effect always uses current values\n // without needing to be recreated when callbacks change\n const onConnectionChangeRef = useRef(onConnectionChange);\n const onErrorRef = useRef(onError);\n const catalogDefinitionsRef = useRef(catalogDefinitions);\n const autoConnectRef = useRef(autoConnect);\n useEffect(() => {\n onConnectionChangeRef.current = onConnectionChange;\n onErrorRef.current = onError;\n catalogDefinitionsRef.current = catalogDefinitions;\n autoConnectRef.current = autoConnect;\n });\n\n // Register custom catalog definitions\n useEffect(() => {\n for (const def of catalogDefinitions) {\n registerCatalog(\n def.namespace as CatalogId,\n def.components as Record<string, FreesailComponent>,\n def.functions,\n def.schema as Record<string, unknown> | undefined\n );\n }\n }, [catalogDefinitions]);\n\n // Merge explicit catalog IDs with catalog definition namespaces\n const mergedCatalogs = useMemo(() => {\n const definitionIds = catalogDefinitions.map((d) => d.namespace as CatalogId);\n const combined = [...catalogs, ...definitionIds];\n return Array.from(new Set(combined));\n }, [catalogs, catalogDefinitions]);\n\n // Build capabilities from catalogs\n const capabilities: A2UIClientCapabilities | undefined = useMemo(() => {\n if (mergedCatalogs.length === 0) return undefined;\n return { catalogs: mergedCatalogs };\n }, [mergedCatalogs]);\n\n // Initialize transport\n useEffect(() => {\n const newTransport = createTransport({\n gateway,\n capabilities,\n ...transportOptions,\n });\n\n // Handle incoming messages\n newTransport.on('message', (message: DownstreamMessage) => {\n if (isGetDataModelMessage(message)) {\n const { surfaceId } = message.getDataModel;\n const dataModel = surfaceManager.getDataModel(surfaceId);\n newTransport.sendAction(\n surfaceId,\n '__get_data_model_response',\n '__system' as ComponentId,\n { current_data_model: dataModel ?? {} }\n );\n return;\n }\n handleMessage(message, surfaceManager, agentDeletedRef.current);\n });\n\n // Notify agent when a surface is deleted client-side (e.g. disconnect cleanup)\n const unsubSurfaceDeleted = surfaceManager.on('surfaceDeleted', (surfaceId: SurfaceId) => {\n if (agentDeletedRef.current.delete(surfaceId as string)) {\n // Agent-initiated delete — don't echo back\n return;\n }\n // Client-initiated delete — notify the agent\n newTransport.sendAction(\n surfaceId,\n 'surface_deleted',\n '__system' as ComponentId,\n { surfaceId, reason: 'client' }\n );\n });\n\n // When a surface has no components after the orphan timeout,\n // send a reminder action so the agent can decide to delete it.\n const unsubOrphan = surfaceManager.on('surfaceOrphan', (surfaceId: SurfaceId) => {\n newTransport.sendAction(\n surfaceId,\n 'surface_cleanup_reminder',\n '__system' as ComponentId,\n { surfaceId, message: `Surface ${String(surfaceId)} has no components. Delete it if no longer needed. Ignore this message if you plan to use the surface.` }\n );\n });\n\n // When orphan components are detected, remind the agent to wire them up\n const unsubOrphanComponents = surfaceManager.on('orphanComponents', (surfaceId: SurfaceId, componentIds: ComponentId[]) => {\n newTransport.sendAction(\n surfaceId,\n 'orphan_components_reminder',\n '__system' as ComponentId,\n {\n surfaceId,\n componentIds,\n message: `These components in surface '${String(surfaceId)}' are not reachable from root and won't render: ${componentIds.join(', ')}. Did you forget to wire them to a parent component? Please update the parent to include them, or ignore if this was intentional.`,\n }\n );\n });\n\n // Handle connection state changes\n newTransport.on('stateChange', (state: string) => {\n const connected = state === 'connected';\n setIsConnected(connected);\n\n if (state === 'disconnected') {\n // Clear all surfaces when connection is lost\n surfaceManager.clearSurfaces();\n }\n\n onConnectionChangeRef.current?.(connected);\n });\n\n // When session starts, register catalog schemas with the gateway\n newTransport.on('sessionStart', (_sessionId: string) => {\n const defs = catalogDefinitionsRef.current;\n if (defs.length > 0) {\n const schemas = defs\n .map((def) => def.schema)\n .filter((s) => s && Object.keys(s).length > 0);\n\n if (schemas.length > 0) {\n newTransport.registerCatalogs(schemas).then((ok: boolean) => {\n if (ok) {\n console.log('[Freesail] Catalogs registered with gateway');\n }\n });\n }\n }\n });\n\n // Handle errors\n newTransport.on('error', (error: Error) => {\n console.error('[Freesail] Transport error:', error);\n onErrorRef.current?.(error);\n });\n\n setTransport(newTransport);\n\n // Auto-connect if enabled\n if (autoConnectRef.current) {\n newTransport.connect();\n }\n\n // Cleanup\n return () => {\n unsubSurfaceDeleted();\n unsubOrphan();\n unsubOrphanComponents();\n newTransport.disconnect();\n surfaceManager.dispose();\n };\n }, [gateway]); // Only recreate if gateway URL changes\n\n // Send action callback (v0.9 format)\n const sendAction = useCallback(\n async (\n surfaceId: SurfaceId,\n name: string,\n sourceComponentId: ComponentId,\n context: Record<string, unknown>\n ) => {\n if (!transport) {\n console.warn('[Freesail] Cannot send action: transport not initialized');\n return;\n }\n\n // Send only the data model of the surface that triggered the action.\n let dataModel: { surfaceId: SurfaceId; dataModel: Record<string, unknown> } | undefined;\n if (surfaceManager.shouldSendDataModel(surfaceId)) {\n const model = surfaceManager.getDataModel(surfaceId);\n if (model && Object.keys(model).length > 0) {\n // Filter out __-prefixed paths (client-only internal state)\n const filtered: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(model)) {\n if (!key.startsWith('__')) {\n filtered[key] = value;\n }\n }\n if (Object.keys(filtered).length > 0) {\n dataModel = { surfaceId, dataModel: filtered };\n }\n }\n }\n\n await transport.sendAction(surfaceId, name, sourceComponentId, context, dataModel);\n },\n [transport, surfaceManager]\n );\n\n // Get surface callback\n const getSurface = useCallback(\n (surfaceId: SurfaceId) => surfaceManager.getSurface(surfaceId),\n [surfaceManager]\n );\n\n // Context value\n const contextValue: FreesailContextValue = useMemo(\n () => ({\n surfaceManager,\n transport,\n sendAction,\n getSurface,\n isConnected,\n }),\n [surfaceManager, transport, sendAction, getSurface, isConnected]\n );\n\n return (\n <FreesailContext.Provider value={contextValue}>\n {children}\n </FreesailContext.Provider>\n );\n}\n\n// =============================================================================\n// Message Handler\n// =============================================================================\n\nfunction handleMessage(message: DownstreamMessage, manager: SurfaceManager, agentDeleted: Set<string>): void {\n if (isCreateSurfaceMessage(message)) {\n const { surfaceId, catalogId, sendDataModel } = message.createSurface;\n manager.createSurface({ surfaceId, catalogId, sendDataModel });\n } else if (isUpdateComponentsMessage(message)) {\n const { surfaceId, components } = message.updateComponents;\n manager.updateComponents(surfaceId, components);\n } else if (isUpdateDataModelMessage(message)) {\n const { surfaceId, path, value } = message.updateDataModel;\n manager.updateDataModel(surfaceId, path, value);\n } else if (isDeleteSurfaceMessage(message)) {\n const { surfaceId } = message.deleteSurface;\n agentDeleted.add(surfaceId as string);\n manager.deleteSurface(surfaceId);\n }\n}\n"]} |
| /** | ||
| * @fileoverview FreesailSurface Component | ||
| * | ||
| * The main container component that renders a single A2UI surface. | ||
| * Users drop this into their app to display agent-driven UI. | ||
| */ | ||
| import { type ReactNode } from 'react'; | ||
| import type { SurfaceId } from '@freesail/core'; | ||
| /** | ||
| * Props for FreesailSurface. | ||
| */ | ||
| export interface FreesailSurfaceProps { | ||
| /** The surface ID to render */ | ||
| surfaceId: SurfaceId; | ||
| /** Optional className for the container */ | ||
| className?: string; | ||
| /** Loading state component */ | ||
| loading?: ReactNode; | ||
| /** Error state component */ | ||
| error?: ReactNode; | ||
| /** Empty state component (when surface exists but has no components) */ | ||
| empty?: ReactNode; | ||
| } | ||
| /** | ||
| * Renders a single A2UI surface. | ||
| * | ||
| * This component subscribes to surface updates and automatically | ||
| * re-renders when the component tree or data model changes. | ||
| */ | ||
| export declare function FreesailSurface({ surfaceId, className, loading, error, empty, }: FreesailSurfaceProps): import("react/jsx-runtime").JSX.Element; | ||
| //# sourceMappingURL=FreesailSurface.d.ts.map |
| {"version":3,"file":"FreesailSurface.d.ts","sourceRoot":"","sources":["../src/FreesailSurface.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAc,EAAwB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMpE,OAAO,KAAK,EACV,SAAS,EAMV,MAAM,gBAAgB,CAAC;AAOxB;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,+BAA+B;IAC/B,SAAS,EAAE,SAAS,CAAC;IACrB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,wEAAwE;IACxE,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAgBD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,SAAS,EACT,OAA4B,EAC5B,KAAwB,EACxB,KAA0B,GAC3B,EAAE,oBAAoB,2CAqDtB"} |
| import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; | ||
| /** | ||
| * @fileoverview FreesailSurface Component | ||
| * | ||
| * The main container component that renders a single A2UI surface. | ||
| * Users drop this into their app to display agent-driven UI. | ||
| */ | ||
| import { useMemo, useCallback } from 'react'; | ||
| import { FREESAIL_LOGO_DATA_URI } from './logo.js'; | ||
| import { isFunctionCall, } from '@freesail/core'; | ||
| import { useSurface, useAction } from './hooks.js'; | ||
| import { registry } from './registry.js'; | ||
| import { useFreesailContext } from './context.js'; | ||
| import { getDataAtPath } from './utils.js'; | ||
| /** | ||
| * Renders a single A2UI surface. | ||
| * | ||
| * This component subscribes to surface updates and automatically | ||
| * re-renders when the component tree or data model changes. | ||
| */ | ||
| export function FreesailSurface({ surfaceId, className, loading = _jsx(DefaultLoading, {}), error = _jsx(DefaultError, {}), empty = _jsx(DefaultLoading, {}), }) { | ||
| const surface = useSurface(surfaceId); | ||
| const dispatch = useAction(surfaceId); | ||
| const { surfaceManager } = useFreesailContext(); | ||
| // Two-way binding: input components write to the local data model. | ||
| // This is local only — no network request. The updated data model | ||
| // reaches the server via resolved data bindings in action context | ||
| // or via the sendDataModel metadata mechanism. | ||
| const onDataChange = useCallback((path, value) => { | ||
| console.log(`[Freesail] onDataChange: surface=${surfaceId} path=${path} value=`, value); | ||
| surfaceManager.updateDataModel(surfaceId, path, value); | ||
| }, [surfaceManager, surfaceId]); | ||
| // Build the component tree | ||
| const renderedTree = useMemo(() => { | ||
| if (!surface) | ||
| return null; | ||
| if (surface.components.size === 0) | ||
| return null; | ||
| if (!surface.rootId) | ||
| return null; | ||
| return renderComponent(surface.rootId, surface.components, surface.catalogId, surface.dataModel, dispatch, onDataChange, undefined, undefined, undefined); | ||
| }, [surface, dispatch, onDataChange]); | ||
| // Loading state - surface doesn't exist yet | ||
| if (!surface) { | ||
| return _jsx("div", { className: className, style: { flex: 1, minHeight: 0 }, children: loading }); | ||
| } | ||
| // Empty state - surface exists but no components | ||
| if (surface.components.size === 0 || !surface.rootId) { | ||
| return _jsx("div", { className: className, style: { flex: 1, minHeight: 0 }, children: empty }); | ||
| } | ||
| // Check if catalog is registered | ||
| if (!registry.hasCatalog(surface.catalogId)) { | ||
| console.error(`[Freesail] Catalog not registered: ${surface.catalogId}`); | ||
| return _jsx("div", { className: className, style: { flex: 1, minHeight: 0 }, children: error }); | ||
| } | ||
| return _jsx("div", { className: className, "data-freesail-surface": surfaceId, style: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }, children: renderedTree }); | ||
| } | ||
| // ============================================================================= | ||
| // Component Renderer | ||
| // ============================================================================= | ||
| function renderComponent(componentId, components, catalogId, dataModel, dispatch, onDataChange, scopeData, keyOverride, scopeBasePath) { | ||
| const componentDef = components.get(componentId); | ||
| if (!componentDef) { | ||
| // Component may arrive in a subsequent update_components batch — render nothing for now | ||
| return null; | ||
| } | ||
| // Get the React component from registry | ||
| const Component = registry.getComponent(catalogId, componentDef.component); | ||
| if (!Component) { | ||
| return _jsx(UnknownComponent, { component: componentDef }); | ||
| } | ||
| // Render children recursively | ||
| let children = null; | ||
| // 1. Handle single child (for Card, etc.) | ||
| if (componentDef.child) { | ||
| children = renderComponent(componentDef.child, components, catalogId, dataModel, dispatch, onDataChange, scopeData, undefined, scopeBasePath); | ||
| } | ||
| // 2. Handle multiple standard children (Column, Row, List, etc.) | ||
| else if (componentDef.children) { | ||
| const childList = componentDef.children; | ||
| if (Array.isArray(childList)) { | ||
| // Static array of child IDs | ||
| children = childList.map((childId) => renderComponent(childId, components, catalogId, dataModel, dispatch, onDataChange, scopeData, undefined, scopeBasePath)); | ||
| } | ||
| else if (typeof childList === 'object' && 'componentId' in childList) { | ||
| // Template for dynamic children | ||
| const template = childList; | ||
| const listData = getDataAtPath(dataModel, template.path); | ||
| if (Array.isArray(listData)) { | ||
| children = listData.map((itemData, index) => { | ||
| // Build the absolute path for this item in the data model | ||
| const itemBasePath = `${template.path}/${index}`; | ||
| return renderComponent(template.componentId, components, catalogId, dataModel, dispatch, onDataChange, itemData, // Pass item data as scope | ||
| `${template.componentId}_${itemData?.id ?? index}`, // Unique key per item | ||
| itemBasePath // Absolute path for two-way binding | ||
| ); | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| // Resolve data bindings in component properties | ||
| const resolvedProps = resolveDataBindings(componentDef, dataModel, catalogId, scopeData, scopeBasePath); | ||
| // Visibility check: if `visible` resolves to exactly false, skip rendering. | ||
| // Data-model override (from show/hide) takes precedence over component prop. | ||
| const visibilityOverride = getDataAtPath(dataModel, `/__componentState/${componentId}/visible`); | ||
| const effectiveVisible = visibilityOverride != null ? visibilityOverride : resolvedProps['visible']; | ||
| if (effectiveVisible === false || effectiveVisible === 'false') { | ||
| return null; | ||
| } | ||
| // Build props | ||
| const props = { | ||
| component: { ...componentDef, ...resolvedProps }, | ||
| children, | ||
| dataModel, | ||
| scopeData, | ||
| onAction: (name, context) => { | ||
| // Resolve data bindings in action context at dispatch time. | ||
| const resolvedContext = resolveActionContext(context, dataModel, catalogId, scopeData); | ||
| return dispatch(name, componentDef.id, resolvedContext); | ||
| }, | ||
| onDataChange, | ||
| onFunctionCall: (call) => { | ||
| const result = evaluateFunction(call, dataModel, catalogId, scopeData); | ||
| // Handle side-effect returns (e.g. show/hide writes to data model) | ||
| if (result && typeof result === 'object' && '__sideEffect' in result) { | ||
| const sideEffect = result; | ||
| if (sideEffect.__sideEffect === 'dataModelUpdate') { | ||
| onDataChange(sideEffect.path, sideEffect.value); | ||
| } | ||
| } | ||
| }, | ||
| }; | ||
| try { | ||
| const rendered = _jsx(Component, { ...props }, keyOverride ?? componentId); | ||
| // Apply weight as flex when the component has a weight property. | ||
| // Uses a data attribute so parent layouts (e.g. GridLayout) can override | ||
| // with display:contents if needed. | ||
| const weight = componentDef['weight']; | ||
| if (weight != null) { | ||
| return _jsx("div", { "data-freesail-weight": true, style: { flex: `${weight} 1 auto`, minWidth: 0, minHeight: 0, display: 'flex', flexDirection: 'column', alignSelf: 'stretch' }, children: rendered }, keyOverride ?? componentId); | ||
| } | ||
| return rendered; | ||
| } | ||
| catch (err) { | ||
| console.error(`[Freesail] Component render error (${componentDef.component}):`, err); | ||
| return _jsx(UnknownComponent, { component: componentDef }); | ||
| } | ||
| } | ||
| /** | ||
| * Resolve data bindings in component properties. | ||
| */ | ||
| function resolveDataBindings(component, dataModel, catalogId, scopeData, scopeBasePath, _depth = 0) { | ||
| if (_depth > 10) | ||
| return {}; | ||
| const resolved = {}; | ||
| for (const [key, value] of Object.entries(component)) { | ||
| if (key === 'id' || key === 'component' || key === 'children' || key === 'child') { | ||
| continue; | ||
| } | ||
| // Robustness: Handle double-encoded bindings | ||
| let effectiveValue = value; | ||
| if (typeof value === 'string' && value.trim().startsWith('{') && value.includes('"path"')) { | ||
| try { | ||
| const parsed = JSON.parse(value); | ||
| if (isDataBindingObject(parsed)) { | ||
| effectiveValue = parsed; | ||
| } | ||
| } | ||
| catch { | ||
| // Ignore parse errors | ||
| } | ||
| } | ||
| if (isFunctionCall(effectiveValue)) { | ||
| // Don't eagerly evaluate function calls inside `action` — they are | ||
| // deferred and executed by the component on user interaction (e.g. Button click). | ||
| if (key === 'action') { | ||
| resolved[key] = effectiveValue; | ||
| } | ||
| else { | ||
| resolved[key] = evaluateFunction(effectiveValue, dataModel, catalogId, scopeData); | ||
| } | ||
| } | ||
| else if (isDataBindingObject(effectiveValue)) { | ||
| // Preserve the raw binding so components can find the path for two-way binding. | ||
| // If inside a scoped template, convert relative paths to absolute paths | ||
| // so onDataChange writes to the correct location in the data model. | ||
| const rawBinding = { ...effectiveValue }; | ||
| if (scopeBasePath && !rawBinding.path.startsWith('/')) { | ||
| rawBinding.path = `${scopeBasePath}/${rawBinding.path}`; | ||
| } | ||
| resolved[`__raw${key.charAt(0).toUpperCase()}${key.slice(1)}`] = rawBinding; | ||
| // Resolve data binding | ||
| resolved[key] = resolveSingleBinding(effectiveValue, dataModel, scopeData); | ||
| } | ||
| else if (typeof value === 'object' && value !== null) { | ||
| // Prevent recursion into LocalAction definitions (which contain FunctionCalls that should NOT be evaluated yet) | ||
| if ('functionCall' in value && isFunctionCall(value.functionCall)) { | ||
| resolved[key] = value; | ||
| continue; | ||
| } | ||
| // Recursively resolve bindings inside objects and arrays | ||
| if (Array.isArray(value)) { | ||
| resolved[key] = value.map(item => { | ||
| if (typeof item === 'object' && item !== null) { | ||
| // Check for LocalAction in array items too | ||
| if ('functionCall' in item && isFunctionCall(item.functionCall)) { | ||
| return item; | ||
| } | ||
| if (isFunctionCall(item)) { | ||
| return evaluateFunction(item, dataModel, catalogId, scopeData); | ||
| } | ||
| if (isDataBindingObject(item)) { | ||
| return resolveSingleBinding(item, dataModel, scopeData); | ||
| } | ||
| return resolveDataBindings(item, dataModel, catalogId, scopeData, undefined, _depth + 1); | ||
| } | ||
| return item; | ||
| }); | ||
| } | ||
| else { | ||
| resolved[key] = resolveDataBindings(value, dataModel, catalogId, scopeData, undefined, _depth + 1); | ||
| } | ||
| } | ||
| else { | ||
| resolved[key] = value; | ||
| } | ||
| } | ||
| return resolved; | ||
| } | ||
| /** | ||
| * Helper to resolve a single binding object, following chains. | ||
| */ | ||
| function resolveSingleBinding(binding, dataModel, scopeData) { | ||
| const path = binding.path; | ||
| let resolvedValue; | ||
| // "." or "" means "the current scoped item" — used when iterating scalar arrays | ||
| if (path === '.' || path === '') { | ||
| return scopeData !== undefined ? scopeData : getDataAtPath(dataModel, '/'); | ||
| } | ||
| if (path.startsWith('/')) { | ||
| resolvedValue = getDataAtPath(dataModel, path); | ||
| } | ||
| else if (scopeData !== undefined) { | ||
| resolvedValue = getDataAtPath(scopeData, '/' + path); | ||
| } | ||
| else { | ||
| resolvedValue = getDataAtPath(dataModel, '/' + path); | ||
| } | ||
| // Chained bindings (max depth 5) | ||
| let depth = 0; | ||
| while (isDataBindingObject(resolvedValue) && depth < 5) { | ||
| const chainedPath = resolvedValue.path; | ||
| resolvedValue = chainedPath.startsWith('/') | ||
| ? getDataAtPath(dataModel, chainedPath) | ||
| : getDataAtPath(dataModel, '/' + chainedPath); | ||
| depth++; | ||
| } | ||
| return resolvedValue; | ||
| } | ||
| function isDataBindingObject(value) { | ||
| if (typeof value !== 'object' || value === null || !('path' in value)) | ||
| return false; | ||
| if (typeof value['path'] !== 'string') | ||
| return false; | ||
| if ('componentId' in value) | ||
| return false; // ChildListTemplate | ||
| if ('event' in value) | ||
| return false; // ServerAction | ||
| if ('call' in value) | ||
| return false; // FunctionCall | ||
| return true; | ||
| } | ||
| /** | ||
| * Evaluate a function call. | ||
| */ | ||
| function evaluateFunction(call, dataModel, catalogId, scopeData) { | ||
| const functionName = call.call; | ||
| const funcImpl = registry.getFunction(catalogId, functionName); | ||
| if (!funcImpl) { | ||
| console.warn(`[Freesail] Function not found: ${functionName} in catalog ${catalogId}`); | ||
| return undefined; | ||
| } | ||
| // Resolve arguments | ||
| let rawArgs = []; | ||
| if (Array.isArray(call.args)) { | ||
| rawArgs = call.args; | ||
| } | ||
| else if (call.args && typeof call.args === 'object') { | ||
| const entries = Object.entries(call.args); | ||
| // Check if the registry declares paramNames for this function | ||
| // and the keys are named (not numeric). | ||
| // If so, reorder entries to match the declared parameter order. | ||
| const paramNames = registry.getParamNames(catalogId, functionName); | ||
| const hasNonNumericKeys = entries.some(([key]) => isNaN(parseInt(key.replace(/^'|'$/g, ''), 10))); | ||
| if (paramNames && hasNonNumericKeys) { | ||
| // Build a lookup from the entries | ||
| const argMap = new Map(entries); | ||
| // Reorder: first pull args matching declared param names in order, | ||
| // then append any extra keys not in paramNames | ||
| const ordered = []; | ||
| const used = new Set(); | ||
| for (const name of paramNames) { | ||
| if (argMap.has(name)) { | ||
| ordered.push(argMap.get(name)); | ||
| used.add(name); | ||
| } | ||
| } | ||
| // Append remaining keys not in paramNames (preserves insertion order) | ||
| for (const [key, value] of entries) { | ||
| if (!used.has(key)) { | ||
| ordered.push(value); | ||
| } | ||
| } | ||
| rawArgs = ordered; | ||
| } | ||
| else { | ||
| // Numeric keys or no paramNames — sort numerically as before | ||
| entries.sort(([keyA], [keyB]) => { | ||
| // Remove surrounding quotes if present to cleanly parse as number | ||
| const numA = parseInt(keyA.replace(/^'|'$/g, ''), 10); | ||
| const numB = parseInt(keyB.replace(/^'|'$/g, ''), 10); | ||
| if (!isNaN(numA) && !isNaN(numB)) { | ||
| return numA - numB; | ||
| } | ||
| return 0; // fallback to stable sort for non-numeric keys | ||
| }); | ||
| rawArgs = entries.map(([, value]) => value); | ||
| } | ||
| // Robustness: agents sometimes wrap multiple positional args in a single-key | ||
| // object as an array, e.g. { "value": [arg0, arg1] } instead of [arg0, arg1]. | ||
| // When there is exactly one entry and its value is an array, spread it so that | ||
| // multi-arg functions like lte(a, b) receive two arguments, not one array. | ||
| if (rawArgs.length === 1 && Array.isArray(rawArgs[0])) { | ||
| rawArgs = rawArgs[0]; | ||
| } | ||
| } | ||
| const args = rawArgs.map(arg => { | ||
| if (isFunctionCall(arg)) { | ||
| return evaluateFunction(arg, dataModel, catalogId, scopeData); | ||
| } | ||
| if (isDataBindingObject(arg)) { | ||
| return resolveSingleBinding(arg, dataModel, scopeData); | ||
| } | ||
| // Handle nested arrays/objects in args | ||
| if (typeof arg === 'object' && arg !== null) { | ||
| if (Array.isArray(arg)) { | ||
| return arg.map(item => { | ||
| if (isFunctionCall(item)) | ||
| return evaluateFunction(item, dataModel, catalogId, scopeData); | ||
| if (isDataBindingObject(item)) | ||
| return resolveSingleBinding(item, dataModel, scopeData); | ||
| return item; | ||
| }); | ||
| } | ||
| } | ||
| return arg; | ||
| }); | ||
| // formatString: pre-process the format string for ${...} template interpolation | ||
| let callArgs = args; | ||
| if (functionName === 'formatString' && callArgs.length > 0 && typeof callArgs[0] === 'string') { | ||
| callArgs = [ | ||
| interpolateTemplate(callArgs[0], dataModel, catalogId, scopeData, (nestedCall) => evaluateFunction(nestedCall, dataModel, catalogId, scopeData)), | ||
| ...callArgs.slice(1), | ||
| ]; | ||
| } | ||
| try { | ||
| return funcImpl(...callArgs); | ||
| } | ||
| catch (error) { | ||
| console.error(`[Freesail] Error evaluating function ${functionName}:`, error); | ||
| return undefined; | ||
| } | ||
| } | ||
| /** | ||
| * Resolve data bindings in an action's context object. | ||
| */ | ||
| function resolveActionContext(context, dataModel, catalogId, scopeData) { | ||
| const resolved = {}; | ||
| for (const [key, value] of Object.entries(context)) { | ||
| if (isFunctionCall(value)) { | ||
| resolved[key] = evaluateFunction(value, dataModel, catalogId, scopeData); | ||
| } | ||
| else if (isDataBindingObject(value)) { | ||
| const path = value.path; | ||
| if (path.startsWith('/')) { | ||
| resolved[key] = getDataAtPath(dataModel, path); | ||
| } | ||
| else if (scopeData !== undefined) { | ||
| resolved[key] = getDataAtPath(scopeData, '/' + path); | ||
| } | ||
| else { | ||
| // Relative path but no scope — normalize to absolute | ||
| resolved[key] = getDataAtPath(dataModel, '/' + path); | ||
| } | ||
| } | ||
| else { | ||
| resolved[key] = value; | ||
| } | ||
| } | ||
| return resolved; | ||
| } | ||
| // ============================================================================= | ||
| // Template Interpolation (for formatString ${...} syntax) | ||
| // ============================================================================= | ||
| /** | ||
| * Finds the position of the closing brace that matches the opening brace at openPos, | ||
| * respecting nested braces and quoted strings. | ||
| */ | ||
| function findMatchingBrace(str, openPos) { | ||
| let depth = 0; | ||
| let inSingleQuote = false; | ||
| let inDoubleQuote = false; | ||
| for (let i = openPos; i < str.length; i++) { | ||
| const ch = str[i]; | ||
| const escaped = i > 0 && str[i - 1] === '\\'; | ||
| if (ch === "'" && !inDoubleQuote && !escaped) | ||
| inSingleQuote = !inSingleQuote; | ||
| if (ch === '"' && !inSingleQuote && !escaped) | ||
| inDoubleQuote = !inDoubleQuote; | ||
| if (!inSingleQuote && !inDoubleQuote) { | ||
| if (ch === '{') | ||
| depth++; | ||
| else if (ch === '}') { | ||
| depth--; | ||
| if (depth === 0) | ||
| return i; | ||
| } | ||
| } | ||
| } | ||
| return -1; | ||
| } | ||
| /** Converts a value to a display string for interpolation output. */ | ||
| function interpolatedValueToString(value) { | ||
| if (value === null || value === undefined) | ||
| return ''; | ||
| if (typeof value === 'object') | ||
| return JSON.stringify(value); | ||
| return String(value); | ||
| } | ||
| /** | ||
| * Splits a comma-separated args string into individual tokens, | ||
| * respecting nested ${...} and quoted strings. | ||
| */ | ||
| function splitInterpolationArgs(argsStr) { | ||
| const parts = []; | ||
| let current = ''; | ||
| let depth = 0; | ||
| let inSingleQuote = false; | ||
| let inDoubleQuote = false; | ||
| for (let i = 0; i < argsStr.length; i++) { | ||
| const ch = argsStr[i]; | ||
| const escaped = i > 0 && argsStr[i - 1] === '\\'; | ||
| if (ch === "'" && !inDoubleQuote && !escaped) | ||
| inSingleQuote = !inSingleQuote; | ||
| else if (ch === '"' && !inSingleQuote && !escaped) | ||
| inDoubleQuote = !inDoubleQuote; | ||
| else if (!inSingleQuote && !inDoubleQuote) { | ||
| if (ch === '{') | ||
| depth++; | ||
| else if (ch === '}') | ||
| depth--; | ||
| else if (ch === ',' && depth === 0) { | ||
| parts.push(current.trim()); | ||
| current = ''; | ||
| continue; | ||
| } | ||
| } | ||
| current += ch; | ||
| } | ||
| if (current.trim()) | ||
| parts.push(current.trim()); | ||
| return parts; | ||
| } | ||
| /** | ||
| * Parses a single argument token from an interpolation expression. | ||
| * Supports: 'string', "string", number, boolean, ${nested}, bare path. | ||
| */ | ||
| function parseInterpolationValue(token, dataModel, catalogId, scopeData, evalFn) { | ||
| token = token.trim(); | ||
| if ((token.startsWith("'") && token.endsWith("'")) || (token.startsWith('"') && token.endsWith('"'))) | ||
| return token.slice(1, -1); | ||
| if (token.startsWith('${') && token.endsWith('}')) | ||
| return evaluateInterpolationExpr(token.slice(2, -1), dataModel, catalogId, scopeData, evalFn); | ||
| if (token === 'true') | ||
| return true; | ||
| if (token === 'false') | ||
| return false; | ||
| const num = Number(token); | ||
| if (!isNaN(num) && token !== '') | ||
| return num; | ||
| if (token.startsWith('/')) | ||
| return getDataAtPath(dataModel, token); | ||
| if (scopeData !== undefined) | ||
| return getDataAtPath(scopeData, '/' + token); | ||
| return getDataAtPath(dataModel, '/' + token); | ||
| } | ||
| /** | ||
| * Evaluates the expression inside ${...}: either a data path or a function call. | ||
| */ | ||
| function evaluateInterpolationExpr(expr, dataModel, catalogId, scopeData, evalFn) { | ||
| expr = expr.trim(); | ||
| // Function call: word(...) | ||
| if (/^\w[\w.]*\(.*\)$/s.test(expr)) { | ||
| const parenOpen = expr.indexOf('('); | ||
| const funcName = expr.slice(0, parenOpen).trim(); | ||
| const argsStr = expr.slice(parenOpen + 1, -1).trim(); | ||
| const args = {}; | ||
| if (argsStr) { | ||
| splitInterpolationArgs(argsStr).forEach((part, index) => { | ||
| const colonIdx = part.indexOf(':'); | ||
| if (colonIdx > 0) { | ||
| const potentialKey = part.slice(0, colonIdx).trim(); | ||
| if (/^[a-zA-Z_]\w*$/.test(potentialKey)) { | ||
| args[potentialKey] = parseInterpolationValue(part.slice(colonIdx + 1).trim(), dataModel, catalogId, scopeData, evalFn); | ||
| return; | ||
| } | ||
| } | ||
| args[String(index)] = parseInterpolationValue(part, dataModel, catalogId, scopeData, evalFn); | ||
| }); | ||
| } | ||
| return evalFn({ call: funcName, args }); | ||
| } | ||
| // Data path | ||
| if (expr.startsWith('/')) | ||
| return getDataAtPath(dataModel, expr); | ||
| if (scopeData !== undefined) | ||
| return getDataAtPath(scopeData, '/' + expr); | ||
| return getDataAtPath(dataModel, '/' + expr); | ||
| } | ||
| /** | ||
| * Processes ${...} template expressions in a formatString format string. | ||
| * Supports: ${/absolute/path}, ${relative/field}, ${funcName(args)}, | ||
| * nested expressions (${upper(${/name})}), and escaped literals (\${). | ||
| */ | ||
| function interpolateTemplate(template, dataModel, catalogId, scopeData, evalFn) { | ||
| let result = ''; | ||
| let i = 0; | ||
| while (i < template.length) { | ||
| // Escaped: \${ → literal ${ | ||
| if (template[i] === '\\' && template[i + 1] === '$' && template[i + 2] === '{') { | ||
| result += '${'; | ||
| i += 3; | ||
| continue; | ||
| } | ||
| // Expression: ${...} | ||
| if (template[i] === '$' && template[i + 1] === '{') { | ||
| const closeBrace = findMatchingBrace(template, i + 1); | ||
| if (closeBrace === -1) { | ||
| result += template[i++]; | ||
| continue; | ||
| } | ||
| const expr = template.slice(i + 2, closeBrace); | ||
| result += interpolatedValueToString(evaluateInterpolationExpr(expr, dataModel, catalogId, scopeData, evalFn)); | ||
| i = closeBrace + 1; | ||
| continue; | ||
| } | ||
| result += template[i++]; | ||
| } | ||
| return result; | ||
| } | ||
| // ============================================================================= | ||
| // Default UI States | ||
| // ============================================================================= | ||
| function DefaultLoading() { | ||
| return (_jsxs("div", { style: { | ||
| display: 'flex', | ||
| flexDirection: 'column', | ||
| alignItems: 'center', | ||
| justifyContent: 'center', | ||
| padding: '40px 16px', | ||
| gap: '16px', | ||
| }, children: [_jsx("style", { children: ` | ||
| @keyframes freesail-pulse { | ||
| 0%, 100% { opacity: 0.4; transform: scale(0.95); } | ||
| 50% { opacity: 1; transform: scale(1); } | ||
| } | ||
| @keyframes freesail-spin { | ||
| 0% { transform: rotate(0deg); } | ||
| 100% { transform: rotate(360deg); } | ||
| } | ||
| ` }), FREESAIL_LOGO_DATA_URI ? (_jsx("img", { src: FREESAIL_LOGO_DATA_URI, alt: "Loading", style: { | ||
| width: '48px', | ||
| height: '48px', | ||
| animation: 'freesail-pulse 1.5s ease-in-out infinite', | ||
| } })) : (_jsx("div", { style: { | ||
| width: '32px', | ||
| height: '32px', | ||
| border: '3px solid var(--freesail-border, #e2e8f0)', | ||
| borderTopColor: 'var(--freesail-primary, #2563eb)', | ||
| borderRadius: '50%', | ||
| animation: 'freesail-spin 0.8s linear infinite', | ||
| } })), _jsx("span", { style: { | ||
| fontSize: '13px', | ||
| color: 'var(--freesail-text-muted, #64748b)', | ||
| letterSpacing: '0.05em', | ||
| }, children: "Preparing\u2026" })] })); | ||
| } | ||
| function DefaultError() { | ||
| return (_jsx("div", { style: { padding: '16px', color: '#c00' }, children: "Error: Unable to render surface" })); | ||
| } | ||
| function UnknownComponent({ component }) { | ||
| return (_jsxs("div", { style: { | ||
| padding: '8px', | ||
| border: '1px dashed #f00', | ||
| background: '#fee', | ||
| margin: '4px', | ||
| }, children: [_jsx("strong", { children: "Unknown Component:" }), " ", component.component, _jsx("pre", { style: { fontSize: '10px' }, children: JSON.stringify(component, null, 2) })] })); | ||
| } | ||
| //# sourceMappingURL=FreesailSurface.js.map |
| {"version":3,"file":"FreesailSurface.js","sourceRoot":"","sources":["../src/FreesailSurface.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview FreesailSurface Component\n *\n * The main container component that renders a single A2UI surface.\n * Users drop this into their app to display agent-driven UI.\n */\n\nimport React, { useMemo, useCallback, type ReactNode } from 'react';\nimport { FREESAIL_LOGO_DATA_URI } from './logo.js';\nimport {\n isChildListTemplate,\n isFunctionCall,\n} from '@freesail/core';\nimport type {\n SurfaceId,\n CatalogId,\n A2UIComponent,\n ComponentId,\n ChildList,\n FunctionCall,\n} from '@freesail/core';\nimport { useSurface, useAction } from './hooks.js';\nimport { registry, type FreesailComponentProps } from './registry.js';\nimport { useFreesailContext } from './context.js';\nimport { getDataAtPath } from './utils.js';\nimport type { FunctionImplementation } from './types.js';\n\n/**\n * Props for FreesailSurface.\n */\nexport interface FreesailSurfaceProps {\n /** The surface ID to render */\n surfaceId: SurfaceId;\n /** Optional className for the container */\n className?: string;\n /** Loading state component */\n loading?: ReactNode;\n /** Error state component */\n error?: ReactNode;\n /** Empty state component (when surface exists but has no components) */\n empty?: ReactNode;\n}\n\n/**\n * Dispatch function type for actions.\n */\ntype ActionDispatch = (\n name: string,\n sourceComponentId: ComponentId,\n context: Record<string, unknown>\n) => Promise<void>;\n\n/**\n * Callback for two-way binding: components write values to the local data model.\n */\ntype DataChangeDispatch = (path: string, value: unknown) => void;\n\n/**\n * Renders a single A2UI surface.\n *\n * This component subscribes to surface updates and automatically\n * re-renders when the component tree or data model changes.\n */\nexport function FreesailSurface({\n surfaceId,\n className,\n loading = <DefaultLoading />,\n error = <DefaultError />,\n empty = <DefaultLoading />,\n}: FreesailSurfaceProps) {\n const surface = useSurface(surfaceId);\n const dispatch = useAction(surfaceId);\n const { surfaceManager } = useFreesailContext();\n\n // Two-way binding: input components write to the local data model.\n // This is local only — no network request. The updated data model\n // reaches the server via resolved data bindings in action context\n // or via the sendDataModel metadata mechanism.\n const onDataChange: DataChangeDispatch = useCallback(\n (path: string, value: unknown) => {\n console.log(`[Freesail] onDataChange: surface=${surfaceId} path=${path} value=`, value);\n surfaceManager.updateDataModel(surfaceId, path, value);\n },\n [surfaceManager, surfaceId]\n );\n\n // Build the component tree\n const renderedTree = useMemo(() => {\n if (!surface) return null;\n if (surface.components.size === 0) return null;\n if (!surface.rootId) return null;\n\n return renderComponent(\n surface.rootId,\n surface.components,\n surface.catalogId,\n surface.dataModel,\n dispatch,\n onDataChange,\n undefined,\n undefined,\n undefined\n );\n }, [surface, dispatch, onDataChange]);\n\n // Loading state - surface doesn't exist yet\n if (!surface) {\n return <div className={className} style={{ flex: 1, minHeight: 0 }}>{loading}</div>;\n }\n\n // Empty state - surface exists but no components\n if (surface.components.size === 0 || !surface.rootId) {\n return <div className={className} style={{ flex: 1, minHeight: 0 }}>{empty}</div>;\n }\n\n // Check if catalog is registered\n if (!registry.hasCatalog(surface.catalogId)) {\n console.error(`[Freesail] Catalog not registered: ${surface.catalogId}`);\n return <div className={className} style={{ flex: 1, minHeight: 0 }}>{error}</div>;\n }\n\n return <div className={className} data-freesail-surface={surfaceId} style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }}>{renderedTree}</div>;\n}\n\n// =============================================================================\n// Component Renderer\n// =============================================================================\n\nfunction renderComponent(\n componentId: ComponentId,\n components: Map<ComponentId, A2UIComponent>,\n catalogId: string,\n dataModel: Record<string, unknown>,\n dispatch: ActionDispatch,\n onDataChange: DataChangeDispatch,\n scopeData?: unknown,\n keyOverride?: string,\n scopeBasePath?: string\n): ReactNode {\n const componentDef = components.get(componentId);\n if (!componentDef) {\n // Component may arrive in a subsequent update_components batch — render nothing for now\n return null;\n }\n\n // Get the React component from registry\n const Component = registry.getComponent(catalogId, componentDef.component);\n if (!Component) {\n return <UnknownComponent component={componentDef} />;\n }\n\n // Render children recursively\n let children: ReactNode = null;\n\n // 1. Handle single child (for Card, etc.)\n if (componentDef.child) {\n children = renderComponent(\n componentDef.child,\n components,\n catalogId,\n dataModel,\n dispatch,\n onDataChange,\n scopeData,\n undefined,\n scopeBasePath\n );\n }\n // 2. Handle multiple standard children (Column, Row, List, etc.)\n else if (componentDef.children) {\n const childList = componentDef.children as ChildList;\n\n if (Array.isArray(childList)) {\n // Static array of child IDs\n children = childList.map((childId) =>\n renderComponent(childId, components, catalogId, dataModel, dispatch, onDataChange, scopeData, undefined, scopeBasePath)\n );\n } else if (typeof childList === 'object' && 'componentId' in childList) {\n // Template for dynamic children\n const template = childList;\n const listData = getDataAtPath(dataModel, template.path);\n\n if (Array.isArray(listData)) {\n children = listData.map((itemData, index) => {\n // Build the absolute path for this item in the data model\n const itemBasePath = `${template.path}/${index}`;\n return renderComponent(\n template.componentId,\n components,\n catalogId,\n dataModel,\n dispatch,\n onDataChange,\n itemData, // Pass item data as scope\n `${template.componentId}_${(itemData as any)?.id ?? index}`, // Unique key per item\n itemBasePath // Absolute path for two-way binding\n );\n });\n }\n }\n }\n\n // Resolve data bindings in component properties\n const resolvedProps = resolveDataBindings(componentDef, dataModel, catalogId, scopeData, scopeBasePath);\n\n // Visibility check: if `visible` resolves to exactly false, skip rendering.\n // Data-model override (from show/hide) takes precedence over component prop.\n const visibilityOverride = getDataAtPath(dataModel, `/__componentState/${componentId}/visible`);\n const effectiveVisible = visibilityOverride != null ? visibilityOverride : resolvedProps['visible'];\n if (effectiveVisible === false || effectiveVisible === 'false') {\n return null;\n }\n\n // Build props\n const props: FreesailComponentProps = {\n component: { ...componentDef, ...resolvedProps },\n children,\n dataModel,\n scopeData,\n onAction: (name, context) => {\n // Resolve data bindings in action context at dispatch time.\n const resolvedContext = resolveActionContext(context, dataModel, catalogId, scopeData);\n return dispatch(name, componentDef.id, resolvedContext);\n },\n onDataChange,\n onFunctionCall: (call) => {\n const result = evaluateFunction(call, dataModel, catalogId, scopeData);\n // Handle side-effect returns (e.g. show/hide writes to data model)\n if (result && typeof result === 'object' && '__sideEffect' in (result as Record<string, unknown>)) {\n const sideEffect = result as { __sideEffect: string; path: string; value: unknown };\n if (sideEffect.__sideEffect === 'dataModelUpdate') {\n onDataChange(sideEffect.path, sideEffect.value);\n }\n }\n },\n };\n\n try {\n const rendered = <Component key={keyOverride ?? componentId} {...props} />;\n // Apply weight as flex when the component has a weight property.\n // Uses a data attribute so parent layouts (e.g. GridLayout) can override\n // with display:contents if needed.\n const weight = componentDef['weight'] as number | undefined;\n if (weight != null) {\n return <div key={keyOverride ?? componentId} data-freesail-weight style={{ flex: `${weight} 1 auto`, minWidth: 0, minHeight: 0, display: 'flex', flexDirection: 'column', alignSelf: 'stretch' }}>{rendered}</div>;\n }\n return rendered;\n } catch (err) {\n console.error(`[Freesail] Component render error (${componentDef.component}):`, err);\n return <UnknownComponent component={componentDef} />;\n }\n}\n\n/**\n * Resolve data bindings in component properties.\n */\nfunction resolveDataBindings(\n component: A2UIComponent,\n dataModel: Record<string, unknown>,\n catalogId: string,\n scopeData?: unknown,\n scopeBasePath?: string,\n _depth = 0\n): Record<string, unknown> {\n if (_depth > 10) return {};\n const resolved: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(component)) {\n if (key === 'id' || key === 'component' || key === 'children' || key === 'child') {\n continue;\n }\n\n // Robustness: Handle double-encoded bindings\n let effectiveValue = value;\n if (typeof value === 'string' && value.trim().startsWith('{') && value.includes('\"path\"')) {\n try {\n const parsed = JSON.parse(value);\n if (isDataBindingObject(parsed)) {\n effectiveValue = parsed;\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n if (isFunctionCall(effectiveValue)) {\n // Don't eagerly evaluate function calls inside `action` — they are\n // deferred and executed by the component on user interaction (e.g. Button click).\n if (key === 'action') {\n resolved[key] = effectiveValue;\n } else {\n resolved[key] = evaluateFunction(effectiveValue, dataModel, catalogId, scopeData);\n }\n } else if (isDataBindingObject(effectiveValue)) {\n // Preserve the raw binding so components can find the path for two-way binding.\n // If inside a scoped template, convert relative paths to absolute paths\n // so onDataChange writes to the correct location in the data model.\n const rawBinding = { ...effectiveValue };\n if (scopeBasePath && !rawBinding.path.startsWith('/')) {\n rawBinding.path = `${scopeBasePath}/${rawBinding.path}`;\n }\n resolved[`__raw${key.charAt(0).toUpperCase()}${key.slice(1)}`] = rawBinding;\n // Resolve data binding\n resolved[key] = resolveSingleBinding(effectiveValue, dataModel, scopeData);\n\n } else if (typeof value === 'object' && value !== null) {\n // Prevent recursion into LocalAction definitions (which contain FunctionCalls that should NOT be evaluated yet)\n if ('functionCall' in value && isFunctionCall((value as any).functionCall)) {\n resolved[key] = value;\n continue;\n }\n\n // Recursively resolve bindings inside objects and arrays\n if (Array.isArray(value)) {\n resolved[key] = value.map(item => {\n if (typeof item === 'object' && item !== null) {\n // Check for LocalAction in array items too\n if ('functionCall' in item && isFunctionCall((item as any).functionCall)) {\n return item;\n }\n if (isFunctionCall(item)) {\n return evaluateFunction(item, dataModel, catalogId, scopeData);\n }\n if (isDataBindingObject(item)) {\n return resolveSingleBinding(item, dataModel, scopeData);\n }\n return resolveDataBindings(item as any, dataModel, catalogId, scopeData, undefined, _depth + 1);\n }\n return item;\n });\n } else {\n resolved[key] = resolveDataBindings(value as any, dataModel, catalogId, scopeData, undefined, _depth + 1);\n }\n } else {\n resolved[key] = value;\n }\n }\n\n return resolved;\n}\n\n/**\n * Helper to resolve a single binding object, following chains.\n */\nfunction resolveSingleBinding(\n binding: { path: string },\n dataModel: Record<string, unknown>,\n scopeData?: unknown\n): unknown {\n const path = binding.path;\n let resolvedValue: unknown;\n\n // \".\" or \"\" means \"the current scoped item\" — used when iterating scalar arrays\n if (path === '.' || path === '') {\n return scopeData !== undefined ? scopeData : getDataAtPath(dataModel, '/');\n }\n\n if (path.startsWith('/')) {\n resolvedValue = getDataAtPath(dataModel, path);\n } else if (scopeData !== undefined) {\n resolvedValue = getDataAtPath(scopeData as Record<string, unknown>, '/' + path);\n } else {\n resolvedValue = getDataAtPath(dataModel, '/' + path);\n }\n\n // Chained bindings (max depth 5)\n let depth = 0;\n while (isDataBindingObject(resolvedValue) && depth < 5) {\n const chainedPath = resolvedValue.path;\n resolvedValue = chainedPath.startsWith('/')\n ? getDataAtPath(dataModel, chainedPath)\n : getDataAtPath(dataModel, '/' + chainedPath);\n depth++;\n }\n\n return resolvedValue;\n}\n\nfunction isDataBindingObject(value: unknown): value is { path: string } {\n if (typeof value !== 'object' || value === null || !('path' in value)) return false;\n if (typeof (value as Record<string, unknown>)['path'] !== 'string') return false;\n if ('componentId' in value) return false; // ChildListTemplate\n if ('event' in value) return false; // ServerAction\n if ('call' in value) return false; // FunctionCall\n return true;\n}\n\n/**\n * Evaluate a function call.\n */\nfunction evaluateFunction(\n call: FunctionCall,\n dataModel: Record<string, unknown>,\n catalogId: string,\n scopeData?: unknown\n): unknown {\n const functionName = call.call;\n const funcImpl = registry.getFunction(catalogId, functionName);\n\n if (!funcImpl) {\n console.warn(`[Freesail] Function not found: ${functionName} in catalog ${catalogId}`);\n return undefined;\n }\n\n // Resolve arguments\n let rawArgs: unknown[] = [];\n if (Array.isArray(call.args)) {\n rawArgs = call.args;\n } else if (call.args && typeof call.args === 'object') {\n const entries = Object.entries(call.args);\n\n // Check if the registry declares paramNames for this function\n // and the keys are named (not numeric).\n // If so, reorder entries to match the declared parameter order.\n const paramNames = registry.getParamNames(catalogId as CatalogId, functionName);\n const hasNonNumericKeys = entries.some(([key]) => isNaN(parseInt(key.replace(/^'|'$/g, ''), 10)));\n\n if (paramNames && hasNonNumericKeys) {\n // Build a lookup from the entries\n const argMap = new Map(entries);\n // Reorder: first pull args matching declared param names in order,\n // then append any extra keys not in paramNames\n const ordered: unknown[] = [];\n const used = new Set<string>();\n for (const name of paramNames) {\n if (argMap.has(name)) {\n ordered.push(argMap.get(name));\n used.add(name);\n }\n }\n // Append remaining keys not in paramNames (preserves insertion order)\n for (const [key, value] of entries) {\n if (!used.has(key)) {\n ordered.push(value);\n }\n }\n rawArgs = ordered;\n } else {\n // Numeric keys or no paramNames — sort numerically as before\n entries.sort(([keyA], [keyB]) => {\n // Remove surrounding quotes if present to cleanly parse as number\n const numA = parseInt(keyA.replace(/^'|'$/g, ''), 10);\n const numB = parseInt(keyB.replace(/^'|'$/g, ''), 10);\n if (!isNaN(numA) && !isNaN(numB)) {\n return numA - numB;\n }\n return 0; // fallback to stable sort for non-numeric keys\n });\n rawArgs = entries.map(([, value]) => value);\n }\n\n // Robustness: agents sometimes wrap multiple positional args in a single-key\n // object as an array, e.g. { \"value\": [arg0, arg1] } instead of [arg0, arg1].\n // When there is exactly one entry and its value is an array, spread it so that\n // multi-arg functions like lte(a, b) receive two arguments, not one array.\n if (rawArgs.length === 1 && Array.isArray(rawArgs[0])) {\n rawArgs = rawArgs[0] as unknown[];\n }\n }\n\n const args = rawArgs.map(arg => {\n if (isFunctionCall(arg)) {\n return evaluateFunction(arg, dataModel, catalogId, scopeData);\n }\n if (isDataBindingObject(arg)) {\n return resolveSingleBinding(arg, dataModel, scopeData);\n }\n // Handle nested arrays/objects in args\n if (typeof arg === 'object' && arg !== null) {\n if (Array.isArray(arg)) {\n return arg.map(item => {\n if (isFunctionCall(item)) return evaluateFunction(item, dataModel, catalogId, scopeData);\n if (isDataBindingObject(item)) return resolveSingleBinding(item, dataModel, scopeData);\n return item;\n });\n }\n }\n return arg;\n });\n\n // formatString: pre-process the format string for ${...} template interpolation\n let callArgs = args;\n if (functionName === 'formatString' && callArgs.length > 0 && typeof callArgs[0] === 'string') {\n callArgs = [\n interpolateTemplate(\n callArgs[0] as string,\n dataModel,\n catalogId,\n scopeData,\n (nestedCall) => evaluateFunction(nestedCall, dataModel, catalogId, scopeData)\n ),\n ...callArgs.slice(1),\n ];\n }\n\n try {\n return funcImpl(...callArgs);\n } catch (error) {\n console.error(`[Freesail] Error evaluating function ${functionName}:`, error);\n return undefined;\n }\n}\n\n/**\n * Resolve data bindings in an action's context object.\n */\nfunction resolveActionContext(\n context: Record<string, unknown>,\n dataModel: Record<string, unknown>,\n catalogId: string,\n scopeData?: unknown\n): Record<string, unknown> {\n const resolved: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(context)) {\n if (isFunctionCall(value)) {\n resolved[key] = evaluateFunction(value, dataModel, catalogId, scopeData);\n } else if (isDataBindingObject(value)) {\n const path = value.path;\n if (path.startsWith('/')) {\n resolved[key] = getDataAtPath(dataModel, path);\n } else if (scopeData !== undefined) {\n resolved[key] = getDataAtPath(scopeData as Record<string, unknown>, '/' + path);\n } else {\n // Relative path but no scope — normalize to absolute\n resolved[key] = getDataAtPath(dataModel, '/' + path);\n }\n } else {\n resolved[key] = value;\n }\n }\n\n return resolved;\n}\n\n// =============================================================================\n// Template Interpolation (for formatString ${...} syntax)\n// =============================================================================\n\n/**\n * Finds the position of the closing brace that matches the opening brace at openPos,\n * respecting nested braces and quoted strings.\n */\nfunction findMatchingBrace(str: string, openPos: number): number {\n let depth = 0;\n let inSingleQuote = false;\n let inDoubleQuote = false;\n for (let i = openPos; i < str.length; i++) {\n const ch = str[i];\n const escaped = i > 0 && str[i - 1] === '\\\\';\n if (ch === \"'\" && !inDoubleQuote && !escaped) inSingleQuote = !inSingleQuote;\n if (ch === '\"' && !inSingleQuote && !escaped) inDoubleQuote = !inDoubleQuote;\n if (!inSingleQuote && !inDoubleQuote) {\n if (ch === '{') depth++;\n else if (ch === '}') { depth--; if (depth === 0) return i; }\n }\n }\n return -1;\n}\n\n/** Converts a value to a display string for interpolation output. */\nfunction interpolatedValueToString(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n}\n\n/**\n * Splits a comma-separated args string into individual tokens,\n * respecting nested ${...} and quoted strings.\n */\nfunction splitInterpolationArgs(argsStr: string): string[] {\n const parts: string[] = [];\n let current = '';\n let depth = 0;\n let inSingleQuote = false;\n let inDoubleQuote = false;\n for (let i = 0; i < argsStr.length; i++) {\n const ch = argsStr[i];\n const escaped = i > 0 && argsStr[i - 1] === '\\\\';\n if (ch === \"'\" && !inDoubleQuote && !escaped) inSingleQuote = !inSingleQuote;\n else if (ch === '\"' && !inSingleQuote && !escaped) inDoubleQuote = !inDoubleQuote;\n else if (!inSingleQuote && !inDoubleQuote) {\n if (ch === '{') depth++;\n else if (ch === '}') depth--;\n else if (ch === ',' && depth === 0) { parts.push(current.trim()); current = ''; continue; }\n }\n current += ch;\n }\n if (current.trim()) parts.push(current.trim());\n return parts;\n}\n\n/**\n * Parses a single argument token from an interpolation expression.\n * Supports: 'string', \"string\", number, boolean, ${nested}, bare path.\n */\nfunction parseInterpolationValue(\n token: string,\n dataModel: Record<string, unknown>,\n catalogId: string,\n scopeData: unknown,\n evalFn: (call: FunctionCall) => unknown\n): unknown {\n token = token.trim();\n if ((token.startsWith(\"'\") && token.endsWith(\"'\")) || (token.startsWith('\"') && token.endsWith('\"')))\n return token.slice(1, -1);\n if (token.startsWith('${') && token.endsWith('}'))\n return evaluateInterpolationExpr(token.slice(2, -1), dataModel, catalogId, scopeData, evalFn);\n if (token === 'true') return true;\n if (token === 'false') return false;\n const num = Number(token);\n if (!isNaN(num) && token !== '') return num;\n if (token.startsWith('/')) return getDataAtPath(dataModel, token);\n if (scopeData !== undefined) return getDataAtPath(scopeData as Record<string, unknown>, '/' + token);\n return getDataAtPath(dataModel, '/' + token);\n}\n\n/**\n * Evaluates the expression inside ${...}: either a data path or a function call.\n */\nfunction evaluateInterpolationExpr(\n expr: string,\n dataModel: Record<string, unknown>,\n catalogId: string,\n scopeData: unknown,\n evalFn: (call: FunctionCall) => unknown\n): unknown {\n expr = expr.trim();\n // Function call: word(...)\n if (/^\\w[\\w.]*\\(.*\\)$/s.test(expr)) {\n const parenOpen = expr.indexOf('(');\n const funcName = expr.slice(0, parenOpen).trim();\n const argsStr = expr.slice(parenOpen + 1, -1).trim();\n const args: Record<string, unknown> = {};\n if (argsStr) {\n splitInterpolationArgs(argsStr).forEach((part, index) => {\n const colonIdx = part.indexOf(':');\n if (colonIdx > 0) {\n const potentialKey = part.slice(0, colonIdx).trim();\n if (/^[a-zA-Z_]\\w*$/.test(potentialKey)) {\n args[potentialKey] = parseInterpolationValue(\n part.slice(colonIdx + 1).trim(), dataModel, catalogId, scopeData, evalFn\n );\n return;\n }\n }\n args[String(index)] = parseInterpolationValue(part, dataModel, catalogId, scopeData, evalFn);\n });\n }\n return evalFn({ call: funcName, args } as unknown as FunctionCall);\n }\n // Data path\n if (expr.startsWith('/')) return getDataAtPath(dataModel, expr);\n if (scopeData !== undefined) return getDataAtPath(scopeData as Record<string, unknown>, '/' + expr);\n return getDataAtPath(dataModel, '/' + expr);\n}\n\n/**\n * Processes ${...} template expressions in a formatString format string.\n * Supports: ${/absolute/path}, ${relative/field}, ${funcName(args)},\n * nested expressions (${upper(${/name})}), and escaped literals (\\${).\n */\nfunction interpolateTemplate(\n template: string,\n dataModel: Record<string, unknown>,\n catalogId: string,\n scopeData: unknown,\n evalFn: (call: FunctionCall) => unknown\n): string {\n let result = '';\n let i = 0;\n while (i < template.length) {\n // Escaped: \\${ → literal ${\n if (template[i] === '\\\\' && template[i + 1] === '$' && template[i + 2] === '{') {\n result += '${';\n i += 3;\n continue;\n }\n // Expression: ${...}\n if (template[i] === '$' && template[i + 1] === '{') {\n const closeBrace = findMatchingBrace(template, i + 1);\n if (closeBrace === -1) { result += template[i++]; continue; }\n const expr = template.slice(i + 2, closeBrace);\n result += interpolatedValueToString(\n evaluateInterpolationExpr(expr, dataModel, catalogId, scopeData, evalFn)\n );\n i = closeBrace + 1;\n continue;\n }\n result += template[i++];\n }\n return result;\n}\n\n// =============================================================================\n// Default UI States\n// =============================================================================\n\nfunction DefaultLoading() {\n return (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '40px 16px',\n gap: '16px',\n }}>\n <style>{`\n @keyframes freesail-pulse {\n 0%, 100% { opacity: 0.4; transform: scale(0.95); }\n 50% { opacity: 1; transform: scale(1); }\n }\n @keyframes freesail-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n `}</style>\n {FREESAIL_LOGO_DATA_URI ? (\n <img\n src={FREESAIL_LOGO_DATA_URI}\n alt=\"Loading\"\n style={{\n width: '48px',\n height: '48px',\n animation: 'freesail-pulse 1.5s ease-in-out infinite',\n }}\n />\n ) : (\n <div style={{\n width: '32px',\n height: '32px',\n border: '3px solid var(--freesail-border, #e2e8f0)',\n borderTopColor: 'var(--freesail-primary, #2563eb)',\n borderRadius: '50%',\n animation: 'freesail-spin 0.8s linear infinite',\n }} />\n )}\n <span style={{\n fontSize: '13px',\n color: 'var(--freesail-text-muted, #64748b)',\n letterSpacing: '0.05em',\n }}>Preparing…</span>\n </div>\n );\n}\n\nfunction DefaultError() {\n return (\n <div style={{ padding: '16px', color: '#c00' }}>\n Error: Unable to render surface\n </div>\n );\n}\n\nfunction UnknownComponent({ component }: { component: A2UIComponent }) {\n return (\n <div\n style={{\n padding: '8px',\n border: '1px dashed #f00',\n background: '#fee',\n margin: '4px',\n }}\n >\n <strong>Unknown Component:</strong> {component.component}\n <pre style={{ fontSize: '10px' }}>\n {JSON.stringify(component, null, 2)}\n </pre>\n </div>\n );\n}\n"]} |
| /** | ||
| * @fileoverview Freesail React Hooks | ||
| * | ||
| * Custom hooks for interacting with Freesail surfaces and data. | ||
| */ | ||
| import type { SurfaceId, Surface, JsonPointer, ComponentId } from '@freesail/core'; | ||
| /** | ||
| * Hook to access and subscribe to a specific surface. | ||
| */ | ||
| export declare function useSurface(surfaceId: SurfaceId): Surface | undefined; | ||
| /** | ||
| * Hook to access data from a surface's data model. | ||
| */ | ||
| export declare function useSurfaceData<T = unknown>(surfaceId: SurfaceId, path?: JsonPointer): T | undefined; | ||
| /** | ||
| * Hook to send user actions (v0.9 format). | ||
| */ | ||
| export declare function useAction(surfaceId: SurfaceId): (name: string, sourceComponentId: ComponentId, context?: Record<string, unknown>) => Promise<void>; | ||
| /** | ||
| * Hook to get connection status. | ||
| */ | ||
| export declare function useConnectionStatus(): { | ||
| isConnected: boolean; | ||
| }; | ||
| /** | ||
| * Hook to get all surfaces. | ||
| */ | ||
| export declare function useSurfaces(): Surface[]; | ||
| /** | ||
| * Hook to access the current session ID assigned by the Gateway. | ||
| * This ID is available after the transport successfully connects. | ||
| */ | ||
| export declare function useSessionId(): string | null; | ||
| //# sourceMappingURL=hooks.d.ts.map |
| {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAInF;;GAEG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CA8CpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,GAAG,OAAO,EACxC,SAAS,EAAE,SAAS,EACpB,IAAI,CAAC,EAAE,WAAW,GACjB,CAAC,GAAG,SAAS,CA8Bf;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,UAKlC,MAAM,qBACO,WAAW,YACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mBAQrC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI;IACrC,WAAW,EAAE,OAAO,CAAC;CACtB,CAGA;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,OAAO,EAAE,CAwBvC;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAiB5C"} |
+137
| /** | ||
| * @fileoverview Freesail React Hooks | ||
| * | ||
| * Custom hooks for interacting with Freesail surfaces and data. | ||
| */ | ||
| import { useState, useEffect, useCallback, useMemo } from 'react'; | ||
| import { useFreesailContext } from './context.js'; | ||
| import { getDataAtPath } from './utils.js'; | ||
| /** | ||
| * Hook to access and subscribe to a specific surface. | ||
| */ | ||
| export function useSurface(surfaceId) { | ||
| const { surfaceManager, getSurface } = useFreesailContext(); | ||
| const [surface, setSurface] = useState(() => getSurface(surfaceId)); | ||
| useEffect(() => { | ||
| // Initial state | ||
| setSurface(getSurface(surfaceId)); | ||
| // Subscribe to surface changes | ||
| const unsubCreate = surfaceManager.on('surfaceCreated', (created) => { | ||
| if (created.id === surfaceId) { | ||
| setSurface(created); | ||
| } | ||
| }); | ||
| const unsubDelete = surfaceManager.on('surfaceDeleted', (deletedId) => { | ||
| if (deletedId === surfaceId) { | ||
| setSurface(undefined); | ||
| } | ||
| }); | ||
| const unsubComponents = surfaceManager.on('componentsUpdated', (updatedId) => { | ||
| if (updatedId === surfaceId) { | ||
| const current = getSurface(surfaceId); | ||
| setSurface(current ? { ...current } : undefined); | ||
| } | ||
| }); | ||
| const unsubData = surfaceManager.on('dataModelUpdated', (updatedId) => { | ||
| if (updatedId === surfaceId) { | ||
| const current = getSurface(surfaceId); | ||
| setSurface(current ? { ...current } : undefined); | ||
| } | ||
| }); | ||
| return () => { | ||
| unsubCreate(); | ||
| unsubDelete(); | ||
| unsubComponents(); | ||
| unsubData(); | ||
| }; | ||
| }, [surfaceId, surfaceManager, getSurface]); | ||
| return surface; | ||
| } | ||
| /** | ||
| * Hook to access data from a surface's data model. | ||
| */ | ||
| export function useSurfaceData(surfaceId, path) { | ||
| const { surfaceManager, getSurface } = useFreesailContext(); | ||
| const [data, setData] = useState(() => { | ||
| const surface = getSurface(surfaceId); | ||
| if (!surface) | ||
| return undefined; | ||
| return getDataAtPath(surface.dataModel, path); | ||
| }); | ||
| useEffect(() => { | ||
| const surface = getSurface(surfaceId); | ||
| if (surface) { | ||
| setData(getDataAtPath(surface.dataModel, path)); | ||
| } | ||
| const unsub = surfaceManager.on('dataModelUpdated', (updatedId, updatedPath) => { | ||
| if (updatedId === surfaceId) { | ||
| // Check if the update affects our path | ||
| if (!path || updatedPath.startsWith(path) || path.startsWith(updatedPath)) { | ||
| const currentSurface = getSurface(surfaceId); | ||
| if (currentSurface) { | ||
| setData(getDataAtPath(currentSurface.dataModel, path)); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| return unsub; | ||
| }, [surfaceId, path, surfaceManager, getSurface]); | ||
| return data; | ||
| } | ||
| /** | ||
| * Hook to send user actions (v0.9 format). | ||
| */ | ||
| export function useAction(surfaceId) { | ||
| const { sendAction } = useFreesailContext(); | ||
| const dispatch = useCallback(async (name, sourceComponentId, context = {}) => { | ||
| await sendAction(surfaceId, name, sourceComponentId, context); | ||
| }, [surfaceId, sendAction]); | ||
| return dispatch; | ||
| } | ||
| /** | ||
| * Hook to get connection status. | ||
| */ | ||
| export function useConnectionStatus() { | ||
| const { isConnected } = useFreesailContext(); | ||
| return useMemo(() => ({ isConnected }), [isConnected]); | ||
| } | ||
| /** | ||
| * Hook to get all surfaces. | ||
| */ | ||
| export function useSurfaces() { | ||
| const { surfaceManager } = useFreesailContext(); | ||
| const [surfaces, setSurfaces] = useState(() => surfaceManager.getAllSurfaces()); | ||
| useEffect(() => { | ||
| setSurfaces(surfaceManager.getAllSurfaces()); | ||
| const unsubCreate = surfaceManager.on('surfaceCreated', () => { | ||
| setSurfaces(surfaceManager.getAllSurfaces()); | ||
| }); | ||
| const unsubDelete = surfaceManager.on('surfaceDeleted', () => { | ||
| setSurfaces(surfaceManager.getAllSurfaces()); | ||
| }); | ||
| return () => { | ||
| unsubCreate(); | ||
| unsubDelete(); | ||
| }; | ||
| }, [surfaceManager]); | ||
| return surfaces; | ||
| } | ||
| /** | ||
| * Hook to access the current session ID assigned by the Gateway. | ||
| * This ID is available after the transport successfully connects. | ||
| */ | ||
| export function useSessionId() { | ||
| const { transport } = useFreesailContext(); | ||
| const [sessionId, setSessionId] = useState(() => transport?.sessionId ?? null); | ||
| useEffect(() => { | ||
| if (!transport) | ||
| return; | ||
| setSessionId(transport.sessionId); | ||
| const unsub = transport.on('sessionStart', (sid) => { | ||
| setSessionId(sid); | ||
| }); | ||
| return unsub; | ||
| }, [transport]); | ||
| return sessionId; | ||
| } | ||
| //# sourceMappingURL=hooks.js.map |
| {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Freesail React Hooks\n *\n * Custom hooks for interacting with Freesail surfaces and data.\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport type { SurfaceId, Surface, JsonPointer, ComponentId } from '@freesail/core';\nimport { useFreesailContext } from './context.js';\nimport { getDataAtPath } from './utils.js';\n\n/**\n * Hook to access and subscribe to a specific surface.\n */\nexport function useSurface(surfaceId: SurfaceId): Surface | undefined {\n const { surfaceManager, getSurface } = useFreesailContext();\n const [surface, setSurface] = useState<Surface | undefined>(() =>\n getSurface(surfaceId)\n );\n\n useEffect(() => {\n // Initial state\n setSurface(getSurface(surfaceId));\n\n // Subscribe to surface changes\n const unsubCreate = surfaceManager.on('surfaceCreated', (created: Surface) => {\n if (created.id === surfaceId) {\n setSurface(created);\n }\n });\n\n const unsubDelete = surfaceManager.on('surfaceDeleted', (deletedId: SurfaceId) => {\n if (deletedId === surfaceId) {\n setSurface(undefined);\n }\n });\n\n const unsubComponents = surfaceManager.on('componentsUpdated', (updatedId: SurfaceId) => {\n if (updatedId === surfaceId) {\n const current = getSurface(surfaceId);\n setSurface(current ? { ...current } : undefined);\n }\n });\n\n const unsubData = surfaceManager.on('dataModelUpdated', (updatedId: SurfaceId) => {\n if (updatedId === surfaceId) {\n const current = getSurface(surfaceId);\n setSurface(current ? { ...current } : undefined);\n }\n });\n\n return () => {\n unsubCreate();\n unsubDelete();\n unsubComponents();\n unsubData();\n };\n }, [surfaceId, surfaceManager, getSurface]);\n\n return surface;\n}\n\n/**\n * Hook to access data from a surface's data model.\n */\nexport function useSurfaceData<T = unknown>(\n surfaceId: SurfaceId,\n path?: JsonPointer\n): T | undefined {\n const { surfaceManager, getSurface } = useFreesailContext();\n const [data, setData] = useState<T | undefined>(() => {\n const surface = getSurface(surfaceId);\n if (!surface) return undefined;\n return getDataAtPath(surface.dataModel, path) as T;\n });\n\n useEffect(() => {\n const surface = getSurface(surfaceId);\n if (surface) {\n setData(getDataAtPath(surface.dataModel, path) as T);\n }\n\n const unsub = surfaceManager.on('dataModelUpdated', (updatedId: SurfaceId, updatedPath: JsonPointer) => {\n if (updatedId === surfaceId) {\n // Check if the update affects our path\n if (!path || updatedPath.startsWith(path) || path.startsWith(updatedPath)) {\n const currentSurface = getSurface(surfaceId);\n if (currentSurface) {\n setData(getDataAtPath(currentSurface.dataModel, path) as T);\n }\n }\n }\n });\n\n return unsub;\n }, [surfaceId, path, surfaceManager, getSurface]);\n\n return data;\n}\n\n/**\n * Hook to send user actions (v0.9 format).\n */\nexport function useAction(surfaceId: SurfaceId) {\n const { sendAction } = useFreesailContext();\n\n const dispatch = useCallback(\n async (\n name: string,\n sourceComponentId: ComponentId,\n context: Record<string, unknown> = {}\n ) => {\n await sendAction(surfaceId, name, sourceComponentId, context);\n },\n [surfaceId, sendAction]\n );\n\n return dispatch;\n}\n\n/**\n * Hook to get connection status.\n */\nexport function useConnectionStatus(): {\n isConnected: boolean;\n} {\n const { isConnected } = useFreesailContext();\n return useMemo(() => ({ isConnected }), [isConnected]);\n}\n\n/**\n * Hook to get all surfaces.\n */\nexport function useSurfaces(): Surface[] {\n const { surfaceManager } = useFreesailContext();\n const [surfaces, setSurfaces] = useState<Surface[]>(() =>\n surfaceManager.getAllSurfaces()\n );\n\n useEffect(() => {\n setSurfaces(surfaceManager.getAllSurfaces());\n\n const unsubCreate = surfaceManager.on('surfaceCreated', () => {\n setSurfaces(surfaceManager.getAllSurfaces());\n });\n\n const unsubDelete = surfaceManager.on('surfaceDeleted', () => {\n setSurfaces(surfaceManager.getAllSurfaces());\n });\n\n return () => {\n unsubCreate();\n unsubDelete();\n };\n }, [surfaceManager]);\n\n return surfaces;\n}\n\n/**\n * Hook to access the current session ID assigned by the Gateway.\n * This ID is available after the transport successfully connects.\n */\nexport function useSessionId(): string | null {\n const { transport } = useFreesailContext();\n const [sessionId, setSessionId] = useState<string | null>(() => transport?.sessionId ?? null);\n\n useEffect(() => {\n if (!transport) return;\n \n setSessionId(transport.sessionId);\n \n const unsub = transport.on('sessionStart', (sid: string) => {\n setSessionId(sid);\n });\n \n return unsub;\n }, [transport]);\n\n return sessionId;\n}\n"]} |
| /** | ||
| * @fileoverview Freesail React - Public API | ||
| */ | ||
| export { FreesailProvider, type FreesailProviderProps } from './FreesailProvider.js'; | ||
| export { FreesailSurface, type FreesailSurfaceProps } from './FreesailSurface.js'; | ||
| export { FreesailContext, useFreesailContext, type FreesailContextValue } from './context.js'; | ||
| export { useSurface, useSurfaceData, useAction, useConnectionStatus, useSurfaces, useSessionId, } from './hooks.js'; | ||
| export { registry, withCatalog, registerCatalog, type FreesailComponent, type FreesailComponentProps, } from './registry.js'; | ||
| export { type CatalogDefinition, type FunctionImplementation } from './types.js'; | ||
| export type { SurfaceId, ComponentId, CatalogId, A2UIComponent, Surface, } from '@freesail/core'; | ||
| export * from './theme.js'; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAGrF,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGlF,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAG9F,OAAO,EACL,UAAU,EACV,cAAc,EACd,SAAS,EACT,mBAAmB,EACnB,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,GAC5B,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGjF,YAAY,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,aAAa,EACb,OAAO,GACR,MAAM,gBAAgB,CAAC;AAGxB,cAAc,YAAY,CAAC"} |
| /** | ||
| * @fileoverview Freesail React - Public API | ||
| */ | ||
| // Provider | ||
| export { FreesailProvider } from './FreesailProvider.js'; | ||
| // Surface Component | ||
| export { FreesailSurface } from './FreesailSurface.js'; | ||
| // Context | ||
| export { FreesailContext, useFreesailContext } from './context.js'; | ||
| // Hooks | ||
| export { useSurface, useSurfaceData, useAction, useConnectionStatus, useSurfaces, useSessionId, } from './hooks.js'; | ||
| // Registry | ||
| export { registry, withCatalog, registerCatalog, } from './registry.js'; | ||
| // Theme | ||
| export * from './theme.js'; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,WAAW;AACX,OAAO,EAAE,gBAAgB,EAA8B,MAAM,uBAAuB,CAAC;AAErF,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAA6B,MAAM,sBAAsB,CAAC;AAElF,UAAU;AACV,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAA6B,MAAM,cAAc,CAAC;AAE9F,QAAQ;AACR,OAAO,EACL,UAAU,EACV,cAAc,EACd,SAAS,EACT,mBAAmB,EACnB,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,WAAW;AACX,OAAO,EACL,QAAQ,EACR,WAAW,EACX,eAAe,GAGhB,MAAM,eAAe,CAAC;AAcvB,QAAQ;AACR,cAAc,YAAY,CAAC","sourcesContent":["/**\n * @fileoverview Freesail React - Public API\n */\n\n// Provider\nexport { FreesailProvider, type FreesailProviderProps } from './FreesailProvider.js';\n\n// Surface Component\nexport { FreesailSurface, type FreesailSurfaceProps } from './FreesailSurface.js';\n\n// Context\nexport { FreesailContext, useFreesailContext, type FreesailContextValue } from './context.js';\n\n// Hooks\nexport {\n useSurface,\n useSurfaceData,\n useAction,\n useConnectionStatus,\n useSurfaces,\n useSessionId,\n} from './hooks.js';\n\n// Registry\nexport {\n registry,\n withCatalog,\n registerCatalog,\n type FreesailComponent,\n type FreesailComponentProps,\n} from './registry.js';\n\n// Types\nexport { type CatalogDefinition, type FunctionImplementation } from './types.js';\n\n// Re-export core types for convenience\nexport type {\n SurfaceId,\n ComponentId,\n CatalogId,\n A2UIComponent,\n Surface,\n} from '@freesail/core';\n\n// Theme\nexport * from './theme.js';\n"]} |
| export declare const FREESAIL_LOGO_DATA_URI = "data:image/png;base64,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"; | ||
| //# sourceMappingURL=logo.d.ts.map |
| {"version":3,"file":"logo.d.ts","sourceRoot":"","sources":["../src/logo.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,sBAAsB,uy7DAAuy7D,CAAC"} |
| // Auto-generated by scripts/generate-logo-base64.ts — do not edit manually | ||
| export const FREESAIL_LOGO_DATA_URI = 'data:image/png;base64,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'; | ||
| //# sourceMappingURL=logo.js.map |
| {"version":3,"file":"logo.js","sourceRoot":"","sources":["../src/logo.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,MAAM,CAAC,MAAM,sBAAsB,GAAG,oy7DAAoy7D,CAAC","sourcesContent":["// Auto-generated by scripts/generate-logo-base64.ts — do not edit manually\nexport const FREESAIL_LOGO_DATA_URI = 'data:image/png;base64,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';\n"]} |
| /** | ||
| * @fileoverview Component Registry | ||
| * | ||
| * Maps component names from the catalog to React components. | ||
| * This enables the renderer to dynamically instantiate components | ||
| * based on A2UI messages. | ||
| */ | ||
| import type { ComponentType, ReactNode } from 'react'; | ||
| import type { A2UIComponent, CatalogId, FunctionCall } from '@freesail/core'; | ||
| import type { FunctionImplementation } from './types.js'; | ||
| /** | ||
| * Props passed to all Freesail components. | ||
| */ | ||
| export interface FreesailComponentProps { | ||
| /** The component definition from the A2UI message (with resolved data bindings) */ | ||
| component: A2UIComponent; | ||
| /** Rendered children (for container components) */ | ||
| children?: ReactNode; | ||
| /** Full data model for the surface (server → client, kept in sync by two-way binding) */ | ||
| dataModel?: Record<string, unknown>; | ||
| /** Scope data when inside a template iteration */ | ||
| scopeData?: unknown; | ||
| /** Callback to dispatch user actions (client → server) */ | ||
| onAction?: (name: string, context: Record<string, unknown>) => void; | ||
| /** | ||
| * Write a value to the local data model at the given JSON Pointer path. | ||
| * This is the "Write" half of A2UI two-way binding — input components | ||
| * call this on every user interaction (keystroke, toggle, etc.). | ||
| * The update is LOCAL only; it does NOT send a message to the server. | ||
| * The updated data model reaches the server when an action is dispatched | ||
| * (either via resolved data bindings in the action context, or via | ||
| * the sendDataModel metadata mechanism). | ||
| */ | ||
| onDataChange?: (path: string, value: unknown) => void; | ||
| /** | ||
| * Execute a function call definition. | ||
| * This is for LocalAction handling (client-side logic). | ||
| */ | ||
| onFunctionCall?: (call: FunctionCall) => void; | ||
| } | ||
| /** | ||
| * A React component that can render an A2UX component. | ||
| */ | ||
| export type FreesailComponent = ComponentType<FreesailComponentProps>; | ||
| /** | ||
| * Component map within a catalog. | ||
| */ | ||
| export type ComponentMap = Map<string, FreesailComponent>; | ||
| /** | ||
| * Registry of all catalogs and their components. | ||
| */ | ||
| declare class ComponentRegistry { | ||
| private catalogs; | ||
| private functions; | ||
| /** Positional parameter names per function, extracted from the catalog schema. */ | ||
| private paramNames; | ||
| private fallbackComponent; | ||
| /** | ||
| * Register a catalog with its components, functions, and optional schema. | ||
| * When a schema is provided, parameter names are extracted from | ||
| * `functions.*.args.properties` keys so `evaluateFunction` can | ||
| * reorder named-key argument objects from the LLM. | ||
| */ | ||
| registerCatalog(catalogId: CatalogId, components: Record<string, FreesailComponent>, functions?: Record<string, FunctionImplementation>, schema?: Record<string, unknown>): void; | ||
| /** | ||
| * Extract positional parameter names from a catalog schema's function definitions. | ||
| */ | ||
| private extractParamNames; | ||
| /** | ||
| * Register a single component in a catalog. | ||
| */ | ||
| registerComponent(catalogId: CatalogId, componentName: string, component: FreesailComponent): void; | ||
| /** | ||
| * Get a component from a catalog. | ||
| */ | ||
| getComponent(catalogId: CatalogId, componentName: string): FreesailComponent | null; | ||
| /** | ||
| * Get a function from a catalog. | ||
| */ | ||
| getFunction(catalogId: CatalogId, functionName: string): FunctionImplementation | null; | ||
| /** | ||
| * Get the declared positional parameter names for a function. | ||
| * Returns undefined if no schema was registered or the function has no named params. | ||
| */ | ||
| getParamNames(catalogId: CatalogId, functionName: string): string[] | undefined; | ||
| /** | ||
| * Check if a catalog is registered. | ||
| */ | ||
| hasCatalog(catalogId: CatalogId): boolean; | ||
| /** | ||
| * Get all registered catalog IDs. | ||
| */ | ||
| getCatalogIds(): CatalogId[]; | ||
| /** | ||
| * Set a fallback component for unknown components. | ||
| */ | ||
| setFallbackComponent(component: FreesailComponent): void; | ||
| /** | ||
| * Clear all registrations. | ||
| */ | ||
| clear(): void; | ||
| } | ||
| /** | ||
| * Global component registry instance. | ||
| */ | ||
| export declare const registry: ComponentRegistry; | ||
| /** | ||
| * Higher-order function to create a component with catalog binding. | ||
| * This ensures the component is registered when imported. | ||
| */ | ||
| export declare function withCatalog<P extends FreesailComponentProps>(catalogId: CatalogId, componentName: string, Component: ComponentType<P>): ComponentType<P>; | ||
| /** | ||
| * Register multiple components for a catalog at once. | ||
| */ | ||
| export declare function registerCatalog(catalogId: CatalogId, components: Record<string, FreesailComponent>, functions?: Record<string, FunctionImplementation>, schema?: Record<string, unknown>): void; | ||
| export {}; | ||
| //# sourceMappingURL=registry.d.ts.map |
| {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"} |
+152
| /** | ||
| * @fileoverview Component Registry | ||
| * | ||
| * Maps component names from the catalog to React components. | ||
| * This enables the renderer to dynamically instantiate components | ||
| * based on A2UI messages. | ||
| */ | ||
| /** | ||
| * Registry of all catalogs and their components. | ||
| */ | ||
| class ComponentRegistry { | ||
| catalogs = new Map(); | ||
| functions = new Map(); | ||
| /** Positional parameter names per function, extracted from the catalog schema. */ | ||
| paramNames = new Map(); | ||
| fallbackComponent = null; | ||
| /** | ||
| * Register a catalog with its components, functions, and optional schema. | ||
| * When a schema is provided, parameter names are extracted from | ||
| * `functions.*.args.properties` keys so `evaluateFunction` can | ||
| * reorder named-key argument objects from the LLM. | ||
| */ | ||
| registerCatalog(catalogId, components, functions, schema) { | ||
| const map = new Map(Object.entries(components)); | ||
| this.catalogs.set(catalogId, map); | ||
| if (functions) { | ||
| this.functions.set(catalogId, functions); | ||
| } | ||
| if (schema) { | ||
| this.extractParamNames(catalogId, schema); | ||
| } | ||
| } | ||
| /** | ||
| * Extract positional parameter names from a catalog schema's function definitions. | ||
| */ | ||
| extractParamNames(catalogId, schema) { | ||
| const funcs = schema['functions']; | ||
| if (!funcs) | ||
| return; | ||
| const names = {}; | ||
| for (const [funcName, funcDef] of Object.entries(funcs)) { | ||
| const propsField = funcDef['properties']; | ||
| const argsDef = propsField?.['args']; | ||
| if (argsDef) { | ||
| const props = argsDef['properties']; | ||
| if (props && Object.keys(props).length > 0) { | ||
| names[funcName] = Object.keys(props); | ||
| } | ||
| } | ||
| } | ||
| if (Object.keys(names).length > 0) { | ||
| this.paramNames.set(catalogId, names); | ||
| } | ||
| } | ||
| /** | ||
| * Register a single component in a catalog. | ||
| */ | ||
| registerComponent(catalogId, componentName, component) { | ||
| if (!this.catalogs.has(catalogId)) { | ||
| this.catalogs.set(catalogId, new Map()); | ||
| } | ||
| this.catalogs.get(catalogId).set(componentName, component); | ||
| } | ||
| /** | ||
| * Get a component from a catalog. | ||
| */ | ||
| getComponent(catalogId, componentName) { | ||
| const catalog = this.catalogs.get(catalogId); | ||
| if (!catalog) { | ||
| console.warn(`Catalog not found: ${catalogId}`); | ||
| return this.fallbackComponent; | ||
| } | ||
| const component = catalog.get(componentName); | ||
| if (!component) { | ||
| console.warn(`Component not found: ${componentName} in catalog ${catalogId}`); | ||
| return this.fallbackComponent; | ||
| } | ||
| return component; | ||
| } | ||
| /** | ||
| * Get a function from a catalog. | ||
| */ | ||
| getFunction(catalogId, functionName) { | ||
| const catalogFunctions = this.functions.get(catalogId); | ||
| if (!catalogFunctions) { | ||
| return null; | ||
| } | ||
| // Direct lookup first | ||
| if (catalogFunctions[functionName] != null) { | ||
| return catalogFunctions[functionName]; | ||
| } | ||
| // Fallback: try snake_case -> camelCase conversion (e.g. open_url -> openUrl) | ||
| if (functionName.includes('_')) { | ||
| const camelName = functionName.replace(/_([a-z])/g, (_match, p1) => p1.toUpperCase()); | ||
| return catalogFunctions[camelName] ?? null; | ||
| } | ||
| return null; | ||
| } | ||
| /** | ||
| * Get the declared positional parameter names for a function. | ||
| * Returns undefined if no schema was registered or the function has no named params. | ||
| */ | ||
| getParamNames(catalogId, functionName) { | ||
| return this.paramNames.get(catalogId)?.[functionName]; | ||
| } | ||
| /** | ||
| * Check if a catalog is registered. | ||
| */ | ||
| hasCatalog(catalogId) { | ||
| return this.catalogs.has(catalogId); | ||
| } | ||
| /** | ||
| * Get all registered catalog IDs. | ||
| */ | ||
| getCatalogIds() { | ||
| return Array.from(this.catalogs.keys()); | ||
| } | ||
| /** | ||
| * Set a fallback component for unknown components. | ||
| */ | ||
| setFallbackComponent(component) { | ||
| this.fallbackComponent = component; | ||
| } | ||
| /** | ||
| * Clear all registrations. | ||
| */ | ||
| clear() { | ||
| this.catalogs.clear(); | ||
| this.functions.clear(); | ||
| this.paramNames.clear(); | ||
| this.fallbackComponent = null; | ||
| } | ||
| } | ||
| /** | ||
| * Global component registry instance. | ||
| */ | ||
| export const registry = new ComponentRegistry(); | ||
| /** | ||
| * Higher-order function to create a component with catalog binding. | ||
| * This ensures the component is registered when imported. | ||
| */ | ||
| export function withCatalog(catalogId, componentName, Component) { | ||
| registry.registerComponent(catalogId, componentName, Component); | ||
| return Component; | ||
| } | ||
| /** | ||
| * Register multiple components for a catalog at once. | ||
| */ | ||
| export function registerCatalog(catalogId, components, functions, schema) { | ||
| registry.registerCatalog(catalogId, components, functions, schema); | ||
| } | ||
| //# sourceMappingURL=registry.js.map |
| {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Component Registry\n *\n * Maps component names from the catalog to React components.\n * This enables the renderer to dynamically instantiate components\n * based on A2UI messages.\n */\n\nimport type { ComponentType, ReactNode } from 'react';\nimport type { A2UIComponent, CatalogId, FunctionCall } from '@freesail/core';\nimport type { FunctionImplementation } from './types.js';\n\n/**\n * Props passed to all Freesail components.\n */\nexport interface FreesailComponentProps {\n /** The component definition from the A2UI message (with resolved data bindings) */\n component: A2UIComponent;\n /** Rendered children (for container components) */\n children?: ReactNode;\n /** Full data model for the surface (server → client, kept in sync by two-way binding) */\n dataModel?: Record<string, unknown>;\n /** Scope data when inside a template iteration */\n scopeData?: unknown;\n /** Callback to dispatch user actions (client → server) */\n onAction?: (name: string, context: Record<string, unknown>) => void;\n /**\n * Write a value to the local data model at the given JSON Pointer path.\n * This is the \"Write\" half of A2UI two-way binding — input components\n * call this on every user interaction (keystroke, toggle, etc.).\n * The update is LOCAL only; it does NOT send a message to the server.\n * The updated data model reaches the server when an action is dispatched\n * (either via resolved data bindings in the action context, or via\n * the sendDataModel metadata mechanism).\n */\n onDataChange?: (path: string, value: unknown) => void;\n /**\n * Execute a function call definition.\n * This is for LocalAction handling (client-side logic).\n */\n onFunctionCall?: (call: FunctionCall) => void;\n}\n\n/**\n * A React component that can render an A2UX component.\n */\nexport type FreesailComponent = ComponentType<FreesailComponentProps>;\n\n/**\n * Component map within a catalog.\n */\nexport type ComponentMap = Map<string, FreesailComponent>;\n\n/**\n * Registry of all catalogs and their components.\n */\nclass ComponentRegistry {\n private catalogs: Map<CatalogId, ComponentMap> = new Map();\n private functions: Map<CatalogId, Record<string, FunctionImplementation>> = new Map();\n /** Positional parameter names per function, extracted from the catalog schema. */\n private paramNames: Map<CatalogId, Record<string, string[]>> = new Map();\n private fallbackComponent: FreesailComponent | null = null;\n\n /**\n * Register a catalog with its components, functions, and optional schema.\n * When a schema is provided, parameter names are extracted from\n * `functions.*.args.properties` keys so `evaluateFunction` can\n * reorder named-key argument objects from the LLM.\n */\n registerCatalog(\n catalogId: CatalogId,\n components: Record<string, FreesailComponent>,\n functions?: Record<string, FunctionImplementation>,\n schema?: Record<string, unknown>\n ): void {\n const map: ComponentMap = new Map(Object.entries(components));\n this.catalogs.set(catalogId, map);\n if (functions) {\n this.functions.set(catalogId, functions);\n }\n if (schema) {\n this.extractParamNames(catalogId, schema);\n }\n }\n\n /**\n * Extract positional parameter names from a catalog schema's function definitions.\n */\n private extractParamNames(catalogId: CatalogId, schema: Record<string, unknown>): void {\n const funcs = schema['functions'] as Record<string, Record<string, unknown>> | undefined;\n if (!funcs) return;\n const names: Record<string, string[]> = {};\n for (const [funcName, funcDef] of Object.entries(funcs)) {\n const propsField = funcDef['properties'] as Record<string, unknown> | undefined;\n const argsDef = propsField?.['args'] as Record<string, unknown> | undefined;\n if (argsDef) {\n const props = argsDef['properties'] as Record<string, unknown> | undefined;\n if (props && Object.keys(props).length > 0) {\n names[funcName] = Object.keys(props);\n }\n }\n }\n if (Object.keys(names).length > 0) {\n this.paramNames.set(catalogId, names);\n }\n }\n\n /**\n * Register a single component in a catalog.\n */\n registerComponent(\n catalogId: CatalogId,\n componentName: string,\n component: FreesailComponent\n ): void {\n if (!this.catalogs.has(catalogId)) {\n this.catalogs.set(catalogId, new Map());\n }\n this.catalogs.get(catalogId)!.set(componentName, component);\n }\n\n /**\n * Get a component from a catalog.\n */\n getComponent(catalogId: CatalogId, componentName: string): FreesailComponent | null {\n const catalog = this.catalogs.get(catalogId);\n if (!catalog) {\n console.warn(`Catalog not found: ${catalogId}`);\n return this.fallbackComponent;\n }\n\n const component = catalog.get(componentName);\n if (!component) {\n console.warn(`Component not found: ${componentName} in catalog ${catalogId}`);\n return this.fallbackComponent;\n }\n\n return component;\n }\n\n /**\n * Get a function from a catalog.\n */\n getFunction(catalogId: CatalogId, functionName: string): FunctionImplementation | null {\n const catalogFunctions = this.functions.get(catalogId);\n if (!catalogFunctions) {\n return null;\n }\n // Direct lookup first\n if (catalogFunctions[functionName] != null) {\n return catalogFunctions[functionName];\n }\n // Fallback: try snake_case -> camelCase conversion (e.g. open_url -> openUrl)\n if (functionName.includes('_')) {\n const camelName = functionName.replace(/_([a-z])/g, (_match, p1) => p1.toUpperCase());\n return catalogFunctions[camelName] ?? null;\n }\n return null;\n }\n\n /**\n * Get the declared positional parameter names for a function.\n * Returns undefined if no schema was registered or the function has no named params.\n */\n getParamNames(catalogId: CatalogId, functionName: string): string[] | undefined {\n return this.paramNames.get(catalogId)?.[functionName];\n }\n\n /**\n * Check if a catalog is registered.\n */\n hasCatalog(catalogId: CatalogId): boolean {\n return this.catalogs.has(catalogId);\n }\n\n /**\n * Get all registered catalog IDs.\n */\n getCatalogIds(): CatalogId[] {\n return Array.from(this.catalogs.keys());\n }\n\n /**\n * Set a fallback component for unknown components.\n */\n setFallbackComponent(component: FreesailComponent): void {\n this.fallbackComponent = component;\n }\n\n /**\n * Clear all registrations.\n */\n clear(): void {\n this.catalogs.clear();\n this.functions.clear();\n this.paramNames.clear();\n this.fallbackComponent = null;\n }\n}\n\n/**\n * Global component registry instance.\n */\nexport const registry = new ComponentRegistry();\n\n/**\n * Higher-order function to create a component with catalog binding.\n * This ensures the component is registered when imported.\n */\nexport function withCatalog<P extends FreesailComponentProps>(\n catalogId: CatalogId,\n componentName: string,\n Component: ComponentType<P>\n): ComponentType<P> {\n registry.registerComponent(catalogId, componentName, Component as FreesailComponent);\n return Component;\n}\n\n/**\n * Register multiple components for a catalog at once.\n */\nexport function registerCatalog(\n catalogId: CatalogId,\n components: Record<string, FreesailComponent>,\n functions?: Record<string, FunctionImplementation>,\n schema?: Record<string, unknown>\n): void {\n registry.registerCatalog(catalogId, components, functions, schema);\n}\n"]} |
| import React from 'react'; | ||
| export type FreesailThemeMode = 'light' | 'dark'; | ||
| export interface FreesailThemeTokens { | ||
| bgRoot: string; | ||
| bgSurface: string; | ||
| bgCard: string; | ||
| bgMuted: string; | ||
| textMain: string; | ||
| textMuted: string; | ||
| primary: string; | ||
| primaryHover: string; | ||
| primaryText: string; | ||
| border: string; | ||
| radiusSm: string; | ||
| radiusMd: string; | ||
| radiusLg: string; | ||
| shadowSm: string; | ||
| shadowMd: string; | ||
| } | ||
| export interface FreesailTheme { | ||
| mode: FreesailThemeMode; | ||
| tokens: FreesailThemeTokens; | ||
| } | ||
| export declare const defaultLightTheme: FreesailThemeTokens; | ||
| export declare const defaultDarkTheme: FreesailThemeTokens; | ||
| export declare const useFreesailTheme: () => FreesailTheme; | ||
| export interface ThemeProviderProps { | ||
| theme?: FreesailThemeMode | Partial<FreesailThemeTokens>; | ||
| children: React.ReactNode; | ||
| } | ||
| export declare function FreesailThemeProvider({ theme, children }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element; | ||
| //# sourceMappingURL=theme.d.ts.map |
| {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwD,MAAM,OAAO,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED,eAAO,MAAM,iBAAiB,EAAE,mBAgB/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,mBAgB9B,CAAC;AAOF,eAAO,MAAM,gBAAgB,qBAAiC,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACzD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,qBAAqB,CAAC,EAAE,KAAe,EAAE,QAAQ,EAAE,EAAE,kBAAkB,2CA2CtF"} |
| import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; | ||
| import { createContext, useContext, useMemo } from 'react'; | ||
| export const defaultLightTheme = { | ||
| bgRoot: '#f8fafc', | ||
| bgSurface: '#ffffff', | ||
| bgCard: '#ffffff', | ||
| bgMuted: '#f1f5f9', | ||
| textMain: '#0f172a', | ||
| textMuted: '#64748b', | ||
| primary: '#2563eb', | ||
| primaryHover: '#1d4ed8', | ||
| primaryText: '#ffffff', | ||
| border: '#cbd5e1', | ||
| radiusSm: '0.25rem', | ||
| radiusMd: '0.5rem', | ||
| radiusLg: '0.75rem', | ||
| shadowSm: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)', | ||
| shadowMd: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', | ||
| }; | ||
| export const defaultDarkTheme = { | ||
| bgRoot: '#020617', | ||
| bgSurface: '#0f172a', | ||
| bgCard: '#1e293b', | ||
| bgMuted: '#1e293b', | ||
| textMain: '#f8fafc', | ||
| textMuted: '#94a3b8', | ||
| primary: '#3b82f6', | ||
| primaryHover: '#2563eb', | ||
| primaryText: '#ffffff', | ||
| border: '#334155', | ||
| radiusSm: '0.25rem', | ||
| radiusMd: '0.5rem', | ||
| radiusLg: '0.75rem', | ||
| shadowSm: '0 1px 2px 0 rgb(0 0 0 / 0.05)', | ||
| shadowMd: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', | ||
| }; | ||
| const ThemeContext = createContext({ | ||
| mode: 'light', | ||
| tokens: defaultLightTheme, | ||
| }); | ||
| export const useFreesailTheme = () => useContext(ThemeContext); | ||
| export function FreesailThemeProvider({ theme = 'light', children }) { | ||
| const currentTheme = useMemo(() => { | ||
| if (theme === 'dark') { | ||
| return { mode: 'dark', tokens: defaultDarkTheme }; | ||
| } | ||
| if (theme === 'light') { | ||
| return { mode: 'light', tokens: defaultLightTheme }; | ||
| } | ||
| // Custom partial theme | ||
| return { | ||
| mode: 'light', // Custom themes default to light baseline unless specified otherwise | ||
| tokens: { ...defaultLightTheme, ...theme }, | ||
| }; | ||
| }, [theme]); | ||
| // Inject CSS variables into the body or a wrapper | ||
| const styleString = ` | ||
| :root { | ||
| color-scheme: ${currentTheme.mode}; | ||
| --freesail-bg-root: ${currentTheme.tokens.bgRoot}; | ||
| --freesail-bg-surface: ${currentTheme.tokens.bgSurface}; | ||
| --freesail-bg-card: ${currentTheme.tokens.bgCard}; | ||
| --freesail-bg-muted: ${currentTheme.tokens.bgMuted}; | ||
| --freesail-text-main: ${currentTheme.tokens.textMain}; | ||
| --freesail-text-muted: ${currentTheme.tokens.textMuted}; | ||
| --freesail-primary: ${currentTheme.tokens.primary}; | ||
| --freesail-primary-hover: ${currentTheme.tokens.primaryHover}; | ||
| --freesail-primary-text: ${currentTheme.tokens.primaryText}; | ||
| --freesail-border: ${currentTheme.tokens.border}; | ||
| --freesail-radius-sm: ${currentTheme.tokens.radiusSm}; | ||
| --freesail-radius-md: ${currentTheme.tokens.radiusMd}; | ||
| --freesail-radius-lg: ${currentTheme.tokens.radiusLg}; | ||
| --freesail-shadow-sm: ${currentTheme.tokens.shadowSm}; | ||
| --freesail-shadow-md: ${currentTheme.tokens.shadowMd}; | ||
| } | ||
| `.trim(); | ||
| return (_jsxs(ThemeContext.Provider, { value: currentTheme, children: [_jsx("style", { children: styleString }), children] })); | ||
| } | ||
| //# sourceMappingURL=theme.js.map |
| {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { createContext, useContext, useEffect, useMemo } from 'react';\n\nexport type FreesailThemeMode = 'light' | 'dark';\n\nexport interface FreesailThemeTokens {\n bgRoot: string;\n bgSurface: string;\n bgCard: string;\n bgMuted: string;\n textMain: string;\n textMuted: string;\n primary: string;\n primaryHover: string;\n primaryText: string;\n border: string;\n radiusSm: string;\n radiusMd: string;\n radiusLg: string;\n shadowSm: string;\n shadowMd: string;\n}\n\nexport interface FreesailTheme {\n mode: FreesailThemeMode;\n tokens: FreesailThemeTokens;\n}\n\nexport const defaultLightTheme: FreesailThemeTokens = {\n bgRoot: '#f8fafc',\n bgSurface: '#ffffff',\n bgCard: '#ffffff',\n bgMuted: '#f1f5f9',\n textMain: '#0f172a',\n textMuted: '#64748b',\n primary: '#2563eb',\n primaryHover: '#1d4ed8',\n primaryText: '#ffffff',\n border: '#cbd5e1',\n radiusSm: '0.25rem',\n radiusMd: '0.5rem',\n radiusLg: '0.75rem',\n shadowSm: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',\n shadowMd: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',\n};\n\nexport const defaultDarkTheme: FreesailThemeTokens = {\n bgRoot: '#020617',\n bgSurface: '#0f172a',\n bgCard: '#1e293b',\n bgMuted: '#1e293b',\n textMain: '#f8fafc',\n textMuted: '#94a3b8',\n primary: '#3b82f6',\n primaryHover: '#2563eb',\n primaryText: '#ffffff',\n border: '#334155',\n radiusSm: '0.25rem',\n radiusMd: '0.5rem',\n radiusLg: '0.75rem',\n shadowSm: '0 1px 2px 0 rgb(0 0 0 / 0.05)',\n shadowMd: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',\n};\n\nconst ThemeContext = createContext<FreesailTheme>({\n mode: 'light',\n tokens: defaultLightTheme,\n});\n\nexport const useFreesailTheme = () => useContext(ThemeContext);\n\nexport interface ThemeProviderProps {\n theme?: FreesailThemeMode | Partial<FreesailThemeTokens>;\n children: React.ReactNode;\n}\n\nexport function FreesailThemeProvider({ theme = 'light', children }: ThemeProviderProps) {\n const currentTheme = useMemo<FreesailTheme>(() => {\n if (theme === 'dark') {\n return { mode: 'dark', tokens: defaultDarkTheme };\n }\n if (theme === 'light') {\n return { mode: 'light', tokens: defaultLightTheme };\n }\n // Custom partial theme\n return {\n mode: 'light', // Custom themes default to light baseline unless specified otherwise\n tokens: { ...defaultLightTheme, ...theme },\n };\n }, [theme]);\n\n // Inject CSS variables into the body or a wrapper\n const styleString = `\n :root {\n color-scheme: ${currentTheme.mode};\n --freesail-bg-root: ${currentTheme.tokens.bgRoot};\n --freesail-bg-surface: ${currentTheme.tokens.bgSurface};\n --freesail-bg-card: ${currentTheme.tokens.bgCard};\n --freesail-bg-muted: ${currentTheme.tokens.bgMuted};\n --freesail-text-main: ${currentTheme.tokens.textMain};\n --freesail-text-muted: ${currentTheme.tokens.textMuted};\n --freesail-primary: ${currentTheme.tokens.primary};\n --freesail-primary-hover: ${currentTheme.tokens.primaryHover};\n --freesail-primary-text: ${currentTheme.tokens.primaryText};\n --freesail-border: ${currentTheme.tokens.border};\n --freesail-radius-sm: ${currentTheme.tokens.radiusSm};\n --freesail-radius-md: ${currentTheme.tokens.radiusMd};\n --freesail-radius-lg: ${currentTheme.tokens.radiusLg};\n --freesail-shadow-sm: ${currentTheme.tokens.shadowSm};\n --freesail-shadow-md: ${currentTheme.tokens.shadowMd};\n }\n `.trim();\n\n return (\n <ThemeContext.Provider value={currentTheme}>\n <style>{styleString}</style>\n {children}\n </ThemeContext.Provider>\n );\n}\n"]} |
| /** | ||
| * @fileoverview Freesail React - Type Definitions | ||
| * | ||
| * Public interfaces for custom catalog integration. | ||
| */ | ||
| import type { ComponentType } from 'react'; | ||
| import type { FreesailComponentProps } from './registry.js'; | ||
| /** | ||
| * Definition of a custom catalog that can be registered with Freesail. | ||
| * | ||
| * Developers create a CatalogDefinition to bundle their JSON schema | ||
| * and React component implementations together, then pass them to | ||
| * FreesailProvider for registration. | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * import catalog from './catalog.json'; | ||
| * import MyCustomCard from './components/MyCustomCard'; | ||
| * | ||
| * export const MyOwnCatalog: CatalogDefinition = { | ||
| * namespace: 'myown', | ||
| * schema: catalog, | ||
| * components: { | ||
| * 'MyCustomCard': MyCustomCard, | ||
| * }, | ||
| * }; | ||
| * ``` | ||
| */ | ||
| export interface CatalogDefinition { | ||
| /** Unique namespace for the catalog (e.g., 'myown' or a full URI) */ | ||
| namespace: string; | ||
| /** The JSON schema object (catalog.json content) describing available components */ | ||
| schema: any; | ||
| /** Map of component names to React components implementing FreesailComponentProps */ | ||
| components: Record<string, ComponentType<FreesailComponentProps>>; | ||
| /** Map of function names to their implementations */ | ||
| functions?: Record<string, FunctionImplementation>; | ||
| } | ||
| /** | ||
| * A function implementation that can be called from the data model. | ||
| */ | ||
| export type FunctionImplementation = (...args: any[]) => any; | ||
| //# sourceMappingURL=types.d.ts.map |
| {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,MAAM,EAAE,GAAG,CAAC;IACZ,qFAAqF;IACrF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAClE,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CACpD;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC"} |
| /** | ||
| * @fileoverview Freesail React - Type Definitions | ||
| * | ||
| * Public interfaces for custom catalog integration. | ||
| */ | ||
| export {}; | ||
| //# sourceMappingURL=types.js.map |
| {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG","sourcesContent":["/**\n * @fileoverview Freesail React - Type Definitions\n *\n * Public interfaces for custom catalog integration.\n */\n\nimport type { ComponentType } from 'react';\nimport type { FreesailComponentProps } from './registry.js';\n\n/**\n * Definition of a custom catalog that can be registered with Freesail.\n *\n * Developers create a CatalogDefinition to bundle their JSON schema\n * and React component implementations together, then pass them to\n * FreesailProvider for registration.\n *\n * @example\n * ```ts\n * import catalog from './catalog.json';\n * import MyCustomCard from './components/MyCustomCard';\n *\n * export const MyOwnCatalog: CatalogDefinition = {\n * namespace: 'myown',\n * schema: catalog,\n * components: {\n * 'MyCustomCard': MyCustomCard,\n * },\n * };\n * ```\n */\nexport interface CatalogDefinition {\n /** Unique namespace for the catalog (e.g., 'myown' or a full URI) */\n namespace: string;\n /** The JSON schema object (catalog.json content) describing available components */\n schema: any;\n /** Map of component names to React components implementing FreesailComponentProps */\n components: Record<string, ComponentType<FreesailComponentProps>>;\n /** Map of function names to their implementations */\n functions?: Record<string, FunctionImplementation>;\n}\n\n/**\n * A function implementation that can be called from the data model.\n */\nexport type FunctionImplementation = (...args: any[]) => any;\n"]} |
| import type { JsonPointer } from '@freesail/core'; | ||
| /** | ||
| * Traverse a nested object/array by JSON pointer or relative path. | ||
| * Returns undefined if the path doesn't exist or data is nullish. | ||
| */ | ||
| export declare function getDataAtPath(data: unknown, path?: JsonPointer | string): unknown; | ||
| //# sourceMappingURL=utils.d.ts.map |
| {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,CAejF"} |
| /** | ||
| * Traverse a nested object/array by JSON pointer or relative path. | ||
| * Returns undefined if the path doesn't exist or data is nullish. | ||
| */ | ||
| export function getDataAtPath(data, path) { | ||
| if (data === null || data === undefined) | ||
| return undefined; | ||
| if (!path || path === '/') | ||
| return data; | ||
| const parts = path.split('/').filter((p) => p !== ''); | ||
| let current = data; | ||
| for (const part of parts) { | ||
| if (current === null || typeof current !== 'object') { | ||
| return undefined; | ||
| } | ||
| current = current[part]; | ||
| } | ||
| return current; | ||
| } | ||
| //# sourceMappingURL=utils.js.map |
| {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAa,EAAE,IAA2B;IACtE,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1D,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IACtD,IAAI,OAAO,GAAY,IAAI,CAAC;IAE5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACpD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,GAAI,OAAmC,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import type { JsonPointer } from '@freesail/core';\n\n/**\n * Traverse a nested object/array by JSON pointer or relative path.\n * Returns undefined if the path doesn't exist or data is nullish.\n */\nexport function getDataAtPath(data: unknown, path?: JsonPointer | string): unknown {\n if (data === null || data === undefined) return undefined;\n if (!path || path === '/') return data;\n\n const parts = path.split('/').filter((p) => p !== '');\n let current: unknown = data;\n\n for (const part of parts) {\n if (current === null || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n\n return current;\n}\n"]} |
+6
-5
| { | ||
| "name": "@freesail/react", | ||
| "version": "0.4.5", | ||
| "version": "0.4.6", | ||
| "description": "React implementation for Freesail - Agent-driven UI SDK", | ||
@@ -26,6 +26,7 @@ "type": "module", | ||
| "keywords": [ | ||
| "a2ui", | ||
| "freesail", | ||
| "react", | ||
| "agent-driven-ui", | ||
| "a2ux" | ||
| "agent-driven ui", | ||
| "generative ui", | ||
| "ai agent" | ||
| ], | ||
@@ -37,3 +38,3 @@ "peerDependencies": { | ||
| "dependencies": { | ||
| "@freesail/core": "^0.4.5", | ||
| "@freesail/core": "^0.4.6", | ||
| "vite": "7.3.1" | ||
@@ -40,0 +41,0 @@ }, |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
364337
16980.97%42
2000%2067
Infinity%1
-50%3
50%3
200%Updated