@almadar/runtime 2.6.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { I as IEventBus } from './types-DYcUvi4H.js';
1
+ import { I as IEventBus } from './types-CM6txTNy.js';
2
2
  import { EventPayload } from '@almadar/core';
3
3
 
4
4
  /**
@@ -1,3 +1,5 @@
1
+ import './chunk-PZ5AY32C.js';
2
+
1
3
  // src/ServerBridge.ts
2
4
  var ServerBridge = class {
3
5
  config;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ServerBridge.ts"],"names":[],"mappings":"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","file":"ServerBridge.js","sourcesContent":["/**\n * ServerBridge - Client-Server Trait Communication\n *\n * Bridges the client EventBus with the server OrbitalRuntime:\n * 1. Forwards specified events from client to server\n * 2. Receives events from server (via polling or WebSocket)\n * 3. Puts server events onto client EventBus\n *\n * This enables cross-orbital communication between client and server traits.\n *\n * @example\n * ```typescript\n * import { ServerBridge } from '@kflow-builder/shared/runtime';\n * import { useEventBus } from './hooks/useEventBus';\n *\n * // In your app initialization\n * const eventBus = useEventBus();\n * const bridge = new ServerBridge({\n * eventBus,\n * serverUrl: '/api/orbitals',\n * // Events to forward from client to server\n * forwardEvents: ['ORDER_PLACED', 'PAYMENT_COMPLETED'],\n * });\n *\n * bridge.connect();\n *\n * // Now when client emits ORDER_PLACED, server traits receive it\n * eventBus.emit('ORDER_PLACED', { orderId: '123' });\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { IEventBus, RuntimeEvent, EventPayload } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ServerBridgeConfig {\n /** Client EventBus to bridge */\n eventBus: IEventBus;\n /** Base URL for orbital server API */\n serverUrl: string;\n /** Events to forward from client to server */\n forwardEvents?: string[];\n /** Forward all events matching pattern (e.g., 'Order*', '*') */\n forwardPattern?: string;\n /** Target orbital for forwarded events (or 'broadcast' for all) */\n targetOrbital?: string;\n /** Enable WebSocket for real-time server events */\n useWebSocket?: boolean;\n /** Polling interval in ms (if not using WebSocket) */\n pollInterval?: number;\n /** Enable debug logging */\n debug?: boolean;\n /** Custom fetch function (for testing or custom auth) */\n fetch?: typeof fetch;\n}\n\nexport interface ServerBridgeState {\n connected: boolean;\n lastError?: string;\n eventsForwarded: number;\n eventsReceived: number;\n}\n\n// ============================================================================\n// ServerBridge\n// ============================================================================\n\n/**\n * Bridges client EventBus with server OrbitalRuntime\n */\nexport class ServerBridge {\n private config: ServerBridgeConfig;\n private state: ServerBridgeState = {\n connected: false,\n eventsForwarded: 0,\n eventsReceived: 0,\n };\n private unsubscribes: Array<() => void> = [];\n private pollTimer?: ReturnType<typeof setInterval>;\n private ws?: WebSocket;\n private fetchFn: typeof fetch;\n\n constructor(config: ServerBridgeConfig) {\n this.config = {\n pollInterval: 5000,\n ...config,\n };\n this.fetchFn = config.fetch || fetch.bind(globalThis);\n }\n\n // ==========================================================================\n // Connection Management\n // ==========================================================================\n\n /**\n * Connect the bridge - start forwarding events\n */\n connect(): void {\n if (this.state.connected) {\n this.log(\"warn\", \"Already connected\");\n return;\n }\n\n this.log(\"info\", \"Connecting bridge...\");\n\n // Subscribe to events to forward\n this.setupEventForwarding();\n\n // Set up server -> client channel\n if (this.config.useWebSocket) {\n this.setupWebSocket();\n } else if (this.config.pollInterval && this.config.pollInterval > 0) {\n this.setupPolling();\n }\n\n this.state.connected = true;\n this.log(\"info\", \"Bridge connected\");\n }\n\n /**\n * Disconnect the bridge\n */\n disconnect(): void {\n // Clean up event subscriptions\n for (const unsub of this.unsubscribes) {\n unsub();\n }\n this.unsubscribes = [];\n\n // Clean up polling\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = undefined;\n }\n\n // Clean up WebSocket\n if (this.ws) {\n this.ws.close();\n this.ws = undefined;\n }\n\n this.state.connected = false;\n this.log(\"info\", \"Bridge disconnected\");\n }\n\n /**\n * Get current bridge state\n */\n getState(): ServerBridgeState {\n return { ...this.state };\n }\n\n // ==========================================================================\n // Event Forwarding (Client -> Server)\n // ==========================================================================\n\n private setupEventForwarding(): void {\n const { eventBus, forwardEvents, forwardPattern } = this.config;\n\n if (forwardEvents && forwardEvents.length > 0) {\n // Forward specific events\n for (const eventType of forwardEvents) {\n const unsub = eventBus.on(eventType, (event: RuntimeEvent) => {\n this.forwardToServer(event);\n });\n this.unsubscribes.push(unsub);\n }\n } else if (forwardPattern) {\n // Forward events matching pattern\n if (forwardPattern === \"*\") {\n // Forward all events\n const unsub = eventBus.on(\"*\", (event: RuntimeEvent) => {\n // Don't forward internal events\n if (\n !event.type.startsWith(\"UI:\") &&\n !event.type.startsWith(\"BRIDGE:\")\n ) {\n this.forwardToServer(event);\n }\n });\n this.unsubscribes.push(unsub);\n } else {\n // Pattern matching (simple prefix match)\n const prefix = forwardPattern.replace(\"*\", \"\");\n const unsub = eventBus.on(\"*\", (event: RuntimeEvent) => {\n if (event.type.startsWith(prefix)) {\n this.forwardToServer(event);\n }\n });\n this.unsubscribes.push(unsub);\n }\n }\n }\n\n private async forwardToServer(event: RuntimeEvent): Promise<void> {\n const { serverUrl, targetOrbital } = this.config;\n\n try {\n // Determine which orbital(s) to send to\n if (targetOrbital && targetOrbital !== \"broadcast\") {\n // Send to specific orbital\n await this.sendEventToOrbital(targetOrbital, event);\n } else {\n // Broadcast to all orbitals\n const orbitals = await this.fetchOrbitals();\n for (const orbital of orbitals) {\n await this.sendEventToOrbital(orbital.name, event);\n }\n }\n\n this.state.eventsForwarded++;\n this.log(\"debug\", `Forwarded event: ${event.type}`);\n } catch (error) {\n this.state.lastError = String(error);\n this.log(\"error\", `Failed to forward event: ${event.type}`, error);\n }\n }\n\n private async sendEventToOrbital(\n orbitalName: string,\n event: RuntimeEvent,\n ): Promise<void> {\n const { serverUrl } = this.config;\n const url = `${serverUrl}/${orbitalName}/events`;\n\n const response = await this.fetchFn(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n event: event.type,\n payload: event.payload,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Server returned ${response.status}`);\n }\n\n const result = (await response.json()) as {\n emittedEvents?: Array<{ event: string; payload?: EventPayload }>;\n };\n\n // If server emitted events, put them on client EventBus\n if (result.emittedEvents && result.emittedEvents.length > 0) {\n for (const emitted of result.emittedEvents) {\n this.config.eventBus.emit(`SERVER:${emitted.event}`, emitted.payload);\n this.state.eventsReceived++;\n }\n }\n }\n\n private async fetchOrbitals(): Promise<Array<{ name: string }>> {\n const response = await this.fetchFn(this.config.serverUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch orbitals: ${response.status}`);\n }\n const data = (await response.json()) as { orbitals?: Array<{ name: string }> };\n return data.orbitals || [];\n }\n\n // ==========================================================================\n // Server -> Client (Polling)\n // ==========================================================================\n\n private setupPolling(): void {\n // For now, polling is handled by the response to forwarded events\n // A more sophisticated implementation would poll a /events endpoint\n this.log(\"debug\", \"Polling mode - events received via forward response\");\n }\n\n // ==========================================================================\n // Server -> Client (WebSocket)\n // ==========================================================================\n\n private setupWebSocket(): void {\n const { serverUrl } = this.config;\n\n // Convert HTTP URL to WebSocket URL\n const wsUrl = serverUrl\n .replace(/^http:/, \"ws:\")\n .replace(/^https:/, \"wss:\")\n .replace(/\\/api\\/orbitals$/, \"/ws/orbitals\");\n\n try {\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => {\n this.log(\"info\", \"WebSocket connected\");\n };\n\n this.ws.onmessage = (msg) => {\n try {\n const data = JSON.parse(msg.data);\n if (data.type === \"event\") {\n // Server pushed an event - put it on client EventBus\n this.config.eventBus.emit(`SERVER:${data.event}`, data.payload);\n this.state.eventsReceived++;\n this.log(\"debug\", `Received server event: ${data.event}`);\n }\n } catch (error) {\n this.log(\"error\", \"Failed to parse WebSocket message\", error);\n }\n };\n\n this.ws.onerror = (error) => {\n this.state.lastError = \"WebSocket error\";\n this.log(\"error\", \"WebSocket error\", error);\n };\n\n this.ws.onclose = () => {\n this.log(\"info\", \"WebSocket closed\");\n // Could implement reconnection logic here\n };\n } catch (error) {\n this.log(\"error\", \"Failed to create WebSocket\", error);\n }\n }\n\n // ==========================================================================\n // Direct Methods\n // ==========================================================================\n\n /**\n * Send an event directly to a specific orbital (bypassing EventBus)\n */\n async sendEvent(\n orbitalName: string,\n event: string,\n payload?: EventPayload,\n ): Promise<{\n success: boolean;\n states?: Record<string, string>;\n emittedEvents?: Array<{ event: string; payload?: unknown }>;\n error?: string;\n }> {\n const { serverUrl } = this.config;\n const url = `${serverUrl}/${orbitalName}/events`;\n\n try {\n const response = await this.fetchFn(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ event, payload }),\n });\n\n return (await response.json()) as {\n success: boolean;\n states?: Record<string, string>;\n emittedEvents?: Array<{ event: string; payload?: unknown }>;\n error?: string;\n };\n } catch (error) {\n return { success: false, error: String(error) };\n }\n }\n\n /**\n * Get current state of an orbital's traits\n */\n async getOrbitalState(orbitalName: string): Promise<{\n success: boolean;\n states?: Record<string, string>;\n error?: string;\n }> {\n const { serverUrl } = this.config;\n const url = `${serverUrl}/${orbitalName}`;\n\n try {\n const response = await this.fetchFn(url);\n const data = (await response.json()) as {\n success: boolean;\n orbital?: { traits: Array<{ name: string; currentState: string }> };\n error?: string;\n };\n\n if (data.success && data.orbital) {\n const states: Record<string, string> = {};\n for (const trait of data.orbital.traits) {\n states[trait.name] = trait.currentState;\n }\n return { success: true, states };\n }\n\n return { success: false, error: data.error };\n } catch (error) {\n return { success: false, error: String(error) };\n }\n }\n\n // ==========================================================================\n // Utilities\n // ==========================================================================\n\n private log(\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n data?: unknown,\n ): void {\n if (!this.config.debug && level === \"debug\") return;\n\n const prefix = \"[ServerBridge]\";\n const logFn =\n level === \"error\"\n ? console.error\n : level === \"warn\"\n ? console.warn\n : console.log;\n logFn(prefix, message, data !== undefined ? data : \"\");\n }\n}\n\n/**\n * Create a ServerBridge instance\n */\nexport function createServerBridge(config: ServerBridgeConfig): ServerBridge {\n return new ServerBridge(config);\n}\n"]}
