@aspectly/transports 0.1.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.
Files changed (55) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +368 -0
  3. package/dist/BaseTransport-CxzIr1Ds.d.mts +80 -0
  4. package/dist/BaseTransport-CxzIr1Ds.d.ts +80 -0
  5. package/dist/cefsharp.d.mts +37 -0
  6. package/dist/cefsharp.d.ts +37 -0
  7. package/dist/cefsharp.js +65 -0
  8. package/dist/cefsharp.js.map +1 -0
  9. package/dist/cefsharp.mjs +62 -0
  10. package/dist/cefsharp.mjs.map +1 -0
  11. package/dist/iframe.d.mts +35 -0
  12. package/dist/iframe.d.ts +35 -0
  13. package/dist/iframe.js +75 -0
  14. package/dist/iframe.js.map +1 -0
  15. package/dist/iframe.mjs +72 -0
  16. package/dist/iframe.mjs.map +1 -0
  17. package/dist/index.d.mts +85 -0
  18. package/dist/index.d.ts +85 -0
  19. package/dist/index.js +374 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/index.mjs +358 -0
  22. package/dist/index.mjs.map +1 -0
  23. package/dist/react-native.d.mts +36 -0
  24. package/dist/react-native.d.ts +36 -0
  25. package/dist/react-native.js +65 -0
  26. package/dist/react-native.js.map +1 -0
  27. package/dist/react-native.mjs +62 -0
  28. package/dist/react-native.mjs.map +1 -0
  29. package/dist/window.d.mts +36 -0
  30. package/dist/window.d.ts +36 -0
  31. package/dist/window.js +79 -0
  32. package/dist/window.js.map +1 -0
  33. package/dist/window.mjs +76 -0
  34. package/dist/window.mjs.map +1 -0
  35. package/package.json +97 -0
  36. package/src/BaseTransport.test.ts +60 -0
  37. package/src/BaseTransport.ts +27 -0
  38. package/src/TransportRegistry.test.ts +345 -0
  39. package/src/TransportRegistry.ts +120 -0
  40. package/src/cefsharp.ts +3 -0
  41. package/src/iframe.ts +3 -0
  42. package/src/index.ts +26 -0
  43. package/src/react-native.ts +3 -0
  44. package/src/transports/CefSharpTransport.test.ts +187 -0
  45. package/src/transports/CefSharpTransport.ts +73 -0
  46. package/src/transports/IframeTransport.test.ts +212 -0
  47. package/src/transports/IframeTransport.ts +79 -0
  48. package/src/transports/NullTransport.test.ts +64 -0
  49. package/src/transports/NullTransport.ts +27 -0
  50. package/src/transports/PostMessageTransport.ts +50 -0
  51. package/src/transports/ReactNativeTransport.test.ts +196 -0
  52. package/src/transports/ReactNativeTransport.ts +73 -0
  53. package/src/transports/WindowTransport.ts +84 -0
  54. package/src/types.ts +69 -0
  55. package/src/window.ts +3 -0
