@goodo/platform-plugin 0.1.2 → 0.1.5
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/dist/host-sdk.d.ts +64 -0
- package/dist/host-sdk.d.ts.map +1 -1
- package/dist/host.cjs +1 -1
- package/dist/host.cjs.map +1 -1
- package/dist/host.js +183 -35
- package/dist/host.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +91 -41
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +18 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/widget-sdk.d.ts +6 -5
- package/dist/widget-sdk.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/host-sdk.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Communicator, PingOptions } from './communicator';
|
|
2
2
|
import { ActionMap } from './types';
|
|
3
|
+
import { ResolvedWidgetManifest } from './manifest';
|
|
3
4
|
export declare class Host {
|
|
4
5
|
private _communicator;
|
|
5
6
|
private iframeWindow;
|
|
@@ -28,4 +29,67 @@ export declare class Host {
|
|
|
28
29
|
init(options?: PingOptions): Promise<Communicator>;
|
|
29
30
|
destroy(): void;
|
|
30
31
|
}
|
|
32
|
+
export type LocalWidgetProps = {
|
|
33
|
+
id?: string;
|
|
34
|
+
mainAddress: string;
|
|
35
|
+
editorAddress?: string;
|
|
36
|
+
runtimeAddress?: string;
|
|
37
|
+
};
|
|
38
|
+
export type ManifestUpdateHandler = (manifest: ResolvedWidgetManifest) => void;
|
|
39
|
+
export type ManifestErrorHandler = (errors: Array<{
|
|
40
|
+
path: string;
|
|
41
|
+
message: string;
|
|
42
|
+
}> | string) => void;
|
|
43
|
+
export type FileChangeHandler = (payload: {
|
|
44
|
+
file: string;
|
|
45
|
+
event: string;
|
|
46
|
+
}) => void;
|
|
47
|
+
export declare class LocalWidget implements LocalWidgetProps {
|
|
48
|
+
id: string;
|
|
49
|
+
mainAddress: string;
|
|
50
|
+
editorAddress?: string;
|
|
51
|
+
runtimeAddress?: string;
|
|
52
|
+
manifest: ResolvedWidgetManifest | null;
|
|
53
|
+
private ws;
|
|
54
|
+
private isDestroyed;
|
|
55
|
+
private reconnectTimer;
|
|
56
|
+
private manifestUpdateHandlers;
|
|
57
|
+
private manifestErrorHandlers;
|
|
58
|
+
private fileChangeHandlers;
|
|
59
|
+
constructor(props: LocalWidgetProps);
|
|
60
|
+
/**
|
|
61
|
+
* Initialize WebSocket connection for mini-HMR with the dev server
|
|
62
|
+
*/
|
|
63
|
+
initHMR(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Fetch the latest manifest from the dev server via HTTP
|
|
66
|
+
*/
|
|
67
|
+
fetchManifest(): Promise<ResolvedWidgetManifest | null>;
|
|
68
|
+
/**
|
|
69
|
+
* Subscribe to manifest update events
|
|
70
|
+
*/
|
|
71
|
+
onManifestUpdate(handler: ManifestUpdateHandler): () => void;
|
|
72
|
+
/**
|
|
73
|
+
* Subscribe to manifest validation errors
|
|
74
|
+
*/
|
|
75
|
+
onManifestError(handler: ManifestErrorHandler): () => void;
|
|
76
|
+
/**
|
|
77
|
+
* Subscribe to file change events in .goodo
|
|
78
|
+
*/
|
|
79
|
+
onFileChange(handler: FileChangeHandler): () => void;
|
|
80
|
+
/**
|
|
81
|
+
* Destroy the instance, closing WebSocket and cleaning up timers and listeners
|
|
82
|
+
*/
|
|
83
|
+
destroy(): void;
|
|
84
|
+
/**
|
|
85
|
+
* JSON serialization helper for localStorage
|
|
86
|
+
*/
|
|
87
|
+
toJSON(): LocalWidgetProps & {
|
|
88
|
+
id: string;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export declare const LOCAL_WIDGETS_STORAGE_KEY = "goodo_local_widgets";
|
|
92
|
+
export declare function getLocalWidgets(): LocalWidget[];
|
|
93
|
+
export declare function createLocalWidget(props: LocalWidgetProps): LocalWidget;
|
|
94
|
+
export declare function removeLocalWidget(id: string): void;
|
|
31
95
|
//# sourceMappingURL=host-sdk.d.ts.map
|
package/dist/host-sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-sdk.d.ts","sourceRoot":"","sources":["../src/host-sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAQ,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"host-sdk.d.ts","sourceRoot":"","sources":["../src/host-sdk.ts"],"names":[],"mappings":"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"}
|
package/dist/host.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var l=Object.defineProperty;var f=(n,e,t)=>e in n?l(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var r=(n,e,t)=>f(n,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./communicator-DQZOTxOF.cjs");class m{constructor(e){r(this,"_communicator",null);r(this,"iframeWindow");r(this,"subscriptions",new Set);r(this,"initPromise",null);r(this,"isDestroyed",!1);this.iframeWindow=e}get communicator(){if(!this._communicator)throw new Error("Host is not initialized. Call init() first.");return this._communicator}onMessage(e,t){const i={actionType:e,handler:t,off:null,cancelled:!1};return this._communicator&&(i.off=this._communicator.registerHandler(e,t)),this.subscriptions.add(i),()=>{i.cancelled||(i.cancelled=!0,this.subscriptions.delete(i),i.off&&(i.off(),i.off=null))}}async sendMessage(e,t,i){return this._communicator?this._communicator.sendRequest(e,t,i):this.initPromise?(await this.initPromise).sendRequest(e,t,i):this.communicator.sendRequest(e,t,i)}async init(e){if(this.isDestroyed)throw new Error("Host has already been destroyed.");return this._communicator?this._communicator:(this.initPromise||(this.initPromise=(async()=>{try{const t=await c.ping(this.iframeWindow,e);if(this.isDestroyed)throw t.destroy(),new Error("Host was destroyed during initialization.");this._communicator=t;for(const i of this.subscriptions)!i.cancelled&&!i.off&&(i.off=t.registerHandler(i.actionType,i.handler));return t}catch(t){throw this.initPromise=null,t}})()),this.initPromise)}destroy(){var e;this.isDestroyed=!0;for(const t of this.subscriptions)t.off&&(t.off(),t.off=null),t.cancelled=!0;this.subscriptions.clear(),(e=this._communicator)==null||e.destroy(),this._communicator=null,this.initPromise=null}}class d{constructor(e){r(this,"id");r(this,"mainAddress");r(this,"editorAddress");r(this,"runtimeAddress");r(this,"manifest",null);r(this,"ws",null);r(this,"isDestroyed",!1);r(this,"reconnectTimer",null);r(this,"manifestUpdateHandlers",new Set);r(this,"manifestErrorHandlers",new Set);r(this,"fileChangeHandlers",new Set);this.mainAddress=e.mainAddress.replace(/\/+$/,""),this.editorAddress=e.editorAddress,this.runtimeAddress=e.runtimeAddress,this.id=e.id||(typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now()}_${Math.random().toString(36).substring(2,9)}`),this.initHMR()}initHMR(){if(!(typeof window>"u"||typeof WebSocket>"u")&&!(this.ws||this.isDestroyed))try{const e=this.mainAddress.replace(/^http(s)?:\/\//i,(i,s)=>s?"wss://":"ws://"),t=new WebSocket(e);this.ws=t,t.onmessage=i=>{try{const s=JSON.parse(i.data);if(s.type==="manifest:update"&&s.data){this.manifest=s.data;for(const a of this.manifestUpdateHandlers)a(s.data)}else if(s.type==="manifest:error")for(const a of this.manifestErrorHandlers)a(s.errors||"Manifest error");else if(s.type==="file:change")for(const a of this.fileChangeHandlers)a({file:s.file,event:s.event})}catch(s){console.error("[LocalWidget] Failed to parse HMR message:",s)}},t.onerror=()=>{},t.onclose=()=>{this.ws=null,this.isDestroyed||(this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=setTimeout(()=>{this.isDestroyed||this.initHMR()},3e3))}}catch(e){console.error("[LocalWidget] Failed to initialize WebSocket HMR:",e)}}async fetchManifest(){if(typeof fetch>"u")return null;try{const e=`${this.mainAddress}/manifest.json`,t=await fetch(e);if(!t.ok)throw new Error(`Failed to fetch manifest: HTTP ${t.status}`);const i=await t.json();return this.manifest=i,i}catch(e){return console.error(`[LocalWidget] Failed to fetch manifest from ${this.mainAddress}:`,e),null}}onManifestUpdate(e){return this.manifestUpdateHandlers.add(e),this.manifest&&e(this.manifest),()=>{this.manifestUpdateHandlers.delete(e)}}onManifestError(e){return this.manifestErrorHandlers.add(e),()=>{this.manifestErrorHandlers.delete(e)}}onFileChange(e){return this.fileChangeHandlers.add(e),()=>{this.fileChangeHandlers.delete(e)}}destroy(){this.isDestroyed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(),this.ws=null),this.manifestUpdateHandlers.clear(),this.manifestErrorHandlers.clear(),this.fileChangeHandlers.clear()}toJSON(){return{id:this.id,mainAddress:this.mainAddress,editorAddress:this.editorAddress,runtimeAddress:this.runtimeAddress}}}const o="goodo_local_widgets";function u(){if(typeof localStorage>"u")return[];try{const n=localStorage.getItem(o);if(!n)return[];const e=JSON.parse(n);return Array.isArray(e)?e.map(t=>new d(t)):[]}catch{return[]}}function h(n){const e=new d(n);if(typeof localStorage<"u")try{const t=localStorage.getItem(o),i=t?JSON.parse(t):[],s=Array.isArray(i)?i:[];s.push(e.toJSON()),localStorage.setItem(o,JSON.stringify(s))}catch(t){console.error("Failed to save local widget to localStorage:",t)}return e}function g(n){if(!(typeof localStorage>"u"))try{const e=localStorage.getItem(o);if(!e)return;const t=JSON.parse(e);if(Array.isArray(t)){const i=t.filter(s=>s.id!==n);localStorage.setItem(o,JSON.stringify(i))}}catch(e){console.error("Failed to remove local widget from localStorage:",e)}}exports.Communicator=c.Communicator;exports.PING_TOKEN=c.PING_TOKEN;exports.PONG_TOKEN=c.PONG_TOKEN;exports.ping=c.ping;exports.Host=m;exports.LOCAL_WIDGETS_STORAGE_KEY=o;exports.LocalWidget=d;exports.createLocalWidget=h;exports.getLocalWidgets=u;exports.removeLocalWidget=g;
|
|
2
2
|
//# sourceMappingURL=host.cjs.map
|
package/dist/host.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.cjs","sources":["../src/host-sdk.ts"],"sourcesContent":["import { Communicator, ping, PingOptions } from './communicator';\nimport { ActionMap } from './types';\n\ninterface HostSubscription {\n actionType: keyof ActionMap;\n handler: (payload: any) => any;\n off: (() => void) | null;\n cancelled: boolean;\n}\n\nexport class Host {\n private _communicator: Communicator | null = null;\n\n private iframeWindow: Window;\n\n private subscriptions = new Set<HostSubscription>();\n\n private initPromise: Promise<Communicator> | null = null;\n\n private isDestroyed = false;\n\n private get communicator(): Communicator {\n if (!this._communicator) {\n throw new Error('Host is not initialized. Call init() first.');\n }\n return this._communicator;\n }\n\n /**\n * Initialize Host SDK for a specific iframe widget\n * @param iframeWindow The contentWindow of the widget's iframe\n */\n constructor(iframeWindow: Window) {\n this.iframeWindow = iframeWindow;\n }\n\n /**\n * Register a unified handler for a specific message action type.\n * Can be called before or after `init()`.\n * Returns an unsubscribe function.\n */\n public onMessage<A extends keyof ActionMap>(\n actionType: A,\n handler: (payload: Parameters<ActionMap[A]>[0]) => Promise<ReturnType<ActionMap[A]>> | ReturnType<ActionMap[A]>\n ): () => void {\n const sub: HostSubscription = {\n actionType,\n handler,\n off: null,\n cancelled: false,\n };\n\n if (this._communicator) {\n sub.off = this._communicator.registerHandler(actionType, handler);\n }\n\n this.subscriptions.add(sub);\n\n return () => {\n if (sub.cancelled) return;\n sub.cancelled = true;\n this.subscriptions.delete(sub);\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n };\n }\n\n /**\n * Send a message/request to the widget and wait for the response.\n */\n public async sendMessage<A extends keyof ActionMap>(\n actionType: A,\n payload?: Parameters<ActionMap[A]>[0],\n timeout?: number\n ): Promise<ReturnType<ActionMap[A]>> {\n if (this._communicator) {\n return this._communicator.sendRequest(actionType, payload, timeout);\n }\n\n if (this.initPromise) {\n const comm = await this.initPromise;\n\n return comm.sendRequest(actionType, payload, timeout);\n }\n\n return this.communicator.sendRequest(actionType, payload, timeout);\n }\n\n /**\n * Complete the handshake with the target widget iframe and attach all registered handlers.\n */\n public async init(options?: PingOptions): Promise<Communicator> {\n if (this.isDestroyed) {\n throw new Error('Host has already been destroyed.');\n }\n\n if (this._communicator) {\n return this._communicator;\n }\n\n if (!this.initPromise) {\n this.initPromise = (async () => {\n try {\n const comm = await ping(this.iframeWindow, options);\n\n if (this.isDestroyed) {\n comm.destroy();\n throw new Error('Host was destroyed during initialization.');\n }\n\n this._communicator = comm;\n\n // Attach all active subscriptions to communicator\n for (const sub of this.subscriptions) {\n if (!sub.cancelled && !sub.off) {\n sub.off = comm.registerHandler(sub.actionType, sub.handler);\n }\n }\n\n return comm;\n } catch (err) {\n this.initPromise = null;\n throw err;\n }\n })();\n }\n\n return this.initPromise;\n }\n\n public destroy(): void {\n this.isDestroyed = true;\n\n for (const sub of this.subscriptions) {\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n sub.cancelled = true;\n }\n this.subscriptions.clear();\n\n this._communicator?.destroy();\n\n this._communicator = null;\n\n this.initPromise = null;\n }\n}\n"],"names":["Host","iframeWindow","__publicField","actionType","handler","sub","payload","timeout","options","comm","ping","err","_a"],"mappings":"mSAUO,MAAMA,CAAK,CAsBhB,YAAYC,EAAsB,CArB1BC,EAAA,qBAAqC,MAErCA,EAAA,qBAEAA,EAAA,yBAAoB,KAEpBA,EAAA,mBAA4C,MAE5CA,EAAA,mBAAc,IAcpB,KAAK,aAAeD,CACtB,CAbA,IAAY,cAA6B,CACvC,GAAI,CAAC,KAAK,cACR,MAAM,IAAI,MAAM,6CAA6C,EAE/D,OAAO,KAAK,aACd,CAeO,UACLE,EACAC,EACY,CACZ,MAAMC,EAAwB,CAC5B,WAAAF,EACA,QAAAC,EACA,IAAK,KACL,UAAW,EAAA,EAGb,OAAI,KAAK,gBACPC,EAAI,IAAM,KAAK,cAAc,gBAAgBF,EAAYC,CAAO,GAGlE,KAAK,cAAc,IAAIC,CAAG,EAEnB,IAAM,CACPA,EAAI,YACRA,EAAI,UAAY,GAChB,KAAK,cAAc,OAAOA,CAAG,EACzBA,EAAI,MACNA,EAAI,IAAA,EACJA,EAAI,IAAM,MAEd,CACF,CAKA,MAAa,YACXF,EACAG,EACAC,EACmC,CACnC,OAAI,KAAK,cACA,KAAK,cAAc,YAAYJ,EAAYG,EAASC,CAAO,EAGhE,KAAK,aACM,MAAM,KAAK,aAEZ,YAAYJ,EAAYG,EAASC,CAAO,EAG/C,KAAK,aAAa,YAAYJ,EAAYG,EAASC,CAAO,CACnE,CAKA,MAAa,KAAKC,EAA8C,CAC9D,GAAI,KAAK,YACP,MAAM,IAAI,MAAM,kCAAkC,EAGpD,OAAI,KAAK,cACA,KAAK,eAGT,KAAK,cACR,KAAK,aAAe,SAAY,CAC9B,GAAI,CACF,MAAMC,EAAO,MAAMC,EAAAA,KAAK,KAAK,aAAcF,CAAO,EAElD,GAAI,KAAK,YACP,MAAAC,EAAK,QAAA,EACC,IAAI,MAAM,2CAA2C,EAG7D,KAAK,cAAgBA,EAGrB,UAAWJ,KAAO,KAAK,cACjB,CAACA,EAAI,WAAa,CAACA,EAAI,MACzBA,EAAI,IAAMI,EAAK,gBAAgBJ,EAAI,WAAYA,EAAI,OAAO,GAI9D,OAAOI,CACT,OAASE,EAAK,CACZ,WAAK,YAAc,KACbA,CACR,CACF,GAAA,GAGK,KAAK,YACd,CAEO,SAAgB,OACrB,KAAK,YAAc,GAEnB,UAAWN,KAAO,KAAK,cACjBA,EAAI,MACNA,EAAI,IAAA,EACJA,EAAI,IAAM,MAEZA,EAAI,UAAY,GAElB,KAAK,cAAc,MAAA,GAEnBO,EAAA,KAAK,gBAAL,MAAAA,EAAoB,UAEpB,KAAK,cAAgB,KAErB,KAAK,YAAc,IACrB,CACF"}
|
|
1
|
+
{"version":3,"file":"host.cjs","sources":["../src/host-sdk.ts"],"sourcesContent":["import { Communicator, ping, PingOptions } from './communicator';\nimport { ActionMap } from './types';\nimport type { ResolvedWidgetManifest } from './manifest';\n\ninterface HostSubscription {\n actionType: keyof ActionMap;\n handler: (payload: any) => any;\n off: (() => void) | null;\n cancelled: boolean;\n}\n\nexport class Host {\n private _communicator: Communicator | null = null;\n\n private iframeWindow: Window;\n\n private subscriptions = new Set<HostSubscription>();\n\n private initPromise: Promise<Communicator> | null = null;\n\n private isDestroyed = false;\n\n private get communicator(): Communicator {\n if (!this._communicator) {\n throw new Error('Host is not initialized. Call init() first.');\n }\n return this._communicator;\n }\n\n /**\n * Initialize Host SDK for a specific iframe widget\n * @param iframeWindow The contentWindow of the widget's iframe\n */\n constructor(iframeWindow: Window) {\n this.iframeWindow = iframeWindow;\n }\n\n /**\n * Register a unified handler for a specific message action type.\n * Can be called before or after `init()`.\n * Returns an unsubscribe function.\n */\n public onMessage<A extends keyof ActionMap>(\n actionType: A,\n handler: (payload: Parameters<ActionMap[A]>[0]) => Promise<ReturnType<ActionMap[A]>> | ReturnType<ActionMap[A]>\n ): () => void {\n const sub: HostSubscription = {\n actionType,\n handler,\n off: null,\n cancelled: false,\n };\n\n if (this._communicator) {\n sub.off = this._communicator.registerHandler(actionType, handler);\n }\n\n this.subscriptions.add(sub);\n\n return () => {\n if (sub.cancelled) return;\n sub.cancelled = true;\n this.subscriptions.delete(sub);\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n };\n }\n\n /**\n * Send a message/request to the widget and wait for the response.\n */\n public async sendMessage<A extends keyof ActionMap>(\n actionType: A,\n payload?: Parameters<ActionMap[A]>[0],\n timeout?: number\n ): Promise<ReturnType<ActionMap[A]>> {\n if (this._communicator) {\n return this._communicator.sendRequest(actionType, payload, timeout);\n }\n\n if (this.initPromise) {\n const comm = await this.initPromise;\n\n return comm.sendRequest(actionType, payload, timeout);\n }\n\n return this.communicator.sendRequest(actionType, payload, timeout);\n }\n\n /**\n * Complete the handshake with the target widget iframe and attach all registered handlers.\n */\n public async init(options?: PingOptions): Promise<Communicator> {\n if (this.isDestroyed) {\n throw new Error('Host has already been destroyed.');\n }\n\n if (this._communicator) {\n return this._communicator;\n }\n\n if (!this.initPromise) {\n this.initPromise = (async () => {\n try {\n const comm = await ping(this.iframeWindow, options);\n\n if (this.isDestroyed) {\n comm.destroy();\n throw new Error('Host was destroyed during initialization.');\n }\n\n this._communicator = comm;\n\n // Attach all active subscriptions to communicator\n for (const sub of this.subscriptions) {\n if (!sub.cancelled && !sub.off) {\n sub.off = comm.registerHandler(sub.actionType, sub.handler);\n }\n }\n\n return comm;\n } catch (err) {\n this.initPromise = null;\n throw err;\n }\n })();\n }\n\n return this.initPromise;\n }\n\n public destroy(): void {\n this.isDestroyed = true;\n\n for (const sub of this.subscriptions) {\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n sub.cancelled = true;\n }\n this.subscriptions.clear();\n\n this._communicator?.destroy();\n\n this._communicator = null;\n\n this.initPromise = null;\n }\n}\n\nexport type LocalWidgetProps = {\n id?: string;\n mainAddress: string;\n editorAddress?: string;\n runtimeAddress?: string;\n};\n\nexport type ManifestUpdateHandler = (manifest: ResolvedWidgetManifest) => void;\nexport type ManifestErrorHandler = (errors: Array<{ path: string; message: string }> | string) => void;\nexport type FileChangeHandler = (payload: { file: string; event: string }) => void;\n\nexport class LocalWidget implements LocalWidgetProps {\n id: string;\n\n mainAddress: string;\n\n editorAddress?: string;\n\n runtimeAddress?: string;\n\n manifest: ResolvedWidgetManifest | null = null;\n\n private ws: WebSocket | null = null;\n\n private isDestroyed = false;\n\n private reconnectTimer: any = null;\n\n private manifestUpdateHandlers = new Set<ManifestUpdateHandler>();\n\n private manifestErrorHandlers = new Set<ManifestErrorHandler>();\n\n private fileChangeHandlers = new Set<FileChangeHandler>();\n\n constructor(props: LocalWidgetProps) {\n this.mainAddress = props.mainAddress.replace(/\\/+$/, '');\n this.editorAddress = props.editorAddress;\n this.runtimeAddress = props.runtimeAddress;\n this.id =\n props.id ||\n (typeof crypto !== 'undefined' && crypto.randomUUID\n ? crypto.randomUUID()\n : `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`);\n\n this.initHMR();\n }\n\n /**\n * Initialize WebSocket connection for mini-HMR with the dev server\n */\n public initHMR(): void {\n if (typeof window === 'undefined' || typeof WebSocket === 'undefined') {\n return;\n }\n\n if (this.ws || this.isDestroyed) {\n return;\n }\n\n try {\n const wsUrl = this.mainAddress.replace(/^http(s)?:\\/\\//i, (_, s) => (s ? 'wss://' : 'ws://'));\n const ws = new WebSocket(wsUrl);\n this.ws = ws;\n\n ws.onmessage = (event) => {\n try {\n const msg = JSON.parse(event.data);\n if (msg.type === 'manifest:update' && msg.data) {\n this.manifest = msg.data;\n for (const handler of this.manifestUpdateHandlers) {\n handler(msg.data);\n }\n } else if (msg.type === 'manifest:error') {\n for (const handler of this.manifestErrorHandlers) {\n handler(msg.errors || 'Manifest error');\n }\n } else if (msg.type === 'file:change') {\n for (const handler of this.fileChangeHandlers) {\n handler({ file: msg.file, event: msg.event });\n }\n }\n } catch (e) {\n console.error('[LocalWidget] Failed to parse HMR message:', e);\n }\n };\n\n ws.onerror = () => { };\n\n ws.onclose = () => {\n this.ws = null;\n if (!this.isDestroyed) {\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\n this.reconnectTimer = setTimeout(() => {\n if (!this.isDestroyed) {\n this.initHMR();\n }\n }, 3000);\n }\n };\n } catch (e) {\n console.error('[LocalWidget] Failed to initialize WebSocket HMR:', e);\n }\n }\n\n /**\n * Fetch the latest manifest from the dev server via HTTP\n */\n public async fetchManifest(): Promise<ResolvedWidgetManifest | null> {\n if (typeof fetch === 'undefined') return null;\n try {\n const url = `${this.mainAddress}/manifest.json`;\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch manifest: HTTP ${res.status}`);\n }\n const data = (await res.json()) as ResolvedWidgetManifest;\n this.manifest = data;\n return data;\n } catch (e) {\n console.error(`[LocalWidget] Failed to fetch manifest from ${this.mainAddress}:`, e);\n return null;\n }\n }\n\n /**\n * Subscribe to manifest update events\n */\n public onManifestUpdate(handler: ManifestUpdateHandler): () => void {\n this.manifestUpdateHandlers.add(handler);\n if (this.manifest) {\n handler(this.manifest);\n }\n return () => {\n this.manifestUpdateHandlers.delete(handler);\n };\n }\n\n /**\n * Subscribe to manifest validation errors\n */\n public onManifestError(handler: ManifestErrorHandler): () => void {\n this.manifestErrorHandlers.add(handler);\n return () => {\n this.manifestErrorHandlers.delete(handler);\n };\n }\n\n /**\n * Subscribe to file change events in .goodo\n */\n public onFileChange(handler: FileChangeHandler): () => void {\n this.fileChangeHandlers.add(handler);\n return () => {\n this.fileChangeHandlers.delete(handler);\n };\n }\n\n /**\n * Destroy the instance, closing WebSocket and cleaning up timers and listeners\n */\n public destroy(): void {\n this.isDestroyed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n this.manifestUpdateHandlers.clear();\n this.manifestErrorHandlers.clear();\n this.fileChangeHandlers.clear();\n }\n\n /**\n * JSON serialization helper for localStorage\n */\n public toJSON(): LocalWidgetProps & { id: string } {\n return {\n id: this.id,\n mainAddress: this.mainAddress,\n editorAddress: this.editorAddress,\n runtimeAddress: this.runtimeAddress,\n };\n }\n}\n\nexport const LOCAL_WIDGETS_STORAGE_KEY = 'goodo_local_widgets';\n\nexport function getLocalWidgets(): LocalWidget[] {\n if (typeof localStorage === 'undefined') {\n return [];\n }\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.map((item: LocalWidgetProps) => new LocalWidget(item));\n } catch {\n return [];\n }\n}\n\nexport function createLocalWidget(props: LocalWidgetProps): LocalWidget {\n const localWidget = new LocalWidget(props);\n\n if (typeof localStorage !== 'undefined') {\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n const list = raw ? JSON.parse(raw) : [];\n const validList = Array.isArray(list) ? list : [];\n validList.push(localWidget.toJSON());\n localStorage.setItem(LOCAL_WIDGETS_STORAGE_KEY, JSON.stringify(validList));\n } catch (e) {\n console.error('Failed to save local widget to localStorage:', e);\n }\n }\n\n return localWidget;\n}\n\nexport function removeLocalWidget(id: string): void {\n if (typeof localStorage === 'undefined') return;\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return;\n const list = JSON.parse(raw);\n if (Array.isArray(list)) {\n const filtered = list.filter((item: { id: string }) => item.id !== id);\n localStorage.setItem(LOCAL_WIDGETS_STORAGE_KEY, JSON.stringify(filtered));\n }\n } catch (e) {\n console.error('Failed to remove local widget from localStorage:', e);\n }\n}"],"names":["Host","iframeWindow","__publicField","actionType","handler","sub","payload","timeout","options","comm","ping","err","_a","LocalWidget","props","wsUrl","_","ws","event","msg","e","url","res","data","LOCAL_WIDGETS_STORAGE_KEY","getLocalWidgets","raw","parsed","item","createLocalWidget","localWidget","list","validList","removeLocalWidget","id","filtered"],"mappings":"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"}
|
package/dist/host.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { p as
|
|
5
|
-
import { C as
|
|
6
|
-
class
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var l = (n, e, t) => e in n ? d(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
|
|
3
|
+
var r = (n, e, t) => l(n, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { p as f } from "./communicator-BF77R7Qs.js";
|
|
5
|
+
import { C as H, P as A, a as _ } from "./communicator-BF77R7Qs.js";
|
|
6
|
+
class u {
|
|
7
7
|
/**
|
|
8
8
|
* Initialize Host SDK for a specific iframe widget
|
|
9
9
|
* @param iframeWindow The contentWindow of the widget's iframe
|
|
10
10
|
*/
|
|
11
|
-
constructor(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
this.iframeWindow =
|
|
11
|
+
constructor(e) {
|
|
12
|
+
r(this, "_communicator", null);
|
|
13
|
+
r(this, "iframeWindow");
|
|
14
|
+
r(this, "subscriptions", /* @__PURE__ */ new Set());
|
|
15
|
+
r(this, "initPromise", null);
|
|
16
|
+
r(this, "isDestroyed", !1);
|
|
17
|
+
this.iframeWindow = e;
|
|
18
18
|
}
|
|
19
19
|
get communicator() {
|
|
20
20
|
if (!this._communicator)
|
|
@@ -26,56 +26,204 @@ class f {
|
|
|
26
26
|
* Can be called before or after `init()`.
|
|
27
27
|
* Returns an unsubscribe function.
|
|
28
28
|
*/
|
|
29
|
-
onMessage(
|
|
29
|
+
onMessage(e, t) {
|
|
30
30
|
const s = {
|
|
31
|
-
actionType:
|
|
32
|
-
handler:
|
|
31
|
+
actionType: e,
|
|
32
|
+
handler: t,
|
|
33
33
|
off: null,
|
|
34
34
|
cancelled: !1
|
|
35
35
|
};
|
|
36
|
-
return this._communicator && (s.off = this._communicator.registerHandler(
|
|
36
|
+
return this._communicator && (s.off = this._communicator.registerHandler(e, t)), this.subscriptions.add(s), () => {
|
|
37
37
|
s.cancelled || (s.cancelled = !0, this.subscriptions.delete(s), s.off && (s.off(), s.off = null));
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* Send a message/request to the widget and wait for the response.
|
|
42
42
|
*/
|
|
43
|
-
async sendMessage(
|
|
44
|
-
return this._communicator ? this._communicator.sendRequest(
|
|
43
|
+
async sendMessage(e, t, s) {
|
|
44
|
+
return this._communicator ? this._communicator.sendRequest(e, t, s) : this.initPromise ? (await this.initPromise).sendRequest(e, t, s) : this.communicator.sendRequest(e, t, s);
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* Complete the handshake with the target widget iframe and attach all registered handlers.
|
|
48
48
|
*/
|
|
49
|
-
async init(
|
|
49
|
+
async init(e) {
|
|
50
50
|
if (this.isDestroyed)
|
|
51
51
|
throw new Error("Host has already been destroyed.");
|
|
52
52
|
return this._communicator ? this._communicator : (this.initPromise || (this.initPromise = (async () => {
|
|
53
53
|
try {
|
|
54
|
-
const
|
|
54
|
+
const t = await f(this.iframeWindow, e);
|
|
55
55
|
if (this.isDestroyed)
|
|
56
|
-
throw
|
|
57
|
-
this._communicator =
|
|
56
|
+
throw t.destroy(), new Error("Host was destroyed during initialization.");
|
|
57
|
+
this._communicator = t;
|
|
58
58
|
for (const s of this.subscriptions)
|
|
59
|
-
!s.cancelled && !s.off && (s.off =
|
|
60
|
-
return
|
|
61
|
-
} catch (
|
|
62
|
-
throw this.initPromise = null,
|
|
59
|
+
!s.cancelled && !s.off && (s.off = t.registerHandler(s.actionType, s.handler));
|
|
60
|
+
return t;
|
|
61
|
+
} catch (t) {
|
|
62
|
+
throw this.initPromise = null, t;
|
|
63
63
|
}
|
|
64
64
|
})()), this.initPromise);
|
|
65
65
|
}
|
|
66
66
|
destroy() {
|
|
67
|
-
var
|
|
67
|
+
var e;
|
|
68
68
|
this.isDestroyed = !0;
|
|
69
|
-
for (const
|
|
70
|
-
|
|
71
|
-
this.subscriptions.clear(), (
|
|
69
|
+
for (const t of this.subscriptions)
|
|
70
|
+
t.off && (t.off(), t.off = null), t.cancelled = !0;
|
|
71
|
+
this.subscriptions.clear(), (e = this._communicator) == null || e.destroy(), this._communicator = null, this.initPromise = null;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
+
class c {
|
|
75
|
+
constructor(e) {
|
|
76
|
+
r(this, "id");
|
|
77
|
+
r(this, "mainAddress");
|
|
78
|
+
r(this, "editorAddress");
|
|
79
|
+
r(this, "runtimeAddress");
|
|
80
|
+
r(this, "manifest", null);
|
|
81
|
+
r(this, "ws", null);
|
|
82
|
+
r(this, "isDestroyed", !1);
|
|
83
|
+
r(this, "reconnectTimer", null);
|
|
84
|
+
r(this, "manifestUpdateHandlers", /* @__PURE__ */ new Set());
|
|
85
|
+
r(this, "manifestErrorHandlers", /* @__PURE__ */ new Set());
|
|
86
|
+
r(this, "fileChangeHandlers", /* @__PURE__ */ new Set());
|
|
87
|
+
this.mainAddress = e.mainAddress.replace(/\/+$/, ""), this.editorAddress = e.editorAddress, this.runtimeAddress = e.runtimeAddress, this.id = e.id || (typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`), this.initHMR();
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Initialize WebSocket connection for mini-HMR with the dev server
|
|
91
|
+
*/
|
|
92
|
+
initHMR() {
|
|
93
|
+
if (!(typeof window > "u" || typeof WebSocket > "u") && !(this.ws || this.isDestroyed))
|
|
94
|
+
try {
|
|
95
|
+
const e = this.mainAddress.replace(/^http(s)?:\/\//i, (s, i) => i ? "wss://" : "ws://"), t = new WebSocket(e);
|
|
96
|
+
this.ws = t, t.onmessage = (s) => {
|
|
97
|
+
try {
|
|
98
|
+
const i = JSON.parse(s.data);
|
|
99
|
+
if (i.type === "manifest:update" && i.data) {
|
|
100
|
+
this.manifest = i.data;
|
|
101
|
+
for (const o of this.manifestUpdateHandlers)
|
|
102
|
+
o(i.data);
|
|
103
|
+
} else if (i.type === "manifest:error")
|
|
104
|
+
for (const o of this.manifestErrorHandlers)
|
|
105
|
+
o(i.errors || "Manifest error");
|
|
106
|
+
else if (i.type === "file:change")
|
|
107
|
+
for (const o of this.fileChangeHandlers)
|
|
108
|
+
o({ file: i.file, event: i.event });
|
|
109
|
+
} catch (i) {
|
|
110
|
+
console.error("[LocalWidget] Failed to parse HMR message:", i);
|
|
111
|
+
}
|
|
112
|
+
}, t.onerror = () => {
|
|
113
|
+
}, t.onclose = () => {
|
|
114
|
+
this.ws = null, this.isDestroyed || (this.reconnectTimer && clearTimeout(this.reconnectTimer), this.reconnectTimer = setTimeout(() => {
|
|
115
|
+
this.isDestroyed || this.initHMR();
|
|
116
|
+
}, 3e3));
|
|
117
|
+
};
|
|
118
|
+
} catch (e) {
|
|
119
|
+
console.error("[LocalWidget] Failed to initialize WebSocket HMR:", e);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Fetch the latest manifest from the dev server via HTTP
|
|
124
|
+
*/
|
|
125
|
+
async fetchManifest() {
|
|
126
|
+
if (typeof fetch > "u") return null;
|
|
127
|
+
try {
|
|
128
|
+
const e = `${this.mainAddress}/manifest.json`, t = await fetch(e);
|
|
129
|
+
if (!t.ok)
|
|
130
|
+
throw new Error(`Failed to fetch manifest: HTTP ${t.status}`);
|
|
131
|
+
const s = await t.json();
|
|
132
|
+
return this.manifest = s, s;
|
|
133
|
+
} catch (e) {
|
|
134
|
+
return console.error(`[LocalWidget] Failed to fetch manifest from ${this.mainAddress}:`, e), null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Subscribe to manifest update events
|
|
139
|
+
*/
|
|
140
|
+
onManifestUpdate(e) {
|
|
141
|
+
return this.manifestUpdateHandlers.add(e), this.manifest && e(this.manifest), () => {
|
|
142
|
+
this.manifestUpdateHandlers.delete(e);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Subscribe to manifest validation errors
|
|
147
|
+
*/
|
|
148
|
+
onManifestError(e) {
|
|
149
|
+
return this.manifestErrorHandlers.add(e), () => {
|
|
150
|
+
this.manifestErrorHandlers.delete(e);
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Subscribe to file change events in .goodo
|
|
155
|
+
*/
|
|
156
|
+
onFileChange(e) {
|
|
157
|
+
return this.fileChangeHandlers.add(e), () => {
|
|
158
|
+
this.fileChangeHandlers.delete(e);
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Destroy the instance, closing WebSocket and cleaning up timers and listeners
|
|
163
|
+
*/
|
|
164
|
+
destroy() {
|
|
165
|
+
this.isDestroyed = !0, this.reconnectTimer && (clearTimeout(this.reconnectTimer), this.reconnectTimer = null), this.ws && (this.ws.close(), this.ws = null), this.manifestUpdateHandlers.clear(), this.manifestErrorHandlers.clear(), this.fileChangeHandlers.clear();
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* JSON serialization helper for localStorage
|
|
169
|
+
*/
|
|
170
|
+
toJSON() {
|
|
171
|
+
return {
|
|
172
|
+
id: this.id,
|
|
173
|
+
mainAddress: this.mainAddress,
|
|
174
|
+
editorAddress: this.editorAddress,
|
|
175
|
+
runtimeAddress: this.runtimeAddress
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const a = "goodo_local_widgets";
|
|
180
|
+
function g() {
|
|
181
|
+
if (typeof localStorage > "u")
|
|
182
|
+
return [];
|
|
183
|
+
try {
|
|
184
|
+
const n = localStorage.getItem(a);
|
|
185
|
+
if (!n) return [];
|
|
186
|
+
const e = JSON.parse(n);
|
|
187
|
+
return Array.isArray(e) ? e.map((t) => new c(t)) : [];
|
|
188
|
+
} catch {
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function w(n) {
|
|
193
|
+
const e = new c(n);
|
|
194
|
+
if (typeof localStorage < "u")
|
|
195
|
+
try {
|
|
196
|
+
const t = localStorage.getItem(a), s = t ? JSON.parse(t) : [], i = Array.isArray(s) ? s : [];
|
|
197
|
+
i.push(e.toJSON()), localStorage.setItem(a, JSON.stringify(i));
|
|
198
|
+
} catch (t) {
|
|
199
|
+
console.error("Failed to save local widget to localStorage:", t);
|
|
200
|
+
}
|
|
201
|
+
return e;
|
|
202
|
+
}
|
|
203
|
+
function y(n) {
|
|
204
|
+
if (!(typeof localStorage > "u"))
|
|
205
|
+
try {
|
|
206
|
+
const e = localStorage.getItem(a);
|
|
207
|
+
if (!e) return;
|
|
208
|
+
const t = JSON.parse(e);
|
|
209
|
+
if (Array.isArray(t)) {
|
|
210
|
+
const s = t.filter((i) => i.id !== n);
|
|
211
|
+
localStorage.setItem(a, JSON.stringify(s));
|
|
212
|
+
}
|
|
213
|
+
} catch (e) {
|
|
214
|
+
console.error("Failed to remove local widget from localStorage:", e);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
74
217
|
export {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
218
|
+
H as Communicator,
|
|
219
|
+
u as Host,
|
|
220
|
+
a as LOCAL_WIDGETS_STORAGE_KEY,
|
|
221
|
+
c as LocalWidget,
|
|
222
|
+
A as PING_TOKEN,
|
|
78
223
|
_ as PONG_TOKEN,
|
|
79
|
-
|
|
224
|
+
w as createLocalWidget,
|
|
225
|
+
g as getLocalWidgets,
|
|
226
|
+
f as ping,
|
|
227
|
+
y as removeLocalWidget
|
|
80
228
|
};
|
|
81
229
|
//# sourceMappingURL=host.js.map
|
package/dist/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","sources":["../src/host-sdk.ts"],"sourcesContent":["import { Communicator, ping, PingOptions } from './communicator';\nimport { ActionMap } from './types';\n\ninterface HostSubscription {\n actionType: keyof ActionMap;\n handler: (payload: any) => any;\n off: (() => void) | null;\n cancelled: boolean;\n}\n\nexport class Host {\n private _communicator: Communicator | null = null;\n\n private iframeWindow: Window;\n\n private subscriptions = new Set<HostSubscription>();\n\n private initPromise: Promise<Communicator> | null = null;\n\n private isDestroyed = false;\n\n private get communicator(): Communicator {\n if (!this._communicator) {\n throw new Error('Host is not initialized. Call init() first.');\n }\n return this._communicator;\n }\n\n /**\n * Initialize Host SDK for a specific iframe widget\n * @param iframeWindow The contentWindow of the widget's iframe\n */\n constructor(iframeWindow: Window) {\n this.iframeWindow = iframeWindow;\n }\n\n /**\n * Register a unified handler for a specific message action type.\n * Can be called before or after `init()`.\n * Returns an unsubscribe function.\n */\n public onMessage<A extends keyof ActionMap>(\n actionType: A,\n handler: (payload: Parameters<ActionMap[A]>[0]) => Promise<ReturnType<ActionMap[A]>> | ReturnType<ActionMap[A]>\n ): () => void {\n const sub: HostSubscription = {\n actionType,\n handler,\n off: null,\n cancelled: false,\n };\n\n if (this._communicator) {\n sub.off = this._communicator.registerHandler(actionType, handler);\n }\n\n this.subscriptions.add(sub);\n\n return () => {\n if (sub.cancelled) return;\n sub.cancelled = true;\n this.subscriptions.delete(sub);\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n };\n }\n\n /**\n * Send a message/request to the widget and wait for the response.\n */\n public async sendMessage<A extends keyof ActionMap>(\n actionType: A,\n payload?: Parameters<ActionMap[A]>[0],\n timeout?: number\n ): Promise<ReturnType<ActionMap[A]>> {\n if (this._communicator) {\n return this._communicator.sendRequest(actionType, payload, timeout);\n }\n\n if (this.initPromise) {\n const comm = await this.initPromise;\n\n return comm.sendRequest(actionType, payload, timeout);\n }\n\n return this.communicator.sendRequest(actionType, payload, timeout);\n }\n\n /**\n * Complete the handshake with the target widget iframe and attach all registered handlers.\n */\n public async init(options?: PingOptions): Promise<Communicator> {\n if (this.isDestroyed) {\n throw new Error('Host has already been destroyed.');\n }\n\n if (this._communicator) {\n return this._communicator;\n }\n\n if (!this.initPromise) {\n this.initPromise = (async () => {\n try {\n const comm = await ping(this.iframeWindow, options);\n\n if (this.isDestroyed) {\n comm.destroy();\n throw new Error('Host was destroyed during initialization.');\n }\n\n this._communicator = comm;\n\n // Attach all active subscriptions to communicator\n for (const sub of this.subscriptions) {\n if (!sub.cancelled && !sub.off) {\n sub.off = comm.registerHandler(sub.actionType, sub.handler);\n }\n }\n\n return comm;\n } catch (err) {\n this.initPromise = null;\n throw err;\n }\n })();\n }\n\n return this.initPromise;\n }\n\n public destroy(): void {\n this.isDestroyed = true;\n\n for (const sub of this.subscriptions) {\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n sub.cancelled = true;\n }\n this.subscriptions.clear();\n\n this._communicator?.destroy();\n\n this._communicator = null;\n\n this.initPromise = null;\n }\n}\n"],"names":["Host","iframeWindow","__publicField","actionType","handler","sub","payload","timeout","options","comm","ping","err","_a"],"mappings":";;;;;AAUO,MAAMA,EAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBhB,YAAYC,GAAsB;AArB1B,IAAAC,EAAA,uBAAqC;AAErC,IAAAA,EAAA;AAEA,IAAAA,EAAA,2CAAoB,IAAA;AAEpB,IAAAA,EAAA,qBAA4C;AAE5C,IAAAA,EAAA,qBAAc;AAcpB,SAAK,eAAeD;AAAA,EACtB;AAAA,EAbA,IAAY,eAA6B;AACvC,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,6CAA6C;AAE/D,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeO,UACLE,GACAC,GACY;AACZ,UAAMC,IAAwB;AAAA,MAC5B,YAAAF;AAAA,MACA,SAAAC;AAAA,MACA,KAAK;AAAA,MACL,WAAW;AAAA,IAAA;AAGb,WAAI,KAAK,kBACPC,EAAI,MAAM,KAAK,cAAc,gBAAgBF,GAAYC,CAAO,IAGlE,KAAK,cAAc,IAAIC,CAAG,GAEnB,MAAM;AACX,MAAIA,EAAI,cACRA,EAAI,YAAY,IAChB,KAAK,cAAc,OAAOA,CAAG,GACzBA,EAAI,QACNA,EAAI,IAAA,GACJA,EAAI,MAAM;AAAA,IAEd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,YACXF,GACAG,GACAC,GACmC;AACnC,WAAI,KAAK,gBACA,KAAK,cAAc,YAAYJ,GAAYG,GAASC,CAAO,IAGhE,KAAK,eACM,MAAM,KAAK,aAEZ,YAAYJ,GAAYG,GAASC,CAAO,IAG/C,KAAK,aAAa,YAAYJ,GAAYG,GAASC,CAAO;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,KAAKC,GAA8C;AAC9D,QAAI,KAAK;AACP,YAAM,IAAI,MAAM,kCAAkC;AAGpD,WAAI,KAAK,gBACA,KAAK,iBAGT,KAAK,gBACR,KAAK,eAAe,YAAY;AAC9B,UAAI;AACF,cAAMC,IAAO,MAAMC,EAAK,KAAK,cAAcF,CAAO;AAElD,YAAI,KAAK;AACP,gBAAAC,EAAK,QAAA,GACC,IAAI,MAAM,2CAA2C;AAG7D,aAAK,gBAAgBA;AAGrB,mBAAWJ,KAAO,KAAK;AACrB,UAAI,CAACA,EAAI,aAAa,CAACA,EAAI,QACzBA,EAAI,MAAMI,EAAK,gBAAgBJ,EAAI,YAAYA,EAAI,OAAO;AAI9D,eAAOI;AAAA,MACT,SAASE,GAAK;AACZ,mBAAK,cAAc,MACbA;AAAA,MACR;AAAA,IACF,GAAA,IAGK,KAAK;AAAA,EACd;AAAA,EAEO,UAAgB;;AACrB,SAAK,cAAc;AAEnB,eAAWN,KAAO,KAAK;AACrB,MAAIA,EAAI,QACNA,EAAI,IAAA,GACJA,EAAI,MAAM,OAEZA,EAAI,YAAY;AAElB,SAAK,cAAc,MAAA,IAEnBO,IAAA,KAAK,kBAAL,QAAAA,EAAoB,WAEpB,KAAK,gBAAgB,MAErB,KAAK,cAAc;AAAA,EACrB;AACF;"}
|
|
1
|
+
{"version":3,"file":"host.js","sources":["../src/host-sdk.ts"],"sourcesContent":["import { Communicator, ping, PingOptions } from './communicator';\nimport { ActionMap } from './types';\nimport type { ResolvedWidgetManifest } from './manifest';\n\ninterface HostSubscription {\n actionType: keyof ActionMap;\n handler: (payload: any) => any;\n off: (() => void) | null;\n cancelled: boolean;\n}\n\nexport class Host {\n private _communicator: Communicator | null = null;\n\n private iframeWindow: Window;\n\n private subscriptions = new Set<HostSubscription>();\n\n private initPromise: Promise<Communicator> | null = null;\n\n private isDestroyed = false;\n\n private get communicator(): Communicator {\n if (!this._communicator) {\n throw new Error('Host is not initialized. Call init() first.');\n }\n return this._communicator;\n }\n\n /**\n * Initialize Host SDK for a specific iframe widget\n * @param iframeWindow The contentWindow of the widget's iframe\n */\n constructor(iframeWindow: Window) {\n this.iframeWindow = iframeWindow;\n }\n\n /**\n * Register a unified handler for a specific message action type.\n * Can be called before or after `init()`.\n * Returns an unsubscribe function.\n */\n public onMessage<A extends keyof ActionMap>(\n actionType: A,\n handler: (payload: Parameters<ActionMap[A]>[0]) => Promise<ReturnType<ActionMap[A]>> | ReturnType<ActionMap[A]>\n ): () => void {\n const sub: HostSubscription = {\n actionType,\n handler,\n off: null,\n cancelled: false,\n };\n\n if (this._communicator) {\n sub.off = this._communicator.registerHandler(actionType, handler);\n }\n\n this.subscriptions.add(sub);\n\n return () => {\n if (sub.cancelled) return;\n sub.cancelled = true;\n this.subscriptions.delete(sub);\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n };\n }\n\n /**\n * Send a message/request to the widget and wait for the response.\n */\n public async sendMessage<A extends keyof ActionMap>(\n actionType: A,\n payload?: Parameters<ActionMap[A]>[0],\n timeout?: number\n ): Promise<ReturnType<ActionMap[A]>> {\n if (this._communicator) {\n return this._communicator.sendRequest(actionType, payload, timeout);\n }\n\n if (this.initPromise) {\n const comm = await this.initPromise;\n\n return comm.sendRequest(actionType, payload, timeout);\n }\n\n return this.communicator.sendRequest(actionType, payload, timeout);\n }\n\n /**\n * Complete the handshake with the target widget iframe and attach all registered handlers.\n */\n public async init(options?: PingOptions): Promise<Communicator> {\n if (this.isDestroyed) {\n throw new Error('Host has already been destroyed.');\n }\n\n if (this._communicator) {\n return this._communicator;\n }\n\n if (!this.initPromise) {\n this.initPromise = (async () => {\n try {\n const comm = await ping(this.iframeWindow, options);\n\n if (this.isDestroyed) {\n comm.destroy();\n throw new Error('Host was destroyed during initialization.');\n }\n\n this._communicator = comm;\n\n // Attach all active subscriptions to communicator\n for (const sub of this.subscriptions) {\n if (!sub.cancelled && !sub.off) {\n sub.off = comm.registerHandler(sub.actionType, sub.handler);\n }\n }\n\n return comm;\n } catch (err) {\n this.initPromise = null;\n throw err;\n }\n })();\n }\n\n return this.initPromise;\n }\n\n public destroy(): void {\n this.isDestroyed = true;\n\n for (const sub of this.subscriptions) {\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n sub.cancelled = true;\n }\n this.subscriptions.clear();\n\n this._communicator?.destroy();\n\n this._communicator = null;\n\n this.initPromise = null;\n }\n}\n\nexport type LocalWidgetProps = {\n id?: string;\n mainAddress: string;\n editorAddress?: string;\n runtimeAddress?: string;\n};\n\nexport type ManifestUpdateHandler = (manifest: ResolvedWidgetManifest) => void;\nexport type ManifestErrorHandler = (errors: Array<{ path: string; message: string }> | string) => void;\nexport type FileChangeHandler = (payload: { file: string; event: string }) => void;\n\nexport class LocalWidget implements LocalWidgetProps {\n id: string;\n\n mainAddress: string;\n\n editorAddress?: string;\n\n runtimeAddress?: string;\n\n manifest: ResolvedWidgetManifest | null = null;\n\n private ws: WebSocket | null = null;\n\n private isDestroyed = false;\n\n private reconnectTimer: any = null;\n\n private manifestUpdateHandlers = new Set<ManifestUpdateHandler>();\n\n private manifestErrorHandlers = new Set<ManifestErrorHandler>();\n\n private fileChangeHandlers = new Set<FileChangeHandler>();\n\n constructor(props: LocalWidgetProps) {\n this.mainAddress = props.mainAddress.replace(/\\/+$/, '');\n this.editorAddress = props.editorAddress;\n this.runtimeAddress = props.runtimeAddress;\n this.id =\n props.id ||\n (typeof crypto !== 'undefined' && crypto.randomUUID\n ? crypto.randomUUID()\n : `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`);\n\n this.initHMR();\n }\n\n /**\n * Initialize WebSocket connection for mini-HMR with the dev server\n */\n public initHMR(): void {\n if (typeof window === 'undefined' || typeof WebSocket === 'undefined') {\n return;\n }\n\n if (this.ws || this.isDestroyed) {\n return;\n }\n\n try {\n const wsUrl = this.mainAddress.replace(/^http(s)?:\\/\\//i, (_, s) => (s ? 'wss://' : 'ws://'));\n const ws = new WebSocket(wsUrl);\n this.ws = ws;\n\n ws.onmessage = (event) => {\n try {\n const msg = JSON.parse(event.data);\n if (msg.type === 'manifest:update' && msg.data) {\n this.manifest = msg.data;\n for (const handler of this.manifestUpdateHandlers) {\n handler(msg.data);\n }\n } else if (msg.type === 'manifest:error') {\n for (const handler of this.manifestErrorHandlers) {\n handler(msg.errors || 'Manifest error');\n }\n } else if (msg.type === 'file:change') {\n for (const handler of this.fileChangeHandlers) {\n handler({ file: msg.file, event: msg.event });\n }\n }\n } catch (e) {\n console.error('[LocalWidget] Failed to parse HMR message:', e);\n }\n };\n\n ws.onerror = () => { };\n\n ws.onclose = () => {\n this.ws = null;\n if (!this.isDestroyed) {\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\n this.reconnectTimer = setTimeout(() => {\n if (!this.isDestroyed) {\n this.initHMR();\n }\n }, 3000);\n }\n };\n } catch (e) {\n console.error('[LocalWidget] Failed to initialize WebSocket HMR:', e);\n }\n }\n\n /**\n * Fetch the latest manifest from the dev server via HTTP\n */\n public async fetchManifest(): Promise<ResolvedWidgetManifest | null> {\n if (typeof fetch === 'undefined') return null;\n try {\n const url = `${this.mainAddress}/manifest.json`;\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch manifest: HTTP ${res.status}`);\n }\n const data = (await res.json()) as ResolvedWidgetManifest;\n this.manifest = data;\n return data;\n } catch (e) {\n console.error(`[LocalWidget] Failed to fetch manifest from ${this.mainAddress}:`, e);\n return null;\n }\n }\n\n /**\n * Subscribe to manifest update events\n */\n public onManifestUpdate(handler: ManifestUpdateHandler): () => void {\n this.manifestUpdateHandlers.add(handler);\n if (this.manifest) {\n handler(this.manifest);\n }\n return () => {\n this.manifestUpdateHandlers.delete(handler);\n };\n }\n\n /**\n * Subscribe to manifest validation errors\n */\n public onManifestError(handler: ManifestErrorHandler): () => void {\n this.manifestErrorHandlers.add(handler);\n return () => {\n this.manifestErrorHandlers.delete(handler);\n };\n }\n\n /**\n * Subscribe to file change events in .goodo\n */\n public onFileChange(handler: FileChangeHandler): () => void {\n this.fileChangeHandlers.add(handler);\n return () => {\n this.fileChangeHandlers.delete(handler);\n };\n }\n\n /**\n * Destroy the instance, closing WebSocket and cleaning up timers and listeners\n */\n public destroy(): void {\n this.isDestroyed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n this.manifestUpdateHandlers.clear();\n this.manifestErrorHandlers.clear();\n this.fileChangeHandlers.clear();\n }\n\n /**\n * JSON serialization helper for localStorage\n */\n public toJSON(): LocalWidgetProps & { id: string } {\n return {\n id: this.id,\n mainAddress: this.mainAddress,\n editorAddress: this.editorAddress,\n runtimeAddress: this.runtimeAddress,\n };\n }\n}\n\nexport const LOCAL_WIDGETS_STORAGE_KEY = 'goodo_local_widgets';\n\nexport function getLocalWidgets(): LocalWidget[] {\n if (typeof localStorage === 'undefined') {\n return [];\n }\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.map((item: LocalWidgetProps) => new LocalWidget(item));\n } catch {\n return [];\n }\n}\n\nexport function createLocalWidget(props: LocalWidgetProps): LocalWidget {\n const localWidget = new LocalWidget(props);\n\n if (typeof localStorage !== 'undefined') {\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n const list = raw ? JSON.parse(raw) : [];\n const validList = Array.isArray(list) ? list : [];\n validList.push(localWidget.toJSON());\n localStorage.setItem(LOCAL_WIDGETS_STORAGE_KEY, JSON.stringify(validList));\n } catch (e) {\n console.error('Failed to save local widget to localStorage:', e);\n }\n }\n\n return localWidget;\n}\n\nexport function removeLocalWidget(id: string): void {\n if (typeof localStorage === 'undefined') return;\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return;\n const list = JSON.parse(raw);\n if (Array.isArray(list)) {\n const filtered = list.filter((item: { id: string }) => item.id !== id);\n localStorage.setItem(LOCAL_WIDGETS_STORAGE_KEY, JSON.stringify(filtered));\n }\n } catch (e) {\n console.error('Failed to remove local widget from localStorage:', e);\n }\n}"],"names":["Host","iframeWindow","__publicField","actionType","handler","sub","payload","timeout","options","comm","ping","err","_a","LocalWidget","props","wsUrl","_","s","ws","event","msg","e","url","res","data","LOCAL_WIDGETS_STORAGE_KEY","getLocalWidgets","raw","parsed","item","createLocalWidget","localWidget","list","validList","removeLocalWidget","id","filtered"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("./communicator-DQZOTxOF.cjs");let f=null;function u(t){return f||(f=l.pong(t).catch(e=>{throw f=null,e})),f}function z(t){u().then(e=>e.sendRequest("widget_ready")).then(e=>{t(e)}).catch(e=>{console.error("Failed to initialize widget:",e)})}function C(t,e){const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Math.random().toString(36).substring(2,9);let i=!1,a=null,c=null;return u().then(o=>{c=o,!i&&(a=o.registerHandler("widget_data_source_update",s=>{(s==null?void 0:s.identity)===n&&e(s.data||[])}),o.sendRequest("add_widget_data_source_listener",{identity:n,config:t}).catch(s=>{console.error("Failed to add data source listener:",s)}))}).catch(o=>{console.error("Failed to initialize communicator for data source listener:",o)}),()=>{i=!0,a&&a(),c&&c.sendRequest("remove_widget_data_source_listener",{identity:n}).catch(o=>{console.error("Failed to remove data source listener:",o)})}}async function D(t,e){return await(await u()).sendRequest("emit_widget_event",{type:t,args:e})}async function I(t){return await(await u()).sendRequest("set_widget_personalization",t)}function N(t){let e=!1,n=null;return u().then(i=>{e||(n=i.registerHandler("widget_filter_change",a=>{t(a)}))}).catch(i=>{console.error("Failed to initialize communicator for filter change listener:",i)}),()=>{e=!0,n&&n()}}async function _(t){return await(await u()).sendRequest("fetch_node_data",t)}function R(t){async function e(r){return await _({...t,...r})}const n=new Set;let i=null,a=!1,c=null,o=null;async function s(){if(a||c)return;a=!0;const r=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Math.random().toString(36).substring(2,9);i=r;try{const d=await u();if(o=d,n.size===0||i!==r)return;c=d.registerHandler("widget_data_source_update",m=>{(m==null?void 0:m.identity)===r&&n.forEach(w=>{try{w()}catch(y){console.error("Error in widget data source onChange callback:",y)}})}),await d.sendRequest("add_widget_data_source_listener",{identity:r,config:t})}catch(d){console.error("Failed to initialize communicator for data source listener:",d)}finally{a=!1,n.size===0&&i===r&&g()}}function g(){const r=i;i=null,a=!1,c&&(c(),c=null),o&&r&&o.sendRequest("remove_widget_data_source_listener",{identity:r}).catch(d=>{console.error("Failed to remove data source listener:",d)})}function h(r){return n.add(r),n.size===1&&s(),()=>{n.delete(r),n.size===0&&g()}}return{fetch:e,onChange:h}}exports.Communicator=l.Communicator;exports.PING_TOKEN=l.PING_TOKEN;exports.PONG_TOKEN=l.PONG_TOKEN;exports.pong=l.pong;exports.addDataSourceListener=C;exports.createDataSource=R;exports.emitWidgetEvent=D;exports.fetchNodeData=_;exports.onWidgetFilterChange=N;exports.onWidgetReady=z;exports.setWidgetPersonalization=I;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/widget-sdk.ts"],"sourcesContent":["import { Communicator, pong, OnPingOptions } from './communicator';\nimport { DataSourceConfig, WidgetConfig } from './types';\n\nlet communicatorPromise: Promise<Communicator> | null = null;\n\n/**\n * Get or initialize the Communicator instance for the widget.\n * Caches the connection promise so that multiple calls reuse the same handshake.\n */\nfunction getCommunicator(options?: OnPingOptions): Promise<Communicator> {\n if (!communicatorPromise) {\n communicatorPromise = pong(options).catch((err) => {\n communicatorPromise = null;\n throw err;\n });\n }\n\n return communicatorPromise;\n}\n\n/**\n * Called when the widget is ready to receive configuration from the host.\n */\nexport function onWidgetReady(callback: (config: WidgetConfig) => void) {\n getCommunicator()\n .then((comm) => comm.sendRequest('widget_ready'))\n .then((config) => {\n callback(config);\n })\n .catch((err) => {\n console.error('Failed to initialize widget:', err);\n });\n}\n\n/**\n * Fetch a data source from the host platform.\n */\nexport async function fetchDataSource(payload: DataSourceConfig): Promise<any[]> {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('fetch_widget_data_source', payload);\n}\n\n/**\n * Add a reactive data source listener on the host platform.\n * Returns an unsubscribe function.\n */\nexport function addDataSourceListener(config: DataSourceConfig, onChange: (value: any[]) => void): () => void {\n const identity =\n typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);\n\n let isCancelled = false;\n\n let unregisterHandler: (() => void) | null = null;\n\n let commInstance: Communicator | null = null;\n\n getCommunicator()\n .then((comm) => {\n commInstance = comm;\n\n if (isCancelled) {\n return;\n }\n\n unregisterHandler = comm.registerHandler('widget_data_source_update', (payload) => {\n if (payload?.identity === identity) {\n onChange(payload.data);\n }\n });\n\n comm.sendRequest('add_widget_data_source_listener', { identity, config }).catch((err) => {\n console.error('Failed to add data source listener:', err);\n });\n })\n .catch((err) => {\n console.error('Failed to initialize communicator for data source listener:', err);\n });\n\n return () => {\n isCancelled = true;\n\n if (unregisterHandler) {\n unregisterHandler();\n }\n\n if (commInstance) {\n commInstance.sendRequest('remove_widget_data_source_listener', { identity }).catch((err) => {\n console.error('Failed to remove data source listener:', err);\n });\n }\n };\n}\n\n/**\n * Emit a custom widget event to the host platform.\n */\nexport async function emitWidgetEvent(type: string, args?: Record<string, any>) {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('emit_widget_event', { type, args });\n}\n\n/**\n * Update widget personalization state on the host platform.\n */\nexport async function setWidgetPersonalization(data: any) {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('set_widget_personalization', data);\n}\n\n/**\n * Register a listener for widget filter changes from the host platform.\n * Returns an unsubscribe function.\n */\nexport function onWidgetFilterChange(callback: (condition: string) => void): () => void {\n let isCancelled = false;\n\n let unregisterHandler: (() => void) | null = null;\n\n getCommunicator()\n .then((comm) => {\n if (isCancelled) {\n return;\n }\n\n unregisterHandler = comm.registerHandler('widget_filter_change', (condition) => {\n callback(condition);\n });\n })\n .catch((err) => {\n console.error('Failed to initialize communicator for filter change listener:', err);\n });\n\n return () => {\n isCancelled = true;\n\n if (unregisterHandler) {\n unregisterHandler();\n }\n };\n}\n"],"names":["communicatorPromise","getCommunicator","options","pong","err","onWidgetReady","callback","comm","config","fetchDataSource","payload","addDataSourceListener","onChange","identity","isCancelled","unregisterHandler","commInstance","emitWidgetEvent","type","args","setWidgetPersonalization","data","onWidgetFilterChange","condition"],"mappings":"+HAGA,IAAIA,EAAoD,KAMxD,SAASC,EAAgBC,EAAgD,CACvE,OAAKF,IACHA,EAAsBG,EAAAA,KAAKD,CAAO,EAAE,MAAOE,GAAQ,CACjD,MAAAJ,EAAsB,KAChBI,CACR,CAAC,GAGIJ,CACT,CAKO,SAASK,EAAcC,EAA0C,CACtEL,IACG,KAAMM,GAASA,EAAK,YAAY,cAAc,CAAC,EAC/C,KAAMC,GAAW,CAChBF,EAASE,CAAM,CACjB,CAAC,EACA,MAAOJ,GAAQ,CACd,QAAQ,MAAM,+BAAgCA,CAAG,CACnD,CAAC,CACL,CAKA,eAAsBK,EAAgBC,EAA2C,CAG/E,OAAO,MAFM,MAAMT,EAAA,GAED,YAAY,2BAA4BS,CAAO,CACnE,CAMO,SAASC,EAAsBH,EAA0BI,EAA8C,CAC5G,MAAMC,EACJ,OAAO,OAAW,KAAe,OAAO,WAAa,OAAO,WAAA,EAAe,KAAK,SAAS,SAAS,EAAE,EAAE,UAAU,EAAG,CAAC,EAEtH,IAAIC,EAAc,GAEdC,EAAyC,KAEzCC,EAAoC,KAExC,OAAAf,EAAA,EACG,KAAMM,GAAS,CACdS,EAAeT,EAEX,CAAAO,IAIJC,EAAoBR,EAAK,gBAAgB,4BAA8BG,GAAY,EAC7EA,GAAA,YAAAA,EAAS,YAAaG,GACxBD,EAASF,EAAQ,IAAI,CAEzB,CAAC,EAEDH,EAAK,YAAY,kCAAmC,CAAE,SAAAM,EAAU,OAAAL,EAAQ,EAAE,MAAOJ,GAAQ,CACvF,QAAQ,MAAM,sCAAuCA,CAAG,CAC1D,CAAC,EACH,CAAC,EACA,MAAOA,GAAQ,CACd,QAAQ,MAAM,8DAA+DA,CAAG,CAClF,CAAC,EAEI,IAAM,CACXU,EAAc,GAEVC,GACFA,EAAA,EAGEC,GACFA,EAAa,YAAY,qCAAsC,CAAE,SAAAH,CAAA,CAAU,EAAE,MAAOT,GAAQ,CAC1F,QAAQ,MAAM,yCAA0CA,CAAG,CAC7D,CAAC,CAEL,CACF,CAKA,eAAsBa,EAAgBC,EAAcC,EAA4B,CAG9E,OAAO,MAFM,MAAMlB,EAAA,GAED,YAAY,oBAAqB,CAAE,KAAAiB,EAAM,KAAAC,EAAM,CACnE,CAKA,eAAsBC,EAAyBC,EAAW,CAGxD,OAAO,MAFM,MAAMpB,EAAA,GAED,YAAY,6BAA8BoB,CAAI,CAClE,CAMO,SAASC,EAAqBhB,EAAmD,CACtF,IAAIQ,EAAc,GAEdC,EAAyC,KAE7C,OAAAd,EAAA,EACG,KAAMM,GAAS,CACVO,IAIJC,EAAoBR,EAAK,gBAAgB,uBAAyBgB,GAAc,CAC9EjB,EAASiB,CAAS,CACpB,CAAC,EACH,CAAC,EACA,MAAOnB,GAAQ,CACd,QAAQ,MAAM,gEAAiEA,CAAG,CACpF,CAAC,EAEI,IAAM,CACXU,EAAc,GAEVC,GACFA,EAAA,CAEJ,CACF"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/widget-sdk.ts"],"sourcesContent":["import { Communicator, pong, OnPingOptions } from './communicator';\nimport { DataSourceConfig, NodeData, NodeDataRequestPayload, WidgetConfig } from './types';\n\nlet communicatorPromise: Promise<Communicator> | null = null;\n\n/**\n * Get or initialize the Communicator instance for the widget.\n * Caches the connection promise so that multiple calls reuse the same handshake.\n */\nfunction getCommunicator(options?: OnPingOptions): Promise<Communicator> {\n if (!communicatorPromise) {\n communicatorPromise = pong(options).catch((err) => {\n communicatorPromise = null;\n throw err;\n });\n }\n\n return communicatorPromise;\n}\n\n/**\n * Called when the widget is ready to receive configuration from the host.\n */\nexport function onWidgetReady(callback: (config: WidgetConfig) => void) {\n getCommunicator()\n .then((comm) => comm.sendRequest('widget_ready'))\n .then((config) => {\n callback(config);\n })\n .catch((err) => {\n console.error('Failed to initialize widget:', err);\n });\n}\n\n/**\n * Add a reactive data source listener on the host platform.\n * Returns an unsubscribe function.\n */\nexport function addDataSourceListener(config: DataSourceConfig, onChange: (value: any[]) => void): () => void {\n const identity =\n typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);\n\n let isCancelled = false;\n\n let unregisterHandler: (() => void) | null = null;\n\n let commInstance: Communicator | null = null;\n\n getCommunicator()\n .then((comm) => {\n commInstance = comm;\n\n if (isCancelled) {\n return;\n }\n\n unregisterHandler = comm.registerHandler('widget_data_source_update', (payload) => {\n if (payload?.identity === identity) {\n onChange(payload.data || []);\n }\n });\n\n comm.sendRequest('add_widget_data_source_listener', { identity, config }).catch((err) => {\n console.error('Failed to add data source listener:', err);\n });\n })\n .catch((err) => {\n console.error('Failed to initialize communicator for data source listener:', err);\n });\n\n return () => {\n isCancelled = true;\n\n if (unregisterHandler) {\n unregisterHandler();\n }\n\n if (commInstance) {\n commInstance.sendRequest('remove_widget_data_source_listener', { identity }).catch((err) => {\n console.error('Failed to remove data source listener:', err);\n });\n }\n };\n}\n\n/**\n * Emit a custom widget event to the host platform.\n */\nexport async function emitWidgetEvent(type: string, args?: Record<string, any>) {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('emit_widget_event', { type, args });\n}\n\n/**\n * Update widget personalization state on the host platform.\n */\nexport async function setWidgetPersonalization(data: any) {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('set_widget_personalization', data);\n}\n\n/**\n * Register a listener for widget filter changes from the host platform.\n * Returns an unsubscribe function.\n */\nexport function onWidgetFilterChange(callback: (condition: string) => void): () => void {\n let isCancelled = false;\n\n let unregisterHandler: (() => void) | null = null;\n\n getCommunicator()\n .then((comm) => {\n if (isCancelled) {\n return;\n }\n\n unregisterHandler = comm.registerHandler('widget_filter_change', (condition) => {\n callback(condition);\n });\n })\n .catch((err) => {\n console.error('Failed to initialize communicator for filter change listener:', err);\n });\n\n return () => {\n isCancelled = true;\n\n if (unregisterHandler) {\n unregisterHandler();\n }\n };\n}\n\nexport async function fetchNodeData(payload: NodeDataRequestPayload): Promise<NodeData> {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('fetch_node_data', payload);\n}\n\nexport function createDataSource(config: Pick<NodeDataRequestPayload, 'node' | 'filterExpression'>) {\n async function fetch(payload?: Omit<NodeDataRequestPayload, 'node' | 'filterExpression'>) {\n return await fetchNodeData({\n ...config,\n ...payload,\n });\n }\n\n const callbacks = new Set<() => void>();\n let identity: string | null = null;\n let isConnecting = false;\n let unregisterHandler: (() => void) | null = null;\n let commInstance: Communicator | null = null;\n\n async function connect() {\n if (isConnecting || unregisterHandler) return;\n isConnecting = true;\n\n const currentIdentity =\n typeof crypto !== 'undefined' && crypto.randomUUID\n ? crypto.randomUUID()\n : Math.random().toString(36).substring(2, 9);\n identity = currentIdentity;\n\n try {\n const comm = await getCommunicator();\n commInstance = comm;\n\n // If all subscribers unsubscribed while connecting, abort\n if (callbacks.size === 0 || identity !== currentIdentity) {\n return;\n }\n\n unregisterHandler = comm.registerHandler('widget_data_source_update', (payload) => {\n if (payload?.identity !== currentIdentity) return;\n\n callbacks.forEach((cb) => {\n try {\n cb();\n } catch (err) {\n console.error('Error in widget data source onChange callback:', err);\n }\n });\n });\n\n await comm.sendRequest('add_widget_data_source_listener', { identity: currentIdentity, config });\n } catch (err) {\n console.error('Failed to initialize communicator for data source listener:', err);\n } finally {\n isConnecting = false;\n // In case subscribers dropped to 0 while add_widget_data_source_listener was in-flight\n if (callbacks.size === 0 && identity === currentIdentity) {\n disconnect();\n }\n }\n }\n\n function disconnect() {\n const activeIdentity = identity;\n identity = null;\n isConnecting = false;\n\n if (unregisterHandler) {\n unregisterHandler();\n unregisterHandler = null;\n }\n\n if (commInstance && activeIdentity) {\n commInstance.sendRequest('remove_widget_data_source_listener', { identity: activeIdentity }).catch((err) => {\n console.error('Failed to remove data source listener:', err);\n });\n }\n }\n\n function onChange(callback: () => void): () => void {\n callbacks.add(callback);\n\n if (callbacks.size === 1) {\n connect();\n }\n\n return () => {\n callbacks.delete(callback);\n\n if (callbacks.size === 0) {\n disconnect();\n }\n };\n }\n\n return {\n fetch,\n onChange,\n };\n}\n\n"],"names":["communicatorPromise","getCommunicator","options","pong","err","onWidgetReady","callback","comm","config","addDataSourceListener","onChange","identity","isCancelled","unregisterHandler","commInstance","payload","emitWidgetEvent","type","args","setWidgetPersonalization","data","onWidgetFilterChange","condition","fetchNodeData","createDataSource","fetch","callbacks","isConnecting","connect","currentIdentity","cb","disconnect","activeIdentity"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,49 +1,46 @@
|
|
|
1
|
-
import { b as
|
|
2
|
-
import { C as
|
|
3
|
-
let
|
|
4
|
-
function
|
|
5
|
-
return
|
|
6
|
-
throw
|
|
7
|
-
})),
|
|
1
|
+
import { b as w } from "./communicator-BF77R7Qs.js";
|
|
2
|
+
import { C as p, P as H, a as E } from "./communicator-BF77R7Qs.js";
|
|
3
|
+
let l = null;
|
|
4
|
+
function u(t) {
|
|
5
|
+
return l || (l = w(t).catch((e) => {
|
|
6
|
+
throw l = null, e;
|
|
7
|
+
})), l;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
|
|
9
|
+
function C(t) {
|
|
10
|
+
u().then((e) => e.sendRequest("widget_ready")).then((e) => {
|
|
11
11
|
t(e);
|
|
12
12
|
}).catch((e) => {
|
|
13
13
|
console.error("Failed to initialize widget:", e);
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
return await (await a()).sendRequest("fetch_widget_data_source", t);
|
|
18
|
-
}
|
|
19
|
-
function g(t, e) {
|
|
16
|
+
function I(t, e) {
|
|
20
17
|
const n = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);
|
|
21
|
-
let i = !1,
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
(
|
|
25
|
-
}),
|
|
26
|
-
console.error("Failed to add data source listener:",
|
|
18
|
+
let i = !1, a = null, c = null;
|
|
19
|
+
return u().then((o) => {
|
|
20
|
+
c = o, !i && (a = o.registerHandler("widget_data_source_update", (s) => {
|
|
21
|
+
(s == null ? void 0 : s.identity) === n && e(s.data || []);
|
|
22
|
+
}), o.sendRequest("add_widget_data_source_listener", { identity: n, config: t }).catch((s) => {
|
|
23
|
+
console.error("Failed to add data source listener:", s);
|
|
27
24
|
}));
|
|
28
|
-
}).catch((
|
|
29
|
-
console.error("Failed to initialize communicator for data source listener:",
|
|
25
|
+
}).catch((o) => {
|
|
26
|
+
console.error("Failed to initialize communicator for data source listener:", o);
|
|
30
27
|
}), () => {
|
|
31
|
-
i = !0,
|
|
32
|
-
console.error("Failed to remove data source listener:",
|
|
28
|
+
i = !0, a && a(), c && c.sendRequest("remove_widget_data_source_listener", { identity: n }).catch((o) => {
|
|
29
|
+
console.error("Failed to remove data source listener:", o);
|
|
33
30
|
});
|
|
34
31
|
};
|
|
35
32
|
}
|
|
36
|
-
async function
|
|
37
|
-
return await (await
|
|
33
|
+
async function R(t, e) {
|
|
34
|
+
return await (await u()).sendRequest("emit_widget_event", { type: t, args: e });
|
|
38
35
|
}
|
|
39
|
-
async function
|
|
40
|
-
return await (await
|
|
36
|
+
async function q(t) {
|
|
37
|
+
return await (await u()).sendRequest("set_widget_personalization", t);
|
|
41
38
|
}
|
|
42
|
-
function
|
|
39
|
+
function F(t) {
|
|
43
40
|
let e = !1, n = null;
|
|
44
|
-
return
|
|
45
|
-
e || (n = i.registerHandler("widget_filter_change", (
|
|
46
|
-
t(
|
|
41
|
+
return u().then((i) => {
|
|
42
|
+
e || (n = i.registerHandler("widget_filter_change", (a) => {
|
|
43
|
+
t(a);
|
|
47
44
|
}));
|
|
48
45
|
}).catch((i) => {
|
|
49
46
|
console.error("Failed to initialize communicator for filter change listener:", i);
|
|
@@ -51,16 +48,69 @@ function w(t) {
|
|
|
51
48
|
e = !0, n && n();
|
|
52
49
|
};
|
|
53
50
|
}
|
|
51
|
+
async function y(t) {
|
|
52
|
+
return await (await u()).sendRequest("fetch_node_data", t);
|
|
53
|
+
}
|
|
54
|
+
function U(t) {
|
|
55
|
+
async function e(r) {
|
|
56
|
+
return await y({
|
|
57
|
+
...t,
|
|
58
|
+
...r
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const n = /* @__PURE__ */ new Set();
|
|
62
|
+
let i = null, a = !1, c = null, o = null;
|
|
63
|
+
async function s() {
|
|
64
|
+
if (a || c) return;
|
|
65
|
+
a = !0;
|
|
66
|
+
const r = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);
|
|
67
|
+
i = r;
|
|
68
|
+
try {
|
|
69
|
+
const d = await u();
|
|
70
|
+
if (o = d, n.size === 0 || i !== r)
|
|
71
|
+
return;
|
|
72
|
+
c = d.registerHandler("widget_data_source_update", (f) => {
|
|
73
|
+
(f == null ? void 0 : f.identity) === r && n.forEach((_) => {
|
|
74
|
+
try {
|
|
75
|
+
_();
|
|
76
|
+
} catch (h) {
|
|
77
|
+
console.error("Error in widget data source onChange callback:", h);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}), await d.sendRequest("add_widget_data_source_listener", { identity: r, config: t });
|
|
81
|
+
} catch (d) {
|
|
82
|
+
console.error("Failed to initialize communicator for data source listener:", d);
|
|
83
|
+
} finally {
|
|
84
|
+
a = !1, n.size === 0 && i === r && m();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function m() {
|
|
88
|
+
const r = i;
|
|
89
|
+
i = null, a = !1, c && (c(), c = null), o && r && o.sendRequest("remove_widget_data_source_listener", { identity: r }).catch((d) => {
|
|
90
|
+
console.error("Failed to remove data source listener:", d);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function g(r) {
|
|
94
|
+
return n.add(r), n.size === 1 && s(), () => {
|
|
95
|
+
n.delete(r), n.size === 0 && m();
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
fetch: e,
|
|
100
|
+
onChange: g
|
|
101
|
+
};
|
|
102
|
+
}
|
|
54
103
|
export {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
104
|
+
p as Communicator,
|
|
105
|
+
H as PING_TOKEN,
|
|
106
|
+
E as PONG_TOKEN,
|
|
107
|
+
I as addDataSourceListener,
|
|
108
|
+
U as createDataSource,
|
|
109
|
+
R as emitWidgetEvent,
|
|
110
|
+
y as fetchNodeData,
|
|
111
|
+
F as onWidgetFilterChange,
|
|
112
|
+
C as onWidgetReady,
|
|
113
|
+
w as pong,
|
|
114
|
+
q as setWidgetPersonalization
|
|
65
115
|
};
|
|
66
116
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/widget-sdk.ts"],"sourcesContent":["import { Communicator, pong, OnPingOptions } from './communicator';\nimport { DataSourceConfig, WidgetConfig } from './types';\n\nlet communicatorPromise: Promise<Communicator> | null = null;\n\n/**\n * Get or initialize the Communicator instance for the widget.\n * Caches the connection promise so that multiple calls reuse the same handshake.\n */\nfunction getCommunicator(options?: OnPingOptions): Promise<Communicator> {\n if (!communicatorPromise) {\n communicatorPromise = pong(options).catch((err) => {\n communicatorPromise = null;\n throw err;\n });\n }\n\n return communicatorPromise;\n}\n\n/**\n * Called when the widget is ready to receive configuration from the host.\n */\nexport function onWidgetReady(callback: (config: WidgetConfig) => void) {\n getCommunicator()\n .then((comm) => comm.sendRequest('widget_ready'))\n .then((config) => {\n callback(config);\n })\n .catch((err) => {\n console.error('Failed to initialize widget:', err);\n });\n}\n\n/**\n * Fetch a data source from the host platform.\n */\nexport async function fetchDataSource(payload: DataSourceConfig): Promise<any[]> {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('fetch_widget_data_source', payload);\n}\n\n/**\n * Add a reactive data source listener on the host platform.\n * Returns an unsubscribe function.\n */\nexport function addDataSourceListener(config: DataSourceConfig, onChange: (value: any[]) => void): () => void {\n const identity =\n typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);\n\n let isCancelled = false;\n\n let unregisterHandler: (() => void) | null = null;\n\n let commInstance: Communicator | null = null;\n\n getCommunicator()\n .then((comm) => {\n commInstance = comm;\n\n if (isCancelled) {\n return;\n }\n\n unregisterHandler = comm.registerHandler('widget_data_source_update', (payload) => {\n if (payload?.identity === identity) {\n onChange(payload.data);\n }\n });\n\n comm.sendRequest('add_widget_data_source_listener', { identity, config }).catch((err) => {\n console.error('Failed to add data source listener:', err);\n });\n })\n .catch((err) => {\n console.error('Failed to initialize communicator for data source listener:', err);\n });\n\n return () => {\n isCancelled = true;\n\n if (unregisterHandler) {\n unregisterHandler();\n }\n\n if (commInstance) {\n commInstance.sendRequest('remove_widget_data_source_listener', { identity }).catch((err) => {\n console.error('Failed to remove data source listener:', err);\n });\n }\n };\n}\n\n/**\n * Emit a custom widget event to the host platform.\n */\nexport async function emitWidgetEvent(type: string, args?: Record<string, any>) {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('emit_widget_event', { type, args });\n}\n\n/**\n * Update widget personalization state on the host platform.\n */\nexport async function setWidgetPersonalization(data: any) {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('set_widget_personalization', data);\n}\n\n/**\n * Register a listener for widget filter changes from the host platform.\n * Returns an unsubscribe function.\n */\nexport function onWidgetFilterChange(callback: (condition: string) => void): () => void {\n let isCancelled = false;\n\n let unregisterHandler: (() => void) | null = null;\n\n getCommunicator()\n .then((comm) => {\n if (isCancelled) {\n return;\n }\n\n unregisterHandler = comm.registerHandler('widget_filter_change', (condition) => {\n callback(condition);\n });\n })\n .catch((err) => {\n console.error('Failed to initialize communicator for filter change listener:', err);\n });\n\n return () => {\n isCancelled = true;\n\n if (unregisterHandler) {\n unregisterHandler();\n }\n };\n}\n"],"names":["communicatorPromise","getCommunicator","options","pong","err","onWidgetReady","callback","comm","config","fetchDataSource","payload","addDataSourceListener","onChange","identity","isCancelled","unregisterHandler","commInstance","emitWidgetEvent","type","args","setWidgetPersonalization","data","onWidgetFilterChange","condition"],"mappings":";;AAGA,IAAIA,IAAoD;AAMxD,SAASC,EAAgBC,GAAgD;AACvE,SAAKF,MACHA,IAAsBG,EAAKD,CAAO,EAAE,MAAM,CAACE,MAAQ;AACjD,UAAAJ,IAAsB,MAChBI;AAAA,EACR,CAAC,IAGIJ;AACT;AAKO,SAASK,EAAcC,GAA0C;AACtE,EAAAL,IACG,KAAK,CAACM,MAASA,EAAK,YAAY,cAAc,CAAC,EAC/C,KAAK,CAACC,MAAW;AAChB,IAAAF,EAASE,CAAM;AAAA,EACjB,CAAC,EACA,MAAM,CAACJ,MAAQ;AACd,YAAQ,MAAM,gCAAgCA,CAAG;AAAA,EACnD,CAAC;AACL;AAKA,eAAsBK,EAAgBC,GAA2C;AAG/E,SAAO,OAFM,MAAMT,EAAA,GAED,YAAY,4BAA4BS,CAAO;AACnE;AAMO,SAASC,EAAsBH,GAA0BI,GAA8C;AAC5G,QAAMC,IACJ,OAAO,SAAW,OAAe,OAAO,aAAa,OAAO,WAAA,IAAe,KAAK,SAAS,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC;AAEtH,MAAIC,IAAc,IAEdC,IAAyC,MAEzCC,IAAoC;AAExC,SAAAf,EAAA,EACG,KAAK,CAACM,MAAS;AAGd,IAFAS,IAAeT,GAEX,CAAAO,MAIJC,IAAoBR,EAAK,gBAAgB,6BAA6B,CAACG,MAAY;AACjF,OAAIA,KAAA,gBAAAA,EAAS,cAAaG,KACxBD,EAASF,EAAQ,IAAI;AAAA,IAEzB,CAAC,GAEDH,EAAK,YAAY,mCAAmC,EAAE,UAAAM,GAAU,QAAAL,GAAQ,EAAE,MAAM,CAACJ,MAAQ;AACvF,cAAQ,MAAM,uCAAuCA,CAAG;AAAA,IAC1D,CAAC;AAAA,EACH,CAAC,EACA,MAAM,CAACA,MAAQ;AACd,YAAQ,MAAM,+DAA+DA,CAAG;AAAA,EAClF,CAAC,GAEI,MAAM;AACX,IAAAU,IAAc,IAEVC,KACFA,EAAA,GAGEC,KACFA,EAAa,YAAY,sCAAsC,EAAE,UAAAH,EAAA,CAAU,EAAE,MAAM,CAACT,MAAQ;AAC1F,cAAQ,MAAM,0CAA0CA,CAAG;AAAA,IAC7D,CAAC;AAAA,EAEL;AACF;AAKA,eAAsBa,EAAgBC,GAAcC,GAA4B;AAG9E,SAAO,OAFM,MAAMlB,EAAA,GAED,YAAY,qBAAqB,EAAE,MAAAiB,GAAM,MAAAC,GAAM;AACnE;AAKA,eAAsBC,EAAyBC,GAAW;AAGxD,SAAO,OAFM,MAAMpB,EAAA,GAED,YAAY,8BAA8BoB,CAAI;AAClE;AAMO,SAASC,EAAqBhB,GAAmD;AACtF,MAAIQ,IAAc,IAEdC,IAAyC;AAE7C,SAAAd,EAAA,EACG,KAAK,CAACM,MAAS;AACd,IAAIO,MAIJC,IAAoBR,EAAK,gBAAgB,wBAAwB,CAACgB,MAAc;AAC9E,MAAAjB,EAASiB,CAAS;AAAA,IACpB,CAAC;AAAA,EACH,CAAC,EACA,MAAM,CAACnB,MAAQ;AACd,YAAQ,MAAM,iEAAiEA,CAAG;AAAA,EACpF,CAAC,GAEI,MAAM;AACX,IAAAU,IAAc,IAEVC,KACFA,EAAA;AAAA,EAEJ;AACF;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/widget-sdk.ts"],"sourcesContent":["import { Communicator, pong, OnPingOptions } from './communicator';\nimport { DataSourceConfig, NodeData, NodeDataRequestPayload, WidgetConfig } from './types';\n\nlet communicatorPromise: Promise<Communicator> | null = null;\n\n/**\n * Get or initialize the Communicator instance for the widget.\n * Caches the connection promise so that multiple calls reuse the same handshake.\n */\nfunction getCommunicator(options?: OnPingOptions): Promise<Communicator> {\n if (!communicatorPromise) {\n communicatorPromise = pong(options).catch((err) => {\n communicatorPromise = null;\n throw err;\n });\n }\n\n return communicatorPromise;\n}\n\n/**\n * Called when the widget is ready to receive configuration from the host.\n */\nexport function onWidgetReady(callback: (config: WidgetConfig) => void) {\n getCommunicator()\n .then((comm) => comm.sendRequest('widget_ready'))\n .then((config) => {\n callback(config);\n })\n .catch((err) => {\n console.error('Failed to initialize widget:', err);\n });\n}\n\n/**\n * Add a reactive data source listener on the host platform.\n * Returns an unsubscribe function.\n */\nexport function addDataSourceListener(config: DataSourceConfig, onChange: (value: any[]) => void): () => void {\n const identity =\n typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);\n\n let isCancelled = false;\n\n let unregisterHandler: (() => void) | null = null;\n\n let commInstance: Communicator | null = null;\n\n getCommunicator()\n .then((comm) => {\n commInstance = comm;\n\n if (isCancelled) {\n return;\n }\n\n unregisterHandler = comm.registerHandler('widget_data_source_update', (payload) => {\n if (payload?.identity === identity) {\n onChange(payload.data || []);\n }\n });\n\n comm.sendRequest('add_widget_data_source_listener', { identity, config }).catch((err) => {\n console.error('Failed to add data source listener:', err);\n });\n })\n .catch((err) => {\n console.error('Failed to initialize communicator for data source listener:', err);\n });\n\n return () => {\n isCancelled = true;\n\n if (unregisterHandler) {\n unregisterHandler();\n }\n\n if (commInstance) {\n commInstance.sendRequest('remove_widget_data_source_listener', { identity }).catch((err) => {\n console.error('Failed to remove data source listener:', err);\n });\n }\n };\n}\n\n/**\n * Emit a custom widget event to the host platform.\n */\nexport async function emitWidgetEvent(type: string, args?: Record<string, any>) {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('emit_widget_event', { type, args });\n}\n\n/**\n * Update widget personalization state on the host platform.\n */\nexport async function setWidgetPersonalization(data: any) {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('set_widget_personalization', data);\n}\n\n/**\n * Register a listener for widget filter changes from the host platform.\n * Returns an unsubscribe function.\n */\nexport function onWidgetFilterChange(callback: (condition: string) => void): () => void {\n let isCancelled = false;\n\n let unregisterHandler: (() => void) | null = null;\n\n getCommunicator()\n .then((comm) => {\n if (isCancelled) {\n return;\n }\n\n unregisterHandler = comm.registerHandler('widget_filter_change', (condition) => {\n callback(condition);\n });\n })\n .catch((err) => {\n console.error('Failed to initialize communicator for filter change listener:', err);\n });\n\n return () => {\n isCancelled = true;\n\n if (unregisterHandler) {\n unregisterHandler();\n }\n };\n}\n\nexport async function fetchNodeData(payload: NodeDataRequestPayload): Promise<NodeData> {\n const comm = await getCommunicator();\n\n return await comm.sendRequest('fetch_node_data', payload);\n}\n\nexport function createDataSource(config: Pick<NodeDataRequestPayload, 'node' | 'filterExpression'>) {\n async function fetch(payload?: Omit<NodeDataRequestPayload, 'node' | 'filterExpression'>) {\n return await fetchNodeData({\n ...config,\n ...payload,\n });\n }\n\n const callbacks = new Set<() => void>();\n let identity: string | null = null;\n let isConnecting = false;\n let unregisterHandler: (() => void) | null = null;\n let commInstance: Communicator | null = null;\n\n async function connect() {\n if (isConnecting || unregisterHandler) return;\n isConnecting = true;\n\n const currentIdentity =\n typeof crypto !== 'undefined' && crypto.randomUUID\n ? crypto.randomUUID()\n : Math.random().toString(36).substring(2, 9);\n identity = currentIdentity;\n\n try {\n const comm = await getCommunicator();\n commInstance = comm;\n\n // If all subscribers unsubscribed while connecting, abort\n if (callbacks.size === 0 || identity !== currentIdentity) {\n return;\n }\n\n unregisterHandler = comm.registerHandler('widget_data_source_update', (payload) => {\n if (payload?.identity !== currentIdentity) return;\n\n callbacks.forEach((cb) => {\n try {\n cb();\n } catch (err) {\n console.error('Error in widget data source onChange callback:', err);\n }\n });\n });\n\n await comm.sendRequest('add_widget_data_source_listener', { identity: currentIdentity, config });\n } catch (err) {\n console.error('Failed to initialize communicator for data source listener:', err);\n } finally {\n isConnecting = false;\n // In case subscribers dropped to 0 while add_widget_data_source_listener was in-flight\n if (callbacks.size === 0 && identity === currentIdentity) {\n disconnect();\n }\n }\n }\n\n function disconnect() {\n const activeIdentity = identity;\n identity = null;\n isConnecting = false;\n\n if (unregisterHandler) {\n unregisterHandler();\n unregisterHandler = null;\n }\n\n if (commInstance && activeIdentity) {\n commInstance.sendRequest('remove_widget_data_source_listener', { identity: activeIdentity }).catch((err) => {\n console.error('Failed to remove data source listener:', err);\n });\n }\n }\n\n function onChange(callback: () => void): () => void {\n callbacks.add(callback);\n\n if (callbacks.size === 1) {\n connect();\n }\n\n return () => {\n callbacks.delete(callback);\n\n if (callbacks.size === 0) {\n disconnect();\n }\n };\n }\n\n return {\n fetch,\n onChange,\n };\n}\n\n"],"names":["communicatorPromise","getCommunicator","options","pong","err","onWidgetReady","callback","comm","config","addDataSourceListener","onChange","identity","isCancelled","unregisterHandler","commInstance","payload","emitWidgetEvent","type","args","setWidgetPersonalization","data","onWidgetFilterChange","condition","fetchNodeData","createDataSource","fetch","callbacks","isConnecting","connect","currentIdentity","cb","disconnect","activeIdentity"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export interface WidgetConfig {
|
|
2
2
|
props: Record<string, any>;
|
|
3
3
|
personalization?: any;
|
|
4
|
+
shouldWaitForFilter?: boolean;
|
|
4
5
|
}
|
|
5
6
|
export interface DataSourceConfig {
|
|
6
7
|
node: string;
|
|
@@ -10,6 +11,20 @@ export interface DataSourceConfig {
|
|
|
10
11
|
size: number;
|
|
11
12
|
};
|
|
12
13
|
}
|
|
14
|
+
export interface NodeDataRequestPayload {
|
|
15
|
+
node: string;
|
|
16
|
+
filterExpression?: string;
|
|
17
|
+
sort?: any[];
|
|
18
|
+
pagination?: {
|
|
19
|
+
no: number;
|
|
20
|
+
size: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface NodeData {
|
|
24
|
+
no: number;
|
|
25
|
+
total: number;
|
|
26
|
+
data: any[];
|
|
27
|
+
}
|
|
13
28
|
export interface Message<A extends keyof ActionMap = keyof ActionMap> {
|
|
14
29
|
id: string;
|
|
15
30
|
type: 'request' | 'response';
|
|
@@ -21,12 +36,11 @@ export interface ActionMap {
|
|
|
21
36
|
widget_ready: () => WidgetConfig;
|
|
22
37
|
widget_data_source_update: (payload: {
|
|
23
38
|
identity: string;
|
|
24
|
-
data
|
|
39
|
+
data?: any[];
|
|
25
40
|
}) => void;
|
|
26
|
-
fetch_widget_data_source: (payload: DataSourceConfig) => any[];
|
|
27
41
|
add_widget_data_source_listener: (payload: {
|
|
28
42
|
identity: string;
|
|
29
|
-
config:
|
|
43
|
+
config: Pick<NodeDataRequestPayload, 'node' | 'filterExpression'>;
|
|
30
44
|
}) => void;
|
|
31
45
|
remove_widget_data_source_listener: (payload: {
|
|
32
46
|
identity: string;
|
|
@@ -40,5 +54,6 @@ export interface ActionMap {
|
|
|
40
54
|
}) => void;
|
|
41
55
|
set_widget_personalization: (payload: any) => void;
|
|
42
56
|
widget_filter_change: (payload: string) => void;
|
|
57
|
+
fetch_node_data: (payload: NodeDataRequestPayload) => NodeData;
|
|
43
58
|
}
|
|
44
59
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,eAAe,CAAC,EAAE,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,eAAe,CAAC,EAAE,GAAG,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,UAAU,CAAC,EAAE;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,CAAC;CACb;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,SAAS,GAAG,MAAM,SAAS;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,GAAG,UAAU,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC;IACV,OAAO,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,YAAY,CAAC;IACjC,yBAAyB,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IACjF,+BAA+B,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,GAAG,kBAAkB,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5I,kCAAkC,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5E,iBAAiB,EAAE,CAAC,OAAO,EAAE;QAC3B,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CACX,MAAM,EACN;YACE,IAAI,EAAE,GAAG,CAAC;YACV,QAAQ,EAAE,MAAM,CAAC;SAClB,CACF,CAAC;KACH,KAAK,IAAI,CAAC;IACX,0BAA0B,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,eAAe,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,QAAQ,CAAC;CAChE"}
|
package/dist/widget-sdk.d.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { DataSourceConfig, WidgetConfig } from './types';
|
|
1
|
+
import { DataSourceConfig, NodeData, NodeDataRequestPayload, WidgetConfig } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Called when the widget is ready to receive configuration from the host.
|
|
4
4
|
*/
|
|
5
5
|
export declare function onWidgetReady(callback: (config: WidgetConfig) => void): void;
|
|
6
|
-
/**
|
|
7
|
-
* Fetch a data source from the host platform.
|
|
8
|
-
*/
|
|
9
|
-
export declare function fetchDataSource(payload: DataSourceConfig): Promise<any[]>;
|
|
10
6
|
/**
|
|
11
7
|
* Add a reactive data source listener on the host platform.
|
|
12
8
|
* Returns an unsubscribe function.
|
|
@@ -25,4 +21,9 @@ export declare function setWidgetPersonalization(data: any): Promise<void>;
|
|
|
25
21
|
* Returns an unsubscribe function.
|
|
26
22
|
*/
|
|
27
23
|
export declare function onWidgetFilterChange(callback: (condition: string) => void): () => void;
|
|
24
|
+
export declare function fetchNodeData(payload: NodeDataRequestPayload): Promise<NodeData>;
|
|
25
|
+
export declare function createDataSource(config: Pick<NodeDataRequestPayload, 'node' | 'filterExpression'>): {
|
|
26
|
+
fetch: (payload?: Omit<NodeDataRequestPayload, "node" | "filterExpression">) => Promise<NodeData>;
|
|
27
|
+
onChange: (callback: () => void) => () => void;
|
|
28
|
+
};
|
|
28
29
|
//# sourceMappingURL=widget-sdk.d.ts.map
|
package/dist/widget-sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widget-sdk.d.ts","sourceRoot":"","sources":["../src/widget-sdk.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"widget-sdk.d.ts","sourceRoot":"","sources":["../src/widget-sdk.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAmB3F;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,QASrE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CA6C5G;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,iBAI7E;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,GAAG,iBAIvD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CA0BtF;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAItF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,GAAG,kBAAkB,CAAC;sBACjE,IAAI,CAAC,sBAAsB,EAAE,MAAM,GAAG,kBAAkB,CAAC;yBAyE5D,MAAM,IAAI,KAAG,MAAM,IAAI;EAoBpD"}
|