Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@freesail/react

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@freesail/react - npm Package Compare versions

Comparing version
0.4.3
to
0.4.5
+2
-2
package.json
{
"name": "@freesail/react",
"version": "0.4.3",
"version": "0.4.5",
"description": "React implementation for Freesail - Agent-driven UI SDK",

@@ -36,3 +36,3 @@ "type": "module",

"dependencies": {
"@freesail/core": "^0.4.3",
"@freesail/core": "^0.4.5",
"vite": "7.3.1"

@@ -39,0 +39,0 @@ },

/**
* @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;
/** SSE endpoint URL */
sseUrl: string;
/** HTTP POST endpoint URL */
postUrl: 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, 'sseUrl' | 'postUrl' | '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, sseUrl, postUrl, 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,EAKZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EASL,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,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,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,QAAQ,GAAG,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC;IAC1F,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,MAAM,EACN,OAAO,EACP,QAAa,EACb,kBAAuB,EACvB,gBAAgB,EAChB,WAAkB,EAClB,kBAAkB,EAClB,OAAO,GACR,EAAE,qBAAqB,2CA0IvB"}
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, } from 'react';
import { createSurfaceManager, createTransport, isCreateSurfaceMessage, isUpdateComponentsMessage, isUpdateDataModelMessage, isDeleteSurfaceMessage, } 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, sseUrl, postUrl, catalogs = [], catalogDefinitions = [], transportOptions, autoConnect = true, onConnectionChange, onError, }) {
const [surfaceManager] = useState(() => createSurfaceManager());
const [transport, setTransport] = useState(null);
const [isConnected, setIsConnected] = useState(false);
// Register custom catalog definitions
useEffect(() => {
for (const def of catalogDefinitions) {
registerCatalog(def.namespace, def.components, def.functions);
}
}, [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({
sseUrl,
postUrl,
capabilities,
...transportOptions,
});
// Handle incoming messages
newTransport.on('message', (message) => {
handleMessage(message, surfaceManager);
});
// Handle connection state changes
newTransport.on('stateChange', (state) => {
const connected = state === 'connected';
setIsConnected(connected);
onConnectionChange?.(connected);
});
// When session starts, register catalog schemas with the gateway
newTransport.on('sessionStart', (_sessionId) => {
if (catalogDefinitions.length > 0) {
const schemas = catalogDefinitions
.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);
onError?.(error);
});
setTransport(newTransport);
// Auto-connect if enabled
if (autoConnect) {
newTransport.connect();
}
// Cleanup
return () => {
newTransport.disconnect();
surfaceManager.dispose();
};
}, [sseUrl, postUrl]); // Only recreate if URLs change
// 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;
}
// Always send all surface data models that have sendDataModel enabled.
// This ensures the agent can see all form/input state across all surfaces,
// not just the one that triggered this action.
const allDataModels = surfaceManager.getAllSendableDataModels();
const dataModel = Object.keys(allDataModels).length > 0
? { surfaceId, dataModel: allDataModels }
: undefined;
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) {
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;
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 type ReactNode,\n} from 'react';\nimport {\n createSurfaceManager,\n createTransport,\n isCreateSurfaceMessage,\n isUpdateComponentsMessage,\n isUpdateDataModelMessage,\n isDeleteSurfaceMessage,\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 /** SSE endpoint URL */\n sseUrl: string;\n /** HTTP POST endpoint URL */\n postUrl: 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, 'sseUrl' | 'postUrl' | '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 sseUrl,\n postUrl,\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\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 );\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 sseUrl,\n postUrl,\n capabilities,\n ...transportOptions,\n });\n\n // Handle incoming messages\n newTransport.on('message', (message: DownstreamMessage) => {\n handleMessage(message, surfaceManager);\n });\n\n\n\n // Handle connection state changes\n newTransport.on('stateChange', (state) => {\n const connected = state === 'connected';\n setIsConnected(connected);\n onConnectionChange?.(connected);\n });\n\n // When session starts, register catalog schemas with the gateway\n newTransport.on('sessionStart', (_sessionId) => {\n if (catalogDefinitions.length > 0) {\n const schemas = catalogDefinitions\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) => {\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) => {\n console.error('[Freesail] Transport error:', error);\n onError?.(error);\n });\n\n setTransport(newTransport);\n\n // Auto-connect if enabled\n if (autoConnect) {\n newTransport.connect();\n }\n\n // Cleanup\n return () => {\n newTransport.disconnect();\n surfaceManager.dispose();\n };\n }, [sseUrl, postUrl]); // Only recreate if URLs change\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 // Always send all surface data models that have sendDataModel enabled.\n // This ensures the agent can see all form/input state across all surfaces,\n // not just the one that triggered this action.\n const allDataModels = surfaceManager.getAllSendableDataModels();\n const dataModel = Object.keys(allDataModels).length > 0\n ? { surfaceId, dataModel: allDataModels }\n : undefined;\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): 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 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, FunctionCall } 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;
/**
* Evaluate a function call.
*/
export declare function evaluateFunction(call: FunctionCall, dataModel: Record<string, unknown>, catalogId: string, scopeData?: unknown): unknown;
//# 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,EAIT,YAAY,EACb,MAAM,gBAAgB,CAAC;AAMxB;;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;AAmQD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAwDT"}
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';
/**
* 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
);
});
}
}
}
// 3. Handle named slots for specific components (Tabs, Modal)
else if (componentDef.component === 'Tabs' && Array.isArray(componentDef.tabs)) {
// Render each tab's child component
children = componentDef.tabs.map((tab, index) => renderComponent(tab.child, components, catalogId, dataModel, dispatch, onDataChange, scopeData, `${componentId}_tab_${index}`, scopeBasePath));
}
else if (componentDef.component === 'Modal') {
// Render trigger and content slots
const triggerId = componentDef.trigger;
const contentId = componentDef.content;
const trigger = triggerId
? renderComponent(triggerId, components, catalogId, dataModel, dispatch, onDataChange, scopeData, `${componentId}_trigger`, scopeBasePath)
: null;
const content = contentId
? renderComponent(contentId, components, catalogId, dataModel, dispatch, onDataChange, scopeData, `${componentId}_content`, scopeBasePath)
: null;
children = [trigger, content];
}
// Resolve data bindings in component properties
const resolvedProps = resolveDataBindings(componentDef, dataModel, catalogId, scopeData, scopeBasePath);
// 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) => {
evaluateFunction(call, dataModel, catalogId, scopeData);
},
};
return _jsx(Component, { ...props }, keyOverride ?? componentId);
}
/**
* Resolve data bindings in component properties.
*/
function resolveDataBindings(component, dataModel, catalogId, scopeData, scopeBasePath) {
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)) {
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);
}
return item;
});
}
else {
resolved[key] = resolveDataBindings(value, dataModel, catalogId, scopeData);
}
}
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.
*/
export 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') {
// If it's an object, we need to extract the values in the correct order.
// Agents often generate object keys like "'0'", "'1'" out of numerical order,
// so we parse the keys as numbers and sort them.
const entries = Object.entries(call.args);
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);
}
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;
});
try {
return funcImpl(...args);
}
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;
}
function getDataAtPath(data, path) {
if (data === null || data === undefined)
return undefined;
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;
}
// =============================================================================
// 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 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 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 // 3. Handle named slots for specific components (Tabs, Modal)\n else if (componentDef.component === 'Tabs' && Array.isArray((componentDef as any).tabs)) {\n // Render each tab's child component\n children = (componentDef as any).tabs.map((tab: any, index: number) =>\n renderComponent(\n tab.child as ComponentId,\n components,\n catalogId,\n dataModel,\n dispatch,\n onDataChange,\n scopeData,\n `${componentId}_tab_${index}`,\n scopeBasePath\n )\n );\n } else if (componentDef.component === 'Modal') {\n // Render trigger and content slots\n const triggerId = (componentDef as any).trigger as ComponentId | undefined;\n const contentId = (componentDef as any).content as ComponentId | undefined;\n\n const trigger = triggerId\n ? renderComponent(triggerId, components, catalogId, dataModel, dispatch, onDataChange, scopeData, `${componentId}_trigger`, scopeBasePath)\n : null;\n const content = contentId\n ? renderComponent(contentId, components, catalogId, dataModel, dispatch, onDataChange, scopeData, `${componentId}_content`, scopeBasePath)\n : null;\n\n children = [trigger, content];\n }\n\n // Resolve data bindings in component properties\n const resolvedProps = resolveDataBindings(componentDef, dataModel, catalogId, scopeData, scopeBasePath);\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 evaluateFunction(call, dataModel, catalogId, scopeData);\n },\n };\n\n return <Component key={keyOverride ?? componentId} {...props} />;\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): Record<string, unknown> {\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 resolved[key] = evaluateFunction(effectiveValue, dataModel, catalogId, scopeData);\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);\n }\n return item;\n });\n } else {\n resolved[key] = resolveDataBindings(value as any, dataModel, catalogId, scopeData);\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 */\nexport function 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 // If it's an object, we need to extract the values in the correct order.\n // Agents often generate object keys like \"'0'\", \"'1'\" out of numerical order,\n // so we parse the keys as numbers and sort them.\n const entries = Object.entries(call.args);\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 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 try {\n return funcImpl(...args);\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\nfunction getDataAtPath(data: unknown, path: string): unknown {\n if (data === null || data === undefined) return undefined;\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\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;AAGnF;;GAEG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CA4CpE;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;AA2BD;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAiB5C"}
/**
* @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';
/**
* 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) {
setSurface({ ...getSurface(surfaceId) });
}
});
const unsubData = surfaceManager.on('dataModelUpdated', (updatedId) => {
if (updatedId === surfaceId) {
setSurface({ ...getSurface(surfaceId) });
}
});
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;
}
// =============================================================================
// Helpers
// =============================================================================
function getDataAtPath(data, path) {
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;
}
/**
* 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';\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) => {\n if (created.id === surfaceId) {\n setSurface(created);\n }\n });\n\n const unsubDelete = surfaceManager.on('surfaceDeleted', (deletedId) => {\n if (deletedId === surfaceId) {\n setSurface(undefined);\n }\n });\n\n const unsubComponents = surfaceManager.on('componentsUpdated', (updatedId) => {\n if (updatedId === surfaceId) {\n setSurface({ ...getSurface(surfaceId)! });\n }\n });\n\n const unsubData = surfaceManager.on('dataModelUpdated', (updatedId) => {\n if (updatedId === surfaceId) {\n setSurface({ ...getSurface(surfaceId)! });\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, updatedPath) => {\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// Helpers\n// =============================================================================\n\nfunction getDataAtPath(\n data: Record<string, unknown>,\n path?: JsonPointer\n): unknown {\n if (!path || path === '/') {\n return data;\n }\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\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) => {\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,24nCAA24nC,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,w4nCAAw4nC,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;
private fallbackComponent;
/**
* Register a catalog with its components and functions.
*/
registerCatalog(catalogId: CatalogId, components: Record<string, FreesailComponent>, functions?: Record<string, FunctionImplementation>): void;
/**
* 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;
/**
* 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>): void;
export {};
//# sourceMappingURL=registry.d.ts.map
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,mFAAmF;IACnF,SAAS,EAAE,aAAa,CAAC;IACzB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACpE;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,aAAa,CAAC,sBAAsB,CAAC,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAE1D;;GAEG;AACH,cAAM,iBAAiB;IACrB,OAAO,CAAC,QAAQ,CAA2C;IAC3D,OAAO,CAAC,SAAS,CAAqE;IACtF,OAAO,CAAC,iBAAiB,CAAkC;IAE3D;;OAEG;IACH,eAAe,CACb,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC7C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,GACjD,IAAI;IAQP;;OAEG;IACH,iBAAiB,CACf,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,iBAAiB,GAC3B,IAAI;IAOP;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAgBnF;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI;IAiBtF;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO;IAIzC;;OAEG;IACH,aAAa,IAAI,SAAS,EAAE;IAI5B;;OAEG;IACH,oBAAoB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAIxD;;OAEG;IACH,KAAK,IAAI,IAAI;CAKd;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ,mBAA0B,CAAC;AAEhD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,sBAAsB,EAC1D,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,GAC1B,aAAa,CAAC,CAAC,CAAC,CAGlB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC7C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,GACjD,IAAI,CAEN"}
/**
* @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();
fallbackComponent = null;
/**
* Register a catalog with its components and functions.
*/
registerCatalog(catalogId, components, functions) {
const map = new Map(Object.entries(components));
this.catalogs.set(catalogId, map);
if (functions) {
this.functions.set(catalogId, functions);
}
}
/**
* 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;
}
/**
* 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.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) {
registry.registerCatalog(catalogId, components, functions);
}
//# 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 private fallbackComponent: FreesailComponent | null = null;\n\n /**\n * Register a catalog with its components and functions.\n */\n registerCatalog(\n catalogId: CatalogId,\n components: Record<string, FreesailComponent>,\n functions?: Record<string, FunctionImplementation>\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 }\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 * 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.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): void {\n registry.registerCatalog(catalogId, components, functions);\n}\n"]}
import React from 'react';
export type FreesailThemeMode = 'light' | 'dark';
export interface FreesailThemeTokens {
bgRoot: string;
bgSurface: 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,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,mBAe/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,mBAe9B,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,2CAyCtF"}
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { createContext, useContext, useMemo } from 'react';
export const defaultLightTheme = {
bgRoot: '#f8fafc',
bgSurface: '#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',
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 {
--freesail-bg-root: ${currentTheme.tokens.bgRoot};
--freesail-bg-surface: ${currentTheme.tokens.bgSurface};
--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 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 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 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 --freesail-bg-root: ${currentTheme.tokens.bgRoot};\n --freesail-bg-surface: ${currentTheme.tokens.bgSurface};\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"]}