@@ -0,0 +1,62 @@
1
+ // src/BaseTransport.ts
2
+ var BaseTransport = class {
3
+ /**
4
+ * Helper to check if window is defined (for SSR safety)
5
+ */
6
+ hasWindow() {
7
+ return typeof window !== "undefined";
8
+ }
9
+ /**
10
+ * Helper to safely get window object
11
+ */
12
+ getWindow() {
13
+ return this.hasWindow() ? window : null;
14
+ }
15
+ };
16
+
17
+ // src/transports/CefSharpTransport.ts
18
+ var CefSharpTransport = class extends BaseTransport {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.name = "cefsharp";
22
+ }
23
+ isAvailable() {
24
+ const win = this.getWindow();
25
+ return typeof win?.CefSharp?.PostMessage === "function";
26
+ }
27
+ send(message) {
28
+ const win = this.getWindow();
29
+ if (!win?.CefSharp?.PostMessage) {
30
+ console.warn("[CefSharpTransport] CefSharp.PostMessage is not available");
31
+ return;
32
+ }
33
+ win.CefSharp.PostMessage(message);
34
+ }
35
+ subscribe(listener) {
36
+ const win = this.getWindow();
37
+ if (!win) {
38
+ return () => {
39
+ };
40
+ }
41
+ const handler = (event) => {
42
+ if (typeof event.data === "string") {
43
+ listener(event.data);
44
+ }
45
+ };
46
+ win.addEventListener("message", handler);
47
+ return () => win.removeEventListener("message", handler);
48
+ }
49
+ };
50
+ var cefSharpDetector = {
51
+ name: "cefsharp",
52
+ priority: 100,
53
+ // Highest priority - check first
54
+ detect: () => {
55
+ return typeof window !== "undefined" && typeof window.CefSharp?.PostMessage === "function";
56
+ },
57
+ createTransport: () => new CefSharpTransport()
58
+ };
59
+
60
+ export { CefSharpTransport, cefSharpDetector };
61
+ //# sourceMappingURL=cefsharp.mjs.map
62
+ //# sourceMappingURL=cefsharp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/BaseTransport.ts","../src/transports/CefSharpTransport.ts"],"names":[],"mappings":";AAMO,IAAe,gBAAf,MAAkD;AAAA;AAAA;AAAA;AAAA,EAU7C,SAAA,GAAqB;AAC7B,IAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKU,SAAA,GAA2B;AACnC,IAAA,OAAO,IAAA,CAAK,SAAA,EAAU,GAAI,MAAA,GAAS,IAAA;AAAA,EACrC;AACF,CAAA;;;ACAO,IAAM,iBAAA,GAAN,cAAgC,aAAA,CAAc;AAAA,EAA9C,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AACL,IAAA,IAAA,CAAS,IAAA,GAAO,UAAA;AAAA,EAAA;AAAA,EAEhB,WAAA,GAAuB;AACrB,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,OAAO,OAAO,GAAA,EAAK,QAAA,EAAU,WAAA,KAAgB,UAAA;AAAA,EAC/C;AAAA,EAEA,KAAK,OAAA,EAAuB;AAC1B,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,GAAA,EAAK,QAAA,EAAU,WAAA,EAAa;AAC/B,MAAA,OAAA,CAAQ,KAAK,2DAA2D,CAAA;AACxE,MAAA;AAAA,IACF;AACA,IAAA,GAAA,CAAI,QAAA,CAAS,YAAY,OAAO,CAAA;AAAA,EAClC;AAAA,EAEA,UAAU,QAAA,EAAmD;AAC3D,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,MAAM;AAAA,MAAC,CAAA;AAAA,IAChB;AAGA,IAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAA8B;AAC7C,MAAA,IAAI,OAAO,KAAA,CAAM,IAAA,KAAS,QAAA,EAAU;AAClC,QAAA,QAAA,CAAS,MAAM,IAAI,CAAA;AAAA,MACrB;AAAA,IACF,CAAA;AAEA,IAAA,GAAA,CAAI,gBAAA,CAAiB,WAAW,OAAO,CAAA;AACvC,IAAA,OAAO,MAAM,GAAA,CAAI,mBAAA,CAAoB,SAAA,EAAW,OAAO,CAAA;AAAA,EACzD;AACF;AAKO,IAAM,gBAAA,GAAsC;AAAA,EACjD,IAAA,EAAM,UAAA;AAAA,EACN,QAAA,EAAU,GAAA;AAAA;AAAA,EACV,QAAQ,MAAM;AACZ,IAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAClB,OAAO,MAAA,CAAO,UAAU,WAAA,KAAgB,UAAA;AAAA,EACjD,CAAA;AAAA,EACA,eAAA,EAAiB,MAAM,IAAI,iBAAA;AAC7B","file":"cefsharp.mjs","sourcesContent":["import type { Transport, TransportListener, TransportUnsubscribe } from './types';\r\n\r\n/**\r\n * Abstract base class for transports\r\n * Provides common functionality for message handling\r\n */\r\nexport abstract class BaseTransport implements Transport {\r\n abstract readonly name: string;\r\n\r\n abstract isAvailable(): boolean;\r\n abstract send(message: string): void;\r\n abstract subscribe(listener: TransportListener): TransportUnsubscribe;\r\n\r\n /**\r\n * Helper to check if window is defined (for SSR safety)\r\n */\r\n protected hasWindow(): boolean {\r\n return typeof window !== 'undefined';\r\n }\r\n\r\n /**\r\n * Helper to safely get window object\r\n */\r\n protected getWindow(): Window | null {\r\n return this.hasWindow() ? window : null;\r\n }\r\n}\r\n","import { BaseTransport } from '../BaseTransport';\r\nimport type { TransportListener, TransportUnsubscribe, TransportDetector } from '../types';\r\n\r\ndeclare global {\r\n interface Window {\r\n CefSharp?: {\r\n PostMessage: (message: string) => void;\r\n BindObjectAsync: (...args: unknown[]) => Promise<void>;\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Transport for CefSharp (Chromium Embedded Framework for .NET)\r\n * Used in desktop applications with embedded Chromium browsers\r\n *\r\n * @example\r\n * ```typescript\r\n * import { CefSharpTransport } from '@aspectly/transports/cefsharp';\r\n *\r\n * const transport = new CefSharpTransport();\r\n * if (transport.isAvailable()) {\r\n * transport.send(JSON.stringify({ type: 'hello' }));\r\n * }\r\n * ```\r\n */\r\nexport class CefSharpTransport extends BaseTransport {\r\n readonly name = 'cefsharp';\r\n\r\n isAvailable(): boolean {\r\n const win = this.getWindow();\r\n return typeof win?.CefSharp?.PostMessage === 'function';\r\n }\r\n\r\n send(message: string): void {\r\n const win = this.getWindow();\r\n if (!win?.CefSharp?.PostMessage) {\r\n console.warn('[CefSharpTransport] CefSharp.PostMessage is not available');\r\n return;\r\n }\r\n win.CefSharp.PostMessage(message);\r\n }\r\n\r\n subscribe(listener: TransportListener): TransportUnsubscribe {\r\n const win = this.getWindow();\r\n if (!win) {\r\n return () => {};\r\n }\r\n\r\n // CefSharp sends messages via window.postMessage\r\n const handler = (event: MessageEvent): void => {\r\n if (typeof event.data === 'string') {\r\n listener(event.data);\r\n }\r\n };\r\n\r\n win.addEventListener('message', handler);\r\n return () => win.removeEventListener('message', handler);\r\n }\r\n}\r\n\r\n/**\r\n * Detector for auto-detection registry\r\n */\r\nexport const cefSharpDetector: TransportDetector = {\r\n name: 'cefsharp',\r\n priority: 100, // Highest priority - check first\r\n detect: () => {\r\n return typeof window !== 'undefined' &&\r\n typeof window.CefSharp?.PostMessage === 'function';\r\n },\r\n createTransport: () => new CefSharpTransport(),\r\n};\r\n"]}
@@ -0,0 +1,35 @@
1
+ import { B as BaseTransport, T as TransportListener, a as TransportUnsubscribe, b as TransportDetector } from './BaseTransport-CxzIr1Ds.mjs';
2
+ export { c as Transport } from './BaseTransport-CxzIr1Ds.mjs';
3
+
4
+ /**
5
+ * Transport for iframe/window.postMessage communication
6
+ * Used when web content is displayed inside an iframe
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { IframeTransport } from '@aspectly/transports/iframe';
11
+ *
12
+ * const transport = new IframeTransport();
13
+ * if (transport.isAvailable()) {
14
+ * transport.send(JSON.stringify({ type: 'hello' }));
15
+ * }
16
+ * ```
17
+ */
18
+ declare class IframeTransport extends BaseTransport {
19
+ readonly name = "iframe";
20
+ private readonly targetOrigin;
21
+ /**
22
+ * Create an iframe transport
23
+ * @param targetOrigin Origin to send messages to (default: '*')
24
+ */
25
+ constructor(targetOrigin?: string);
26
+ isAvailable(): boolean;
27
+ send(message: string): void;
28
+ subscribe(listener: TransportListener): TransportUnsubscribe;
29
+ }
30
+ /**
31
+ * Detector for auto-detection registry
32
+ */
33
+ declare const iframeDetector: TransportDetector;
34
+
35
+ export { IframeTransport, TransportListener, TransportUnsubscribe, iframeDetector };
@@ -0,0 +1,35 @@
1
+ import { B as BaseTransport, T as TransportListener, a as TransportUnsubscribe, b as TransportDetector } from './BaseTransport-CxzIr1Ds.js';
2
+ export { c as Transport } from './BaseTransport-CxzIr1Ds.js';
3
+
4
+ /**
5
+ * Transport for iframe/window.postMessage communication
6
+ * Used when web content is displayed inside an iframe
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { IframeTransport } from '@aspectly/transports/iframe';
11
+ *
12
+ * const transport = new IframeTransport();
13
+ * if (transport.isAvailable()) {
14
+ * transport.send(JSON.stringify({ type: 'hello' }));
15
+ * }
16
+ * ```
17
+ */
18
+ declare class IframeTransport extends BaseTransport {
19
+ readonly name = "iframe";
20
+ private readonly targetOrigin;
21
+ /**
22
+ * Create an iframe transport
23
+ * @param targetOrigin Origin to send messages to (default: '*')
24
+ */
25
+ constructor(targetOrigin?: string);
26
+ isAvailable(): boolean;
27
+ send(message: string): void;
28
+ subscribe(listener: TransportListener): TransportUnsubscribe;
29
+ }
30
+ /**
31
+ * Detector for auto-detection registry
32
+ */
33
+ declare const iframeDetector: TransportDetector;
34
+
35
+ export { IframeTransport, TransportListener, TransportUnsubscribe, iframeDetector };
package/dist/iframe.js ADDED
@@ -0,0 +1,75 @@
1
+ 'use strict';
2
+
3
+ // src/BaseTransport.ts
4
+ var BaseTransport = class {
5
+ /**
6
+ * Helper to check if window is defined (for SSR safety)
7
+ */
8
+ hasWindow() {
9
+ return typeof window !== "undefined";
10
+ }
11
+ /**
12
+ * Helper to safely get window object
13
+ */
14
+ getWindow() {
15
+ return this.hasWindow() ? window : null;
16
+ }
17
+ };
18
+
19
+ // src/transports/IframeTransport.ts
20
+ var IframeTransport = class extends BaseTransport {
21
+ /**
22
+ * Create an iframe transport
23
+ * @param targetOrigin Origin to send messages to (default: '*')
24
+ */
25
+ constructor(targetOrigin = "*") {
26
+ super();
27
+ this.name = "iframe";
28
+ this.targetOrigin = targetOrigin;
29
+ }
30
+ isAvailable() {
31
+ const win = this.getWindow();
32
+ if (!win) return false;
33
+ return win.parent !== win;
34
+ }
35
+ send(message) {
36
+ const win = this.getWindow();
37
+ if (!win) {
38
+ console.warn("[IframeTransport] Window is not available");
39
+ return;
40
+ }
41
+ if (win.parent === win) {
42
+ console.warn("[IframeTransport] Not inside an iframe");
43
+ return;
44
+ }
45
+ win.parent.postMessage(message, this.targetOrigin);
46
+ }
47
+ subscribe(listener) {
48
+ const win = this.getWindow();
49
+ if (!win) {
50
+ return () => {
51
+ };
52
+ }
53
+ const handler = (event) => {
54
+ if (typeof event.data === "string") {
55
+ listener(event.data);
56
+ }
57
+ };
58
+ win.addEventListener("message", handler);
59
+ return () => win.removeEventListener("message", handler);
60
+ }
61
+ };
62
+ var iframeDetector = {
63
+ name: "iframe",
64
+ priority: 80,
65
+ // Lowest priority - fallback
66
+ detect: () => {
67
+ return typeof window !== "undefined" && window.parent !== window;
68
+ },
69
+ createTransport: () => new IframeTransport()
70
+ };
71
+
72
+ exports.IframeTransport = IframeTransport;
73
+ exports.iframeDetector = iframeDetector;
74
+ //# sourceMappingURL=iframe.js.map
75
+ //# sourceMappingURL=iframe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/BaseTransport.ts","../src/transports/IframeTransport.ts"],"names":[],"mappings":";;;AAMO,IAAe,gBAAf,MAAkD;AAAA;AAAA;AAAA;AAAA,EAU7C,SAAA,GAAqB;AAC7B,IAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKU,SAAA,GAA2B;AACnC,IAAA,OAAO,IAAA,CAAK,SAAA,EAAU,GAAI,MAAA,GAAS,IAAA;AAAA,EACrC;AACF,CAAA;;;ACTO,IAAM,eAAA,GAAN,cAA8B,aAAA,CAAc;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjD,WAAA,CAAY,eAAuB,GAAA,EAAK;AACtC,IAAA,KAAA,EAAM;AARR,IAAA,IAAA,CAAS,IAAA,GAAO,QAAA;AASd,IAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AAAA,EACtB;AAAA,EAEA,WAAA,GAAuB;AACrB,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,KAAK,OAAO,KAAA;AAEjB,IAAA,OAAO,IAAI,MAAA,KAAW,GAAA;AAAA,EACxB;AAAA,EAEA,KAAK,OAAA,EAAuB;AAC1B,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAA,CAAQ,KAAK,2CAA2C,CAAA;AACxD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,GAAA,CAAI,WAAW,GAAA,EAAK;AACtB,MAAA,OAAA,CAAQ,KAAK,wCAAwC,CAAA;AACrD,MAAA;AAAA,IACF;AACA,IAAA,GAAA,CAAI,MAAA,CAAO,WAAA,CAAY,OAAA,EAAS,IAAA,CAAK,YAAY,CAAA;AAAA,EACnD;AAAA,EAEA,UAAU,QAAA,EAAmD;AAC3D,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,MAAM;AAAA,MAAC,CAAA;AAAA,IAChB;AAEA,IAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAA8B;AAE7C,MAAA,IAAI,OAAO,KAAA,CAAM,IAAA,KAAS,QAAA,EAAU;AAClC,QAAA,QAAA,CAAS,MAAM,IAAI,CAAA;AAAA,MACrB;AAAA,IACF,CAAA;AAEA,IAAA,GAAA,CAAI,gBAAA,CAAiB,WAAW,OAAO,CAAA;AACvC,IAAA,OAAO,MAAM,GAAA,CAAI,mBAAA,CAAoB,SAAA,EAAW,OAAO,CAAA;AAAA,EACzD;AACF;AAKO,IAAM,cAAA,GAAoC;AAAA,EAC/C,IAAA,EAAM,QAAA;AAAA,EACN,QAAA,EAAU,EAAA;AAAA;AAAA,EACV,QAAQ,MAAM;AACZ,IAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,MAAA,KAAW,MAAA;AAAA,EAC5D,CAAA;AAAA,EACA,eAAA,EAAiB,MAAM,IAAI,eAAA;AAC7B","file":"iframe.js","sourcesContent":["import type { Transport, TransportListener, TransportUnsubscribe } from './types';\r\n\r\n/**\r\n * Abstract base class for transports\r\n * Provides common functionality for message handling\r\n */\r\nexport abstract class BaseTransport implements Transport {\r\n abstract readonly name: string;\r\n\r\n abstract isAvailable(): boolean;\r\n abstract send(message: string): void;\r\n abstract subscribe(listener: TransportListener): TransportUnsubscribe;\r\n\r\n /**\r\n * Helper to check if window is defined (for SSR safety)\r\n */\r\n protected hasWindow(): boolean {\r\n return typeof window !== 'undefined';\r\n }\r\n\r\n /**\r\n * Helper to safely get window object\r\n */\r\n protected getWindow(): Window | null {\r\n return this.hasWindow() ? window : null;\r\n }\r\n}\r\n","import { BaseTransport } from '../BaseTransport';\r\nimport type { TransportListener, TransportUnsubscribe, TransportDetector } from '../types';\r\n\r\n/**\r\n * Transport for iframe/window.postMessage communication\r\n * Used when web content is displayed inside an iframe\r\n *\r\n * @example\r\n * ```typescript\r\n * import { IframeTransport } from '@aspectly/transports/iframe';\r\n *\r\n * const transport = new IframeTransport();\r\n * if (transport.isAvailable()) {\r\n * transport.send(JSON.stringify({ type: 'hello' }));\r\n * }\r\n * ```\r\n */\r\nexport class IframeTransport extends BaseTransport {\r\n readonly name = 'iframe';\r\n private readonly targetOrigin: string;\r\n\r\n /**\r\n * Create an iframe transport\r\n * @param targetOrigin Origin to send messages to (default: '*')\r\n */\r\n constructor(targetOrigin: string = '*') {\r\n super();\r\n this.targetOrigin = targetOrigin;\r\n }\r\n\r\n isAvailable(): boolean {\r\n const win = this.getWindow();\r\n if (!win) return false;\r\n // Check if we're inside an iframe (parent !== self)\r\n return win.parent !== win;\r\n }\r\n\r\n send(message: string): void {\r\n const win = this.getWindow();\r\n if (!win) {\r\n console.warn('[IframeTransport] Window is not available');\r\n return;\r\n }\r\n if (win.parent === win) {\r\n console.warn('[IframeTransport] Not inside an iframe');\r\n return;\r\n }\r\n win.parent.postMessage(message, this.targetOrigin);\r\n }\r\n\r\n subscribe(listener: TransportListener): TransportUnsubscribe {\r\n const win = this.getWindow();\r\n if (!win) {\r\n return () => {};\r\n }\r\n\r\n const handler = (event: MessageEvent): void => {\r\n // Optionally filter by origin here if targetOrigin !== '*'\r\n if (typeof event.data === 'string') {\r\n listener(event.data);\r\n }\r\n };\r\n\r\n win.addEventListener('message', handler);\r\n return () => win.removeEventListener('message', handler);\r\n }\r\n}\r\n\r\n/**\r\n * Detector for auto-detection registry\r\n */\r\nexport const iframeDetector: TransportDetector = {\r\n name: 'iframe',\r\n priority: 80, // Lowest priority - fallback\r\n detect: () => {\r\n return typeof window !== 'undefined' && window.parent !== window;\r\n },\r\n createTransport: () => new IframeTransport(),\r\n};\r\n"]}
@@ -0,0 +1,72 @@
1
+ // src/BaseTransport.ts
2
+ var BaseTransport = class {
3
+ /**
4
+ * Helper to check if window is defined (for SSR safety)
5
+ */
6
+ hasWindow() {
7
+ return typeof window !== "undefined";
8
+ }
9
+ /**
10
+ * Helper to safely get window object
11
+ */
12
+ getWindow() {
13
+ return this.hasWindow() ? window : null;
14
+ }
15
+ };
16
+
17
+ // src/transports/IframeTransport.ts
18
+ var IframeTransport = class extends BaseTransport {
19
+ /**
20
+ * Create an iframe transport
21
+ * @param targetOrigin Origin to send messages to (default: '*')
22
+ */
23
+ constructor(targetOrigin = "*") {
24
+ super();
25
+ this.name = "iframe";
26
+ this.targetOrigin = targetOrigin;
27
+ }
28
+ isAvailable() {
29
+ const win = this.getWindow();
30
+ if (!win) return false;
31
+ return win.parent !== win;
32
+ }
33
+ send(message) {
34
+ const win = this.getWindow();
35
+ if (!win) {
36
+ console.warn("[IframeTransport] Window is not available");
37
+ return;
38
+ }
39
+ if (win.parent === win) {
40
+ console.warn("[IframeTransport] Not inside an iframe");
41
+ return;
42
+ }
43
+ win.parent.postMessage(message, this.targetOrigin);
44
+ }
45
+ subscribe(listener) {
46
+ const win = this.getWindow();
47
+ if (!win) {
48
+ return () => {
49
+ };
50
+ }
51
+ const handler = (event) => {
52
+ if (typeof event.data === "string") {
53
+ listener(event.data);
54
+ }
55
+ };
56
+ win.addEventListener("message", handler);
57
+ return () => win.removeEventListener("message", handler);
58
+ }
59
+ };
60
+ var iframeDetector = {
61
+ name: "iframe",
62
+ priority: 80,
63
+ // Lowest priority - fallback
64
+ detect: () => {
65
+ return typeof window !== "undefined" && window.parent !== window;
66
+ },
67
+ createTransport: () => new IframeTransport()
68
+ };
69
+
70
+ export { IframeTransport, iframeDetector };
71
+ //# sourceMappingURL=iframe.mjs.map
72
+ //# sourceMappingURL=iframe.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/BaseTransport.ts","../src/transports/IframeTransport.ts"],"names":[],"mappings":";AAMO,IAAe,gBAAf,MAAkD;AAAA;AAAA;AAAA;AAAA,EAU7C,SAAA,GAAqB;AAC7B,IAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKU,SAAA,GAA2B;AACnC,IAAA,OAAO,IAAA,CAAK,SAAA,EAAU,GAAI,MAAA,GAAS,IAAA;AAAA,EACrC;AACF,CAAA;;;ACTO,IAAM,eAAA,GAAN,cAA8B,aAAA,CAAc;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjD,WAAA,CAAY,eAAuB,GAAA,EAAK;AACtC,IAAA,KAAA,EAAM;AARR,IAAA,IAAA,CAAS,IAAA,GAAO,QAAA;AASd,IAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AAAA,EACtB;AAAA,EAEA,WAAA,GAAuB;AACrB,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,KAAK,OAAO,KAAA;AAEjB,IAAA,OAAO,IAAI,MAAA,KAAW,GAAA;AAAA,EACxB;AAAA,EAEA,KAAK,OAAA,EAAuB;AAC1B,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAA,CAAQ,KAAK,2CAA2C,CAAA;AACxD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,GAAA,CAAI,WAAW,GAAA,EAAK;AACtB,MAAA,OAAA,CAAQ,KAAK,wCAAwC,CAAA;AACrD,MAAA;AAAA,IACF;AACA,IAAA,GAAA,CAAI,MAAA,CAAO,WAAA,CAAY,OAAA,EAAS,IAAA,CAAK,YAAY,CAAA;AAAA,EACnD;AAAA,EAEA,UAAU,QAAA,EAAmD;AAC3D,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,MAAM;AAAA,MAAC,CAAA;AAAA,IAChB;AAEA,IAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAA8B;AAE7C,MAAA,IAAI,OAAO,KAAA,CAAM,IAAA,KAAS,QAAA,EAAU;AAClC,QAAA,QAAA,CAAS,MAAM,IAAI,CAAA;AAAA,MACrB;AAAA,IACF,CAAA;AAEA,IAAA,GAAA,CAAI,gBAAA,CAAiB,WAAW,OAAO,CAAA;AACvC,IAAA,OAAO,MAAM,GAAA,CAAI,mBAAA,CAAoB,SAAA,EAAW,OAAO,CAAA;AAAA,EACzD;AACF;AAKO,IAAM,cAAA,GAAoC;AAAA,EAC/C,IAAA,EAAM,QAAA;AAAA,EACN,QAAA,EAAU,EAAA;AAAA;AAAA,EACV,QAAQ,MAAM;AACZ,IAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,MAAA,KAAW,MAAA;AAAA,EAC5D,CAAA;AAAA,EACA,eAAA,EAAiB,MAAM,IAAI,eAAA;AAC7B","file":"iframe.mjs","sourcesContent":["import type { Transport, TransportListener, TransportUnsubscribe } from './types';\r\n\r\n/**\r\n * Abstract base class for transports\r\n * Provides common functionality for message handling\r\n */\r\nexport abstract class BaseTransport implements Transport {\r\n abstract readonly name: string;\r\n\r\n abstract isAvailable(): boolean;\r\n abstract send(message: string): void;\r\n abstract subscribe(listener: TransportListener): TransportUnsubscribe;\r\n\r\n /**\r\n * Helper to check if window is defined (for SSR safety)\r\n */\r\n protected hasWindow(): boolean {\r\n return typeof window !== 'undefined';\r\n }\r\n\r\n /**\r\n * Helper to safely get window object\r\n */\r\n protected getWindow(): Window | null {\r\n return this.hasWindow() ? window : null;\r\n }\r\n}\r\n","import { BaseTransport } from '../BaseTransport';\r\nimport type { TransportListener, TransportUnsubscribe, TransportDetector } from '../types';\r\n\r\n/**\r\n * Transport for iframe/window.postMessage communication\r\n * Used when web content is displayed inside an iframe\r\n *\r\n * @example\r\n * ```typescript\r\n * import { IframeTransport } from '@aspectly/transports/iframe';\r\n *\r\n * const transport = new IframeTransport();\r\n * if (transport.isAvailable()) {\r\n * transport.send(JSON.stringify({ type: 'hello' }));\r\n * }\r\n * ```\r\n */\r\nexport class IframeTransport extends BaseTransport {\r\n readonly name = 'iframe';\r\n private readonly targetOrigin: string;\r\n\r\n /**\r\n * Create an iframe transport\r\n * @param targetOrigin Origin to send messages to (default: '*')\r\n */\r\n constructor(targetOrigin: string = '*') {\r\n super();\r\n this.targetOrigin = targetOrigin;\r\n }\r\n\r\n isAvailable(): boolean {\r\n const win = this.getWindow();\r\n if (!win) return false;\r\n // Check if we're inside an iframe (parent !== self)\r\n return win.parent !== win;\r\n }\r\n\r\n send(message: string): void {\r\n const win = this.getWindow();\r\n if (!win) {\r\n console.warn('[IframeTransport] Window is not available');\r\n return;\r\n }\r\n if (win.parent === win) {\r\n console.warn('[IframeTransport] Not inside an iframe');\r\n return;\r\n }\r\n win.parent.postMessage(message, this.targetOrigin);\r\n }\r\n\r\n subscribe(listener: TransportListener): TransportUnsubscribe {\r\n const win = this.getWindow();\r\n if (!win) {\r\n return () => {};\r\n }\r\n\r\n const handler = (event: MessageEvent): void => {\r\n // Optionally filter by origin here if targetOrigin !== '*'\r\n if (typeof event.data === 'string') {\r\n listener(event.data);\r\n }\r\n };\r\n\r\n win.addEventListener('message', handler);\r\n return () => win.removeEventListener('message', handler);\r\n }\r\n}\r\n\r\n/**\r\n * Detector for auto-detection registry\r\n */\r\nexport const iframeDetector: TransportDetector = {\r\n name: 'iframe',\r\n priority: 80, // Lowest priority - fallback\r\n detect: () => {\r\n return typeof window !== 'undefined' && window.parent !== window;\r\n },\r\n createTransport: () => new IframeTransport(),\r\n};\r\n"]}
@@ -0,0 +1,85 @@
1
+ import { B as BaseTransport, T as TransportListener, a as TransportUnsubscribe, b as TransportDetector, c as Transport } from './BaseTransport-CxzIr1Ds.mjs';
2
+ export { d as TransportFactory } from './BaseTransport-CxzIr1Ds.mjs';
3
+ export { CefSharpTransport, cefSharpDetector } from './cefsharp.mjs';
4
+ export { ReactNativeTransport, reactNativeDetector } from './react-native.mjs';
5
+ export { IframeTransport, iframeDetector } from './iframe.mjs';
6
+ export { WindowTransport, windowDetector } from './window.mjs';
7
+
8
+ /**
9
+ * Fallback transport for browser environments.
10
+ * Listens for window.postMessage events, allowing parent windows
11
+ * to receive messages from child iframes.
12
+ */
13
+ declare class PostMessageTransport extends BaseTransport {
14
+ readonly name = "postmessage";
15
+ isAvailable(): boolean;
16
+ send(message: string): void;
17
+ subscribe(listener: TransportListener): TransportUnsubscribe;
18
+ }
19
+ /**
20
+ * Detector for auto-detection registry
21
+ */
22
+ declare const postMessageDetector: TransportDetector;
23
+
24
+ /**
25
+ * Null transport - used when no transport is available
26
+ * All operations are no-ops. Useful for SSR or testing.
27
+ */
28
+ declare class NullTransport extends BaseTransport {
29
+ readonly name = "null";
30
+ isAvailable(): boolean;
31
+ send(_message: string): void;
32
+ subscribe(_listener: TransportListener): TransportUnsubscribe;
33
+ }
34
+
35
+ /**
36
+ * Registry for transport detectors
37
+ * Manages auto-detection of the current environment
38
+ */
39
+ declare class TransportRegistryClass {
40
+ private detectors;
41
+ private cachedTransport;
42
+ constructor();
43
+ /**
44
+ * Register a custom transport detector
45
+ * @param detector The detector to register
46
+ */
47
+ register(detector: TransportDetector): void;
48
+ /**
49
+ * Unregister a transport detector by name
50
+ * @param name Name of the detector to remove
51
+ */
52
+ unregister(name: string): void;
53
+ /**
54
+ * Get all registered detectors
55
+ */
56
+ getDetectors(): readonly TransportDetector[];
57
+ /**
58
+ * Detect and return the appropriate transport for the current environment
59
+ * Results are cached for performance
60
+ * @param forceRedetect Force re-detection (ignores cache)
61
+ */
62
+ detect(forceRedetect?: boolean): Transport;
63
+ /**
64
+ * Clear the cached transport (useful for testing)
65
+ */
66
+ clearCache(): void;
67
+ /**
68
+ * Reset registry to default state (built-in detectors only)
69
+ */
70
+ reset(): void;
71
+ }
72
+ /**
73
+ * Global transport registry instance
74
+ */
75
+ declare const TransportRegistry: TransportRegistryClass;
76
+ /**
77
+ * Convenience function to detect transport
78
+ */
79
+ declare const detectTransport: (forceRedetect?: boolean) => Transport;
80
+ /**
81
+ * Convenience function to register a custom detector
82
+ */
83
+ declare const registerTransport: (detector: TransportDetector) => void;
84
+
85
+ export { BaseTransport, NullTransport, PostMessageTransport, Transport, TransportDetector, TransportListener, TransportRegistry, TransportUnsubscribe, detectTransport, postMessageDetector, registerTransport };
@@ -0,0 +1,85 @@
1
+ import { B as BaseTransport, T as TransportListener, a as TransportUnsubscribe, b as TransportDetector, c as Transport } from './BaseTransport-CxzIr1Ds.js';
2
+ export { d as TransportFactory } from './BaseTransport-CxzIr1Ds.js';
3
+ export { CefSharpTransport, cefSharpDetector } from './cefsharp.js';
4
+ export { ReactNativeTransport, reactNativeDetector } from './react-native.js';
5
+ export { IframeTransport, iframeDetector } from './iframe.js';
6
+ export { WindowTransport, windowDetector } from './window.js';
7
+
8
+ /**
9
+ * Fallback transport for browser environments.
10
+ * Listens for window.postMessage events, allowing parent windows
11
+ * to receive messages from child iframes.
12
+ */
13
+ declare class PostMessageTransport extends BaseTransport {
14
+ readonly name = "postmessage";
15
+ isAvailable(): boolean;
16
+ send(message: string): void;
17
+ subscribe(listener: TransportListener): TransportUnsubscribe;
18
+ }
19
+ /**
20
+ * Detector for auto-detection registry
21
+ */
22
+ declare const postMessageDetector: TransportDetector;
23
+
24
+ /**
25
+ * Null transport - used when no transport is available
26
+ * All operations are no-ops. Useful for SSR or testing.
27
+ */
28
+ declare class NullTransport extends BaseTransport {
29
+ readonly name = "null";
30
+ isAvailable(): boolean;
31
+ send(_message: string): void;
32
+ subscribe(_listener: TransportListener): TransportUnsubscribe;
33
+ }
34
+
35
+ /**
36
+ * Registry for transport detectors
37
+ * Manages auto-detection of the current environment
38
+ */
39
+ declare class TransportRegistryClass {
40
+ private detectors;
41
+ private cachedTransport;
42
+ constructor();
43
+ /**
44
+ * Register a custom transport detector
45
+ * @param detector The detector to register
46
+ */
47
+ register(detector: TransportDetector): void;
48
+ /**
49
+ * Unregister a transport detector by name
50
+ * @param name Name of the detector to remove
51
+ */
52
+ unregister(name: string): void;
53
+ /**
54
+ * Get all registered detectors
55
+ */
56
+ getDetectors(): readonly TransportDetector[];
57
+ /**
58
+ * Detect and return the appropriate transport for the current environment
59
+ * Results are cached for performance
60
+ * @param forceRedetect Force re-detection (ignores cache)
61
+ */
62
+ detect(forceRedetect?: boolean): Transport;
63
+ /**
64
+ * Clear the cached transport (useful for testing)
65
+ */
66
+ clearCache(): void;
67
+ /**
68
+ * Reset registry to default state (built-in detectors only)
69
+ */
70
+ reset(): void;
71
+ }
72
+ /**
73
+ * Global transport registry instance
74
+ */
75
+ declare const TransportRegistry: TransportRegistryClass;
76
+ /**
77
+ * Convenience function to detect transport
78
+ */
79
+ declare const detectTransport: (forceRedetect?: boolean) => Transport;
80
+ /**
81
+ * Convenience function to register a custom detector
82
+ */
83
+ declare const registerTransport: (detector: TransportDetector) => void;
84
+
85
+ export { BaseTransport, NullTransport, PostMessageTransport, Transport, TransportDetector, TransportListener, TransportRegistry, TransportUnsubscribe, detectTransport, postMessageDetector, registerTransport };