1
+ {"version":3,"sources":["../src/ServerBridge.ts"],"names":[],"mappings":";;;AA0EO,IAAM,eAAN,MAAmB;AAAA,EAChB,MAAA;AAAA,EACA,KAAA,GAA2B;AAAA,IACjC,SAAA,EAAW,KAAA;AAAA,IACX,eAAA,EAAiB,CAAA;AAAA,IACjB,cAAA,EAAgB;AAAA,GAClB;AAAA,EACQ,eAAkC,EAAC;AAAA,EACnC,SAAA;AAAA,EACA,EAAA;AAAA,EACA,OAAA;AAAA,EAER,YAAY,MAAA,EAA4B;AACtC,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,YAAA,EAAc,GAAA;AAAA,MACd,GAAG;AAAA,KACL;AACA,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA,CAAO,KAAA,IAAS,KAAA,CAAM,KAAK,UAAU,CAAA;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAA,GAAgB;AACd,IAAA,IAAI,IAAA,CAAK,MAAM,SAAA,EAAW;AACxB,MAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,mBAAmB,CAAA;AACpC,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,sBAAsB,CAAA;AAGvC,IAAA,IAAA,CAAK,oBAAA,EAAqB;AAG1B,IAAA,IAAI,IAAA,CAAK,OAAO,YAAA,EAAc;AAC5B,MAAA,IAAA,CAAK,cAAA,EAAe;AAAA,IACtB,WAAW,IAAA,CAAK,MAAA,CAAO,gBAAgB,IAAA,CAAK,MAAA,CAAO,eAAe,CAAA,EAAG;AACnE,MAAA,IAAA,CAAK,YAAA,EAAa;AAAA,IACpB;AAEA,IAAA,IAAA,CAAK,MAAM,SAAA,GAAY,IAAA;AACvB,IAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,kBAAkB,CAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAAmB;AAEjB,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,YAAA,EAAc;AACrC,MAAA,KAAA,EAAM;AAAA,IACR;AACA,IAAA,IAAA,CAAK,eAAe,EAAC;AAGrB,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,aAAA,CAAc,KAAK,SAAS,CAAA;AAC5B,MAAA,IAAA,CAAK,SAAA,GAAY,MAAA;AAAA,IACnB;AAGA,IAAA,IAAI,KAAK,EAAA,EAAI;AACX,MAAA,IAAA,CAAK,GAAG,KAAA,EAAM;AACd,MAAA,IAAA,CAAK,EAAA,GAAK,MAAA;AAAA,IACZ;AAEA,IAAA,IAAA,CAAK,MAAM,SAAA,GAAY,KAAA;AACvB,IAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,qBAAqB,CAAA;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAA8B;AAC5B,IAAA,OAAO,EAAE,GAAG,IAAA,CAAK,KAAA,EAAM;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAMQ,oBAAA,GAA6B;AACnC,IAAA,MAAM,EAAE,QAAA,EAAU,aAAA,EAAe,cAAA,KAAmB,IAAA,CAAK,MAAA;AAEzD,IAAA,IAAI,aAAA,IAAiB,aAAA,CAAc,MAAA,GAAS,CAAA,EAAG;AAE7C,MAAA,KAAA,MAAW,aAAa,aAAA,EAAe;AACrC,QAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,EAAA,CAAG,SAAA,EAAW,CAAC,KAAA,KAAwB;AAC5D,UAAA,IAAA,CAAK,gBAAgB,KAAK,CAAA;AAAA,QAC5B,CAAC,CAAA;AACD,QAAA,IAAA,CAAK,YAAA,CAAa,KAAK,KAAK,CAAA;AAAA,MAC9B;AAAA,IACF,WAAW,cAAA,EAAgB;AAEzB,MAAA,IAAI,mBAAmB,GAAA,EAAK;AAE1B,QAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,EAAA,CAAG,GAAA,EAAK,CAAC,KAAA,KAAwB;AAEtD,UAAA,IACE,CAAC,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,KAAK,CAAA,IAC5B,CAAC,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,SAAS,CAAA,EAChC;AACA,YAAA,IAAA,CAAK,gBAAgB,KAAK,CAAA;AAAA,UAC5B;AAAA,QACF,CAAC,CAAA;AACD,QAAA,IAAA,CAAK,YAAA,CAAa,KAAK,KAAK,CAAA;AAAA,MAC9B,CAAA,MAAO;AAEL,QAAA,MAAM,MAAA,GAAS,cAAA,CAAe,OAAA,CAAQ,GAAA,EAAK,EAAE,CAAA;AAC7C,QAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,EAAA,CAAG,GAAA,EAAK,CAAC,KAAA,KAAwB;AACtD,UAAA,IAAI,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,MAAM,CAAA,EAAG;AACjC,YAAA,IAAA,CAAK,gBAAgB,KAAK,CAAA;AAAA,UAC5B;AAAA,QACF,CAAC,CAAA;AACD,QAAA,IAAA,CAAK,YAAA,CAAa,KAAK,KAAK,CAAA;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,gBAAgB,KAAA,EAAoC;AAChE,IAAA,MAAM,EAAE,SAAA,EAAW,aAAA,EAAc,GAAI,IAAA,CAAK,MAAA;AAE1C,IAAA,IAAI;AAEF,MAAA,IAAI,aAAA,IAAiB,kBAAkB,WAAA,EAAa;AAElD,QAAA,MAAM,IAAA,CAAK,kBAAA,CAAmB,aAAA,EAAe,KAAK,CAAA;AAAA,MACpD,CAAA,MAAO;AAEL,QAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,aAAA,EAAc;AAC1C,QAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,UAAA,MAAM,IAAA,CAAK,kBAAA,CAAmB,OAAA,CAAQ,IAAA,EAAM,KAAK,CAAA;AAAA,QACnD;AAAA,MACF;AAEA,MAAA,IAAA,CAAK,KAAA,CAAM,eAAA,EAAA;AACX,MAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,CAAA,iBAAA,EAAoB,KAAA,CAAM,IAAI,CAAA,CAAE,CAAA;AAAA,IACpD,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,MAAA,CAAO,KAAK,CAAA;AACnC,MAAA,IAAA,CAAK,IAAI,OAAA,EAAS,CAAA,yBAAA,EAA4B,KAAA,CAAM,IAAI,IAAI,KAAK,CAAA;AAAA,IACnE;AAAA,EACF;AAAA,EAEA,MAAc,kBAAA,CACZ,WAAA,EACA,KAAA,EACe;AACf,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,IAAA,CAAK,MAAA;AAC3B,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,WAAW,CAAA,OAAA,CAAA;AAEvC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,OAAO,KAAA,CAAM,IAAA;AAAA,QACb,SAAS,KAAA,CAAM;AAAA,OAChB;AAAA,KACF,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IACtD;AAEA,IAAA,MAAM,MAAA,GAAU,MAAM,QAAA,CAAS,IAAA,EAAK;AAKpC,IAAA,IAAI,MAAA,CAAO,aAAA,IAAiB,MAAA,CAAO,aAAA,CAAc,SAAS,CAAA,EAAG;AAC3D,MAAA,KAAA,MAAW,OAAA,IAAW,OAAO,aAAA,EAAe;AAC1C,QAAA,IAAA,CAAK,MAAA,CAAO,SAAS,IAAA,CAAK,CAAA,OAAA,EAAU,QAAQ,KAAK,CAAA,CAAA,EAAI,QAAQ,OAAO,CAAA;AACpE,QAAA,IAAA,CAAK,KAAA,CAAM,cAAA,EAAA;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,aAAA,GAAkD;AAC9D,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,OAAO,SAAS,CAAA;AACzD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IAChE;AACA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,OAAO,IAAA,CAAK,YAAY,EAAC;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAMQ,YAAA,GAAqB;AAG3B,IAAA,IAAA,CAAK,GAAA,CAAI,SAAS,qDAAqD,CAAA;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAA,GAAuB;AAC7B,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,IAAA,CAAK,MAAA;AAG3B,IAAA,MAAM,KAAA,GAAQ,SAAA,CACX,OAAA,CAAQ,QAAA,EAAU,KAAK,CAAA,CACvB,OAAA,CAAQ,SAAA,EAAW,MAAM,CAAA,CACzB,OAAA,CAAQ,kBAAA,EAAoB,cAAc,CAAA;AAE7C,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,EAAA,GAAK,IAAI,SAAA,CAAU,KAAK,CAAA;AAE7B,MAAA,IAAA,CAAK,EAAA,CAAG,SAAS,MAAM;AACrB,QAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,qBAAqB,CAAA;AAAA,MACxC,CAAA;AAEA,MAAA,IAAA,CAAK,EAAA,CAAG,SAAA,GAAY,CAAC,GAAA,KAAQ;AAC3B,QAAA,IAAI;AACF,UAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA;AAChC,UAAA,IAAI,IAAA,CAAK,SAAS,OAAA,EAAS;AAEzB,YAAA,IAAA,CAAK,MAAA,CAAO,SAAS,IAAA,CAAK,CAAA,OAAA,EAAU,KAAK,KAAK,CAAA,CAAA,EAAI,KAAK,OAAO,CAAA;AAC9D,YAAA,IAAA,CAAK,KAAA,CAAM,cAAA,EAAA;AACX,YAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,CAAA,uBAAA,EAA0B,IAAA,CAAK,KAAK,CAAA,CAAE,CAAA;AAAA,UAC1D;AAAA,QACF,SAAS,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,mCAAA,EAAqC,KAAK,CAAA;AAAA,QAC9D;AAAA,MACF,CAAA;AAEA,MAAA,IAAA,CAAK,EAAA,CAAG,OAAA,GAAU,CAAC,KAAA,KAAU;AAC3B,QAAA,IAAA,CAAK,MAAM,SAAA,GAAY,iBAAA;AACvB,QAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,iBAAA,EAAmB,KAAK,CAAA;AAAA,MAC5C,CAAA;AAEA,MAAA,IAAA,CAAK,EAAA,CAAG,UAAU,MAAM;AACtB,QAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,kBAAkB,CAAA;AAAA,MAErC,CAAA;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,4BAAA,EAA8B,KAAK,CAAA;AAAA,IACvD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SAAA,CACJ,WAAA,EACA,KAAA,EACA,OAAA,EAMC;AACD,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,IAAA,CAAK,MAAA;AAC3B,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,WAAW,CAAA,OAAA,CAAA;AAEvC,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK;AAAA,QACvC,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,SAAS;AAAA,OACxC,CAAA;AAED,MAAA,OAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,IAM9B,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,MAAA,CAAO,KAAK,CAAA,EAAE;AAAA,IAChD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,WAAA,EAInB;AACD,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,IAAA,CAAK,MAAA;AAC3B,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA;AAEvC,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AACvC,MAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAMlC,MAAA,IAAI,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,OAAA,EAAS;AAChC,QAAA,MAAM,SAAiC,EAAC;AACxC,QAAA,KAAA,MAAW,KAAA,IAAS,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ;AACvC,UAAA,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA,CAAM,YAAA;AAAA,QAC7B;AACA,QAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,MAAA,EAAO;AAAA,MACjC;AAEA,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAK,KAAA,EAAM;AAAA,IAC7C,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,MAAA,CAAO,KAAK,CAAA,EAAE;AAAA,IAChD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMQ,GAAA,CACN,KAAA,EACA,OAAA,EACA,IAAA,EACM;AACN,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,KAAA,IAAS,UAAU,OAAA,EAAS;AAE7C,IAAA,MAAM,MAAA,GAAS,gBAAA;AACf,IAAA,MAAM,KAAA,GACJ,UAAU,OAAA,GACN,OAAA,CAAQ,QACR,KAAA,KAAU,MAAA,GACR,OAAA,CAAQ,IAAA,GACR,OAAA,CAAQ,GAAA;AAChB,IAAA,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,KAAS,MAAA,GAAY,OAAO,EAAE,CAAA;AAAA,EACvD;AACF;AAKO,SAAS,mBAAmB,MAAA,EAA0C;AAC3E,EAAA,OAAO,IAAI,aAAa,MAAM,CAAA;AAChC","file":"ServerBridge.js","sourcesContent":["/**\n * ServerBridge - Client-Server Trait Communication\n *\n * Bridges the client EventBus with the server OrbitalRuntime:\n * 1. Forwards specified events from client to server\n * 2. Receives events from server (via polling or WebSocket)\n * 3. Puts server events onto client EventBus\n *\n * This enables cross-orbital communication between client and server traits.\n *\n * @example\n * ```typescript\n * import { ServerBridge } from '@kflow-builder/shared/runtime';\n * import { useEventBus } from './hooks/useEventBus';\n *\n * // In your app initialization\n * const eventBus = useEventBus();\n * const bridge = new ServerBridge({\n * eventBus,\n * serverUrl: '/api/orbitals',\n * // Events to forward from client to server\n * forwardEvents: ['ORDER_PLACED', 'PAYMENT_COMPLETED'],\n * });\n *\n * bridge.connect();\n *\n * // Now when client emits ORDER_PLACED, server traits receive it\n * eventBus.emit('ORDER_PLACED', { orderId: '123' });\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { IEventBus, RuntimeEvent, EventPayload } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ServerBridgeConfig {\n /** Client EventBus to bridge */\n eventBus: IEventBus;\n /** Base URL for orbital server API */\n serverUrl: string;\n /** Events to forward from client to server */\n forwardEvents?: string[];\n /** Forward all events matching pattern (e.g., 'Order*', '*') */\n forwardPattern?: string;\n /** Target orbital for forwarded events (or 'broadcast' for all) */\n targetOrbital?: string;\n /** Enable WebSocket for real-time server events */\n useWebSocket?: boolean;\n /** Polling interval in ms (if not using WebSocket) */\n pollInterval?: number;\n /** Enable debug logging */\n debug?: boolean;\n /** Custom fetch function (for testing or custom auth) */\n fetch?: typeof fetch;\n}\n\nexport interface ServerBridgeState {\n connected: boolean;\n lastError?: string;\n eventsForwarded: number;\n eventsReceived: number;\n}\n\n// ============================================================================\n// ServerBridge\n// ============================================================================\n\n/**\n * Bridges client EventBus with server OrbitalRuntime\n */\nexport class ServerBridge {\n private config: ServerBridgeConfig;\n private state: ServerBridgeState = {\n connected: false,\n eventsForwarded: 0,\n eventsReceived: 0,\n };\n private unsubscribes: Array<() => void> = [];\n private pollTimer?: ReturnType<typeof setInterval>;\n private ws?: WebSocket;\n private fetchFn: typeof fetch;\n\n constructor(config: ServerBridgeConfig) {\n this.config = {\n pollInterval: 5000,\n ...config,\n };\n this.fetchFn = config.fetch || fetch.bind(globalThis);\n }\n\n // ==========================================================================\n // Connection Management\n // ==========================================================================\n\n /**\n * Connect the bridge - start forwarding events\n */\n connect(): void {\n if (this.state.connected) {\n this.log(\"warn\", \"Already connected\");\n return;\n }\n\n this.log(\"info\", \"Connecting bridge...\");\n\n // Subscribe to events to forward\n this.setupEventForwarding();\n\n // Set up server -> client channel\n if (this.config.useWebSocket) {\n this.setupWebSocket();\n } else if (this.config.pollInterval && this.config.pollInterval > 0) {\n this.setupPolling();\n }\n\n this.state.connected = true;\n this.log(\"info\", \"Bridge connected\");\n }\n\n /**\n * Disconnect the bridge\n */\n disconnect(): void {\n // Clean up event subscriptions\n for (const unsub of this.unsubscribes) {\n unsub();\n }\n this.unsubscribes = [];\n\n // Clean up polling\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = undefined;\n }\n\n // Clean up WebSocket\n if (this.ws) {\n this.ws.close();\n this.ws = undefined;\n }\n\n this.state.connected = false;\n this.log(\"info\", \"Bridge disconnected\");\n }\n\n /**\n * Get current bridge state\n */\n getState(): ServerBridgeState {\n return { ...this.state };\n }\n\n // ==========================================================================\n // Event Forwarding (Client -> Server)\n // ==========================================================================\n\n private setupEventForwarding(): void {\n const { eventBus, forwardEvents, forwardPattern } = this.config;\n\n if (forwardEvents && forwardEvents.length > 0) {\n // Forward specific events\n for (const eventType of forwardEvents) {\n const unsub = eventBus.on(eventType, (event: RuntimeEvent) => {\n this.forwardToServer(event);\n });\n this.unsubscribes.push(unsub);\n }\n } else if (forwardPattern) {\n // Forward events matching pattern\n if (forwardPattern === \"*\") {\n // Forward all events\n const unsub = eventBus.on(\"*\", (event: RuntimeEvent) => {\n // Don't forward internal events\n if (\n !event.type.startsWith(\"UI:\") &&\n !event.type.startsWith(\"BRIDGE:\")\n ) {\n this.forwardToServer(event);\n }\n });\n this.unsubscribes.push(unsub);\n } else {\n // Pattern matching (simple prefix match)\n const prefix = forwardPattern.replace(\"*\", \"\");\n const unsub = eventBus.on(\"*\", (event: RuntimeEvent) => {\n if (event.type.startsWith(prefix)) {\n this.forwardToServer(event);\n }\n });\n this.unsubscribes.push(unsub);\n }\n }\n }\n\n private async forwardToServer(event: RuntimeEvent): Promise<void> {\n const { serverUrl, targetOrbital } = this.config;\n\n try {\n // Determine which orbital(s) to send to\n if (targetOrbital && targetOrbital !== \"broadcast\") {\n // Send to specific orbital\n await this.sendEventToOrbital(targetOrbital, event);\n } else {\n // Broadcast to all orbitals\n const orbitals = await this.fetchOrbitals();\n for (const orbital of orbitals) {\n await this.sendEventToOrbital(orbital.name, event);\n }\n }\n\n this.state.eventsForwarded++;\n this.log(\"debug\", `Forwarded event: ${event.type}`);\n } catch (error) {\n this.state.lastError = String(error);\n this.log(\"error\", `Failed to forward event: ${event.type}`, error);\n }\n }\n\n private async sendEventToOrbital(\n orbitalName: string,\n event: RuntimeEvent,\n ): Promise<void> {\n const { serverUrl } = this.config;\n const url = `${serverUrl}/${orbitalName}/events`;\n\n const response = await this.fetchFn(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n event: event.type,\n payload: event.payload,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Server returned ${response.status}`);\n }\n\n const result = (await response.json()) as {\n emittedEvents?: Array<{ event: string; payload?: EventPayload }>;\n };\n\n // If server emitted events, put them on client EventBus\n if (result.emittedEvents && result.emittedEvents.length > 0) {\n for (const emitted of result.emittedEvents) {\n this.config.eventBus.emit(`SERVER:${emitted.event}`, emitted.payload);\n this.state.eventsReceived++;\n }\n }\n }\n\n private async fetchOrbitals(): Promise<Array<{ name: string }>> {\n const response = await this.fetchFn(this.config.serverUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch orbitals: ${response.status}`);\n }\n const data = (await response.json()) as { orbitals?: Array<{ name: string }> };\n return data.orbitals || [];\n }\n\n // ==========================================================================\n // Server -> Client (Polling)\n // ==========================================================================\n\n private setupPolling(): void {\n // For now, polling is handled by the response to forwarded events\n // A more sophisticated implementation would poll a /events endpoint\n this.log(\"debug\", \"Polling mode - events received via forward response\");\n }\n\n // ==========================================================================\n // Server -> Client (WebSocket)\n // ==========================================================================\n\n private setupWebSocket(): void {\n const { serverUrl } = this.config;\n\n // Convert HTTP URL to WebSocket URL\n const wsUrl = serverUrl\n .replace(/^http:/, \"ws:\")\n .replace(/^https:/, \"wss:\")\n .replace(/\\/api\\/orbitals$/, \"/ws/orbitals\");\n\n try {\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => {\n this.log(\"info\", \"WebSocket connected\");\n };\n\n this.ws.onmessage = (msg) => {\n try {\n const data = JSON.parse(msg.data);\n if (data.type === \"event\") {\n // Server pushed an event - put it on client EventBus\n this.config.eventBus.emit(`SERVER:${data.event}`, data.payload);\n this.state.eventsReceived++;\n this.log(\"debug\", `Received server event: ${data.event}`);\n }\n } catch (error) {\n this.log(\"error\", \"Failed to parse WebSocket message\", error);\n }\n };\n\n this.ws.onerror = (error) => {\n this.state.lastError = \"WebSocket error\";\n this.log(\"error\", \"WebSocket error\", error);\n };\n\n this.ws.onclose = () => {\n this.log(\"info\", \"WebSocket closed\");\n // Could implement reconnection logic here\n };\n } catch (error) {\n this.log(\"error\", \"Failed to create WebSocket\", error);\n }\n }\n\n // ==========================================================================\n // Direct Methods\n // ==========================================================================\n\n /**\n * Send an event directly to a specific orbital (bypassing EventBus)\n */\n async sendEvent(\n orbitalName: string,\n event: string,\n payload?: EventPayload,\n ): Promise<{\n success: boolean;\n states?: Record<string, string>;\n emittedEvents?: Array<{ event: string; payload?: unknown }>;\n error?: string;\n }> {\n const { serverUrl } = this.config;\n const url = `${serverUrl}/${orbitalName}/events`;\n\n try {\n const response = await this.fetchFn(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ event, payload }),\n });\n\n return (await response.json()) as {\n success: boolean;\n states?: Record<string, string>;\n emittedEvents?: Array<{ event: string; payload?: unknown }>;\n error?: string;\n };\n } catch (error) {\n return { success: false, error: String(error) };\n }\n }\n\n /**\n * Get current state of an orbital's traits\n */\n async getOrbitalState(orbitalName: string): Promise<{\n success: boolean;\n states?: Record<string, string>;\n error?: string;\n }> {\n const { serverUrl } = this.config;\n const url = `${serverUrl}/${orbitalName}`;\n\n try {\n const response = await this.fetchFn(url);\n const data = (await response.json()) as {\n success: boolean;\n orbital?: { traits: Array<{ name: string; currentState: string }> };\n error?: string;\n };\n\n if (data.success && data.orbital) {\n const states: Record<string, string> = {};\n for (const trait of data.orbital.traits) {\n states[trait.name] = trait.currentState;\n }\n return { success: true, states };\n }\n\n return { success: false, error: data.error };\n } catch (error) {\n return { success: false, error: String(error) };\n }\n }\n\n // ==========================================================================\n // Utilities\n // ==========================================================================\n\n private log(\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n data?: unknown,\n ): void {\n if (!this.config.debug && level === \"debug\") return;\n\n const prefix = \"[ServerBridge]\";\n const logFn =\n level === \"error\"\n ? console.error\n : level === \"warn\"\n ? console.warn\n : console.log;\n logFn(prefix, message, data !== undefined ? data : \"\");\n }\n}\n\n/**\n * Create a ServerBridge instance\n */\nexport function createServerBridge(config: ServerBridgeConfig): ServerBridge {\n return new ServerBridge(config);\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { resolveBinding, evaluate, createMinimalContext, evaluateGuard } from '@almadar/evaluator';
2
2
  export { createMinimalContext } from '@almadar/evaluator';
3
3
  import { isKnownOperator } from '@almadar/operators';
4
- import { OrbitalSchemaSchema, isEntityReference, parseEntityRef, parseImportedTraitRef, isPageReference, isPageReferenceString, isPageReferenceObject, parsePageRef } from '@almadar/core';
4
+ import { OrbitalSchemaSchema, isEntityCall, isEntityReference, parseEntityRef, parseImportedTraitRef, isPageReference, isPageReferenceString, isPageReferenceObject, parsePageRef } from '@almadar/core';
5
5
 
6
6
  // src/EventBus.ts
7
7
  var EventBus = class {
@@ -266,7 +266,7 @@ function extractBindings(value) {
266
266
  collect(value);
267
267
  return [...new Set(bindings)];
268
268
  }
269
- function createContextFromBindings(bindings, strictBindings) {
269
+ function createContextFromBindings(bindings, strictBindings, contextExtensions) {
270
270
  const ctx = createMinimalContext(
271
271
  bindings.entity || {},
272
272
  bindings.payload || {},
@@ -280,6 +280,9 @@ function createContextFromBindings(bindings, strictBindings) {
280
280
  ctx.singletons.set(key, value);
281
281
  }
282
282
  }
283
+ if (contextExtensions) {
284
+ Object.assign(ctx, contextExtensions);
285
+ }
283
286
  return ctx;
284
287
  }
285
288
  var smLog = createLogger("almadar:runtime:sm");
@@ -324,7 +327,8 @@ function processEvent(options) {
324
327
  payload,
325
328
  entityData,
326
329
  guardMode = "permissive",
327
- strictBindings = false
330
+ strictBindings = false,
331
+ contextExtensions
328
332
  } = options;
329
333
  const normalizedEvent = normalizeEventKey(eventKey);
330
334
  const transition = findTransition(trait, traitState.currentState, normalizedEvent);
@@ -343,7 +347,7 @@ function processEvent(options) {
343
347
  entity: entityData,
344
348
  payload,
345
349
  state: traitState.currentState
346
- }, strictBindings);
350
+ }, strictBindings, contextExtensions);
347
351
  try {
348
352
  const guardPasses = evaluateGuard(
349
353
  transition.guard,
@@ -474,7 +478,8 @@ var StateMachineManager = class {
474
478
  payload,
475
479
  entityData,
476
480
  guardMode: this.config.guardMode,
477
- strictBindings: this.config.strictBindings
481
+ strictBindings: this.config.strictBindings,
482
+ contextExtensions: this.config.contextExtensions
478
483
  });
479
484
  if (result.executed) {
480
485
  this.states.set(traitName, {
@@ -544,7 +549,8 @@ var StateMachineManager = class {
544
549
  payload: entry.payload,
545
550
  entityData: entry.entityData,
546
551
  guardMode: this.config.guardMode,
547
- strictBindings: this.config.strictBindings
552
+ strictBindings: this.config.strictBindings,
553
+ contextExtensions: this.config.contextExtensions
548
554
  });
549
555
  if (result.executed) {
550
556
  this.states.set(traitName, {
@@ -638,8 +644,8 @@ function parseEffect(effect) {
638
644
  }
639
645
  return { operator, args };
640
646
  }
641
- function resolveArgs(args, bindings, strictBindings) {
642
- const ctx = createContextFromBindings(bindings, strictBindings);
647
+ function resolveArgs(args, bindings, strictBindings, contextExtensions) {
648
+ const ctx = createContextFromBindings(bindings, strictBindings, contextExtensions);
643
649
  return args.map((arg) => interpolateValue(arg, ctx));
644
650
  }
645
651
  var EffectExecutor = class {
@@ -648,12 +654,14 @@ var EffectExecutor = class {
648
654
  context;
649
655
  debug;
650
656
  strictBindings;
657
+ contextExtensions;
651
658
  constructor(options) {
652
659
  this.handlers = options.handlers;
653
660
  this.bindings = options.bindings;
654
661
  this.context = options.context;
655
662
  this.debug = options.debug ?? false;
656
663
  this.strictBindings = options.strictBindings ?? false;
664
+ this.contextExtensions = options.contextExtensions;
657
665
  }
658
666
  // ==========================================================================
659
667
  // Handler Manifest Validation (RCG-03)
@@ -714,7 +722,11 @@ var EffectExecutor = class {
714
722
  "deref": this.handlers.deref,
715
723
  "swap!": this.handlers.swap,
716
724
  "watch": this.handlers.watch,
717
- "atomic": this.handlers.atomic
725
+ "atomic": this.handlers.atomic,
726
+ "behavior/compose": this.handlers.composeBehaviors,
727
+ "behavior/wire": this.handlers.applyEventWiring,
728
+ "behavior/detect-layout": this.handlers.detectLayoutStrategy,
729
+ "behavior/pipe": this.handlers.pipeBehaviors
718
730
  };
719
731
  for (const [name, handler] of Object.entries(handlerMap)) {
720
732
  if (handler) {
@@ -737,7 +749,7 @@ var EffectExecutor = class {
737
749
  }
738
750
  const { operator, args } = parsed;
739
751
  const isCompound = operator === "do" || operator === "when";
740
- const resolvedArgs = isCompound ? args : resolveArgs(args, this.bindings, this.strictBindings);
752
+ const resolvedArgs = isCompound ? args : resolveArgs(args, this.bindings, this.strictBindings, this.contextExtensions);
741
753
  effectLog.debug("execute", { operator, argCount: resolvedArgs.length, context: this.context.traitName });
742
754
  if (this.debug) {
743
755
  console.log("[EffectExecutor] Executing:", operator, resolvedArgs);
@@ -791,7 +803,7 @@ var EffectExecutor = class {
791
803
  const start = Date.now();
792
804
  const { operator, args: rawArgs } = parsed;
793
805
  const isCompound = operator === "do" || operator === "when";
794
- const resolvedArgs = isCompound ? rawArgs : resolveArgs(rawArgs, this.bindings, this.strictBindings);
806
+ const resolvedArgs = isCompound ? rawArgs : resolveArgs(rawArgs, this.bindings, this.strictBindings, this.contextExtensions);
795
807
  try {
796
808
  await this.dispatch(operator, resolvedArgs);
797
809
  results.push({
@@ -995,7 +1007,7 @@ var EffectExecutor = class {
995
1007
  break;
996
1008
  }
997
1009
  case "when": {
998
- const ctx = createContextFromBindings(this.bindings);
1010
+ const ctx = createContextFromBindings(this.bindings, false, this.contextExtensions);
999
1011
  const condition = interpolateValue(args[0], ctx);
1000
1012
  const thenEffect = args[1];
1001
1013
  const elseEffect = args[2];
@@ -1073,6 +1085,48 @@ var EffectExecutor = class {
1073
1085
  }
1074
1086
  break;
1075
1087
  }
1088
+ // === Composition operators (compile-time, optional) ===
1089
+ case "behavior/compose": {
1090
+ if (this.handlers.composeBehaviors) {
1091
+ const config = args[0];
1092
+ await this.handlers.composeBehaviors(config);
1093
+ } else {
1094
+ this.logUnsupported("behavior/compose");
1095
+ }
1096
+ break;
1097
+ }
1098
+ case "behavior/wire": {
1099
+ if (this.handlers.applyEventWiring) {
1100
+ const wireOrbitals = args[0];
1101
+ const wireEntries = args[1];
1102
+ await this.handlers.applyEventWiring(wireOrbitals, wireEntries);
1103
+ } else {
1104
+ this.logUnsupported("behavior/wire");
1105
+ }
1106
+ break;
1107
+ }
1108
+ case "behavior/detect-layout": {
1109
+ if (this.handlers.detectLayoutStrategy) {
1110
+ const layoutOrbitals = args[0];
1111
+ const layoutWiring = args[1];
1112
+ await this.handlers.detectLayoutStrategy(layoutOrbitals, layoutWiring);
1113
+ } else {
1114
+ this.logUnsupported("behavior/detect-layout");
1115
+ }
1116
+ break;
1117
+ }
1118
+ case "behavior/pipe": {
1119
+ if (this.handlers.pipeBehaviors) {
1120
+ const [pipeSeed, ...pipeSteps] = args;
1121
+ await this.handlers.pipeBehaviors(
1122
+ pipeSeed,
1123
+ ...pipeSteps
1124
+ );
1125
+ } else {
1126
+ this.logUnsupported("behavior/pipe");
1127
+ }
1128
+ break;
1129
+ }
1076
1130
  default: {
1077
1131
  if (this.debug) {
1078
1132
  console.warn("[EffectExecutor] Unknown operator:", operator);
@@ -1462,7 +1516,7 @@ async function getExternalLoaderModule() {
1462
1516
  return null;
1463
1517
  }
1464
1518
  try {
1465
- externalLoaderModule = await import('./external-loader-FJVQACFN.js');
1519
+ externalLoaderModule = await import('./external-loader-UBJ6VRW5.js');
1466
1520
  return externalLoaderModule;
1467
1521
  } catch {
1468
1522
  return null;
@@ -1731,7 +1785,7 @@ var ReferenceResolver = class {
1731
1785
  if (this.loader || this.loaderInitialized) return;
1732
1786
  this.loaderInitialized = true;
1733
1787
  try {
1734
- const { ExternalOrbitalLoader } = await import('./external-loader-FJVQACFN.js');
1788
+ const { ExternalOrbitalLoader } = await import('./external-loader-UBJ6VRW5.js');
1735
1789
  this.loader = new ExternalOrbitalLoader(this.options);
1736
1790
  } catch {
1737
1791
  }
@@ -1836,6 +1890,21 @@ var ReferenceResolver = class {
1836
1890
  * Resolve entity reference.
1837
1891
  */
1838
1892
  resolveEntity(entityRef, imports) {
1893
+ if (isEntityCall(entityRef)) {
1894
+ const fallbackName = entityRef.name ?? entityRef.extends.replace(/\.entity$/, "");
1895
+ return {
1896
+ success: true,
1897
+ data: {
1898
+ entity: {
1899
+ name: fallbackName,
1900
+ fields: entityRef.fields ?? [],
1901
+ ...entityRef.persistence ? { persistence: entityRef.persistence } : {},
1902
+ ...entityRef.collection ? { collection: entityRef.collection } : {}
1903
+ }
1904
+ },
1905
+ warnings: []
1906
+ };
1907
+ }
1839
1908
  if (!isEntityReference(entityRef)) {
1840
1909
  return {
1841
1910
  success: true,
@@ -1889,6 +1958,15 @@ var ReferenceResolver = class {
1889
1958
  if (typeof entityRef === "string") {
1890
1959
  return null;
1891
1960
  }
1961
+ if (isEntityCall(entityRef)) {
1962
+ const fallbackName = entityRef.name ?? entityRef.extends.replace(/\.entity$/, "");
1963
+ return {
1964
+ name: fallbackName,
1965
+ fields: entityRef.fields ?? [],
1966
+ ...entityRef.persistence ? { persistence: entityRef.persistence } : {},
1967
+ ...entityRef.collection ? { collection: entityRef.collection } : {}
1968
+ };
1969
+ }
1892
1970
  return entityRef;
1893
1971
  }
1894
1972
  /**
@@ -2315,5 +2393,5 @@ function parseNamespacedEvent(eventName) {
2315
2393
  }
2316
2394
 
2317
2395
  export { EffectExecutor, EventBus, HANDLER_MANIFEST, StateMachineManager, containsBindings, createContextFromBindings, createInitialTraitState, createTestExecutor, createUnifiedLoader, extractBindings, findInitialState, findTransition, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isNamespacedEvent, normalizeEventKey, parseNamespacedEvent, preprocessSchema, processEvent };
2318
- //# sourceMappingURL=chunk-ESNML4B4.js.map
2319
- //# sourceMappingURL=chunk-ESNML4B4.js.map
2396
+ //# sourceMappingURL=chunk-HIM4HJAN.js.map
2397
+ //# sourceMappingURL=chunk-HIM4HJAN.js.map