@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.
- package/LICENSE +20 -0
- package/README.md +368 -0
- package/dist/BaseTransport-CxzIr1Ds.d.mts +80 -0
- package/dist/BaseTransport-CxzIr1Ds.d.ts +80 -0
- package/dist/cefsharp.d.mts +37 -0
- package/dist/cefsharp.d.ts +37 -0
- package/dist/cefsharp.js +65 -0
- package/dist/cefsharp.js.map +1 -0
- package/dist/cefsharp.mjs +62 -0
- package/dist/cefsharp.mjs.map +1 -0
- package/dist/iframe.d.mts +35 -0
- package/dist/iframe.d.ts +35 -0
- package/dist/iframe.js +75 -0
- package/dist/iframe.js.map +1 -0
- package/dist/iframe.mjs +72 -0
- package/dist/iframe.mjs.map +1 -0
- package/dist/index.d.mts +85 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +374 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +358 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react-native.d.mts +36 -0
- package/dist/react-native.d.ts +36 -0
- package/dist/react-native.js +65 -0
- package/dist/react-native.js.map +1 -0
- package/dist/react-native.mjs +62 -0
- package/dist/react-native.mjs.map +1 -0
- package/dist/window.d.mts +36 -0
- package/dist/window.d.ts +36 -0
- package/dist/window.js +79 -0
- package/dist/window.js.map +1 -0
- package/dist/window.mjs +76 -0
- package/dist/window.mjs.map +1 -0
- package/package.json +97 -0
- package/src/BaseTransport.test.ts +60 -0
- package/src/BaseTransport.ts +27 -0
- package/src/TransportRegistry.test.ts +345 -0
- package/src/TransportRegistry.ts +120 -0
- package/src/cefsharp.ts +3 -0
- package/src/iframe.ts +3 -0
- package/src/index.ts +26 -0
- package/src/react-native.ts +3 -0
- package/src/transports/CefSharpTransport.test.ts +187 -0
- package/src/transports/CefSharpTransport.ts +73 -0
- package/src/transports/IframeTransport.test.ts +212 -0
- package/src/transports/IframeTransport.ts +79 -0
- package/src/transports/NullTransport.test.ts +64 -0
- package/src/transports/NullTransport.ts +27 -0
- package/src/transports/PostMessageTransport.ts +50 -0
- package/src/transports/ReactNativeTransport.test.ts +196 -0
- package/src/transports/ReactNativeTransport.ts +73 -0
- package/src/transports/WindowTransport.ts +84 -0
- package/src/types.ts +69 -0
- 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 };
|
package/dist/iframe.d.ts
ADDED
|
@@ -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"]}
|
package/dist/iframe.mjs
ADDED
|
@@ -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"]}
|
package/dist/index.d.mts
ADDED
|
@@ -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 };
|
package/dist/index.d.ts
ADDED
|
@@ -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 };
|