@aspectly/core 0.1.0 → 2.0.8

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.
@@ -123,6 +123,20 @@ declare class BridgeInternal {
123
123
  private readonly sendEvent;
124
124
  private readonly timeout;
125
125
  constructor(sendEvent: InternalEventSender, options?: BridgeOptions);
126
+ /**
127
+ * Reset bridge state for a new connection context.
128
+ * Call this when the remote side has changed (e.g., new popup window).
129
+ */
130
+ reset: () => void;
131
+ /**
132
+ * Register a single handler for a method.
133
+ * Can be called before or after init().
134
+ */
135
+ registerHandler: (method: string, handler: BridgeHandler) => void;
136
+ /**
137
+ * Remove a previously registered handler.
138
+ */
139
+ unregisterHandler: (method: string) => void;
126
140
  /**
127
141
  * Subscribe to all result events
128
142
  */
@@ -201,12 +215,28 @@ declare class BridgeBase {
201
215
  * @param listener The listener to remove
202
216
  */
203
217
  unsubscribe: (listener: BridgeListener) => void;
218
+ /**
219
+ * Register a single handler for a method.
220
+ * Can be called before or after init().
221
+ * @param method Method name to handle
222
+ * @param handler Async function to handle the method
223
+ */
224
+ registerHandler: (method: string, handler: BridgeHandler) => void;
225
+ /**
226
+ * Remove a previously registered handler.
227
+ * @param method Method name to remove
228
+ */
229
+ unregisterHandler: (method: string) => void;
204
230
  /**
205
231
  * Initialize the bridge with handlers
206
232
  * @param handlers Map of method names to handler functions
207
233
  * @returns Promise resolving when initialization is complete
208
234
  */
209
235
  init: (handlers?: BridgeHandlers) => Promise<boolean>;
236
+ /**
237
+ * Reset bridge state for a new connection context
238
+ */
239
+ reset: () => void;
210
240
  }
211
241
 
212
242
  /**
@@ -123,6 +123,20 @@ declare class BridgeInternal {
123
123
  private readonly sendEvent;
124
124
  private readonly timeout;
125
125
  constructor(sendEvent: InternalEventSender, options?: BridgeOptions);
126
+ /**
127
+ * Reset bridge state for a new connection context.
128
+ * Call this when the remote side has changed (e.g., new popup window).
129
+ */
130
+ reset: () => void;
131
+ /**
132
+ * Register a single handler for a method.
133
+ * Can be called before or after init().
134
+ */
135
+ registerHandler: (method: string, handler: BridgeHandler) => void;
136
+ /**
137
+ * Remove a previously registered handler.
138
+ */
139
+ unregisterHandler: (method: string) => void;
126
140
  /**
127
141
  * Subscribe to all result events
128
142
  */
@@ -201,12 +215,28 @@ declare class BridgeBase {
201
215
  * @param listener The listener to remove
202
216
  */
203
217
  unsubscribe: (listener: BridgeListener) => void;
218
+ /**
219
+ * Register a single handler for a method.
220
+ * Can be called before or after init().
221
+ * @param method Method name to handle
222
+ * @param handler Async function to handle the method
223
+ */
224
+ registerHandler: (method: string, handler: BridgeHandler) => void;
225
+ /**
226
+ * Remove a previously registered handler.
227
+ * @param method Method name to remove
228
+ */
229
+ unregisterHandler: (method: string) => void;
204
230
  /**
205
231
  * Initialize the bridge with handlers
206
232
  * @param handlers Map of method names to handler functions
207
233
  * @returns Promise resolving when initialization is complete
208
234
  */
209
235
  init: (handlers?: BridgeHandlers) => Promise<boolean>;
236
+ /**
237
+ * Reset bridge state for a new connection context
238
+ */
239
+ reset: () => void;
210
240
  }
211
241
 
212
242
  /**
@@ -1,4 +1,4 @@
1
- import { A as AspectlyBridge } from './AspectlyBridge-hGuDjcI6.mjs';
1
+ import { A as AspectlyBridge } from './AspectlyBridge-sN8ppiCb.mjs';
2
2
 
3
3
  /**
4
4
  * Browser entry point for direct script inclusion.
package/dist/browser.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as AspectlyBridge } from './AspectlyBridge-hGuDjcI6.js';
1
+ import { A as AspectlyBridge } from './AspectlyBridge-sN8ppiCb.js';
2
2
 
3
3
  /**
4
4
  * Browser entry point for direct script inclusion.
package/dist/browser.js CHANGED
@@ -1,9 +1,39 @@
1
1
  'use strict';
2
2
 
3
+ var transports = require('@aspectly/transports');
4
+
3
5
  // src/BridgeCore.ts
4
6
  var _BridgeCore = class _BridgeCore {
7
+ /**
8
+ * Get the current transport (lazy initialization)
9
+ */
10
+ static getTransport() {
11
+ if (!_BridgeCore.transport) {
12
+ _BridgeCore.transport = transports.detectTransport();
13
+ }
14
+ return _BridgeCore.transport;
15
+ }
16
+ /**
17
+ * Set a custom transport (useful for testing or manual configuration)
18
+ */
19
+ static setTransport(transport) {
20
+ _BridgeCore.transport = transport;
21
+ }
22
+ /**
23
+ * Reset transport to auto-detect on next use
24
+ */
25
+ static resetTransport() {
26
+ _BridgeCore.transport = null;
27
+ }
28
+ /**
29
+ * Get the name of the current transport
30
+ */
31
+ static getTransportName() {
32
+ return _BridgeCore.getTransport().name;
33
+ }
5
34
  };
6
35
  _BridgeCore.BRIDGE_EVENT_TYPE = "BridgeEvent";
36
+ _BridgeCore.transport = null;
7
37
  _BridgeCore.isJSONObject = (str) => {
8
38
  return str.startsWith("{") && str.endsWith("}");
9
39
  };
@@ -43,60 +73,21 @@ _BridgeCore.wrapListener = (listener) => (data) => {
43
73
  }
44
74
  };
45
75
  /**
46
- * Creates a browser-specific message event listener
47
- */
48
- _BridgeCore.browserListener = (listener) => {
49
- const triggerEvent = _BridgeCore.wrapListener(listener);
50
- return (originalEvent) => {
51
- if (!originalEvent?.data) {
52
- return;
53
- }
54
- triggerEvent(originalEvent.data);
55
- };
56
- };
57
- /**
58
- * Creates a React Native WebView message listener
59
- */
60
- _BridgeCore.webViewListener = (listener) => {
61
- const triggerEvent = _BridgeCore.wrapListener(listener);
62
- return (originalEvent) => {
63
- if (!originalEvent?.nativeEvent?.data) {
64
- return;
65
- }
66
- triggerEvent(originalEvent.nativeEvent.data);
67
- };
68
- };
69
- /**
70
- * Sends an event to the parent context (WebView or iframe parent)
76
+ * Sends an event to the parent context using the detected transport
71
77
  */
72
78
  _BridgeCore.sendEvent = (event) => {
73
79
  const bridgeEvent = _BridgeCore.wrapBridgeEvent(event);
74
- if (typeof window === "undefined") {
75
- console.warn("Window is undefined");
76
- return;
77
- }
78
- const RNW = window.ReactNativeWebView;
79
- if (typeof RNW?.postMessage === "function") {
80
- RNW.postMessage(`'${bridgeEvent}'`);
81
- return;
82
- }
83
- if (window.parent === window) {
84
- return;
85
- }
86
- window.parent.postMessage(bridgeEvent, "*");
80
+ const transport = _BridgeCore.getTransport();
81
+ transport.send(bridgeEvent);
87
82
  };
88
83
  /**
89
- * Subscribes to window message events
84
+ * Subscribes to incoming messages via the detected transport
90
85
  * @returns Cleanup function to unsubscribe
91
86
  */
92
87
  _BridgeCore.subscribe = (listener) => {
93
- const browserListener = _BridgeCore.browserListener(listener);
94
- if (typeof window === "undefined" || !window.addEventListener) {
95
- return () => {
96
- };
97
- }
98
- window.addEventListener("message", browserListener);
99
- return () => window.removeEventListener("message", browserListener);
88
+ const transport = _BridgeCore.getTransport();
89
+ const wrappedListener = _BridgeCore.wrapListener(listener);
90
+ return transport.subscribe(wrappedListener);
100
91
  };
101
92
  var BridgeCore = _BridgeCore;
102
93
 
