@almadar/runtime 2.4.1 → 2.6.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,5 @@
1
- import { I as IEventBus } from './types-BrbvZxzX.js';
1
+ import { I as IEventBus } from './types-DYcUvi4H.js';
2
+ import { EventPayload } from '@almadar/core';
2
3
 
3
4
  /**
4
5
  * ServerBridge - Client-Server Trait Communication
@@ -91,7 +92,7 @@ declare class ServerBridge {
91
92
  /**
92
93
  * Send an event directly to a specific orbital (bypassing EventBus)
93
94
  */
94
- sendEvent(orbitalName: string, event: string, payload?: Record<string, unknown>): Promise<{
95
+ sendEvent(orbitalName: string, event: string, payload?: EventPayload): Promise<{
95
96
  success: boolean;
96
97
  states?: Record<string, string>;
97
98
  emittedEvents?: Array<{
@@ -1 +1 @@
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 } 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?: Record<string, unknown> }>;\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?: Record<string, unknown>,\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"]}
@@ -130,6 +130,53 @@ var EventBus = class {
130
130
  return this.listeners.get(type)?.size ?? 0;
131
131
  }
132
132
  };
133
+
134
+ // src/logger.ts
135
+ var LEVEL_PRIORITY = { DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3 };
136
+ var ENV = typeof process !== "undefined" && process.env ? process.env : {};
137
+ var NODE_ENV = ENV.NODE_ENV ?? "development";
138
+ var CONFIGURED_LEVEL = (ENV.LOG_LEVEL ?? (NODE_ENV === "production" ? "info" : "debug")).toUpperCase();
139
+ var MIN_PRIORITY = LEVEL_PRIORITY[CONFIGURED_LEVEL] ?? 0;
140
+ var DEBUG_FILTER = (ENV.ALMADAR_DEBUG ?? "").split(",").map((s) => s.trim()).filter(Boolean);
141
+ function matchesNamespace(namespace) {
142
+ if (DEBUG_FILTER.length === 0) return true;
143
+ return DEBUG_FILTER.some((pattern) => {
144
+ if (pattern === "*" || pattern === "almadar:*") return true;
145
+ if (pattern.endsWith(":*")) return namespace.startsWith(pattern.slice(0, -1));
146
+ return namespace === pattern;
147
+ });
148
+ }
149
+ function createLogger(namespace) {
150
+ const nsAllowed = matchesNamespace(namespace);
151
+ const log = (level, message, data) => {
152
+ if (LEVEL_PRIORITY[level] < MIN_PRIORITY) return;
153
+ if (level === "DEBUG" && !nsAllowed) return;
154
+ const prefix = `[${namespace}]`;
155
+ switch (level) {
156
+ case "DEBUG":
157
+ console.debug(prefix, message, data ?? "");
158
+ break;
159
+ case "INFO":
160
+ console.info(prefix, message, data ?? "");
161
+ break;
162
+ case "WARN":
163
+ console.warn(prefix, message, data ?? "");
164
+ break;
165
+ case "ERROR":
166
+ console.error(prefix, message, data ?? "");
167
+ break;
168
+ }
169
+ };
170
+ return {
171
+ debug: (msg, data) => log("DEBUG", msg, data),
172
+ info: (msg, data) => log("INFO", msg, data),
173
+ warn: (msg, data) => log("WARN", msg, data),
174
+ error: (msg, data) => log("ERROR", msg, data)
175
+ };
176
+ }
177
+
178
+ // src/BindingResolver.ts
179
+ var bindLog = createLogger("almadar:runtime:bindings");
133
180
  function interpolateProps(props, ctx) {
134
181
  const result = {};
135
182
  for (const [key, value] of Object.entries(props)) {
@@ -154,7 +201,9 @@ function interpolateValue(value, ctx) {
154
201
  }
155
202
  function interpolateString(value, ctx) {
156
203
  if (value.startsWith("@") && isPureBinding(value)) {
157
- return resolveBinding(value, ctx);
204
+ const resolved = resolveBinding(value, ctx);
205
+ bindLog.debug("resolve", { binding: value, resolvedType: typeof resolved });
206
+ return resolved;
158
207
  }
159
208
  if (value.includes("@")) {
160
209
  return interpolateEmbeddedBindings(value, ctx);
@@ -233,6 +282,7 @@ function createContextFromBindings(bindings, strictBindings) {
233
282
  }
234
283
  return ctx;
235
284
  }
285
+ var smLog = createLogger("almadar:runtime:sm");
236
286
  function findInitialState(trait) {
237
287
  if (!trait.states || trait.states.length === 0) {
238
288
  console.warn(`[StateMachine] Trait "${trait.name}" has no states defined, using "unknown"`);
@@ -279,6 +329,7 @@ function processEvent(options) {
279
329
  const normalizedEvent = normalizeEventKey(eventKey);
280
330
  const transition = findTransition(trait, traitState.currentState, normalizedEvent);
281
331
  if (!transition) {
332
+ smLog.debug("noTransition", { trait: trait.name, event: normalizedEvent, currentState: traitState.currentState });
282
333
  return {
283
334
  executed: false,
284
335
  newState: traitState.currentState,
@@ -286,6 +337,7 @@ function processEvent(options) {
286
337
  effects: []
287
338
  };
288
339
  }
340
+ smLog.debug("processEvent", { trait: trait.name, event: normalizedEvent, currentState: traitState.currentState, to: transition.to });
289
341
  if (transition.guard) {
290
342
  const ctx = createContextFromBindings({
291
343
  entity: entityData,
@@ -297,6 +349,7 @@ function processEvent(options) {
297
349
  transition.guard,
298
350
  ctx
299
351
  );
352
+ smLog.debug("guard:evaluate", { trait: trait.name, event: normalizedEvent, guardResult: guardPasses });
300
353
  if (!guardPasses) {
301
354
  return {
302
355
  executed: false,
@@ -574,6 +627,7 @@ var HANDLER_MANIFEST = {
574
627
  };
575
628
 
576
629
  // src/EffectExecutor.ts
630
+ var effectLog = createLogger("almadar:runtime:effects");
577
631
  function parseEffect(effect) {
578
632
  if (!Array.isArray(effect) || effect.length === 0) {
579
633
  return null;
@@ -684,12 +738,15 @@ var EffectExecutor = class {
684
738
  const { operator, args } = parsed;
685
739
  const isCompound = operator === "do" || operator === "when";
686
740
  const resolvedArgs = isCompound ? args : resolveArgs(args, this.bindings, this.strictBindings);
741
+ effectLog.debug("execute", { operator, argCount: resolvedArgs.length, context: this.context.traitName });
687
742
  if (this.debug) {
688
743
  console.log("[EffectExecutor] Executing:", operator, resolvedArgs);
689
744
  }
690
745
  try {
691
746
  await this.dispatch(operator, resolvedArgs);
747
+ effectLog.debug("execute:result", { operator, success: true });
692
748
  } catch (error) {
749
+ effectLog.warn("execute:error", { operator, error: error instanceof Error ? error.message : String(error) });
693
750
  console.error("[EffectExecutor] Error executing effect:", operator, error);
694
751
  throw error;
695
752
  }
@@ -2258,5 +2315,5 @@ function parseNamespacedEvent(eventName) {
2258
2315
  }
2259
2316
 
2260
2317
  export { EffectExecutor, EventBus, HANDLER_MANIFEST, StateMachineManager, containsBindings, createContextFromBindings, createInitialTraitState, createTestExecutor, createUnifiedLoader, extractBindings, findInitialState, findTransition, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isNamespacedEvent, normalizeEventKey, parseNamespacedEvent, preprocessSchema, processEvent };
2261
- //# sourceMappingURL=chunk-ATXSXMQQ.js.map
2262
- //# sourceMappingURL=chunk-ATXSXMQQ.js.map
2318
+ //# sourceMappingURL=chunk-ESNML4B4.js.map
2319
+ //# sourceMappingURL=chunk-ESNML4B4.js.map