@goodo/platform-plugin 0.1.5 → 0.1.7

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.
@@ -90,6 +90,8 @@ export declare class LocalWidget implements LocalWidgetProps {
90
90
  }
91
91
  export declare const LOCAL_WIDGETS_STORAGE_KEY = "goodo_local_widgets";
92
92
  export declare function getLocalWidgets(): LocalWidget[];
93
+ export declare function getLocalWidgetById(id?: string): LocalWidgetProps | null;
93
94
  export declare function createLocalWidget(props: LocalWidgetProps): LocalWidget;
94
95
  export declare function removeLocalWidget(id: string): void;
96
+ export declare function updateLocalWidget(id: string, props: Partial<LocalWidgetProps>): LocalWidgetProps | null;
95
97
  //# sourceMappingURL=host-sdk.d.ts.map
@@ -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;AACpC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AASzD,qBAAa,IAAI;IACf,OAAO,CAAC,aAAa,CAA6B;IAElD,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,CAAC,aAAa,CAA+B;IAEpD,OAAO,CAAC,WAAW,CAAsC;IAEzD,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,KAAK,YAAY,GAKvB;IAED;;;OAGG;gBACS,YAAY,EAAE,MAAM;IAIhC;;;;OAIG;IACI,SAAS,CAAC,CAAC,SAAS,MAAM,SAAS,EACxC,UAAU,EAAE,CAAC,EACb,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAC9G,MAAM,IAAI;IAyBb;;OAEG;IACU,WAAW,CAAC,CAAC,SAAS,MAAM,SAAS,EAChD,UAAU,EAAE,CAAC,EACb,OAAO,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACrC,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAcpC;;OAEG;IACU,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAuCxD,OAAO,IAAI,IAAI;CAkBvB;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,CAAC;AAC/E,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC;AACvG,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC;AAEnF,qBAAa,WAAY,YAAW,gBAAgB;IAClD,EAAE,EAAE,MAAM,CAAC;IAEX,WAAW,EAAE,MAAM,CAAC;IAEpB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,QAAQ,EAAE,sBAAsB,GAAG,IAAI,CAAQ;IAE/C,OAAO,CAAC,EAAE,CAA0B;IAEpC,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,cAAc,CAAa;IAEnC,OAAO,CAAC,sBAAsB,CAAoC;IAElE,OAAO,CAAC,qBAAqB,CAAmC;IAEhE,OAAO,CAAC,kBAAkB,CAAgC;gBAE9C,KAAK,EAAE,gBAAgB;IAanC;;OAEG;IACI,OAAO,IAAI,IAAI;IAsDtB;;OAEG;IACU,aAAa,IAAI,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAiBpE;;OAEG;IACI,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,IAAI;IAUnE;;OAEG;IACI,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAOjE;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAO3D;;OAEG;IACI,OAAO,IAAI,IAAI;IAetB;;OAEG;IACI,MAAM,IAAI,gBAAgB,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE;CAQnD;AAED,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,wBAAgB,eAAe,IAAI,WAAW,EAAE,CAa/C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAgBtE;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAalD"}
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 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;
1
+ "use strict";var u=Object.defineProperty;var m=(s,e,t)=>e in s?u(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var n=(s,e,t)=>m(s,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./communicator-DQZOTxOF.cjs");class h{constructor(e){n(this,"_communicator",null);n(this,"iframeWindow");n(this,"subscriptions",new Set);n(this,"initPromise",null);n(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 r={actionType:e,handler:t,off:null,cancelled:!1};return this._communicator&&(r.off=this._communicator.registerHandler(e,t)),this.subscriptions.add(r),()=>{r.cancelled||(r.cancelled=!0,this.subscriptions.delete(r),r.off&&(r.off(),r.off=null))}}async sendMessage(e,t,r){return this._communicator?this._communicator.sendRequest(e,t,r):this.initPromise?(await this.initPromise).sendRequest(e,t,r):this.communicator.sendRequest(e,t,r)}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 r of this.subscriptions)!r.cancelled&&!r.off&&(r.off=t.registerHandler(r.actionType,r.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 l{constructor(e){n(this,"id");n(this,"mainAddress");n(this,"editorAddress");n(this,"runtimeAddress");n(this,"manifest",null);n(this,"ws",null);n(this,"isDestroyed",!1);n(this,"reconnectTimer",null);n(this,"manifestUpdateHandlers",new Set);n(this,"manifestErrorHandlers",new Set);n(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,(r,i)=>i?"wss://":"ws://"),t=new WebSocket(e);this.ws=t,t.onmessage=r=>{try{const i=JSON.parse(r.data);if(i.type==="manifest:update"&&i.data){this.manifest=i.data;for(const a of this.manifestUpdateHandlers)a(i.data)}else if(i.type==="manifest:error")for(const a of this.manifestErrorHandlers)a(i.errors||"Manifest error");else if(i.type==="file:change")for(const a of this.fileChangeHandlers)a({file:i.file,event:i.event})}catch(i){console.error("[LocalWidget] Failed to parse HMR message:",i)}},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 r=await t.json();return this.manifest=r,r}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 g(){if(typeof localStorage>"u")return[];try{const s=localStorage.getItem(o);if(!s)return[];const e=JSON.parse(s);return Array.isArray(e)?e.map(t=>new l(t)):[]}catch{return[]}}function y(s){if(typeof localStorage>"u"||!s)return null;try{const e=localStorage.getItem(o);if(!e)return null;const t=JSON.parse(e);return Array.isArray(t)&&t.find(r=>r.id===s)||null}catch{return null}}function w(s){const e=new l(s);if(typeof localStorage<"u")try{const t=localStorage.getItem(o),r=t?JSON.parse(t):[],i=Array.isArray(r)?r:[];i.push(e.toJSON()),localStorage.setItem(o,JSON.stringify(i))}catch(t){console.error("Failed to save local widget to localStorage:",t)}return e}function S(s){if(!(typeof localStorage>"u"))try{const e=localStorage.getItem(o);if(!e)return;const t=JSON.parse(e);if(Array.isArray(t)){const r=t.filter(i=>i.id!==s);localStorage.setItem(o,JSON.stringify(r))}}catch(e){console.error("Failed to remove local widget from localStorage:",e)}}function p(s,e){if(typeof localStorage>"u"||!s)return null;try{const t=localStorage.getItem(o);if(!t)return null;const r=JSON.parse(t);if(!Array.isArray(r))return null;const i=r.findIndex(f=>f.id===s);if(i===-1)return null;const a=r[i],d={...a,...e,id:s,mainAddress:e.mainAddress!==void 0?e.mainAddress.replace(/\/+$/,""):a.mainAddress};return r[i]=d,localStorage.setItem(o,JSON.stringify(r)),d}catch(t){return console.error("Failed to update local widget in localStorage:",t),null}}exports.Communicator=c.Communicator;exports.PING_TOKEN=c.PING_TOKEN;exports.PONG_TOKEN=c.PONG_TOKEN;exports.ping=c.ping;exports.Host=h;exports.LOCAL_WIDGETS_STORAGE_KEY=o;exports.LocalWidget=l;exports.createLocalWidget=w;exports.getLocalWidgetById=y;exports.getLocalWidgets=g;exports.removeLocalWidget=S;exports.updateLocalWidget=p;
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';\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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"}
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 getLocalWidgetById(id?: string): LocalWidgetProps | null {\n if (typeof localStorage === 'undefined' || !id) return null;\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return null;\n return parsed.find((item: LocalWidgetProps) => item.id === id) || null;\n } catch {\n return null;\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}\n\nexport function updateLocalWidget(id: string, props: Partial<LocalWidgetProps>): LocalWidgetProps | null {\n if (typeof localStorage === 'undefined' || !id) return null;\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return null;\n const list = JSON.parse(raw);\n if (!Array.isArray(list)) return null;\n const idx = list.findIndex((item: LocalWidgetProps) => item.id === id);\n if (idx === -1) return null;\n const existing = list[idx];\n const updated: LocalWidgetProps = {\n ...existing,\n ...props,\n id,\n mainAddress: props.mainAddress !== undefined ? props.mainAddress.replace(/\\/+$/, '') : existing.mainAddress\n };\n list[idx] = updated;\n localStorage.setItem(LOCAL_WIDGETS_STORAGE_KEY, JSON.stringify(list));\n return updated;\n } catch (e) {\n console.error('Failed to update local widget in localStorage:', e);\n return null;\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","getLocalWidgetById","id","createLocalWidget","localWidget","list","validList","removeLocalWidget","filtered","updateLocalWidget","idx","existing","updated"],"mappings":"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"}
package/dist/host.js CHANGED
@@ -1,19 +1,19 @@
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 {
1
+ var f = Object.defineProperty;
2
+ var u = (s, e, t) => e in s ? f(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
+ var n = (s, e, t) => u(s, typeof e != "symbol" ? e + "" : e, t);
4
+ import { p as m } from "./communicator-BF77R7Qs.js";
5
+ import { C as O, P as E, a as N } from "./communicator-BF77R7Qs.js";
6
+ class y {
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
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);
12
+ n(this, "_communicator", null);
13
+ n(this, "iframeWindow");
14
+ n(this, "subscriptions", /* @__PURE__ */ new Set());
15
+ n(this, "initPromise", null);
16
+ n(this, "isDestroyed", !1);
17
17
  this.iframeWindow = e;
18
18
  }
19
19
  get communicator() {
@@ -27,21 +27,21 @@ class u {
27
27
  * Returns an unsubscribe function.
28
28
  */
29
29
  onMessage(e, t) {
30
- const s = {
30
+ const r = {
31
31
  actionType: e,
32
32
  handler: t,
33
33
  off: null,
34
34
  cancelled: !1
35
35
  };
36
- return this._communicator && (s.off = this._communicator.registerHandler(e, t)), this.subscriptions.add(s), () => {
37
- s.cancelled || (s.cancelled = !0, this.subscriptions.delete(s), s.off && (s.off(), s.off = null));
36
+ return this._communicator && (r.off = this._communicator.registerHandler(e, t)), this.subscriptions.add(r), () => {
37
+ r.cancelled || (r.cancelled = !0, this.subscriptions.delete(r), r.off && (r.off(), r.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(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);
43
+ async sendMessage(e, t, r) {
44
+ return this._communicator ? this._communicator.sendRequest(e, t, r) : this.initPromise ? (await this.initPromise).sendRequest(e, t, r) : this.communicator.sendRequest(e, t, r);
45
45
  }
46
46
  /**
47
47
  * Complete the handshake with the target widget iframe and attach all registered handlers.
@@ -51,12 +51,12 @@ class u {
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 t = await f(this.iframeWindow, e);
54
+ const t = await m(this.iframeWindow, e);
55
55
  if (this.isDestroyed)
56
56
  throw t.destroy(), new Error("Host was destroyed during initialization.");
57
57
  this._communicator = t;
58
- for (const s of this.subscriptions)
59
- !s.cancelled && !s.off && (s.off = t.registerHandler(s.actionType, s.handler));
58
+ for (const r of this.subscriptions)
59
+ !r.cancelled && !r.off && (r.off = t.registerHandler(r.actionType, r.handler));
60
60
  return t;
61
61
  } catch (t) {
62
62
  throw this.initPromise = null, t;
@@ -73,17 +73,17 @@ class u {
73
73
  }
74
74
  class c {
75
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());
76
+ n(this, "id");
77
+ n(this, "mainAddress");
78
+ n(this, "editorAddress");
79
+ n(this, "runtimeAddress");
80
+ n(this, "manifest", null);
81
+ n(this, "ws", null);
82
+ n(this, "isDestroyed", !1);
83
+ n(this, "reconnectTimer", null);
84
+ n(this, "manifestUpdateHandlers", /* @__PURE__ */ new Set());
85
+ n(this, "manifestErrorHandlers", /* @__PURE__ */ new Set());
86
+ n(this, "fileChangeHandlers", /* @__PURE__ */ new Set());
87
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
88
  }
89
89
  /**
@@ -92,10 +92,10 @@ class c {
92
92
  initHMR() {
93
93
  if (!(typeof window > "u" || typeof WebSocket > "u") && !(this.ws || this.isDestroyed))
94
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) => {
95
+ const e = this.mainAddress.replace(/^http(s)?:\/\//i, (r, i) => i ? "wss://" : "ws://"), t = new WebSocket(e);
96
+ this.ws = t, t.onmessage = (r) => {
97
97
  try {
98
- const i = JSON.parse(s.data);
98
+ const i = JSON.parse(r.data);
99
99
  if (i.type === "manifest:update" && i.data) {
100
100
  this.manifest = i.data;
101
101
  for (const o of this.manifestUpdateHandlers)
@@ -128,8 +128,8 @@ class c {
128
128
  const e = `${this.mainAddress}/manifest.json`, t = await fetch(e);
129
129
  if (!t.ok)
130
130
  throw new Error(`Failed to fetch manifest: HTTP ${t.status}`);
131
- const s = await t.json();
132
- return this.manifest = s, s;
131
+ const r = await t.json();
132
+ return this.manifest = r, r;
133
133
  } catch (e) {
134
134
  return console.error(`[LocalWidget] Failed to fetch manifest from ${this.mainAddress}:`, e), null;
135
135
  }
@@ -177,53 +177,86 @@ class c {
177
177
  }
178
178
  }
179
179
  const a = "goodo_local_widgets";
180
- function g() {
180
+ function w() {
181
181
  if (typeof localStorage > "u")
182
182
  return [];
183
183
  try {
184
- const n = localStorage.getItem(a);
185
- if (!n) return [];
186
- const e = JSON.parse(n);
184
+ const s = localStorage.getItem(a);
185
+ if (!s) return [];
186
+ const e = JSON.parse(s);
187
187
  return Array.isArray(e) ? e.map((t) => new c(t)) : [];
188
188
  } catch {
189
189
  return [];
190
190
  }
191
191
  }
192
- function w(n) {
193
- const e = new c(n);
192
+ function p(s) {
193
+ if (typeof localStorage > "u" || !s) return null;
194
+ try {
195
+ const e = localStorage.getItem(a);
196
+ if (!e) return null;
197
+ const t = JSON.parse(e);
198
+ return Array.isArray(t) && t.find((r) => r.id === s) || null;
199
+ } catch {
200
+ return null;
201
+ }
202
+ }
203
+ function S(s) {
204
+ const e = new c(s);
194
205
  if (typeof localStorage < "u")
195
206
  try {
196
- const t = localStorage.getItem(a), s = t ? JSON.parse(t) : [], i = Array.isArray(s) ? s : [];
207
+ const t = localStorage.getItem(a), r = t ? JSON.parse(t) : [], i = Array.isArray(r) ? r : [];
197
208
  i.push(e.toJSON()), localStorage.setItem(a, JSON.stringify(i));
198
209
  } catch (t) {
199
210
  console.error("Failed to save local widget to localStorage:", t);
200
211
  }
201
212
  return e;
202
213
  }
203
- function y(n) {
214
+ function A(s) {
204
215
  if (!(typeof localStorage > "u"))
205
216
  try {
206
217
  const e = localStorage.getItem(a);
207
218
  if (!e) return;
208
219
  const t = JSON.parse(e);
209
220
  if (Array.isArray(t)) {
210
- const s = t.filter((i) => i.id !== n);
211
- localStorage.setItem(a, JSON.stringify(s));
221
+ const r = t.filter((i) => i.id !== s);
222
+ localStorage.setItem(a, JSON.stringify(r));
212
223
  }
213
224
  } catch (e) {
214
225
  console.error("Failed to remove local widget from localStorage:", e);
215
226
  }
216
227
  }
228
+ function H(s, e) {
229
+ if (typeof localStorage > "u" || !s) return null;
230
+ try {
231
+ const t = localStorage.getItem(a);
232
+ if (!t) return null;
233
+ const r = JSON.parse(t);
234
+ if (!Array.isArray(r)) return null;
235
+ const i = r.findIndex((d) => d.id === s);
236
+ if (i === -1) return null;
237
+ const o = r[i], l = {
238
+ ...o,
239
+ ...e,
240
+ id: s,
241
+ mainAddress: e.mainAddress !== void 0 ? e.mainAddress.replace(/\/+$/, "") : o.mainAddress
242
+ };
243
+ return r[i] = l, localStorage.setItem(a, JSON.stringify(r)), l;
244
+ } catch (t) {
245
+ return console.error("Failed to update local widget in localStorage:", t), null;
246
+ }
247
+ }
217
248
  export {
218
- H as Communicator,
219
- u as Host,
249
+ O as Communicator,
250
+ y as Host,
220
251
  a as LOCAL_WIDGETS_STORAGE_KEY,
221
252
  c as LocalWidget,
222
- A as PING_TOKEN,
223
- _ as PONG_TOKEN,
224
- w as createLocalWidget,
225
- g as getLocalWidgets,
226
- f as ping,
227
- y as removeLocalWidget
253
+ E as PING_TOKEN,
254
+ N as PONG_TOKEN,
255
+ S as createLocalWidget,
256
+ p as getLocalWidgetById,
257
+ w as getLocalWidgets,
258
+ m as ping,
259
+ A as removeLocalWidget,
260
+ H as updateLocalWidget
228
261
  };
229
262
  //# 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';\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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"}
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 getLocalWidgetById(id?: string): LocalWidgetProps | null {\n if (typeof localStorage === 'undefined' || !id) return null;\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return null;\n return parsed.find((item: LocalWidgetProps) => item.id === id) || null;\n } catch {\n return null;\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}\n\nexport function updateLocalWidget(id: string, props: Partial<LocalWidgetProps>): LocalWidgetProps | null {\n if (typeof localStorage === 'undefined' || !id) return null;\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return null;\n const list = JSON.parse(raw);\n if (!Array.isArray(list)) return null;\n const idx = list.findIndex((item: LocalWidgetProps) => item.id === id);\n if (idx === -1) return null;\n const existing = list[idx];\n const updated: LocalWidgetProps = {\n ...existing,\n ...props,\n id,\n mainAddress: props.mainAddress !== undefined ? props.mainAddress.replace(/\\/+$/, '') : existing.mainAddress\n };\n list[idx] = updated;\n localStorage.setItem(LOCAL_WIDGETS_STORAGE_KEY, JSON.stringify(list));\n return updated;\n } catch (e) {\n console.error('Failed to update local widget in localStorage:', e);\n return null;\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","getLocalWidgetById","id","createLocalWidget","localWidget","list","validList","removeLocalWidget","filtered","updateLocalWidget","idx","existing","updated"],"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 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;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("./communicator-DQZOTxOF.cjs");let d=null;function c(t){return d||(d=u.pong(t).catch(e=>{throw d=null,e})),d}function z(t){c().then(e=>e.sendRequest("widget_ready")).then(e=>{t(e)}).catch(e=>{console.error("Failed to initialize widget:",e)})}async function N(t,e){return await(await c()).sendRequest("emit_widget_event",{type:t,args:e})}async function C(t){return await(await c()).sendRequest("set_widget_personalization",t)}function E(t){let e=!1,i=null;return c().then(r=>{e||(i=r.registerHandler("widget_filter_change",a=>{t(a)}))}).catch(r=>{console.error("Failed to initialize communicator for filter change listener:",r)}),()=>{e=!0,i&&i()}}async function g(t){return await(await c()).sendRequest("fetch_node_data",t)}function P(t){async function e(n){return await g({...t,...n})}const i=new Set;let r=null,a=!1,s=null,l=null;async function _(){if(a||s)return;a=!0;const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Math.random().toString(36).substring(2,9);r=n;try{const o=await c();if(l=o,i.size===0||r!==n)return;s=o.registerHandler("widget_data_source_update",m=>{(m==null?void 0:m.identity)===n&&i.forEach(w=>{try{w()}catch(y){console.error("Error in widget data source onChange callback:",y)}})}),await o.sendRequest("add_widget_data_source_listener",{identity:n,config:t})}catch(o){console.error("Failed to initialize communicator for data source listener:",o)}finally{a=!1,i.size===0&&r===n&&f()}}function f(){const n=r;r=null,a=!1,s&&(s(),s=null),l&&n&&l.sendRequest("remove_widget_data_source_listener",{identity:n}).catch(o=>{console.error("Failed to remove data source listener:",o)})}function h(n){return i.add(n),i.size===1&&_(),()=>{i.delete(n),i.size===0&&f()}}return{fetch:e,onChange:h}}exports.Communicator=u.Communicator;exports.PING_TOKEN=u.PING_TOKEN;exports.PONG_TOKEN=u.PONG_TOKEN;exports.pong=u.pong;exports.createDataSource=P;exports.emitWidgetEvent=N;exports.fetchNodeData=g;exports.onWidgetFilterChange=E;exports.onWidgetReady=z;exports.setWidgetPersonalization=C;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
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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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/widget-sdk.ts"],"sourcesContent":["import { Communicator, pong, OnPingOptions } from './communicator';\nimport { DataSourceConfig, NodeData, NodeDataRequestPayload, WidgetConfig, WidgetFilter } 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 * 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: WidgetFilter) => 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","emitWidgetEvent","type","args","setWidgetPersonalization","data","onWidgetFilterChange","isCancelled","unregisterHandler","condition","fetchNodeData","payload","createDataSource","fetch","callbacks","identity","isConnecting","commInstance","connect","currentIdentity","cb","disconnect","activeIdentity","onChange"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,98 +1,81 @@
1
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;
2
+ import { C as F, P as N, a as P } from "./communicator-BF77R7Qs.js";
3
+ let u = null;
4
+ function c(t) {
5
+ return u || (u = w(t).catch((e) => {
6
+ throw u = null, e;
7
+ })), u;
8
8
  }
9
9
  function C(t) {
10
- u().then((e) => e.sendRequest("widget_ready")).then((e) => {
10
+ c().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
- function I(t, e) {
17
- const n = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);
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);
24
- }));
25
- }).catch((o) => {
26
- console.error("Failed to initialize communicator for data source listener:", o);
27
- }), () => {
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);
30
- });
31
- };
32
- }
33
16
  async function R(t, e) {
34
- return await (await u()).sendRequest("emit_widget_event", { type: t, args: e });
17
+ return await (await c()).sendRequest("emit_widget_event", { type: t, args: e });
35
18
  }
36
- async function q(t) {
37
- return await (await u()).sendRequest("set_widget_personalization", t);
19
+ async function p(t) {
20
+ return await (await c()).sendRequest("set_widget_personalization", t);
38
21
  }
39
- function F(t) {
40
- let e = !1, n = null;
41
- return u().then((i) => {
42
- e || (n = i.registerHandler("widget_filter_change", (a) => {
22
+ function q(t) {
23
+ let e = !1, i = null;
24
+ return c().then((r) => {
25
+ e || (i = r.registerHandler("widget_filter_change", (a) => {
43
26
  t(a);
44
27
  }));
45
- }).catch((i) => {
46
- console.error("Failed to initialize communicator for filter change listener:", i);
28
+ }).catch((r) => {
29
+ console.error("Failed to initialize communicator for filter change listener:", r);
47
30
  }), () => {
48
- e = !0, n && n();
31
+ e = !0, i && i();
49
32
  };
50
33
  }
51
34
  async function y(t) {
52
- return await (await u()).sendRequest("fetch_node_data", t);
35
+ return await (await c()).sendRequest("fetch_node_data", t);
53
36
  }
54
- function U(t) {
55
- async function e(r) {
37
+ function I(t) {
38
+ async function e(n) {
56
39
  return await y({
57
40
  ...t,
58
- ...r
41
+ ...n
59
42
  });
60
43
  }
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;
44
+ const i = /* @__PURE__ */ new Set();
45
+ let r = null, a = !1, s = null, l = null;
46
+ async function m() {
47
+ if (a || s) return;
65
48
  a = !0;
66
- const r = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);
67
- i = r;
49
+ const n = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);
50
+ r = n;
68
51
  try {
69
- const d = await u();
70
- if (o = d, n.size === 0 || i !== r)
52
+ const o = await c();
53
+ if (l = o, i.size === 0 || r !== n)
71
54
  return;
72
- c = d.registerHandler("widget_data_source_update", (f) => {
73
- (f == null ? void 0 : f.identity) === r && n.forEach((_) => {
55
+ s = o.registerHandler("widget_data_source_update", (d) => {
56
+ (d == null ? void 0 : d.identity) === n && i.forEach((_) => {
74
57
  try {
75
58
  _();
76
59
  } catch (h) {
77
60
  console.error("Error in widget data source onChange callback:", h);
78
61
  }
79
62
  });
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);
63
+ }), await o.sendRequest("add_widget_data_source_listener", { identity: n, config: t });
64
+ } catch (o) {
65
+ console.error("Failed to initialize communicator for data source listener:", o);
83
66
  } finally {
84
- a = !1, n.size === 0 && i === r && m();
67
+ a = !1, i.size === 0 && r === n && f();
85
68
  }
86
69
  }
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);
70
+ function f() {
71
+ const n = r;
72
+ r = null, a = !1, s && (s(), s = null), l && n && l.sendRequest("remove_widget_data_source_listener", { identity: n }).catch((o) => {
73
+ console.error("Failed to remove data source listener:", o);
91
74
  });
92
75
  }
93
- function g(r) {
94
- return n.add(r), n.size === 1 && s(), () => {
95
- n.delete(r), n.size === 0 && m();
76
+ function g(n) {
77
+ return i.add(n), i.size === 1 && m(), () => {
78
+ i.delete(n), i.size === 0 && f();
96
79
  };
97
80
  }
98
81
  return {
@@ -101,16 +84,15 @@ function U(t) {
101
84
  };
102
85
  }
103
86
  export {
104
- p as Communicator,
105
- H as PING_TOKEN,
106
- E as PONG_TOKEN,
107
- I as addDataSourceListener,
108
- U as createDataSource,
87
+ F as Communicator,
88
+ N as PING_TOKEN,
89
+ P as PONG_TOKEN,
90
+ I as createDataSource,
109
91
  R as emitWidgetEvent,
110
92
  y as fetchNodeData,
111
- F as onWidgetFilterChange,
93
+ q as onWidgetFilterChange,
112
94
  C as onWidgetReady,
113
95
  w as pong,
114
- q as setWidgetPersonalization
96
+ p as setWidgetPersonalization
115
97
  };
116
98
  //# 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, 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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"}
1
+ {"version":3,"file":"index.js","sources":["../src/widget-sdk.ts"],"sourcesContent":["import { Communicator, pong, OnPingOptions } from './communicator';\nimport { DataSourceConfig, NodeData, NodeDataRequestPayload, WidgetConfig, WidgetFilter } 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 * 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: WidgetFilter) => 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","emitWidgetEvent","type","args","setWidgetPersonalization","data","onWidgetFilterChange","isCancelled","unregisterHandler","condition","fetchNodeData","payload","createDataSource","fetch","callbacks","identity","isConnecting","commInstance","connect","currentIdentity","cb","disconnect","activeIdentity","onChange"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -53,7 +53,8 @@ export interface ActionMap {
53
53
  }>;
54
54
  }) => void;
55
55
  set_widget_personalization: (payload: any) => void;
56
- widget_filter_change: (payload: string) => void;
56
+ widget_filter_change: (payload: WidgetFilter) => void;
57
57
  fetch_node_data: (payload: NodeDataRequestPayload) => NodeData;
58
58
  }
59
+ export type WidgetFilter = Record<string, string>;
59
60
  //# sourceMappingURL=types.d.ts.map
@@ -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;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"}
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,YAAY,KAAK,IAAI,CAAC;IACtD,eAAe,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,QAAQ,CAAC;CAChE;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA"}
@@ -1,13 +1,8 @@
1
- import { DataSourceConfig, NodeData, NodeDataRequestPayload, WidgetConfig } from './types';
1
+ import { NodeData, NodeDataRequestPayload, WidgetConfig, WidgetFilter } 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
- * Add a reactive data source listener on the host platform.
8
- * Returns an unsubscribe function.
9
- */
10
- export declare function addDataSourceListener(config: DataSourceConfig, onChange: (value: any[]) => void): () => void;
11
6
  /**
12
7
  * Emit a custom widget event to the host platform.
13
8
  */
@@ -20,7 +15,7 @@ export declare function setWidgetPersonalization(data: any): Promise<void>;
20
15
  * Register a listener for widget filter changes from the host platform.
21
16
  * Returns an unsubscribe function.
22
17
  */
23
- export declare function onWidgetFilterChange(callback: (condition: string) => void): () => void;
18
+ export declare function onWidgetFilterChange(callback: (condition: WidgetFilter) => void): () => void;
24
19
  export declare function fetchNodeData(payload: NodeDataRequestPayload): Promise<NodeData>;
25
20
  export declare function createDataSource(config: Pick<NodeDataRequestPayload, 'node' | 'filterExpression'>): {
26
21
  fetch: (payload?: Omit<NodeDataRequestPayload, "node" | "filterExpression">) => Promise<NodeData>;
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"widget-sdk.d.ts","sourceRoot":"","sources":["../src/widget-sdk.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,QAAQ,EAAE,sBAAsB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAmBzG;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,QASrE;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,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI,CA0B5F;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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodo/platform-plugin",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "goodo platform plugin sdk",
5
5
  "type": "module",
6
6
  "publishConfig": {