@@ -114,6 +105,29 @@ var BridgeInternal = class {
114
105
  this.available = false;
115
106
  this.supportedMethods = [];
116
107
  this.listeners = [];
108
+ /**
109
+ * Reset bridge state for a new connection context.
110
+ * Call this when the remote side has changed (e.g., new popup window).
111
+ */
112
+ this.reset = () => {
113
+ this.handlers = {};
114
+ this.available = false;
115
+ this.supportedMethods = [];
116
+ this.initPromise = void 0;
117
+ };
118
+ /**
119
+ * Register a single handler for a method.
120
+ * Can be called before or after init().
121
+ */
122
+ this.registerHandler = (method, handler) => {
123
+ this.handlers[method] = handler;
124
+ };
125
+ /**
126
+ * Remove a previously registered handler.
127
+ */
128
+ this.unregisterHandler = (method) => {
129
+ delete this.handlers[method];
130
+ };
117
131
  /**
118
132
  * Subscribe to all result events
119
133
  */
@@ -361,12 +375,32 @@ var BridgeBase = class {
361
375
  this.unsubscribe = (listener) => {
362
376
  return this.bridge.unsubscribe(listener);
363
377
  };
378
+ /**
379
+ * Register a single handler for a method.
380
+ * Can be called before or after init().
381
+ * @param method Method name to handle
382
+ * @param handler Async function to handle the method
383
+ */
384
+ this.registerHandler = (method, handler) => {
385
+ this.bridge.registerHandler(method, handler);
386
+ };
387
+ /**
388
+ * Remove a previously registered handler.
389
+ * @param method Method name to remove
390
+ */
391
+ this.unregisterHandler = (method) => {
392
+ this.bridge.unregisterHandler(method);
393
+ };
364
394
  /**
365
395
  * Initialize the bridge with handlers
366
396
  * @param handlers Map of method names to handler functions
367
397
  * @returns Promise resolving when initialization is complete
368
398
  */
369
399
  this.init = (handlers) => this.bridge.init(handlers);
400
+ /**
401
+ * Reset bridge state for a new connection context
402
+ */
403
+ this.reset = () => this.bridge.reset();
370
404
  this.bridge = bridge;
371
405
  }
372
406
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/BridgeCore.ts","../src/BridgeInternal.ts","../src/BridgeBase.ts","../src/AspectlyBridge.ts","../src/browser.ts"],"names":[],"mappings":";;;AA+BO,IAAM,WAAA,GAAN,MAAM,WAAA,CAAW;AA0GxB,CAAA;AA1Ga,WAAA,CACI,iBAAA,GAAoB,aAAA;AADxB,WAAA,CAGI,YAAA,GAAe,CAAC,GAAA,KAAyB;AACtD,EAAA,OAAO,IAAI,UAAA,CAAW,GAAG,CAAA,IAAK,GAAA,CAAI,SAAS,GAAG,CAAA;AAChD,CAAA;AAAA;AAAA;AAAA;AALW,WAAA,CAUG,eAAA,GAAkB,CAAC,KAAA,KAAyB;AACxD,EAAA,OAAO,KAAK,SAAA,CAAU;AAAA,IACpB,KAAA;AAAA,IACA,MAAM,WAAA,CAAW;AAAA,GAClB,CAAA;AACH,CAAA;AAAA;AAAA;AAAA;AAfW,WAAA,CAoBJ,YAAA,GACL,CAAC,QAAA,KACD,CAAC,IAAA,KAAwB;AACvB,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA;AAAA,EACF;AACA,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA;AAAA,EACF;AACA,EAAA,IAAI,aAAA,GAAgB,IAAA;AAEpB,EAAA,IAAI,cAAc,UAAA,CAAW,GAAG,KAAK,aAAA,CAAc,QAAA,CAAS,GAAG,CAAA,EAAG;AAChE,IAAA,aAAA,GAAgB,aAAA,CAAc,SAAA,CAAU,CAAA,EAAG,aAAA,CAAc,SAAS,CAAC,CAAA;AAAA,EACrE;AACA,EAAA,IAAI,CAAC,WAAA,CAAW,YAAA,CAAa,aAAa,CAAA,EAAG;AAC3C,IAAA;AAAA,EACF;AACA,EAAA,IAAI;AACF,IAAA,MAAM,SAAA,GAA6B,IAAA,CAAK,KAAA,CAAM,aAAa,CAAA;AAC3D,IAAA,IAAI,CAAC,SAAA,IAAa,SAAA,CAAU,IAAA,KAAS,YAAW,iBAAA,EAAmB;AACjE,MAAA;AAAA,IACF;AACA,IAAA,QAAA,CAAS,UAAU,KAAK,CAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AAAA,EAER;AACF,CAAA;AAAA;AAAA;AAAA;AA9CS,WAAA,CAmDJ,eAAA,GAAkB,CAAC,QAAA,KAAiC;AACzD,EAAA,MAAM,YAAA,GAAe,WAAA,CAAW,YAAA,CAAa,QAAQ,CAAA;AACrD,EAAA,OAAO,CAAC,aAAA,KAAsC;AAC5C,IAAA,IAAI,CAAC,eAAe,IAAA,EAAM;AACxB,MAAA;AAAA,IACF;AACA,IAAA,YAAA,CAAa,cAAc,IAAI,CAAA;AAAA,EACjC,CAAA;AACF,CAAA;AAAA;AAAA;AAAA;AA3DW,WAAA,CAgEJ,eAAA,GAAkB,CAAC,QAAA,KAAiC;AACzD,EAAA,MAAM,YAAA,GAAe,WAAA,CAAW,YAAA,CAAa,QAAQ,CAAA;AACrD,EAAA,OAAO,CAAC,aAAA,KAAwC;AAC9C,IAAA,IAAI,CAAC,aAAA,EAAe,WAAA,EAAa,IAAA,EAAM;AACrC,MAAA;AAAA,IACF;AACA,IAAA,YAAA,CAAa,aAAA,CAAc,YAAY,IAAI,CAAA;AAAA,EAC7C,CAAA;AACF,CAAA;AAAA;AAAA;AAAA;AAxEW,WAAA,CA6EJ,SAAA,GAAY,CAAC,KAAA,KAAuB;AACzC,EAAA,MAAM,WAAA,GAAc,WAAA,CAAW,eAAA,CAAgB,KAAK,CAAA;AACpD,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,OAAA,CAAQ,KAAK,qBAAqB,CAAA;AAClC,IAAA;AAAA,EACF;AACA,EAAA,MAAM,MAAM,MAAA,CAAO,kBAAA;AACnB,EAAA,IAAI,OAAO,GAAA,EAAK,WAAA,KAAgB,UAAA,EAAY;AAC1C,IAAA,GAAA,CAAI,WAAA,CAAY,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA,CAAG,CAAA;AAClC,IAAA;AAAA,EACF;AACA,EAAA,IAAI,MAAA,CAAO,WAAW,MAAA,EAAQ;AAC5B,IAAA;AAAA,EACF;AACA,EAAA,MAAA,CAAO,MAAA,CAAO,WAAA,CAAY,WAAA,EAAa,GAAG,CAAA;AAC5C,CAAA;AAAA;AAAA;AAAA;AAAA;AA5FW,WAAA,CAkGJ,SAAA,GAAY,CAAC,QAAA,KAA+C;AACjE,EAAA,MAAM,eAAA,GAAkB,WAAA,CAAW,eAAA,CAAgB,QAAQ,CAAA;AAC3D,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,CAAC,OAAO,gBAAA,EAAkB;AAC7D,IAAA,OAAO,MAAM;AAAA,IAAC,CAAA;AAAA,EAChB;AACA,EAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,eAAe,CAAA;AAClD,EAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,eAAe,CAAA;AACpE,CAAA;AAzGK,IAAM,UAAA,GAAN,WAAA;;;ACTA,IAAM,aAAA,GAAgB,CAC3B,IAAA,EACA,IAAA,MACiB;AAAA,EACjB,IAAA;AAAA,EACA;AACF,CAAA,CAAA;AAKO,IAAM,mBAAA,GAAsB,CAAC,IAAA,KAClC,aAAA,CAAA,QAAA,eAAsC,IAAI,CAAA;AAc5C,IAAM,eAAA,GAAkB,GAAA;AAMjB,IAAM,iBAAN,MAAqB;AAAA,EAU1B,WAAA,CAAY,WAAgC,OAAA,EAAyB;AATrE,IAAA,IAAA,CAAQ,WAAqC,EAAC;AAC9C,IAAA,IAAA,CAAQ,WAA2B,EAAC;AACpC,IAAA,IAAA,CAAQ,SAAA,GAAY,KAAA;AACpB,IAAA,IAAA,CAAQ,mBAA6B,EAAC;AACtC,IAAA,IAAA,CAAQ,YAA8B,EAAC;AAavC;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,SAAA,GAAY,CAAC,QAAA,KAAqC;AACvD,MAAA,OAAO,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,QAAQ,CAAA;AAAA,IACrC,CAAA;AAKA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,WAAA,GAAc,CAAC,QAAA,KAAmC;AACvD,MAAA,IAAA,CAAK,SAAA,GAAY,KAAK,SAAA,CAAU,MAAA;AAAA,QAC9B,CAAC,gBAAgB,WAAA,KAAgB;AAAA,OACnC;AAAA,IACF,CAAA;AAEA,IAAA,IAAA,CAAQ,SAAA,GAAY,CAAC,CAAA,EAAa,CAAA,KAAyB;AACzD,MAAA,OACE,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA,CAAE,MAAA,GAAS,KACzC,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,EAAE,QAAA,CAAS,CAAC,CAAC,CAAA,CAAE,MAAA,GAAS,CAAA;AAAA,IAE7C,CAAA;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,IAAA,GAAO,CAAC,QAAA,GAA2B,EAAC,KAAwB;AACjE,MAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA;AAC5C,MAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA;AACvC,MAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,MAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,UAAA,EAAY,UAAU,CAAA,EAAG;AAC3C,QAAA,OAAO,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,MAC7B;AACA,MAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,QAAA,IAAA,CAAK,WAAA,GAAc,EAAE,OAAA,EAAS,MAAA,EAAO;AACrC,QAAA,IAAA,CAAK,SAAA;AAAA,UACH,aAAA,CAAA,MAAA,aAAoC;AAAA,YAClC,OAAA,EAAS;AAAA,WACV;AAAA,SACH;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAA;AAKA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,eAAA,GAAkB,CAAC,KAAA,KAA6B;AACrD,MAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAK,GAAI,KAAA;AACvB,MAAA,QAAQ,IAAA;AAAM,QACZ,KAAA,MAAA;AACE,UAAA,IAAA,CAAK,WAAW,IAAuB,CAAA;AACvC,UAAA;AAAA,QACF,KAAA,YAAA;AACE,UAAA,IAAA,CAAK,iBAAiB,IAA6B,CAAA;AACnD,UAAA;AAAA,QACF,KAAA,SAAA;AACE,UAAA,IAAA,CAAK,cAAc,IAA0B,CAAA;AAC7C,UAAA;AAAA,QACF,KAAA,QAAA;AACE,UAAA,IAAA,CAAK,aAAa,IAAyB,CAAA;AAC3C,UAAA;AAAA;AACJ,IACF,CAAA;AAKA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,aAAA,GAAgB,CAAC,OAAA,KAAsC;AAC5D,MAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAQ,UAAA,EAAW,GAAI,OAAA;AACvC,MAAA,IAAI,OAAA,CAA0B,CAAC,OAAA,EAAS,MAAA,KAAW;AACjD,QAAA,IAAI,OAAA,GAAU,KAAA;AACd,QAAA,IAAI,CAAC,OAAO,SAAA,CAAU,cAAA,CAAe,KAAK,IAAA,CAAK,QAAA,EAAU,MAAM,CAAA,EAAG;AAChE,UAAA,MAAA,CAAO;AAAA,YACL,UAAA,EAAA,oBAAA;AAAA,YACA,KAAA,EAAO,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAgB,MAAM,CAAA,sBAAA,CAAqB;AAAA,WAC7D,CAAA;AACD,UAAA;AAAA,QACF;AACA,QAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,UAAA,OAAA,GAAU,IAAA;AACV,UAAA,MAAA,CAAO;AAAA,YACL,UAAA,EAAA,0BAAA;AAAA,YACA,KAAA,EAAO,IAAI,KAAA,CAAM,4BAA4B;AAAA,WAC9C,CAAA;AAAA,QACH,CAAA,EAAG,KAAK,OAAO,CAAA;AACf,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA;AACpC,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,MAAA,CAAO;AAAA,YACL,UAAA,EAAA,oBAAA;AAAA,YACA,KAAA,EAAO,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAgB,MAAM,CAAA,iBAAA,CAAgB;AAAA,WACxD,CAAA;AACD,UAAA;AAAA,QACF;AACA,QAAA,OAAA,CAAQ,MAAM,CAAA,CACX,IAAA,CAAK,CAAC,MAAA,KAAW;AAChB,UAAA,IAAI,OAAA,EAAS;AACX,YAAA;AAAA,UACF;AACA,UAAA,YAAA,CAAa,KAAK,CAAA;AAClB,UAAA,OAAA,CAAQ,MAA0B,CAAA;AAAA,QACpC,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,KAAA,KAAiB;AACvB,UAAA,IAAI,OAAA,EAAS;AACX,YAAA;AAAA,UACF;AACA,UAAA,YAAA,CAAa,KAAK,CAAA;AAClB,UAAA,MAAA,CAAO;AAAA,YACL,UAAA,EAAA,UAAA;AAAA,YACA;AAAA,WACD,CAAA;AAAA,QACH,CAAC,CAAA;AAAA,MACL,CAAC,CAAA,CACE,IAAA,CAAK,CAAC,IAAA,KAA2B;AAChC,QAAA,IAAA,CAAK,SAAA;AAAA,UACH,mBAAA,CAAoB;AAAA,YAClB,IAAA,EAAA,SAAA;AAAA,YACA,IAAA;AAAA,YACA,MAAA;AAAA,YACA;AAAA,WACD;AAAA,SACH;AAAA,MACF,CAAC,CAAA,CACA,KAAA;AAAA,QACC,CAAC;AAAA,UACC,UAAA;AAAA,UACA;AAAA,SACF,KAGM;AACJ,UAAA,IAAA,CAAK,SAAA;AAAA,YACH,mBAAA,CAAoB;AAAA,cAClB,IAAA,EAAA,OAAA;AAAA,cACA,UAAA;AAAA,cACA,MAAA;AAAA,cACA,IAAA,EAAM;AAAA,gBACJ,eAAe,KAAA,CAAM,OAAA;AAAA,gBACrB;AAAA;AACF,aACD;AAAA,WACH;AAAA,QACF;AAAA,OACF;AAAA,IACJ,CAAA;AAEA,IAAA,IAAA,CAAQ,YAAA,GAAe,CAAC,MAAA,KAAoC;AAC1D,MAAA,IAAA,CAAK,oBAAoB,MAAM,CAAA;AAC/B,MAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,CAAC,QAAA,KAAa,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,IACvD,CAAA;AAEA,IAAA,IAAA,CAAQ,mBAAA,GAAsB,CAAC,MAAA,KAAoC;AACjE,MAAA,IAAI,CAAC,UAAU,CAAC,MAAA,CAAO,UAAU,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,YAAY,CAAA,EAAG;AAC1E,QAAA;AAAA,MACF;AACA,MAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,eAAe,IAAA,CAAK,MAAA,EAAQ,MAAM,CAAA,EAAG;AACzD,QAAA,OAAA,CAAQ,IAAA,CAAK,kBAAkB,MAAM,CAAA;AACrC,QAAA;AAAA,MACF;AACA,MAAA,MAAM,EAAE,UAAA,EAAY,IAAA,EAAM,IAAA,EAAK,GAAI,MAAA;AACnC,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,UAAU,CAAC,CAAA;AAChD,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA;AAAA,MACF;AACA,MAAA,IAAI,IAAA,KAAA,SAAA,gBAAmC;AACrC,QAAA,OAAA,CAAQ,QAAQ,IAAI,CAAA;AACpB,QAAA;AAAA,MACF;AACA,MAAA,IAAI,IAAA,KAAA,OAAA,cAAiC;AACnC,QAAA,OAAA,CAAQ,OAAO,IAAyB,CAAA;AAAA,MAC1C;AAAA,IACF,CAAA;AAEA,IAAA,IAAA,CAAQ,UAAA,GAAa,CAAC,IAAA,KAAgC;AACpD,MAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,MAAA,IAAA,CAAK,mBAAmB,IAAA,CAAK,OAAA;AAC7B,MAAA,IAAA,CAAK,SAAA,CAAU,aAAA,CAAA,YAAA,mBAA0C,IAAI,CAAC,CAAA;AAAA,IAChE,CAAA;AAEA,IAAA,IAAA,CAAQ,gBAAA,GAAmB,CAAC,OAAA,KAAyC;AACnE,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,IAAA,CAAK,WAAA,EAAa,QAAQ,IAAI,CAAA;AAAA,MAChC,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,aAAa,MAAA,EAAO;AAAA,MAC3B;AAAA,IACF,CAAA;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,IAAA,GAAO,CACZ,MAAA,EACA,MAAA,KAEA,IAAI,OAAA,CAAQ,CAAC,SAAS,MAAA,KAAW;AAC/B,MAAA,MAAM,UAAA,GAAA,CACJ,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,EAAE,SAAwD,MAAA,EAAQ,CAAA,GAAI,CAAA,EACzF,QAAA,EAAS;AACX,MAAA,IAAI,CAAC,IAAA,CAAK,WAAA,EAAY,EAAG;AACvB,QAAA,IAAA,CAAK,eAAA;AAAA,UACH,mBAAA,CAAoB;AAAA,YAClB,IAAA,EAAA,OAAA;AAAA,YACA,UAAA;AAAA,YACA,MAAA;AAAA,YACA,IAAA,EAAM;AAAA,cACJ,aAAA,EAAe,yBAAA;AAAA,cACf,UAAA,EAAA,sBAAA;AAAA;AACF,WACD;AAAA,SACH;AACA,QAAA;AAAA,MACF;AACA,MAAA,IAAA,CAAK,SAAA;AAAA,QACH,aAAA,CAAA,SAAA,gBAAuC;AAAA,UACrC,MAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACD;AAAA,OACH;AAAA,IACF,CAAC,CAAA;AAKH;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,WAAW,CAAC,MAAA,KACjB,IAAA,CAAK,gBAAA,CAAiB,SAAS,MAAM,CAAA;AAKvC;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,WAAA,GAAc,MAAe,IAAA,CAAK,SAAA;AA9OvC,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,OAAA,GAAU,SAAS,OAAA,IAAW,eAAA;AAAA,EACrC;AA6OF,CAAA;;;ACzSO,IAAM,aAAN,MAAiB;AAAA,EAGtB,YAAY,MAAA,EAAwB;AAQpC;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,WAAW,CAAC,MAAA,KAA4B,IAAA,CAAK,MAAA,CAAO,SAAS,MAAM,CAAA;AAK1E;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,WAAA,GAAc,MAAe,IAAA,CAAK,MAAA,CAAO,WAAA,EAAY;AAQ5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,IAAA,GAAO,CACZ,MAAA,EACA,MAAA,GAAiB,EAAC,KACG;AACrB,MAAA,OAAO,IAAA,CAAK,MAAA,CAAO,IAAA,CAAc,MAAA,EAAQ,MAAM,CAAA;AAAA,IACjD,CAAA;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,SAAA,GAAY,CAAC,QAAA,KAAqC;AACvD,MAAA,OAAO,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,QAAQ,CAAA;AAAA,IACvC,CAAA;AAMA;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,WAAA,GAAc,CAAC,QAAA,KAAmC;AACvD,MAAA,OAAO,IAAA,CAAK,MAAA,CAAO,WAAA,CAAY,QAAQ,CAAA;AAAA,IACzC,CAAA;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,OAAO,CAAC,QAAA,KACb,IAAA,CAAK,MAAA,CAAO,KAAK,QAAQ,CAAA;AAlDzB,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAkDF,CAAA;;;ACpCO,IAAM,cAAA,GAAN,cAA6B,UAAA,CAAW;AAAA,EAG7C,YAAY,OAAA,EAAyB;AACnC,IAAA,MAAM,MAAA,GAAS,IAAI,cAAA,CAAe,UAAA,CAAW,WAAW,OAAO,CAAA;AAC/D,IAAA,KAAA,CAAM,MAAM,CAAA;AASd;AAAA;AAAA;AAAA,IAAA,IAAA,CAAO,UAAU,MAAY;AAC3B,MAAA,IAAA,CAAK,mBAAA,EAAoB;AAAA,IAC3B,CAAA;AAVE,IAAA,IAAA,CAAK,sBAAsB,UAAA,CAAW,SAAA;AAAA,MACpC,MAAA,CAAO;AAAA,KACT;AAAA,EACF;AAQF;;;ACrBA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,EAAA,MAAA,CAAO,cAAA,GAAiB,IAAI,cAAA,EAAe;AAC7C","file":"browser.js","sourcesContent":["/**\n * Low-level bridge core handling platform-specific message passing\n */\n\nexport type Event = unknown;\n\ninterface BridgeCoreEvent {\n type: string;\n event: Event;\n}\n\ninterface WebViewMessage {\n nativeEvent?: {\n data?: string;\n };\n}\n\nexport type BridgeCoreListener = (event: Event) => void;\n\ndeclare global {\n interface Window {\n ReactNativeWebView?: {\n postMessage: (message: string) => void;\n };\n }\n}\n\n/**\n * BridgeCore handles the low-level platform detection and message serialization.\n * It provides static methods for wrapping events, creating listeners, and sending messages.\n */\nexport class BridgeCore {\n private static BRIDGE_EVENT_TYPE = 'BridgeEvent';\n\n private static isJSONObject = (str: string): boolean => {\n return str.startsWith('{') && str.endsWith('}');\n };\n\n /**\n * Wraps an event in the bridge protocol format\n */\n public static wrapBridgeEvent = (event: Event): string => {\n return JSON.stringify({\n event,\n type: BridgeCore.BRIDGE_EVENT_TYPE,\n });\n };\n\n /**\n * Creates a listener wrapper that parses incoming messages\n */\n static wrapListener =\n (listener: BridgeCoreListener) =>\n (data?: string): void => {\n if (typeof data !== 'string') {\n return;\n }\n if (!data) {\n return;\n }\n let processedData = data;\n // iOS wraps JSON with additional quotes\n if (processedData.startsWith(\"'\") && processedData.endsWith(\"'\")) {\n processedData = processedData.substring(1, processedData.length - 1);\n }\n if (!BridgeCore.isJSONObject(processedData)) {\n return;\n }\n try {\n const eventData: BridgeCoreEvent = JSON.parse(processedData);\n if (!eventData || eventData.type !== BridgeCore.BRIDGE_EVENT_TYPE) {\n return;\n }\n listener(eventData.event);\n } catch {\n // Ignore parse errors\n }\n };\n\n /**\n * Creates a browser-specific message event listener\n */\n static browserListener = (listener: BridgeCoreListener) => {\n const triggerEvent = BridgeCore.wrapListener(listener);\n return (originalEvent: MessageEvent): void => {\n if (!originalEvent?.data) {\n return;\n }\n triggerEvent(originalEvent.data);\n };\n };\n\n /**\n * Creates a React Native WebView message listener\n */\n static webViewListener = (listener: BridgeCoreListener) => {\n const triggerEvent = BridgeCore.wrapListener(listener);\n return (originalEvent: WebViewMessage): void => {\n if (!originalEvent?.nativeEvent?.data) {\n return;\n }\n triggerEvent(originalEvent.nativeEvent.data);\n };\n };\n\n /**\n * Sends an event to the parent context (WebView or iframe parent)\n */\n static sendEvent = (event: Event): void => {\n const bridgeEvent = BridgeCore.wrapBridgeEvent(event);\n if (typeof window === 'undefined') {\n console.warn('Window is undefined');\n return;\n }\n const RNW = window.ReactNativeWebView;\n if (typeof RNW?.postMessage === 'function') {\n RNW.postMessage(`'${bridgeEvent}'`);\n return;\n }\n if (window.parent === window) {\n return;\n }\n window.parent.postMessage(bridgeEvent, '*');\n };\n\n /**\n * Subscribes to window message events\n * @returns Cleanup function to unsubscribe\n */\n static subscribe = (listener: BridgeCoreListener): VoidFunction => {\n const browserListener = BridgeCore.browserListener(listener);\n if (typeof window === 'undefined' || !window.addEventListener) {\n return () => {};\n }\n window.addEventListener('message', browserListener);\n return () => window.removeEventListener('message', browserListener);\n };\n}\n","import type {\n BridgeData,\n BridgeEvent,\n BridgeHandlers,\n BridgeInitEvent,\n BridgeInitResultEvent,\n BridgeListener,\n BridgeOptions,\n BridgeRequestEvent,\n BridgeResultData,\n BridgeResultError,\n BridgeResultEvent,\n} from './types';\nimport {\n BridgeErrorType,\n BridgeEventType,\n BridgeResultType,\n} from './types';\n\n/**\n * Creates a bridge event with the specified type and data\n */\nexport const internalEvent = (\n type: BridgeEventType,\n data: BridgeData\n): BridgeEvent => ({\n type,\n data,\n});\n\n/**\n * Creates a result event\n */\nexport const internalResultEvent = (data: BridgeData): BridgeEvent =>\n internalEvent(BridgeEventType.Result, data);\n\ninterface InternalRequestPromise {\n reject: (error: BridgeResultError) => void;\n resolve: (result: BridgeResultData) => void;\n}\n\ninterface InitPromise {\n reject: () => void;\n resolve: (success: boolean) => void;\n}\n\ntype InternalEventSender = (event: BridgeEvent) => void;\n\nconst DEFAULT_TIMEOUT = 100000;\n\n/**\n * BridgeInternal handles the business logic of the bridge protocol.\n * It manages request/response lifecycle, handler registration, and event routing.\n */\nexport class BridgeInternal {\n private requests: InternalRequestPromise[] = [];\n private handlers: BridgeHandlers = {};\n private available = false;\n private supportedMethods: string[] = [];\n private listeners: BridgeListener[] = [];\n private initPromise?: InitPromise;\n private readonly sendEvent: InternalEventSender;\n private readonly timeout: number;\n\n constructor(sendEvent: InternalEventSender, options?: BridgeOptions) {\n this.sendEvent = sendEvent;\n this.timeout = options?.timeout ?? DEFAULT_TIMEOUT;\n }\n\n /**\n * Subscribe to all result events\n */\n public subscribe = (listener: BridgeListener): number => {\n return this.listeners.push(listener);\n };\n\n /**\n * Unsubscribe from result events\n */\n public unsubscribe = (listener: BridgeListener): void => {\n this.listeners = this.listeners.filter(\n (oldListener) => oldListener !== listener\n );\n };\n\n private checkDiff = (a: string[], b: string[]): boolean => {\n return (\n a.filter((x) => !b.includes(x)).length > 0 ||\n b.filter((x) => !a.includes(x)).length > 0\n );\n };\n\n /**\n * Initialize the bridge with handlers\n * @param handlers Map of method names to handler functions\n * @returns Promise that resolves when the other side acknowledges\n */\n public init = (handlers: BridgeHandlers = {}): Promise<boolean> => {\n const oldMethods = Object.keys(this.handlers);\n const newMethods = Object.keys(handlers);\n this.handlers = handlers;\n if (!this.checkDiff(oldMethods, newMethods)) {\n return Promise.resolve(true);\n }\n return new Promise((resolve, reject) => {\n this.initPromise = { resolve, reject };\n this.sendEvent(\n internalEvent(BridgeEventType.Init, {\n methods: newMethods,\n })\n );\n });\n };\n\n /**\n * Handle incoming bridge events\n */\n public handleCoreEvent = (event: BridgeEvent): void => {\n const { type, data } = event;\n switch (type) {\n case BridgeEventType.Init:\n this.handleInit(data as BridgeInitEvent);\n break;\n case BridgeEventType.InitResult:\n this.handleInitResult(data as BridgeInitResultEvent);\n break;\n case BridgeEventType.Request:\n this.handleRequest(data as BridgeRequestEvent);\n break;\n case BridgeEventType.Result:\n this.handleResult(data as BridgeResultEvent);\n break;\n }\n };\n\n /**\n * Handle incoming requests and execute the appropriate handler\n */\n public handleRequest = (request: BridgeRequestEvent): void => {\n const { method, params, request_id } = request;\n new Promise<BridgeResultData>((resolve, reject) => {\n let timeout = false;\n if (!Object.prototype.hasOwnProperty.call(this.handlers, method)) {\n reject({\n error_type: BridgeErrorType.UNSUPPORTED_METHOD,\n error: new Error(`Handler for «${method}» is not registered`),\n });\n return;\n }\n const timer = setTimeout(() => {\n timeout = true;\n reject({\n error_type: BridgeErrorType.METHOD_EXECUTION_TIMEOUT,\n error: new Error('Execution timeout exceeded'),\n });\n }, this.timeout);\n const handler = this.handlers[method];\n if (!handler) {\n reject({\n error_type: BridgeErrorType.UNSUPPORTED_METHOD,\n error: new Error(`Handler for «${method}» is undefined`),\n });\n return;\n }\n handler(params)\n .then((result) => {\n if (timeout) {\n return;\n }\n clearTimeout(timer);\n resolve(result as BridgeResultData);\n })\n .catch((error: Error) => {\n if (timeout) {\n return;\n }\n clearTimeout(timer);\n reject({\n error_type: BridgeErrorType.REJECTED,\n error: error,\n });\n });\n })\n .then((data: BridgeResultData) => {\n this.sendEvent(\n internalResultEvent({\n type: BridgeResultType.Success,\n data,\n method,\n request_id,\n })\n );\n })\n .catch(\n ({\n error_type,\n error,\n }: {\n error_type: BridgeErrorType;\n error: Error;\n }) => {\n this.sendEvent(\n internalResultEvent({\n type: BridgeResultType.Error,\n request_id,\n method,\n data: {\n error_message: error.message,\n error_type,\n },\n })\n );\n }\n );\n };\n\n private handleResult = (result: BridgeResultEvent): void => {\n this.handleRequestResult(result);\n this.listeners.forEach((listener) => listener(result));\n };\n\n private handleRequestResult = (result: BridgeResultEvent): void => {\n if (!result || !Object.prototype.hasOwnProperty.call(result, 'request_id')) {\n return;\n }\n if (!Object.prototype.hasOwnProperty.call(result, 'type')) {\n console.warn('unknown result', result);\n return;\n }\n const { request_id, data, type } = result;\n const request = this.requests[Number(request_id)];\n if (!request) {\n return;\n }\n if (type === BridgeResultType.Success) {\n request.resolve(data);\n return;\n }\n if (type === BridgeResultType.Error) {\n request.reject(data as BridgeResultError);\n }\n };\n\n private handleInit = (data: BridgeInitEvent): void => {\n this.available = true;\n this.supportedMethods = data.methods;\n this.sendEvent(internalEvent(BridgeEventType.InitResult, true));\n };\n\n private handleInitResult = (success: BridgeInitResultEvent): void => {\n if (success) {\n this.initPromise?.resolve(true);\n } else {\n this.initPromise?.reject();\n }\n };\n\n /**\n * Send a request to the other side\n * @param method Method name to invoke\n * @param params Parameters to pass to the method\n * @returns Promise that resolves with the result\n */\n public send = <TResult = unknown>(\n method: string,\n params: object\n ): Promise<TResult> =>\n new Promise((resolve, reject) => {\n const request_id = (\n this.requests.push({ resolve: resolve as (result: BridgeResultData) => void, reject }) - 1\n ).toString();\n if (!this.isAvailable()) {\n this.handleCoreEvent(\n internalResultEvent({\n type: BridgeResultType.Error,\n request_id,\n method,\n data: {\n error_message: 'Bridge is not available',\n error_type: BridgeErrorType.BRIDGE_NOT_AVAILABLE,\n },\n })\n );\n return;\n }\n this.sendEvent(\n internalEvent(BridgeEventType.Request, {\n method,\n params,\n request_id,\n })\n );\n });\n\n /**\n * Check if a method is supported by the other side\n */\n public supports = (method: string): boolean =>\n this.supportedMethods.includes(method);\n\n /**\n * Check if the bridge is available (initialized)\n */\n public isAvailable = (): boolean => this.available;\n}\n","import type { BridgeHandlers, BridgeListener } from './types';\nimport type { BridgeInternal } from './BridgeInternal';\n\n/**\n * BridgeBase provides the public API for bridge communication.\n * It wraps BridgeInternal and exposes a clean interface for consumers.\n */\nexport class BridgeBase {\n protected bridge: BridgeInternal;\n\n constructor(bridge: BridgeInternal) {\n this.bridge = bridge;\n }\n\n /**\n * Check if a method is supported by the other side\n * @param method Method name to check\n */\n public supports = (method: string): boolean => this.bridge.supports(method);\n\n /**\n * Check if the bridge is available (initialized)\n */\n public isAvailable = (): boolean => this.bridge.isAvailable();\n\n /**\n * Send a request to invoke a method on the other side\n * @param method Method name to invoke\n * @param params Parameters to pass\n * @returns Promise resolving with the result\n */\n public send = <TResult = unknown>(\n method: string,\n params: object = {}\n ): Promise<TResult> => {\n return this.bridge.send<TResult>(method, params);\n };\n\n /**\n * Subscribe to all result events\n * @param listener Callback for result events\n * @returns Subscription index\n */\n public subscribe = (listener: BridgeListener): number => {\n return this.bridge.subscribe(listener);\n };\n\n /**\n * Unsubscribe from result events\n * @param listener The listener to remove\n */\n public unsubscribe = (listener: BridgeListener): void => {\n return this.bridge.unsubscribe(listener);\n };\n\n /**\n * Initialize the bridge with handlers\n * @param handlers Map of method names to handler functions\n * @returns Promise resolving when initialization is complete\n */\n public init = (handlers?: BridgeHandlers): Promise<boolean> =>\n this.bridge.init(handlers);\n}\n","import { BridgeCore } from './BridgeCore';\nimport { BridgeInternal } from './BridgeInternal';\nimport { BridgeBase } from './BridgeBase';\nimport type { BridgeOptions } from './types';\n\n/**\n * AspectlyBridge is the main entry point for bridge communication.\n * Use this class when running inside a WebView or iframe that needs\n * to communicate with its parent container.\n *\n * @example\n * ```typescript\n * // Inside a WebView or iframe\n * const bridge = new AspectlyBridge();\n *\n * // Initialize with handlers\n * await bridge.init({\n * greet: async (params) => {\n * return { message: `Hello, ${params.name}!` };\n * }\n * });\n *\n * // Send messages to parent\n * const result = await bridge.send('someMethod', { data: 'value' });\n * ```\n */\nexport class AspectlyBridge extends BridgeBase {\n private cleanupSubscription: VoidFunction;\n\n constructor(options?: BridgeOptions) {\n const bridge = new BridgeInternal(BridgeCore.sendEvent, options);\n super(bridge);\n this.cleanupSubscription = BridgeCore.subscribe(\n bridge.handleCoreEvent as (event: unknown) => void\n );\n }\n\n /**\n * Cleanup bridge subscriptions\n */\n public destroy = (): void => {\n this.cleanupSubscription();\n };\n}\n","/**\n * Browser entry point for direct script inclusion.\n * Creates a global `aspectlyBridge` instance on the window object.\n *\n * @example\n * ```html\n * <script src=\"https://unpkg.com/@aspectly/core/dist/browser.js\"></script>\n * <script>\n * window.aspectlyBridge.init({\n * greet: async (params) => ({ message: 'Hello!' })\n * });\n * </script>\n * ```\n */\nimport { AspectlyBridge } from './AspectlyBridge';\n\ndeclare global {\n interface Window {\n aspectlyBridge: AspectlyBridge;\n }\n}\n\nif (typeof window !== 'undefined') {\n window.aspectlyBridge = new AspectlyBridge();\n}\n\nexport { AspectlyBridge };\n"]}
1
+ {"version":3,"sources":["../src/BridgeCore.ts","../src/BridgeInternal.ts","../src/BridgeBase.ts","../src/AspectlyBridge.ts","../src/browser.ts"],"names":["detectTransport"],"mappings":"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","file":"browser.js","sourcesContent":["/**\n * Low-level bridge core handling platform-specific message passing\n * Now delegates to @aspectly/transports for platform detection\n */\n\nimport { detectTransport, type Transport } from '@aspectly/transports';\n\nexport type Event = unknown;\n\ninterface BridgeCoreEvent {\n type: string;\n event: Event;\n}\n\nexport type BridgeCoreListener = (event: Event) => void;\n\n/**\n * BridgeCore handles the low-level platform detection and message serialization.\n * It provides static methods for wrapping events, creating listeners, and sending messages.\n *\n * Platform detection is now handled by @aspectly/transports which supports:\n * - CefSharp (Chromium Embedded Framework for .NET)\n * - React Native WebView\n * - Iframe (window.parent.postMessage)\n * - Custom transports via TransportRegistry\n */\nexport class BridgeCore {\n private static BRIDGE_EVENT_TYPE = 'BridgeEvent';\n private static transport: Transport | null = null;\n\n private static isJSONObject = (str: string): boolean => {\n return str.startsWith('{') && str.endsWith('}');\n };\n\n /**\n * Get the current transport (lazy initialization)\n */\n private static getTransport(): Transport {\n if (!BridgeCore.transport) {\n BridgeCore.transport = detectTransport();\n }\n return BridgeCore.transport;\n }\n\n /**\n * Set a custom transport (useful for testing or manual configuration)\n */\n public static setTransport(transport: Transport): void {\n BridgeCore.transport = transport;\n }\n\n /**\n * Reset transport to auto-detect on next use\n */\n public static resetTransport(): void {\n BridgeCore.transport = null;\n }\n\n /**\n * Get the name of the current transport\n */\n public static getTransportName(): string {\n return BridgeCore.getTransport().name;\n }\n\n /**\n * Wraps an event in the bridge protocol format\n */\n public static wrapBridgeEvent = (event: Event): string => {\n return JSON.stringify({\n event,\n type: BridgeCore.BRIDGE_EVENT_TYPE,\n });\n };\n\n /**\n * Creates a listener wrapper that parses incoming messages\n */\n static wrapListener =\n (listener: BridgeCoreListener) =>\n (data?: string): void => {\n if (typeof data !== 'string') {\n return;\n }\n if (!data) {\n return;\n }\n let processedData = data;\n // iOS wraps JSON with additional quotes\n if (processedData.startsWith(\"'\") && processedData.endsWith(\"'\")) {\n processedData = processedData.substring(1, processedData.length - 1);\n }\n if (!BridgeCore.isJSONObject(processedData)) {\n return;\n }\n try {\n const eventData: BridgeCoreEvent = JSON.parse(processedData);\n if (!eventData || eventData.type !== BridgeCore.BRIDGE_EVENT_TYPE) {\n return;\n }\n listener(eventData.event);\n } catch {\n // Ignore parse errors\n }\n };\n\n /**\n * Sends an event to the parent context using the detected transport\n */\n static sendEvent = (event: Event): void => {\n const bridgeEvent = BridgeCore.wrapBridgeEvent(event);\n const transport = BridgeCore.getTransport();\n transport.send(bridgeEvent);\n };\n\n /**\n * Subscribes to incoming messages via the detected transport\n * @returns Cleanup function to unsubscribe\n */\n static subscribe = (listener: BridgeCoreListener): VoidFunction => {\n const transport = BridgeCore.getTransport();\n const wrappedListener = BridgeCore.wrapListener(listener);\n return transport.subscribe(wrappedListener);\n };\n}\n","import type {\n BridgeData,\n BridgeEvent,\n BridgeHandler,\n BridgeHandlers,\n BridgeInitEvent,\n BridgeInitResultEvent,\n BridgeListener,\n BridgeOptions,\n BridgeRequestEvent,\n BridgeResultData,\n BridgeResultError,\n BridgeResultEvent,\n} from './types';\nimport {\n BridgeErrorType,\n BridgeEventType,\n BridgeResultType,\n} from './types';\n\n/**\n * Creates a bridge event with the specified type and data\n */\nexport const internalEvent = (\n type: BridgeEventType,\n data: BridgeData\n): BridgeEvent => ({\n type,\n data,\n});\n\n/**\n * Creates a result event\n */\nexport const internalResultEvent = (data: BridgeData): BridgeEvent =>\n internalEvent(BridgeEventType.Result, data);\n\ninterface InternalRequestPromise {\n reject: (error: BridgeResultError) => void;\n resolve: (result: BridgeResultData) => void;\n}\n\ninterface InitPromise {\n reject: () => void;\n resolve: (success: boolean) => void;\n}\n\ntype InternalEventSender = (event: BridgeEvent) => void;\n\nconst DEFAULT_TIMEOUT = 100000;\n\n/**\n * BridgeInternal handles the business logic of the bridge protocol.\n * It manages request/response lifecycle, handler registration, and event routing.\n */\nexport class BridgeInternal {\n private requests: InternalRequestPromise[] = [];\n private handlers: BridgeHandlers = {};\n private available = false;\n private supportedMethods: string[] = [];\n private listeners: BridgeListener[] = [];\n private initPromise?: InitPromise;\n private readonly sendEvent: InternalEventSender;\n private readonly timeout: number;\n\n constructor(sendEvent: InternalEventSender, options?: BridgeOptions) {\n this.sendEvent = sendEvent;\n this.timeout = options?.timeout ?? DEFAULT_TIMEOUT;\n }\n\n /**\n * Reset bridge state for a new connection context.\n * Call this when the remote side has changed (e.g., new popup window).\n */\n public reset = (): void => {\n this.handlers = {};\n this.available = false;\n this.supportedMethods = [];\n this.initPromise = undefined;\n };\n\n /**\n * Register a single handler for a method.\n * Can be called before or after init().\n */\n public registerHandler = (method: string, handler: BridgeHandler): void => {\n this.handlers[method] = handler;\n };\n\n /**\n * Remove a previously registered handler.\n */\n public unregisterHandler = (method: string): void => {\n delete this.handlers[method];\n };\n\n /**\n * Subscribe to all result events\n */\n public subscribe = (listener: BridgeListener): number => {\n return this.listeners.push(listener);\n };\n\n /**\n * Unsubscribe from result events\n */\n public unsubscribe = (listener: BridgeListener): void => {\n this.listeners = this.listeners.filter(\n (oldListener) => oldListener !== listener\n );\n };\n\n private checkDiff = (a: string[], b: string[]): boolean => {\n return (\n a.filter((x) => !b.includes(x)).length > 0 ||\n b.filter((x) => !a.includes(x)).length > 0\n );\n };\n\n /**\n * Initialize the bridge with handlers\n * @param handlers Map of method names to handler functions\n * @returns Promise that resolves when the other side acknowledges\n */\n public init = (handlers: BridgeHandlers = {}): Promise<boolean> => {\n const oldMethods = Object.keys(this.handlers);\n const newMethods = Object.keys(handlers);\n this.handlers = handlers;\n if (!this.checkDiff(oldMethods, newMethods)) {\n return Promise.resolve(true);\n }\n return new Promise((resolve, reject) => {\n this.initPromise = { resolve, reject };\n this.sendEvent(\n internalEvent(BridgeEventType.Init, {\n methods: newMethods,\n })\n );\n });\n };\n\n /**\n * Handle incoming bridge events\n */\n public handleCoreEvent = (event: BridgeEvent): void => {\n const { type, data } = event;\n switch (type) {\n case BridgeEventType.Init:\n this.handleInit(data as BridgeInitEvent);\n break;\n case BridgeEventType.InitResult:\n this.handleInitResult(data as BridgeInitResultEvent);\n break;\n case BridgeEventType.Request:\n this.handleRequest(data as BridgeRequestEvent);\n break;\n case BridgeEventType.Result:\n this.handleResult(data as BridgeResultEvent);\n break;\n }\n };\n\n /**\n * Handle incoming requests and execute the appropriate handler\n */\n public handleRequest = (request: BridgeRequestEvent): void => {\n const { method, params, request_id } = request;\n new Promise<BridgeResultData>((resolve, reject) => {\n let timeout = false;\n if (!Object.prototype.hasOwnProperty.call(this.handlers, method)) {\n reject({\n error_type: BridgeErrorType.UNSUPPORTED_METHOD,\n error: new Error(`Handler for «${method}» is not registered`),\n });\n return;\n }\n const timer = setTimeout(() => {\n timeout = true;\n reject({\n error_type: BridgeErrorType.METHOD_EXECUTION_TIMEOUT,\n error: new Error('Execution timeout exceeded'),\n });\n }, this.timeout);\n const handler = this.handlers[method];\n if (!handler) {\n reject({\n error_type: BridgeErrorType.UNSUPPORTED_METHOD,\n error: new Error(`Handler for «${method}» is undefined`),\n });\n return;\n }\n handler(params)\n .then((result) => {\n if (timeout) {\n return;\n }\n clearTimeout(timer);\n resolve(result as BridgeResultData);\n })\n .catch((error: Error) => {\n if (timeout) {\n return;\n }\n clearTimeout(timer);\n reject({\n error_type: BridgeErrorType.REJECTED,\n error: error,\n });\n });\n })\n .then((data: BridgeResultData) => {\n this.sendEvent(\n internalResultEvent({\n type: BridgeResultType.Success,\n data,\n method,\n request_id,\n })\n );\n })\n .catch(\n ({\n error_type,\n error,\n }: {\n error_type: BridgeErrorType;\n error: Error;\n }) => {\n this.sendEvent(\n internalResultEvent({\n type: BridgeResultType.Error,\n request_id,\n method,\n data: {\n error_message: error.message,\n error_type,\n },\n })\n );\n }\n );\n };\n\n private handleResult = (result: BridgeResultEvent): void => {\n this.handleRequestResult(result);\n this.listeners.forEach((listener) => listener(result));\n };\n\n private handleRequestResult = (result: BridgeResultEvent): void => {\n if (!result || !Object.prototype.hasOwnProperty.call(result, 'request_id')) {\n return;\n }\n if (!Object.prototype.hasOwnProperty.call(result, 'type')) {\n console.warn('unknown result', result);\n return;\n }\n const { request_id, data, type } = result;\n const request = this.requests[Number(request_id)];\n if (!request) {\n return;\n }\n if (type === BridgeResultType.Success) {\n request.resolve(data);\n return;\n }\n if (type === BridgeResultType.Error) {\n request.reject(data as BridgeResultError);\n }\n };\n\n private handleInit = (data: BridgeInitEvent): void => {\n this.available = true;\n this.supportedMethods = data.methods;\n this.sendEvent(internalEvent(BridgeEventType.InitResult, true));\n };\n\n private handleInitResult = (success: BridgeInitResultEvent): void => {\n if (success) {\n this.initPromise?.resolve(true);\n } else {\n this.initPromise?.reject();\n }\n };\n\n /**\n * Send a request to the other side\n * @param method Method name to invoke\n * @param params Parameters to pass to the method\n * @returns Promise that resolves with the result\n */\n public send = <TResult = unknown>(\n method: string,\n params: object\n ): Promise<TResult> =>\n new Promise((resolve, reject) => {\n const request_id = (\n this.requests.push({ resolve: resolve as (result: BridgeResultData) => void, reject }) - 1\n ).toString();\n if (!this.isAvailable()) {\n this.handleCoreEvent(\n internalResultEvent({\n type: BridgeResultType.Error,\n request_id,\n method,\n data: {\n error_message: 'Bridge is not available',\n error_type: BridgeErrorType.BRIDGE_NOT_AVAILABLE,\n },\n })\n );\n return;\n }\n this.sendEvent(\n internalEvent(BridgeEventType.Request, {\n method,\n params,\n request_id,\n })\n );\n });\n\n /**\n * Check if a method is supported by the other side\n */\n public supports = (method: string): boolean =>\n this.supportedMethods.includes(method);\n\n /**\n * Check if the bridge is available (initialized)\n */\n public isAvailable = (): boolean => this.available;\n}\n","import type { BridgeHandler, BridgeHandlers, BridgeListener } from './types';\nimport type { BridgeInternal } from './BridgeInternal';\n\n/**\n * BridgeBase provides the public API for bridge communication.\n * It wraps BridgeInternal and exposes a clean interface for consumers.\n */\nexport class BridgeBase {\n protected bridge: BridgeInternal;\n\n constructor(bridge: BridgeInternal) {\n this.bridge = bridge;\n }\n\n /**\n * Check if a method is supported by the other side\n * @param method Method name to check\n */\n public supports = (method: string): boolean => this.bridge.supports(method);\n\n /**\n * Check if the bridge is available (initialized)\n */\n public isAvailable = (): boolean => this.bridge.isAvailable();\n\n /**\n * Send a request to invoke a method on the other side\n * @param method Method name to invoke\n * @param params Parameters to pass\n * @returns Promise resolving with the result\n */\n public send = <TResult = unknown>(\n method: string,\n params: object = {}\n ): Promise<TResult> => {\n return this.bridge.send<TResult>(method, params);\n };\n\n /**\n * Subscribe to all result events\n * @param listener Callback for result events\n * @returns Subscription index\n */\n public subscribe = (listener: BridgeListener): number => {\n return this.bridge.subscribe(listener);\n };\n\n /**\n * Unsubscribe from result events\n * @param listener The listener to remove\n */\n public unsubscribe = (listener: BridgeListener): void => {\n return this.bridge.unsubscribe(listener);\n };\n\n /**\n * Register a single handler for a method.\n * Can be called before or after init().\n * @param method Method name to handle\n * @param handler Async function to handle the method\n */\n public registerHandler = (method: string, handler: BridgeHandler): void => {\n this.bridge.registerHandler(method, handler);\n };\n\n /**\n * Remove a previously registered handler.\n * @param method Method name to remove\n */\n public unregisterHandler = (method: string): void => {\n this.bridge.unregisterHandler(method);\n };\n\n /**\n * Initialize the bridge with handlers\n * @param handlers Map of method names to handler functions\n * @returns Promise resolving when initialization is complete\n */\n public init = (handlers?: BridgeHandlers): Promise<boolean> =>\n this.bridge.init(handlers);\n\n /**\n * Reset bridge state for a new connection context\n */\n public reset = (): void => this.bridge.reset();\n}\n","import { BridgeCore } from './BridgeCore';\nimport { BridgeInternal } from './BridgeInternal';\nimport { BridgeBase } from './BridgeBase';\nimport type { BridgeOptions } from './types';\n\n/**\n * AspectlyBridge is the main entry point for bridge communication.\n * Use this class when running inside a WebView or iframe that needs\n * to communicate with its parent container.\n *\n * @example\n * ```typescript\n * // Inside a WebView or iframe\n * const bridge = new AspectlyBridge();\n *\n * // Initialize with handlers\n * await bridge.init({\n * greet: async (params) => {\n * return { message: `Hello, ${params.name}!` };\n * }\n * });\n *\n * // Send messages to parent\n * const result = await bridge.send('someMethod', { data: 'value' });\n * ```\n */\nexport class AspectlyBridge extends BridgeBase {\n private cleanupSubscription: VoidFunction;\n\n constructor(options?: BridgeOptions) {\n const bridge = new BridgeInternal(BridgeCore.sendEvent, options);\n super(bridge);\n this.cleanupSubscription = BridgeCore.subscribe(\n bridge.handleCoreEvent as (event: unknown) => void\n );\n }\n\n /**\n * Cleanup bridge subscriptions\n */\n public destroy = (): void => {\n this.cleanupSubscription();\n };\n}\n","/**\n * Browser entry point for direct script inclusion.\n * Creates a global `aspectlyBridge` instance on the window object.\n *\n * @example\n * ```html\n * <script src=\"https://unpkg.com/@aspectly/core/dist/browser.js\"></script>\n * <script>\n * window.aspectlyBridge.init({\n * greet: async (params) => ({ message: 'Hello!' })\n * });\n * </script>\n * ```\n */\nimport { AspectlyBridge } from './AspectlyBridge';\n\ndeclare global {\n interface Window {\n aspectlyBridge: AspectlyBridge;\n }\n}\n\nif (typeof window !== 'undefined') {\n window.aspectlyBridge = new AspectlyBridge();\n}\n\nexport { AspectlyBridge };\n"]}
package/dist/browser.mjs CHANGED
@@ -1,7 +1,37 @@
1
+ import { detectTransport } from '@aspectly/transports';
2
+
1
3
  // src/BridgeCore.ts
2
4
  var _BridgeCore = class _BridgeCore {
5
+ /**
6
+ * Get the current transport (lazy initialization)
7
+ */
8
+ static getTransport() {
9
+ if (!_BridgeCore.transport) {
10
+ _BridgeCore.transport = detectTransport();
11
+ }
12
+ return _BridgeCore.transport;
13
+ }
14
+ /**
15
+ * Set a custom transport (useful for testing or manual configuration)
16
+ */
17
+ static setTransport(transport) {
18
+ _BridgeCore.transport = transport;
19
+ }
20
+ /**
21
+ * Reset transport to auto-detect on next use
22
+ */
23
+ static resetTransport() {
24
+ _BridgeCore.transport = null;
25
+ }
26
+ /**
27
+ * Get the name of the current transport
28
+ */
29
+ static getTransportName() {
30
+ return _BridgeCore.getTransport().name;
31
+ }
3
32
  };
4
33
  _BridgeCore.BRIDGE_EVENT_TYPE = "BridgeEvent";
34
+ _BridgeCore.transport = null;
5
35
  _BridgeCore.isJSONObject = (str) => {
6
36
  return str.startsWith("{") && str.endsWith("}");
7
37
  };
@@ -41,60 +71,21 @@ _BridgeCore.wrapListener = (listener) => (data) => {
41
71
  }
42
72
  };
43
73
  /**
44
- * Creates a browser-specific message event listener
45
- */
46
- _BridgeCore.browserListener = (listener) => {
47
- const triggerEvent = _BridgeCore.wrapListener(listener);
48
- return (originalEvent) => {
49
- if (!originalEvent?.data) {
50
- return;
51
- }
52
- triggerEvent(originalEvent.data);
53
- };
54
- };
55
- /**
56
- * Creates a React Native WebView message listener
57
- */
58
- _BridgeCore.webViewListener = (listener) => {
59
- const triggerEvent = _BridgeCore.wrapListener(listener);
60
- return (originalEvent) => {
61
- if (!originalEvent?.nativeEvent?.data) {
62
- return;
63
- }
64
- triggerEvent(originalEvent.nativeEvent.data);
65
- };
66
- };
67
- /**
68
- * Sends an event to the parent context (WebView or iframe parent)
74
+ * Sends an event to the parent context using the detected transport
69
75
  */
70
76
  _BridgeCore.sendEvent = (event) => {
71
77
  const bridgeEvent = _BridgeCore.wrapBridgeEvent(event);
72
- if (typeof window === "undefined") {
73
- console.warn("Window is undefined");
74
- return;
75
- }
76
- const RNW = window.ReactNativeWebView;
77
- if (typeof RNW?.postMessage === "function") {
78
- RNW.postMessage(`'${bridgeEvent}'`);
79
- return;
80
- }
81
- if (window.parent === window) {
82
- return;
83
- }
84
- window.parent.postMessage(bridgeEvent, "*");
78
+ const transport = _BridgeCore.getTransport();
79
+ transport.send(bridgeEvent);
85
80
  };
86
81
  /**
87
- * Subscribes to window message events
82
+ * Subscribes to incoming messages via the detected transport
88
83
  * @returns Cleanup function to unsubscribe
89
84
  */
90
85
  _BridgeCore.subscribe = (listener) => {
91
- const browserListener = _BridgeCore.browserListener(listener);
92
- if (typeof window === "undefined" || !window.addEventListener) {
93
- return () => {
94
- };
95
- }
96
- window.addEventListener("message", browserListener);
97
- return () => window.removeEventListener("message", browserListener);
86
+ const transport = _BridgeCore.getTransport();
87
+ const wrappedListener = _BridgeCore.wrapListener(listener);
88
+ return transport.subscribe(wrappedListener);
98
89
  };
99
90
  var BridgeCore = _BridgeCore;
100
91
 
@@ -112,6 +103,29 @@ var BridgeInternal = class {
112
103
  this.available = false;
113
104
  this.supportedMethods = [];
114
105
  this.listeners = [];
106
+ /**
107
+ * Reset bridge state for a new connection context.
108
+ * Call this when the remote side has changed (e.g., new popup window).
109
+ */
110
+ this.reset = () => {
111
+ this.handlers = {};
112
+ this.available = false;
113
+ this.supportedMethods = [];
114
+ this.initPromise = void 0;
115
+ };
116
+ /**
117
+ * Register a single handler for a method.
118
+ * Can be called before or after init().
119
+ */
120
+ this.registerHandler = (method, handler) => {
121
+ this.handlers[method] = handler;
122
+ };
123
+ /**
124
+ * Remove a previously registered handler.
125
+ */
126
+ this.unregisterHandler = (method) => {
127
+ delete this.handlers[method];
128
+ };
115
129
  /**
116
130
  * Subscribe to all result events
117
131
  */
@@ -359,12 +373,32 @@ var BridgeBase = class {
359
373
  this.unsubscribe = (listener) => {
360
374
  return this.bridge.unsubscribe(listener);
361
375
  };
376
+ /**
377
+ * Register a single handler for a method.
378
+ * Can be called before or after init().
379
+ * @param method Method name to handle
380
+ * @param handler Async function to handle the method
381
+ */
382
+ this.registerHandler = (method, handler) => {
383
+ this.bridge.registerHandler(method, handler);
384
+ };
385
+ /**
386
+ * Remove a previously registered handler.
387
+ * @param method Method name to remove
388
+ */
389
+ this.unregisterHandler = (method) => {
390
+ this.bridge.unregisterHandler(method);
391
+ };
362
392
  /**
363
393
  * Initialize the bridge with handlers
364
394
  * @param handlers Map of method names to handler functions
365
395
  * @returns Promise resolving when initialization is complete
366
396
  */
367
397
  this.init = (handlers) => this.bridge.init(handlers);
398
+ /**
399
+ * Reset bridge state for a new connection context
400
+ */
401
+ this.reset = () => this.bridge.reset();
368
402
  this.bridge = bridge;
369
403
  }
370
404
  };