@goodo/platform-plugin 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/host-sdk.d.ts +64 -0
- package/dist/host-sdk.d.ts.map +1 -1
- package/dist/host.cjs +1 -1
- package/dist/host.cjs.map +1 -1
- package/dist/host.js +183 -35
- package/dist/host.js.map +1 -1
- package/dist/manifest.cjs +1 -1
- package/dist/manifest.cjs.map +1 -1
- package/dist/manifest.d.ts +0 -52
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +28 -41
- package/dist/manifest.js.map +1 -1
- package/package.json +1 -1
package/dist/host-sdk.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Communicator, PingOptions } from './communicator';
|
|
2
2
|
import { ActionMap } from './types';
|
|
3
|
+
import { ResolvedWidgetManifest } from './manifest';
|
|
3
4
|
export declare class Host {
|
|
4
5
|
private _communicator;
|
|
5
6
|
private iframeWindow;
|
|
@@ -28,4 +29,67 @@ export declare class Host {
|
|
|
28
29
|
init(options?: PingOptions): Promise<Communicator>;
|
|
29
30
|
destroy(): void;
|
|
30
31
|
}
|
|
32
|
+
export type LocalWidgetProps = {
|
|
33
|
+
id?: string;
|
|
34
|
+
mainAddress: string;
|
|
35
|
+
editorAddress?: string;
|
|
36
|
+
runtimeAddress?: string;
|
|
37
|
+
};
|
|
38
|
+
export type ManifestUpdateHandler = (manifest: ResolvedWidgetManifest) => void;
|
|
39
|
+
export type ManifestErrorHandler = (errors: Array<{
|
|
40
|
+
path: string;
|
|
41
|
+
message: string;
|
|
42
|
+
}> | string) => void;
|
|
43
|
+
export type FileChangeHandler = (payload: {
|
|
44
|
+
file: string;
|
|
45
|
+
event: string;
|
|
46
|
+
}) => void;
|
|
47
|
+
export declare class LocalWidget implements LocalWidgetProps {
|
|
48
|
+
id: string;
|
|
49
|
+
mainAddress: string;
|
|
50
|
+
editorAddress?: string;
|
|
51
|
+
runtimeAddress?: string;
|
|
52
|
+
manifest: ResolvedWidgetManifest | null;
|
|
53
|
+
private ws;
|
|
54
|
+
private isDestroyed;
|
|
55
|
+
private reconnectTimer;
|
|
56
|
+
private manifestUpdateHandlers;
|
|
57
|
+
private manifestErrorHandlers;
|
|
58
|
+
private fileChangeHandlers;
|
|
59
|
+
constructor(props: LocalWidgetProps);
|
|
60
|
+
/**
|
|
61
|
+
* Initialize WebSocket connection for mini-HMR with the dev server
|
|
62
|
+
*/
|
|
63
|
+
initHMR(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Fetch the latest manifest from the dev server via HTTP
|
|
66
|
+
*/
|
|
67
|
+
fetchManifest(): Promise<ResolvedWidgetManifest | null>;
|
|
68
|
+
/**
|
|
69
|
+
* Subscribe to manifest update events
|
|
70
|
+
*/
|
|
71
|
+
onManifestUpdate(handler: ManifestUpdateHandler): () => void;
|
|
72
|
+
/**
|
|
73
|
+
* Subscribe to manifest validation errors
|
|
74
|
+
*/
|
|
75
|
+
onManifestError(handler: ManifestErrorHandler): () => void;
|
|
76
|
+
/**
|
|
77
|
+
* Subscribe to file change events in .goodo
|
|
78
|
+
*/
|
|
79
|
+
onFileChange(handler: FileChangeHandler): () => void;
|
|
80
|
+
/**
|
|
81
|
+
* Destroy the instance, closing WebSocket and cleaning up timers and listeners
|
|
82
|
+
*/
|
|
83
|
+
destroy(): void;
|
|
84
|
+
/**
|
|
85
|
+
* JSON serialization helper for localStorage
|
|
86
|
+
*/
|
|
87
|
+
toJSON(): LocalWidgetProps & {
|
|
88
|
+
id: string;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export declare const LOCAL_WIDGETS_STORAGE_KEY = "goodo_local_widgets";
|
|
92
|
+
export declare function getLocalWidgets(): LocalWidget[];
|
|
93
|
+
export declare function createLocalWidget(props: LocalWidgetProps): LocalWidget;
|
|
94
|
+
export declare function removeLocalWidget(id: string): void;
|
|
31
95
|
//# sourceMappingURL=host-sdk.d.ts.map
|
package/dist/host-sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-sdk.d.ts","sourceRoot":"","sources":["../src/host-sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAQ,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"host-sdk.d.ts","sourceRoot":"","sources":["../src/host-sdk.ts"],"names":[],"mappings":"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"}
|
package/dist/host.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var l=Object.defineProperty;var f=(n,e,t)=>e in n?l(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var r=(n,e,t)=>f(n,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./communicator-DQZOTxOF.cjs");class m{constructor(e){r(this,"_communicator",null);r(this,"iframeWindow");r(this,"subscriptions",new Set);r(this,"initPromise",null);r(this,"isDestroyed",!1);this.iframeWindow=e}get communicator(){if(!this._communicator)throw new Error("Host is not initialized. Call init() first.");return this._communicator}onMessage(e,t){const i={actionType:e,handler:t,off:null,cancelled:!1};return this._communicator&&(i.off=this._communicator.registerHandler(e,t)),this.subscriptions.add(i),()=>{i.cancelled||(i.cancelled=!0,this.subscriptions.delete(i),i.off&&(i.off(),i.off=null))}}async sendMessage(e,t,i){return this._communicator?this._communicator.sendRequest(e,t,i):this.initPromise?(await this.initPromise).sendRequest(e,t,i):this.communicator.sendRequest(e,t,i)}async init(e){if(this.isDestroyed)throw new Error("Host has already been destroyed.");return this._communicator?this._communicator:(this.initPromise||(this.initPromise=(async()=>{try{const t=await c.ping(this.iframeWindow,e);if(this.isDestroyed)throw t.destroy(),new Error("Host was destroyed during initialization.");this._communicator=t;for(const i of this.subscriptions)!i.cancelled&&!i.off&&(i.off=t.registerHandler(i.actionType,i.handler));return t}catch(t){throw this.initPromise=null,t}})()),this.initPromise)}destroy(){var e;this.isDestroyed=!0;for(const t of this.subscriptions)t.off&&(t.off(),t.off=null),t.cancelled=!0;this.subscriptions.clear(),(e=this._communicator)==null||e.destroy(),this._communicator=null,this.initPromise=null}}class d{constructor(e){r(this,"id");r(this,"mainAddress");r(this,"editorAddress");r(this,"runtimeAddress");r(this,"manifest",null);r(this,"ws",null);r(this,"isDestroyed",!1);r(this,"reconnectTimer",null);r(this,"manifestUpdateHandlers",new Set);r(this,"manifestErrorHandlers",new Set);r(this,"fileChangeHandlers",new Set);this.mainAddress=e.mainAddress.replace(/\/+$/,""),this.editorAddress=e.editorAddress,this.runtimeAddress=e.runtimeAddress,this.id=e.id||(typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now()}_${Math.random().toString(36).substring(2,9)}`),this.initHMR()}initHMR(){if(!(typeof window>"u"||typeof WebSocket>"u")&&!(this.ws||this.isDestroyed))try{const e=this.mainAddress.replace(/^http(s)?:\/\//i,(i,s)=>s?"wss://":"ws://"),t=new WebSocket(e);this.ws=t,t.onmessage=i=>{try{const s=JSON.parse(i.data);if(s.type==="manifest:update"&&s.data){this.manifest=s.data;for(const a of this.manifestUpdateHandlers)a(s.data)}else if(s.type==="manifest:error")for(const a of this.manifestErrorHandlers)a(s.errors||"Manifest error");else if(s.type==="file:change")for(const a of this.fileChangeHandlers)a({file:s.file,event:s.event})}catch(s){console.error("[LocalWidget] Failed to parse HMR message:",s)}},t.onerror=()=>{},t.onclose=()=>{this.ws=null,this.isDestroyed||(this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=setTimeout(()=>{this.isDestroyed||this.initHMR()},3e3))}}catch(e){console.error("[LocalWidget] Failed to initialize WebSocket HMR:",e)}}async fetchManifest(){if(typeof fetch>"u")return null;try{const e=`${this.mainAddress}/manifest.json`,t=await fetch(e);if(!t.ok)throw new Error(`Failed to fetch manifest: HTTP ${t.status}`);const i=await t.json();return this.manifest=i,i}catch(e){return console.error(`[LocalWidget] Failed to fetch manifest from ${this.mainAddress}:`,e),null}}onManifestUpdate(e){return this.manifestUpdateHandlers.add(e),this.manifest&&e(this.manifest),()=>{this.manifestUpdateHandlers.delete(e)}}onManifestError(e){return this.manifestErrorHandlers.add(e),()=>{this.manifestErrorHandlers.delete(e)}}onFileChange(e){return this.fileChangeHandlers.add(e),()=>{this.fileChangeHandlers.delete(e)}}destroy(){this.isDestroyed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(),this.ws=null),this.manifestUpdateHandlers.clear(),this.manifestErrorHandlers.clear(),this.fileChangeHandlers.clear()}toJSON(){return{id:this.id,mainAddress:this.mainAddress,editorAddress:this.editorAddress,runtimeAddress:this.runtimeAddress}}}const o="goodo_local_widgets";function u(){if(typeof localStorage>"u")return[];try{const n=localStorage.getItem(o);if(!n)return[];const e=JSON.parse(n);return Array.isArray(e)?e.map(t=>new d(t)):[]}catch{return[]}}function h(n){const e=new d(n);if(typeof localStorage<"u")try{const t=localStorage.getItem(o),i=t?JSON.parse(t):[],s=Array.isArray(i)?i:[];s.push(e.toJSON()),localStorage.setItem(o,JSON.stringify(s))}catch(t){console.error("Failed to save local widget to localStorage:",t)}return e}function g(n){if(!(typeof localStorage>"u"))try{const e=localStorage.getItem(o);if(!e)return;const t=JSON.parse(e);if(Array.isArray(t)){const i=t.filter(s=>s.id!==n);localStorage.setItem(o,JSON.stringify(i))}}catch(e){console.error("Failed to remove local widget from localStorage:",e)}}exports.Communicator=c.Communicator;exports.PING_TOKEN=c.PING_TOKEN;exports.PONG_TOKEN=c.PONG_TOKEN;exports.ping=c.ping;exports.Host=m;exports.LOCAL_WIDGETS_STORAGE_KEY=o;exports.LocalWidget=d;exports.createLocalWidget=h;exports.getLocalWidgets=u;exports.removeLocalWidget=g;
|
|
2
2
|
//# sourceMappingURL=host.cjs.map
|
package/dist/host.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.cjs","sources":["../src/host-sdk.ts"],"sourcesContent":["import { Communicator, ping, PingOptions } from './communicator';\nimport { ActionMap } from './types';\n\ninterface HostSubscription {\n actionType: keyof ActionMap;\n handler: (payload: any) => any;\n off: (() => void) | null;\n cancelled: boolean;\n}\n\nexport class Host {\n private _communicator: Communicator | null = null;\n\n private iframeWindow: Window;\n\n private subscriptions = new Set<HostSubscription>();\n\n private initPromise: Promise<Communicator> | null = null;\n\n private isDestroyed = false;\n\n private get communicator(): Communicator {\n if (!this._communicator) {\n throw new Error('Host is not initialized. Call init() first.');\n }\n return this._communicator;\n }\n\n /**\n * Initialize Host SDK for a specific iframe widget\n * @param iframeWindow The contentWindow of the widget's iframe\n */\n constructor(iframeWindow: Window) {\n this.iframeWindow = iframeWindow;\n }\n\n /**\n * Register a unified handler for a specific message action type.\n * Can be called before or after `init()`.\n * Returns an unsubscribe function.\n */\n public onMessage<A extends keyof ActionMap>(\n actionType: A,\n handler: (payload: Parameters<ActionMap[A]>[0]) => Promise<ReturnType<ActionMap[A]>> | ReturnType<ActionMap[A]>\n ): () => void {\n const sub: HostSubscription = {\n actionType,\n handler,\n off: null,\n cancelled: false,\n };\n\n if (this._communicator) {\n sub.off = this._communicator.registerHandler(actionType, handler);\n }\n\n this.subscriptions.add(sub);\n\n return () => {\n if (sub.cancelled) return;\n sub.cancelled = true;\n this.subscriptions.delete(sub);\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n };\n }\n\n /**\n * Send a message/request to the widget and wait for the response.\n */\n public async sendMessage<A extends keyof ActionMap>(\n actionType: A,\n payload?: Parameters<ActionMap[A]>[0],\n timeout?: number\n ): Promise<ReturnType<ActionMap[A]>> {\n if (this._communicator) {\n return this._communicator.sendRequest(actionType, payload, timeout);\n }\n\n if (this.initPromise) {\n const comm = await this.initPromise;\n\n return comm.sendRequest(actionType, payload, timeout);\n }\n\n return this.communicator.sendRequest(actionType, payload, timeout);\n }\n\n /**\n * Complete the handshake with the target widget iframe and attach all registered handlers.\n */\n public async init(options?: PingOptions): Promise<Communicator> {\n if (this.isDestroyed) {\n throw new Error('Host has already been destroyed.');\n }\n\n if (this._communicator) {\n return this._communicator;\n }\n\n if (!this.initPromise) {\n this.initPromise = (async () => {\n try {\n const comm = await ping(this.iframeWindow, options);\n\n if (this.isDestroyed) {\n comm.destroy();\n throw new Error('Host was destroyed during initialization.');\n }\n\n this._communicator = comm;\n\n // Attach all active subscriptions to communicator\n for (const sub of this.subscriptions) {\n if (!sub.cancelled && !sub.off) {\n sub.off = comm.registerHandler(sub.actionType, sub.handler);\n }\n }\n\n return comm;\n } catch (err) {\n this.initPromise = null;\n throw err;\n }\n })();\n }\n\n return this.initPromise;\n }\n\n public destroy(): void {\n this.isDestroyed = true;\n\n for (const sub of this.subscriptions) {\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n sub.cancelled = true;\n }\n this.subscriptions.clear();\n\n this._communicator?.destroy();\n\n this._communicator = null;\n\n this.initPromise = null;\n }\n}\n"],"names":["Host","iframeWindow","__publicField","actionType","handler","sub","payload","timeout","options","comm","ping","err","_a"],"mappings":"mSAUO,MAAMA,CAAK,CAsBhB,YAAYC,EAAsB,CArB1BC,EAAA,qBAAqC,MAErCA,EAAA,qBAEAA,EAAA,yBAAoB,KAEpBA,EAAA,mBAA4C,MAE5CA,EAAA,mBAAc,IAcpB,KAAK,aAAeD,CACtB,CAbA,IAAY,cAA6B,CACvC,GAAI,CAAC,KAAK,cACR,MAAM,IAAI,MAAM,6CAA6C,EAE/D,OAAO,KAAK,aACd,CAeO,UACLE,EACAC,EACY,CACZ,MAAMC,EAAwB,CAC5B,WAAAF,EACA,QAAAC,EACA,IAAK,KACL,UAAW,EAAA,EAGb,OAAI,KAAK,gBACPC,EAAI,IAAM,KAAK,cAAc,gBAAgBF,EAAYC,CAAO,GAGlE,KAAK,cAAc,IAAIC,CAAG,EAEnB,IAAM,CACPA,EAAI,YACRA,EAAI,UAAY,GAChB,KAAK,cAAc,OAAOA,CAAG,EACzBA,EAAI,MACNA,EAAI,IAAA,EACJA,EAAI,IAAM,MAEd,CACF,CAKA,MAAa,YACXF,EACAG,EACAC,EACmC,CACnC,OAAI,KAAK,cACA,KAAK,cAAc,YAAYJ,EAAYG,EAASC,CAAO,EAGhE,KAAK,aACM,MAAM,KAAK,aAEZ,YAAYJ,EAAYG,EAASC,CAAO,EAG/C,KAAK,aAAa,YAAYJ,EAAYG,EAASC,CAAO,CACnE,CAKA,MAAa,KAAKC,EAA8C,CAC9D,GAAI,KAAK,YACP,MAAM,IAAI,MAAM,kCAAkC,EAGpD,OAAI,KAAK,cACA,KAAK,eAGT,KAAK,cACR,KAAK,aAAe,SAAY,CAC9B,GAAI,CACF,MAAMC,EAAO,MAAMC,EAAAA,KAAK,KAAK,aAAcF,CAAO,EAElD,GAAI,KAAK,YACP,MAAAC,EAAK,QAAA,EACC,IAAI,MAAM,2CAA2C,EAG7D,KAAK,cAAgBA,EAGrB,UAAWJ,KAAO,KAAK,cACjB,CAACA,EAAI,WAAa,CAACA,EAAI,MACzBA,EAAI,IAAMI,EAAK,gBAAgBJ,EAAI,WAAYA,EAAI,OAAO,GAI9D,OAAOI,CACT,OAASE,EAAK,CACZ,WAAK,YAAc,KACbA,CACR,CACF,GAAA,GAGK,KAAK,YACd,CAEO,SAAgB,OACrB,KAAK,YAAc,GAEnB,UAAWN,KAAO,KAAK,cACjBA,EAAI,MACNA,EAAI,IAAA,EACJA,EAAI,IAAM,MAEZA,EAAI,UAAY,GAElB,KAAK,cAAc,MAAA,GAEnBO,EAAA,KAAK,gBAAL,MAAAA,EAAoB,UAEpB,KAAK,cAAgB,KAErB,KAAK,YAAc,IACrB,CACF"}
|
|
1
|
+
{"version":3,"file":"host.cjs","sources":["../src/host-sdk.ts"],"sourcesContent":["import { Communicator, ping, PingOptions } from './communicator';\nimport { ActionMap } from './types';\nimport type { ResolvedWidgetManifest } from './manifest';\n\ninterface HostSubscription {\n actionType: keyof ActionMap;\n handler: (payload: any) => any;\n off: (() => void) | null;\n cancelled: boolean;\n}\n\nexport class Host {\n private _communicator: Communicator | null = null;\n\n private iframeWindow: Window;\n\n private subscriptions = new Set<HostSubscription>();\n\n private initPromise: Promise<Communicator> | null = null;\n\n private isDestroyed = false;\n\n private get communicator(): Communicator {\n if (!this._communicator) {\n throw new Error('Host is not initialized. Call init() first.');\n }\n return this._communicator;\n }\n\n /**\n * Initialize Host SDK for a specific iframe widget\n * @param iframeWindow The contentWindow of the widget's iframe\n */\n constructor(iframeWindow: Window) {\n this.iframeWindow = iframeWindow;\n }\n\n /**\n * Register a unified handler for a specific message action type.\n * Can be called before or after `init()`.\n * Returns an unsubscribe function.\n */\n public onMessage<A extends keyof ActionMap>(\n actionType: A,\n handler: (payload: Parameters<ActionMap[A]>[0]) => Promise<ReturnType<ActionMap[A]>> | ReturnType<ActionMap[A]>\n ): () => void {\n const sub: HostSubscription = {\n actionType,\n handler,\n off: null,\n cancelled: false,\n };\n\n if (this._communicator) {\n sub.off = this._communicator.registerHandler(actionType, handler);\n }\n\n this.subscriptions.add(sub);\n\n return () => {\n if (sub.cancelled) return;\n sub.cancelled = true;\n this.subscriptions.delete(sub);\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n };\n }\n\n /**\n * Send a message/request to the widget and wait for the response.\n */\n public async sendMessage<A extends keyof ActionMap>(\n actionType: A,\n payload?: Parameters<ActionMap[A]>[0],\n timeout?: number\n ): Promise<ReturnType<ActionMap[A]>> {\n if (this._communicator) {\n return this._communicator.sendRequest(actionType, payload, timeout);\n }\n\n if (this.initPromise) {\n const comm = await this.initPromise;\n\n return comm.sendRequest(actionType, payload, timeout);\n }\n\n return this.communicator.sendRequest(actionType, payload, timeout);\n }\n\n /**\n * Complete the handshake with the target widget iframe and attach all registered handlers.\n */\n public async init(options?: PingOptions): Promise<Communicator> {\n if (this.isDestroyed) {\n throw new Error('Host has already been destroyed.');\n }\n\n if (this._communicator) {\n return this._communicator;\n }\n\n if (!this.initPromise) {\n this.initPromise = (async () => {\n try {\n const comm = await ping(this.iframeWindow, options);\n\n if (this.isDestroyed) {\n comm.destroy();\n throw new Error('Host was destroyed during initialization.');\n }\n\n this._communicator = comm;\n\n // Attach all active subscriptions to communicator\n for (const sub of this.subscriptions) {\n if (!sub.cancelled && !sub.off) {\n sub.off = comm.registerHandler(sub.actionType, sub.handler);\n }\n }\n\n return comm;\n } catch (err) {\n this.initPromise = null;\n throw err;\n }\n })();\n }\n\n return this.initPromise;\n }\n\n public destroy(): void {\n this.isDestroyed = true;\n\n for (const sub of this.subscriptions) {\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n sub.cancelled = true;\n }\n this.subscriptions.clear();\n\n this._communicator?.destroy();\n\n this._communicator = null;\n\n this.initPromise = null;\n }\n}\n\nexport type LocalWidgetProps = {\n id?: string;\n mainAddress: string;\n editorAddress?: string;\n runtimeAddress?: string;\n};\n\nexport type ManifestUpdateHandler = (manifest: ResolvedWidgetManifest) => void;\nexport type ManifestErrorHandler = (errors: Array<{ path: string; message: string }> | string) => void;\nexport type FileChangeHandler = (payload: { file: string; event: string }) => void;\n\nexport class LocalWidget implements LocalWidgetProps {\n id: string;\n\n mainAddress: string;\n\n editorAddress?: string;\n\n runtimeAddress?: string;\n\n manifest: ResolvedWidgetManifest | null = null;\n\n private ws: WebSocket | null = null;\n\n private isDestroyed = false;\n\n private reconnectTimer: any = null;\n\n private manifestUpdateHandlers = new Set<ManifestUpdateHandler>();\n\n private manifestErrorHandlers = new Set<ManifestErrorHandler>();\n\n private fileChangeHandlers = new Set<FileChangeHandler>();\n\n constructor(props: LocalWidgetProps) {\n this.mainAddress = props.mainAddress.replace(/\\/+$/, '');\n this.editorAddress = props.editorAddress;\n this.runtimeAddress = props.runtimeAddress;\n this.id =\n props.id ||\n (typeof crypto !== 'undefined' && crypto.randomUUID\n ? crypto.randomUUID()\n : `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`);\n\n this.initHMR();\n }\n\n /**\n * Initialize WebSocket connection for mini-HMR with the dev server\n */\n public initHMR(): void {\n if (typeof window === 'undefined' || typeof WebSocket === 'undefined') {\n return;\n }\n\n if (this.ws || this.isDestroyed) {\n return;\n }\n\n try {\n const wsUrl = this.mainAddress.replace(/^http(s)?:\\/\\//i, (_, s) => (s ? 'wss://' : 'ws://'));\n const ws = new WebSocket(wsUrl);\n this.ws = ws;\n\n ws.onmessage = (event) => {\n try {\n const msg = JSON.parse(event.data);\n if (msg.type === 'manifest:update' && msg.data) {\n this.manifest = msg.data;\n for (const handler of this.manifestUpdateHandlers) {\n handler(msg.data);\n }\n } else if (msg.type === 'manifest:error') {\n for (const handler of this.manifestErrorHandlers) {\n handler(msg.errors || 'Manifest error');\n }\n } else if (msg.type === 'file:change') {\n for (const handler of this.fileChangeHandlers) {\n handler({ file: msg.file, event: msg.event });\n }\n }\n } catch (e) {\n console.error('[LocalWidget] Failed to parse HMR message:', e);\n }\n };\n\n ws.onerror = () => {};\n\n ws.onclose = () => {\n this.ws = null;\n if (!this.isDestroyed) {\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\n this.reconnectTimer = setTimeout(() => {\n if (!this.isDestroyed) {\n this.initHMR();\n }\n }, 3000);\n }\n };\n } catch (e) {\n console.error('[LocalWidget] Failed to initialize WebSocket HMR:', e);\n }\n }\n\n /**\n * Fetch the latest manifest from the dev server via HTTP\n */\n public async fetchManifest(): Promise<ResolvedWidgetManifest | null> {\n if (typeof fetch === 'undefined') return null;\n try {\n const url = `${this.mainAddress}/manifest.json`;\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch manifest: HTTP ${res.status}`);\n }\n const data = (await res.json()) as ResolvedWidgetManifest;\n this.manifest = data;\n return data;\n } catch (e) {\n console.error(`[LocalWidget] Failed to fetch manifest from ${this.mainAddress}:`, e);\n return null;\n }\n }\n\n /**\n * Subscribe to manifest update events\n */\n public onManifestUpdate(handler: ManifestUpdateHandler): () => void {\n this.manifestUpdateHandlers.add(handler);\n if (this.manifest) {\n handler(this.manifest);\n }\n return () => {\n this.manifestUpdateHandlers.delete(handler);\n };\n }\n\n /**\n * Subscribe to manifest validation errors\n */\n public onManifestError(handler: ManifestErrorHandler): () => void {\n this.manifestErrorHandlers.add(handler);\n return () => {\n this.manifestErrorHandlers.delete(handler);\n };\n }\n\n /**\n * Subscribe to file change events in .goodo\n */\n public onFileChange(handler: FileChangeHandler): () => void {\n this.fileChangeHandlers.add(handler);\n return () => {\n this.fileChangeHandlers.delete(handler);\n };\n }\n\n /**\n * Destroy the instance, closing WebSocket and cleaning up timers and listeners\n */\n public destroy(): void {\n this.isDestroyed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n this.manifestUpdateHandlers.clear();\n this.manifestErrorHandlers.clear();\n this.fileChangeHandlers.clear();\n }\n\n /**\n * JSON serialization helper for localStorage\n */\n public toJSON(): LocalWidgetProps & { id: string } {\n return {\n id: this.id,\n mainAddress: this.mainAddress,\n editorAddress: this.editorAddress,\n runtimeAddress: this.runtimeAddress,\n };\n }\n}\n\nexport const LOCAL_WIDGETS_STORAGE_KEY = 'goodo_local_widgets';\n\nexport function getLocalWidgets(): LocalWidget[] {\n if (typeof localStorage === 'undefined') {\n return [];\n }\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.map((item: LocalWidgetProps) => new LocalWidget(item));\n } catch {\n return [];\n }\n}\n\nexport function createLocalWidget(props: LocalWidgetProps): LocalWidget {\n const localWidget = new LocalWidget(props);\n\n if (typeof localStorage !== 'undefined') {\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n const list = raw ? JSON.parse(raw) : [];\n const validList = Array.isArray(list) ? list : [];\n validList.push(localWidget.toJSON());\n localStorage.setItem(LOCAL_WIDGETS_STORAGE_KEY, JSON.stringify(validList));\n } catch (e) {\n console.error('Failed to save local widget to localStorage:', e);\n }\n }\n\n return localWidget;\n}\n\nexport function removeLocalWidget(id: string): void {\n if (typeof localStorage === 'undefined') return;\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return;\n const list = JSON.parse(raw);\n if (Array.isArray(list)) {\n const filtered = list.filter((item: { id: string }) => item.id !== id);\n localStorage.setItem(LOCAL_WIDGETS_STORAGE_KEY, JSON.stringify(filtered));\n }\n } catch (e) {\n console.error('Failed to remove local widget from localStorage:', e);\n }\n}"],"names":["Host","iframeWindow","__publicField","actionType","handler","sub","payload","timeout","options","comm","ping","err","_a","LocalWidget","props","wsUrl","_","ws","event","msg","e","url","res","data","LOCAL_WIDGETS_STORAGE_KEY","getLocalWidgets","raw","parsed","item","createLocalWidget","localWidget","list","validList","removeLocalWidget","id","filtered"],"mappings":"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"}
|
package/dist/host.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { p as
|
|
5
|
-
import { C as
|
|
6
|
-
class
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var l = (n, e, t) => e in n ? d(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
|
|
3
|
+
var r = (n, e, t) => l(n, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { p as f } from "./communicator-BF77R7Qs.js";
|
|
5
|
+
import { C as H, P as A, a as _ } from "./communicator-BF77R7Qs.js";
|
|
6
|
+
class u {
|
|
7
7
|
/**
|
|
8
8
|
* Initialize Host SDK for a specific iframe widget
|
|
9
9
|
* @param iframeWindow The contentWindow of the widget's iframe
|
|
10
10
|
*/
|
|
11
|
-
constructor(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
this.iframeWindow =
|
|
11
|
+
constructor(e) {
|
|
12
|
+
r(this, "_communicator", null);
|
|
13
|
+
r(this, "iframeWindow");
|
|
14
|
+
r(this, "subscriptions", /* @__PURE__ */ new Set());
|
|
15
|
+
r(this, "initPromise", null);
|
|
16
|
+
r(this, "isDestroyed", !1);
|
|
17
|
+
this.iframeWindow = e;
|
|
18
18
|
}
|
|
19
19
|
get communicator() {
|
|
20
20
|
if (!this._communicator)
|
|
@@ -26,56 +26,204 @@ class f {
|
|
|
26
26
|
* Can be called before or after `init()`.
|
|
27
27
|
* Returns an unsubscribe function.
|
|
28
28
|
*/
|
|
29
|
-
onMessage(
|
|
29
|
+
onMessage(e, t) {
|
|
30
30
|
const s = {
|
|
31
|
-
actionType:
|
|
32
|
-
handler:
|
|
31
|
+
actionType: e,
|
|
32
|
+
handler: t,
|
|
33
33
|
off: null,
|
|
34
34
|
cancelled: !1
|
|
35
35
|
};
|
|
36
|
-
return this._communicator && (s.off = this._communicator.registerHandler(
|
|
36
|
+
return this._communicator && (s.off = this._communicator.registerHandler(e, t)), this.subscriptions.add(s), () => {
|
|
37
37
|
s.cancelled || (s.cancelled = !0, this.subscriptions.delete(s), s.off && (s.off(), s.off = null));
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* Send a message/request to the widget and wait for the response.
|
|
42
42
|
*/
|
|
43
|
-
async sendMessage(
|
|
44
|
-
return this._communicator ? this._communicator.sendRequest(
|
|
43
|
+
async sendMessage(e, t, s) {
|
|
44
|
+
return this._communicator ? this._communicator.sendRequest(e, t, s) : this.initPromise ? (await this.initPromise).sendRequest(e, t, s) : this.communicator.sendRequest(e, t, s);
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* Complete the handshake with the target widget iframe and attach all registered handlers.
|
|
48
48
|
*/
|
|
49
|
-
async init(
|
|
49
|
+
async init(e) {
|
|
50
50
|
if (this.isDestroyed)
|
|
51
51
|
throw new Error("Host has already been destroyed.");
|
|
52
52
|
return this._communicator ? this._communicator : (this.initPromise || (this.initPromise = (async () => {
|
|
53
53
|
try {
|
|
54
|
-
const
|
|
54
|
+
const t = await f(this.iframeWindow, e);
|
|
55
55
|
if (this.isDestroyed)
|
|
56
|
-
throw
|
|
57
|
-
this._communicator =
|
|
56
|
+
throw t.destroy(), new Error("Host was destroyed during initialization.");
|
|
57
|
+
this._communicator = t;
|
|
58
58
|
for (const s of this.subscriptions)
|
|
59
|
-
!s.cancelled && !s.off && (s.off =
|
|
60
|
-
return
|
|
61
|
-
} catch (
|
|
62
|
-
throw this.initPromise = null,
|
|
59
|
+
!s.cancelled && !s.off && (s.off = t.registerHandler(s.actionType, s.handler));
|
|
60
|
+
return t;
|
|
61
|
+
} catch (t) {
|
|
62
|
+
throw this.initPromise = null, t;
|
|
63
63
|
}
|
|
64
64
|
})()), this.initPromise);
|
|
65
65
|
}
|
|
66
66
|
destroy() {
|
|
67
|
-
var
|
|
67
|
+
var e;
|
|
68
68
|
this.isDestroyed = !0;
|
|
69
|
-
for (const
|
|
70
|
-
|
|
71
|
-
this.subscriptions.clear(), (
|
|
69
|
+
for (const t of this.subscriptions)
|
|
70
|
+
t.off && (t.off(), t.off = null), t.cancelled = !0;
|
|
71
|
+
this.subscriptions.clear(), (e = this._communicator) == null || e.destroy(), this._communicator = null, this.initPromise = null;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
+
class c {
|
|
75
|
+
constructor(e) {
|
|
76
|
+
r(this, "id");
|
|
77
|
+
r(this, "mainAddress");
|
|
78
|
+
r(this, "editorAddress");
|
|
79
|
+
r(this, "runtimeAddress");
|
|
80
|
+
r(this, "manifest", null);
|
|
81
|
+
r(this, "ws", null);
|
|
82
|
+
r(this, "isDestroyed", !1);
|
|
83
|
+
r(this, "reconnectTimer", null);
|
|
84
|
+
r(this, "manifestUpdateHandlers", /* @__PURE__ */ new Set());
|
|
85
|
+
r(this, "manifestErrorHandlers", /* @__PURE__ */ new Set());
|
|
86
|
+
r(this, "fileChangeHandlers", /* @__PURE__ */ new Set());
|
|
87
|
+
this.mainAddress = e.mainAddress.replace(/\/+$/, ""), this.editorAddress = e.editorAddress, this.runtimeAddress = e.runtimeAddress, this.id = e.id || (typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`), this.initHMR();
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Initialize WebSocket connection for mini-HMR with the dev server
|
|
91
|
+
*/
|
|
92
|
+
initHMR() {
|
|
93
|
+
if (!(typeof window > "u" || typeof WebSocket > "u") && !(this.ws || this.isDestroyed))
|
|
94
|
+
try {
|
|
95
|
+
const e = this.mainAddress.replace(/^http(s)?:\/\//i, (s, i) => i ? "wss://" : "ws://"), t = new WebSocket(e);
|
|
96
|
+
this.ws = t, t.onmessage = (s) => {
|
|
97
|
+
try {
|
|
98
|
+
const i = JSON.parse(s.data);
|
|
99
|
+
if (i.type === "manifest:update" && i.data) {
|
|
100
|
+
this.manifest = i.data;
|
|
101
|
+
for (const o of this.manifestUpdateHandlers)
|
|
102
|
+
o(i.data);
|
|
103
|
+
} else if (i.type === "manifest:error")
|
|
104
|
+
for (const o of this.manifestErrorHandlers)
|
|
105
|
+
o(i.errors || "Manifest error");
|
|
106
|
+
else if (i.type === "file:change")
|
|
107
|
+
for (const o of this.fileChangeHandlers)
|
|
108
|
+
o({ file: i.file, event: i.event });
|
|
109
|
+
} catch (i) {
|
|
110
|
+
console.error("[LocalWidget] Failed to parse HMR message:", i);
|
|
111
|
+
}
|
|
112
|
+
}, t.onerror = () => {
|
|
113
|
+
}, t.onclose = () => {
|
|
114
|
+
this.ws = null, this.isDestroyed || (this.reconnectTimer && clearTimeout(this.reconnectTimer), this.reconnectTimer = setTimeout(() => {
|
|
115
|
+
this.isDestroyed || this.initHMR();
|
|
116
|
+
}, 3e3));
|
|
117
|
+
};
|
|
118
|
+
} catch (e) {
|
|
119
|
+
console.error("[LocalWidget] Failed to initialize WebSocket HMR:", e);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Fetch the latest manifest from the dev server via HTTP
|
|
124
|
+
*/
|
|
125
|
+
async fetchManifest() {
|
|
126
|
+
if (typeof fetch > "u") return null;
|
|
127
|
+
try {
|
|
128
|
+
const e = `${this.mainAddress}/manifest.json`, t = await fetch(e);
|
|
129
|
+
if (!t.ok)
|
|
130
|
+
throw new Error(`Failed to fetch manifest: HTTP ${t.status}`);
|
|
131
|
+
const s = await t.json();
|
|
132
|
+
return this.manifest = s, s;
|
|
133
|
+
} catch (e) {
|
|
134
|
+
return console.error(`[LocalWidget] Failed to fetch manifest from ${this.mainAddress}:`, e), null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Subscribe to manifest update events
|
|
139
|
+
*/
|
|
140
|
+
onManifestUpdate(e) {
|
|
141
|
+
return this.manifestUpdateHandlers.add(e), this.manifest && e(this.manifest), () => {
|
|
142
|
+
this.manifestUpdateHandlers.delete(e);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Subscribe to manifest validation errors
|
|
147
|
+
*/
|
|
148
|
+
onManifestError(e) {
|
|
149
|
+
return this.manifestErrorHandlers.add(e), () => {
|
|
150
|
+
this.manifestErrorHandlers.delete(e);
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Subscribe to file change events in .goodo
|
|
155
|
+
*/
|
|
156
|
+
onFileChange(e) {
|
|
157
|
+
return this.fileChangeHandlers.add(e), () => {
|
|
158
|
+
this.fileChangeHandlers.delete(e);
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Destroy the instance, closing WebSocket and cleaning up timers and listeners
|
|
163
|
+
*/
|
|
164
|
+
destroy() {
|
|
165
|
+
this.isDestroyed = !0, this.reconnectTimer && (clearTimeout(this.reconnectTimer), this.reconnectTimer = null), this.ws && (this.ws.close(), this.ws = null), this.manifestUpdateHandlers.clear(), this.manifestErrorHandlers.clear(), this.fileChangeHandlers.clear();
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* JSON serialization helper for localStorage
|
|
169
|
+
*/
|
|
170
|
+
toJSON() {
|
|
171
|
+
return {
|
|
172
|
+
id: this.id,
|
|
173
|
+
mainAddress: this.mainAddress,
|
|
174
|
+
editorAddress: this.editorAddress,
|
|
175
|
+
runtimeAddress: this.runtimeAddress
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const a = "goodo_local_widgets";
|
|
180
|
+
function g() {
|
|
181
|
+
if (typeof localStorage > "u")
|
|
182
|
+
return [];
|
|
183
|
+
try {
|
|
184
|
+
const n = localStorage.getItem(a);
|
|
185
|
+
if (!n) return [];
|
|
186
|
+
const e = JSON.parse(n);
|
|
187
|
+
return Array.isArray(e) ? e.map((t) => new c(t)) : [];
|
|
188
|
+
} catch {
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function w(n) {
|
|
193
|
+
const e = new c(n);
|
|
194
|
+
if (typeof localStorage < "u")
|
|
195
|
+
try {
|
|
196
|
+
const t = localStorage.getItem(a), s = t ? JSON.parse(t) : [], i = Array.isArray(s) ? s : [];
|
|
197
|
+
i.push(e.toJSON()), localStorage.setItem(a, JSON.stringify(i));
|
|
198
|
+
} catch (t) {
|
|
199
|
+
console.error("Failed to save local widget to localStorage:", t);
|
|
200
|
+
}
|
|
201
|
+
return e;
|
|
202
|
+
}
|
|
203
|
+
function y(n) {
|
|
204
|
+
if (!(typeof localStorage > "u"))
|
|
205
|
+
try {
|
|
206
|
+
const e = localStorage.getItem(a);
|
|
207
|
+
if (!e) return;
|
|
208
|
+
const t = JSON.parse(e);
|
|
209
|
+
if (Array.isArray(t)) {
|
|
210
|
+
const s = t.filter((i) => i.id !== n);
|
|
211
|
+
localStorage.setItem(a, JSON.stringify(s));
|
|
212
|
+
}
|
|
213
|
+
} catch (e) {
|
|
214
|
+
console.error("Failed to remove local widget from localStorage:", e);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
74
217
|
export {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
218
|
+
H as Communicator,
|
|
219
|
+
u as Host,
|
|
220
|
+
a as LOCAL_WIDGETS_STORAGE_KEY,
|
|
221
|
+
c as LocalWidget,
|
|
222
|
+
A as PING_TOKEN,
|
|
78
223
|
_ as PONG_TOKEN,
|
|
79
|
-
|
|
224
|
+
w as createLocalWidget,
|
|
225
|
+
g as getLocalWidgets,
|
|
226
|
+
f as ping,
|
|
227
|
+
y as removeLocalWidget
|
|
80
228
|
};
|
|
81
229
|
//# sourceMappingURL=host.js.map
|
package/dist/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","sources":["../src/host-sdk.ts"],"sourcesContent":["import { Communicator, ping, PingOptions } from './communicator';\nimport { ActionMap } from './types';\n\ninterface HostSubscription {\n actionType: keyof ActionMap;\n handler: (payload: any) => any;\n off: (() => void) | null;\n cancelled: boolean;\n}\n\nexport class Host {\n private _communicator: Communicator | null = null;\n\n private iframeWindow: Window;\n\n private subscriptions = new Set<HostSubscription>();\n\n private initPromise: Promise<Communicator> | null = null;\n\n private isDestroyed = false;\n\n private get communicator(): Communicator {\n if (!this._communicator) {\n throw new Error('Host is not initialized. Call init() first.');\n }\n return this._communicator;\n }\n\n /**\n * Initialize Host SDK for a specific iframe widget\n * @param iframeWindow The contentWindow of the widget's iframe\n */\n constructor(iframeWindow: Window) {\n this.iframeWindow = iframeWindow;\n }\n\n /**\n * Register a unified handler for a specific message action type.\n * Can be called before or after `init()`.\n * Returns an unsubscribe function.\n */\n public onMessage<A extends keyof ActionMap>(\n actionType: A,\n handler: (payload: Parameters<ActionMap[A]>[0]) => Promise<ReturnType<ActionMap[A]>> | ReturnType<ActionMap[A]>\n ): () => void {\n const sub: HostSubscription = {\n actionType,\n handler,\n off: null,\n cancelled: false,\n };\n\n if (this._communicator) {\n sub.off = this._communicator.registerHandler(actionType, handler);\n }\n\n this.subscriptions.add(sub);\n\n return () => {\n if (sub.cancelled) return;\n sub.cancelled = true;\n this.subscriptions.delete(sub);\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n };\n }\n\n /**\n * Send a message/request to the widget and wait for the response.\n */\n public async sendMessage<A extends keyof ActionMap>(\n actionType: A,\n payload?: Parameters<ActionMap[A]>[0],\n timeout?: number\n ): Promise<ReturnType<ActionMap[A]>> {\n if (this._communicator) {\n return this._communicator.sendRequest(actionType, payload, timeout);\n }\n\n if (this.initPromise) {\n const comm = await this.initPromise;\n\n return comm.sendRequest(actionType, payload, timeout);\n }\n\n return this.communicator.sendRequest(actionType, payload, timeout);\n }\n\n /**\n * Complete the handshake with the target widget iframe and attach all registered handlers.\n */\n public async init(options?: PingOptions): Promise<Communicator> {\n if (this.isDestroyed) {\n throw new Error('Host has already been destroyed.');\n }\n\n if (this._communicator) {\n return this._communicator;\n }\n\n if (!this.initPromise) {\n this.initPromise = (async () => {\n try {\n const comm = await ping(this.iframeWindow, options);\n\n if (this.isDestroyed) {\n comm.destroy();\n throw new Error('Host was destroyed during initialization.');\n }\n\n this._communicator = comm;\n\n // Attach all active subscriptions to communicator\n for (const sub of this.subscriptions) {\n if (!sub.cancelled && !sub.off) {\n sub.off = comm.registerHandler(sub.actionType, sub.handler);\n }\n }\n\n return comm;\n } catch (err) {\n this.initPromise = null;\n throw err;\n }\n })();\n }\n\n return this.initPromise;\n }\n\n public destroy(): void {\n this.isDestroyed = true;\n\n for (const sub of this.subscriptions) {\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n sub.cancelled = true;\n }\n this.subscriptions.clear();\n\n this._communicator?.destroy();\n\n this._communicator = null;\n\n this.initPromise = null;\n }\n}\n"],"names":["Host","iframeWindow","__publicField","actionType","handler","sub","payload","timeout","options","comm","ping","err","_a"],"mappings":";;;;;AAUO,MAAMA,EAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBhB,YAAYC,GAAsB;AArB1B,IAAAC,EAAA,uBAAqC;AAErC,IAAAA,EAAA;AAEA,IAAAA,EAAA,2CAAoB,IAAA;AAEpB,IAAAA,EAAA,qBAA4C;AAE5C,IAAAA,EAAA,qBAAc;AAcpB,SAAK,eAAeD;AAAA,EACtB;AAAA,EAbA,IAAY,eAA6B;AACvC,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,6CAA6C;AAE/D,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeO,UACLE,GACAC,GACY;AACZ,UAAMC,IAAwB;AAAA,MAC5B,YAAAF;AAAA,MACA,SAAAC;AAAA,MACA,KAAK;AAAA,MACL,WAAW;AAAA,IAAA;AAGb,WAAI,KAAK,kBACPC,EAAI,MAAM,KAAK,cAAc,gBAAgBF,GAAYC,CAAO,IAGlE,KAAK,cAAc,IAAIC,CAAG,GAEnB,MAAM;AACX,MAAIA,EAAI,cACRA,EAAI,YAAY,IAChB,KAAK,cAAc,OAAOA,CAAG,GACzBA,EAAI,QACNA,EAAI,IAAA,GACJA,EAAI,MAAM;AAAA,IAEd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,YACXF,GACAG,GACAC,GACmC;AACnC,WAAI,KAAK,gBACA,KAAK,cAAc,YAAYJ,GAAYG,GAASC,CAAO,IAGhE,KAAK,eACM,MAAM,KAAK,aAEZ,YAAYJ,GAAYG,GAASC,CAAO,IAG/C,KAAK,aAAa,YAAYJ,GAAYG,GAASC,CAAO;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,KAAKC,GAA8C;AAC9D,QAAI,KAAK;AACP,YAAM,IAAI,MAAM,kCAAkC;AAGpD,WAAI,KAAK,gBACA,KAAK,iBAGT,KAAK,gBACR,KAAK,eAAe,YAAY;AAC9B,UAAI;AACF,cAAMC,IAAO,MAAMC,EAAK,KAAK,cAAcF,CAAO;AAElD,YAAI,KAAK;AACP,gBAAAC,EAAK,QAAA,GACC,IAAI,MAAM,2CAA2C;AAG7D,aAAK,gBAAgBA;AAGrB,mBAAWJ,KAAO,KAAK;AACrB,UAAI,CAACA,EAAI,aAAa,CAACA,EAAI,QACzBA,EAAI,MAAMI,EAAK,gBAAgBJ,EAAI,YAAYA,EAAI,OAAO;AAI9D,eAAOI;AAAA,MACT,SAASE,GAAK;AACZ,mBAAK,cAAc,MACbA;AAAA,MACR;AAAA,IACF,GAAA,IAGK,KAAK;AAAA,EACd;AAAA,EAEO,UAAgB;;AACrB,SAAK,cAAc;AAEnB,eAAWN,KAAO,KAAK;AACrB,MAAIA,EAAI,QACNA,EAAI,IAAA,GACJA,EAAI,MAAM,OAEZA,EAAI,YAAY;AAElB,SAAK,cAAc,MAAA,IAEnBO,IAAA,KAAK,kBAAL,QAAAA,EAAoB,WAEpB,KAAK,gBAAgB,MAErB,KAAK,cAAc;AAAA,EACrB;AACF;"}
|
|
1
|
+
{"version":3,"file":"host.js","sources":["../src/host-sdk.ts"],"sourcesContent":["import { Communicator, ping, PingOptions } from './communicator';\nimport { ActionMap } from './types';\nimport type { ResolvedWidgetManifest } from './manifest';\n\ninterface HostSubscription {\n actionType: keyof ActionMap;\n handler: (payload: any) => any;\n off: (() => void) | null;\n cancelled: boolean;\n}\n\nexport class Host {\n private _communicator: Communicator | null = null;\n\n private iframeWindow: Window;\n\n private subscriptions = new Set<HostSubscription>();\n\n private initPromise: Promise<Communicator> | null = null;\n\n private isDestroyed = false;\n\n private get communicator(): Communicator {\n if (!this._communicator) {\n throw new Error('Host is not initialized. Call init() first.');\n }\n return this._communicator;\n }\n\n /**\n * Initialize Host SDK for a specific iframe widget\n * @param iframeWindow The contentWindow of the widget's iframe\n */\n constructor(iframeWindow: Window) {\n this.iframeWindow = iframeWindow;\n }\n\n /**\n * Register a unified handler for a specific message action type.\n * Can be called before or after `init()`.\n * Returns an unsubscribe function.\n */\n public onMessage<A extends keyof ActionMap>(\n actionType: A,\n handler: (payload: Parameters<ActionMap[A]>[0]) => Promise<ReturnType<ActionMap[A]>> | ReturnType<ActionMap[A]>\n ): () => void {\n const sub: HostSubscription = {\n actionType,\n handler,\n off: null,\n cancelled: false,\n };\n\n if (this._communicator) {\n sub.off = this._communicator.registerHandler(actionType, handler);\n }\n\n this.subscriptions.add(sub);\n\n return () => {\n if (sub.cancelled) return;\n sub.cancelled = true;\n this.subscriptions.delete(sub);\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n };\n }\n\n /**\n * Send a message/request to the widget and wait for the response.\n */\n public async sendMessage<A extends keyof ActionMap>(\n actionType: A,\n payload?: Parameters<ActionMap[A]>[0],\n timeout?: number\n ): Promise<ReturnType<ActionMap[A]>> {\n if (this._communicator) {\n return this._communicator.sendRequest(actionType, payload, timeout);\n }\n\n if (this.initPromise) {\n const comm = await this.initPromise;\n\n return comm.sendRequest(actionType, payload, timeout);\n }\n\n return this.communicator.sendRequest(actionType, payload, timeout);\n }\n\n /**\n * Complete the handshake with the target widget iframe and attach all registered handlers.\n */\n public async init(options?: PingOptions): Promise<Communicator> {\n if (this.isDestroyed) {\n throw new Error('Host has already been destroyed.');\n }\n\n if (this._communicator) {\n return this._communicator;\n }\n\n if (!this.initPromise) {\n this.initPromise = (async () => {\n try {\n const comm = await ping(this.iframeWindow, options);\n\n if (this.isDestroyed) {\n comm.destroy();\n throw new Error('Host was destroyed during initialization.');\n }\n\n this._communicator = comm;\n\n // Attach all active subscriptions to communicator\n for (const sub of this.subscriptions) {\n if (!sub.cancelled && !sub.off) {\n sub.off = comm.registerHandler(sub.actionType, sub.handler);\n }\n }\n\n return comm;\n } catch (err) {\n this.initPromise = null;\n throw err;\n }\n })();\n }\n\n return this.initPromise;\n }\n\n public destroy(): void {\n this.isDestroyed = true;\n\n for (const sub of this.subscriptions) {\n if (sub.off) {\n sub.off();\n sub.off = null;\n }\n sub.cancelled = true;\n }\n this.subscriptions.clear();\n\n this._communicator?.destroy();\n\n this._communicator = null;\n\n this.initPromise = null;\n }\n}\n\nexport type LocalWidgetProps = {\n id?: string;\n mainAddress: string;\n editorAddress?: string;\n runtimeAddress?: string;\n};\n\nexport type ManifestUpdateHandler = (manifest: ResolvedWidgetManifest) => void;\nexport type ManifestErrorHandler = (errors: Array<{ path: string; message: string }> | string) => void;\nexport type FileChangeHandler = (payload: { file: string; event: string }) => void;\n\nexport class LocalWidget implements LocalWidgetProps {\n id: string;\n\n mainAddress: string;\n\n editorAddress?: string;\n\n runtimeAddress?: string;\n\n manifest: ResolvedWidgetManifest | null = null;\n\n private ws: WebSocket | null = null;\n\n private isDestroyed = false;\n\n private reconnectTimer: any = null;\n\n private manifestUpdateHandlers = new Set<ManifestUpdateHandler>();\n\n private manifestErrorHandlers = new Set<ManifestErrorHandler>();\n\n private fileChangeHandlers = new Set<FileChangeHandler>();\n\n constructor(props: LocalWidgetProps) {\n this.mainAddress = props.mainAddress.replace(/\\/+$/, '');\n this.editorAddress = props.editorAddress;\n this.runtimeAddress = props.runtimeAddress;\n this.id =\n props.id ||\n (typeof crypto !== 'undefined' && crypto.randomUUID\n ? crypto.randomUUID()\n : `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`);\n\n this.initHMR();\n }\n\n /**\n * Initialize WebSocket connection for mini-HMR with the dev server\n */\n public initHMR(): void {\n if (typeof window === 'undefined' || typeof WebSocket === 'undefined') {\n return;\n }\n\n if (this.ws || this.isDestroyed) {\n return;\n }\n\n try {\n const wsUrl = this.mainAddress.replace(/^http(s)?:\\/\\//i, (_, s) => (s ? 'wss://' : 'ws://'));\n const ws = new WebSocket(wsUrl);\n this.ws = ws;\n\n ws.onmessage = (event) => {\n try {\n const msg = JSON.parse(event.data);\n if (msg.type === 'manifest:update' && msg.data) {\n this.manifest = msg.data;\n for (const handler of this.manifestUpdateHandlers) {\n handler(msg.data);\n }\n } else if (msg.type === 'manifest:error') {\n for (const handler of this.manifestErrorHandlers) {\n handler(msg.errors || 'Manifest error');\n }\n } else if (msg.type === 'file:change') {\n for (const handler of this.fileChangeHandlers) {\n handler({ file: msg.file, event: msg.event });\n }\n }\n } catch (e) {\n console.error('[LocalWidget] Failed to parse HMR message:', e);\n }\n };\n\n ws.onerror = () => {};\n\n ws.onclose = () => {\n this.ws = null;\n if (!this.isDestroyed) {\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\n this.reconnectTimer = setTimeout(() => {\n if (!this.isDestroyed) {\n this.initHMR();\n }\n }, 3000);\n }\n };\n } catch (e) {\n console.error('[LocalWidget] Failed to initialize WebSocket HMR:', e);\n }\n }\n\n /**\n * Fetch the latest manifest from the dev server via HTTP\n */\n public async fetchManifest(): Promise<ResolvedWidgetManifest | null> {\n if (typeof fetch === 'undefined') return null;\n try {\n const url = `${this.mainAddress}/manifest.json`;\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch manifest: HTTP ${res.status}`);\n }\n const data = (await res.json()) as ResolvedWidgetManifest;\n this.manifest = data;\n return data;\n } catch (e) {\n console.error(`[LocalWidget] Failed to fetch manifest from ${this.mainAddress}:`, e);\n return null;\n }\n }\n\n /**\n * Subscribe to manifest update events\n */\n public onManifestUpdate(handler: ManifestUpdateHandler): () => void {\n this.manifestUpdateHandlers.add(handler);\n if (this.manifest) {\n handler(this.manifest);\n }\n return () => {\n this.manifestUpdateHandlers.delete(handler);\n };\n }\n\n /**\n * Subscribe to manifest validation errors\n */\n public onManifestError(handler: ManifestErrorHandler): () => void {\n this.manifestErrorHandlers.add(handler);\n return () => {\n this.manifestErrorHandlers.delete(handler);\n };\n }\n\n /**\n * Subscribe to file change events in .goodo\n */\n public onFileChange(handler: FileChangeHandler): () => void {\n this.fileChangeHandlers.add(handler);\n return () => {\n this.fileChangeHandlers.delete(handler);\n };\n }\n\n /**\n * Destroy the instance, closing WebSocket and cleaning up timers and listeners\n */\n public destroy(): void {\n this.isDestroyed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n this.manifestUpdateHandlers.clear();\n this.manifestErrorHandlers.clear();\n this.fileChangeHandlers.clear();\n }\n\n /**\n * JSON serialization helper for localStorage\n */\n public toJSON(): LocalWidgetProps & { id: string } {\n return {\n id: this.id,\n mainAddress: this.mainAddress,\n editorAddress: this.editorAddress,\n runtimeAddress: this.runtimeAddress,\n };\n }\n}\n\nexport const LOCAL_WIDGETS_STORAGE_KEY = 'goodo_local_widgets';\n\nexport function getLocalWidgets(): LocalWidget[] {\n if (typeof localStorage === 'undefined') {\n return [];\n }\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.map((item: LocalWidgetProps) => new LocalWidget(item));\n } catch {\n return [];\n }\n}\n\nexport function createLocalWidget(props: LocalWidgetProps): LocalWidget {\n const localWidget = new LocalWidget(props);\n\n if (typeof localStorage !== 'undefined') {\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n const list = raw ? JSON.parse(raw) : [];\n const validList = Array.isArray(list) ? list : [];\n validList.push(localWidget.toJSON());\n localStorage.setItem(LOCAL_WIDGETS_STORAGE_KEY, JSON.stringify(validList));\n } catch (e) {\n console.error('Failed to save local widget to localStorage:', e);\n }\n }\n\n return localWidget;\n}\n\nexport function removeLocalWidget(id: string): void {\n if (typeof localStorage === 'undefined') return;\n try {\n const raw = localStorage.getItem(LOCAL_WIDGETS_STORAGE_KEY);\n if (!raw) return;\n const list = JSON.parse(raw);\n if (Array.isArray(list)) {\n const filtered = list.filter((item: { id: string }) => item.id !== id);\n localStorage.setItem(LOCAL_WIDGETS_STORAGE_KEY, JSON.stringify(filtered));\n }\n } catch (e) {\n console.error('Failed to remove local widget from localStorage:', e);\n }\n}"],"names":["Host","iframeWindow","__publicField","actionType","handler","sub","payload","timeout","options","comm","ping","err","_a","LocalWidget","props","wsUrl","_","s","ws","event","msg","e","url","res","data","LOCAL_WIDGETS_STORAGE_KEY","getLocalWidgets","raw","parsed","item","createLocalWidget","localWidget","list","validList","removeLocalWidget","id","filtered"],"mappings":"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"}
|
package/dist/manifest.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("zod"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("zod"),o=e.z.enum(["input","checkbox","color-picker","date","data-time-range","datetime","input-number","monaco-editor","radio","select","tree-select","time","textarea","switch","slider","select-cascader","data-node","data-node-fields","context-menu"]),r=e.z.object({type:o,group:e.z.string().optional(),label:e.z.string().min(1,"Property config label is required")}),c=e.z.object({name:e.z.string().min(1,"Property name is required"),defaultValue:e.z.any().optional().default(null),config:r.optional()}),s=e.z.enum(["SelectedObject","MultipleSelectedObject","CurrentMenu"]),i=e.z.lazy(()=>e.z.object({bindProp:e.z.string().optional(),name:e.z.string().optional(),generic:e.z.array(e.z.lazy(()=>i)).optional()})),d=e.z.object({name:s,type:i}),m=e.z.object({options:e.z.object({bindProp:e.z.string().min(1,"options.bindProp is required")})}),g=e.z.object({name:e.z.string().min(1,"Event name is required"),label:e.z.string().min(1,"Event label is required"),arguments:e.z.array(d).optional().default([]),contextmenu:m.optional()}),u=e.z.object({id:e.z.string().min(1,"'id' is required and cannot be empty"),name:e.z.string().min(1,"'name' is required and cannot be empty"),icon:e.z.string().optional(),entry:e.z.string().optional().default("dist"),props:e.z.array(c).optional().default([]),events:e.z.array(g).optional().default([])});function l(t){return t}function p(t){const n=u.safeParse(t);return n.success?{success:!0,data:n.data}:{success:!1,errors:n.error.issues.map(a=>({path:a.path.join(".")||"root",message:a.message}))}}exports.defineWidget=l;exports.validateWidgetManifest=p;exports.widgetArgumentTypeSchema=i;exports.widgetConfigTypeSchema=o;exports.widgetEventArgumentNameSchema=s;exports.widgetEventArgumentSchema=d;exports.widgetEventContextMenuSchema=m;exports.widgetEventSchema=g;exports.widgetManifestSchema=u;exports.widgetPropConfigSchema=r;exports.widgetPropSchema=c;
|
|
2
2
|
//# sourceMappingURL=manifest.cjs.map
|
package/dist/manifest.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.cjs","sources":["../src/manifest.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ==========================================\n// 1. Props Configuration Schemas\n// ==========================================\n\nexport const widgetConfigTypeSchema = z.enum([\n 'input',\n 'checkbox',\n 'color-picker',\n 'date',\n 'data-time-range',\n 'datetime',\n 'input-number',\n 'monaco-editor',\n 'radio',\n 'select',\n 'tree-select',\n 'time',\n 'textarea',\n 'switch',\n 'slider',\n 'select-cascader',\n 'data-node',\n 'data-node-fields',\n 'context-menu',\n]);\n\nexport const widgetPropConfigSchema = z.object({\n type: widgetConfigTypeSchema,\n group: z.string().optional(),\n label: z.string().min(1, 'Property config label is required'),\n});\n\nexport const widgetPropSchema = z.object({\n name: z.string().min(1, 'Property name is required'),\n defaultValue: z.any().optional().default(null),\n config: widgetPropConfigSchema.optional(),\n});\n\n// ==========================================\n// 2. Events & Arguments Configuration Schemas\n// ==========================================\n\n/**\n * Supported standard event argument names (3.3)\n */\nexport const widgetEventArgumentNameSchema = z.enum([\n 'SelectedObject',\n 'MultipleSelectedObject',\n 'CurrentMenu',\n
|
|
1
|
+
{"version":3,"file":"manifest.cjs","sources":["../src/manifest.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ==========================================\n// 1. Props Configuration Schemas\n// ==========================================\n\nexport const widgetConfigTypeSchema = z.enum([\n 'input',\n 'checkbox',\n 'color-picker',\n 'date',\n 'data-time-range',\n 'datetime',\n 'input-number',\n 'monaco-editor',\n 'radio',\n 'select',\n 'tree-select',\n 'time',\n 'textarea',\n 'switch',\n 'slider',\n 'select-cascader',\n 'data-node',\n 'data-node-fields',\n 'context-menu',\n]);\n\nexport const widgetPropConfigSchema = z.object({\n type: widgetConfigTypeSchema,\n group: z.string().optional(),\n label: z.string().min(1, 'Property config label is required'),\n});\n\nexport const widgetPropSchema = z.object({\n name: z.string().min(1, 'Property name is required'),\n defaultValue: z.any().optional().default(null),\n config: widgetPropConfigSchema.optional(),\n});\n\n// ==========================================\n// 2. Events & Arguments Configuration Schemas\n// ==========================================\n\n/**\n * Supported standard event argument names (3.3)\n */\nexport const widgetEventArgumentNameSchema = z.enum([\n 'SelectedObject',\n 'MultipleSelectedObject',\n 'CurrentMenu',\n]);\n\n/**\n * Recursive schema for event argument types (3.2):\n * 1. Entity type bound to property: { bindProp: 'dataSourceNode' }\n * 2. Generic collection type: { name: 'List', generic: [{ bindProp: 'dataSourceNode' }] }\n * 3. Fixed internal platform type: { name: 'CurrentMenu' }\n */\nexport type WidgetArgumentType = {\n bindProp?: string;\n name?: string;\n generic?: WidgetArgumentType[];\n};\n\nexport const widgetArgumentTypeSchema: z.ZodType<WidgetArgumentType> = z.lazy(() =>\n z.object({\n bindProp: z.string().optional(),\n name: z.string().optional(),\n generic: z.array(z.lazy(() => widgetArgumentTypeSchema)).optional(),\n })\n);\n\n/**\n * Event Argument configuration item (3.2)\n */\nexport const widgetEventArgumentSchema = z.object({\n name: widgetEventArgumentNameSchema,\n type: widgetArgumentTypeSchema,\n});\n\n/**\n * Context menu binding configuration for event (3.4)\n */\nexport const widgetEventContextMenuSchema = z.object({\n options: z.object({\n bindProp: z.string().min(1, 'options.bindProp is required'),\n }),\n});\n\n/**\n * Event configuration item (3.1)\n */\nexport const widgetEventSchema = z.object({\n name: z.string().min(1, 'Event name is required'),\n label: z.string().min(1, 'Event label is required'),\n arguments: z.array(widgetEventArgumentSchema).optional().default([]),\n contextmenu: widgetEventContextMenuSchema.optional(),\n});\n\n// ==========================================\n// 3. Widget Manifest Root Schema\n// ==========================================\n\nexport const widgetManifestSchema = z.object({\n id: z.string().min(1, \"'id' is required and cannot be empty\"),\n name: z.string().min(1, \"'name' is required and cannot be empty\"),\n icon: z.string().optional(),\n entry: z.string().optional().default('dist'),\n props: z.array(widgetPropSchema).optional().default([]),\n events: z.array(widgetEventSchema).optional().default([]),\n});\n\n// ==========================================\n// 4. Inferred TypeScript Types\n// ==========================================\n\nexport type WidgetConfigType = z.infer<typeof widgetConfigTypeSchema>;\nexport type WidgetPropConfig = z.infer<typeof widgetPropConfigSchema>;\nexport type WidgetProp = z.infer<typeof widgetPropSchema>;\n\nexport type WidgetEventArgumentName = z.infer<typeof widgetEventArgumentNameSchema>;\nexport type WidgetEventArgument = z.infer<typeof widgetEventArgumentSchema>;\nexport type WidgetEventContextMenu = z.infer<typeof widgetEventContextMenuSchema>;\nexport type WidgetEvent = z.infer<typeof widgetEventSchema>;\n\nexport type WidgetManifest = z.input<typeof widgetManifestSchema>;\nexport type ResolvedWidgetManifest = z.output<typeof widgetManifestSchema>;\n\n// ==========================================\n// 5. Helper & Validation Functions\n// ==========================================\n\n/**\n * Type-helper for defining widget manifest in `.goodo/manifest.ts`.\n * Provides full IDE autocomplete and compile-time type validation.\n */\nexport function defineWidget(config: WidgetManifest): WidgetManifest {\n return config;\n}\n\nexport interface ManifestValidationResult {\n success: boolean;\n data?: ResolvedWidgetManifest;\n errors?: Array<{ path: string; message: string }>;\n}\n\n/**\n * Validates raw manifest data using Zod schema for Node.js environments (e.g. CLI, backend).\n */\nexport function validateWidgetManifest(raw: unknown): ManifestValidationResult {\n const result = widgetManifestSchema.safeParse(raw);\n if (result.success) {\n return {\n success: true,\n data: result.data,\n };\n }\n\n return {\n success: false,\n errors: result.error.issues.map((issue) => ({\n path: issue.path.join('.') || 'root',\n message: issue.message,\n })),\n };\n}"],"names":["widgetConfigTypeSchema","z","widgetPropConfigSchema","widgetPropSchema","widgetEventArgumentNameSchema","widgetArgumentTypeSchema","widgetEventArgumentSchema","widgetEventContextMenuSchema","widgetEventSchema","widgetManifestSchema","defineWidget","config","validateWidgetManifest","raw","result","issue"],"mappings":"uGAMaA,EAAyBC,EAAAA,EAAE,KAAK,CAC3C,QACA,WACA,eACA,OACA,kBACA,WACA,eACA,gBACA,QACA,SACA,cACA,OACA,WACA,SACA,SACA,kBACA,YACA,mBACA,cACF,CAAC,EAEYC,EAAyBD,EAAAA,EAAE,OAAO,CAC7C,KAAMD,EACN,MAAOC,EAAAA,EAAE,OAAA,EAAS,SAAA,EAClB,MAAOA,EAAAA,EAAE,OAAA,EAAS,IAAI,EAAG,mCAAmC,CAC9D,CAAC,EAEYE,EAAmBF,EAAAA,EAAE,OAAO,CACvC,KAAMA,EAAAA,EAAE,OAAA,EAAS,IAAI,EAAG,2BAA2B,EACnD,aAAcA,EAAAA,EAAE,IAAA,EAAM,SAAA,EAAW,QAAQ,IAAI,EAC7C,OAAQC,EAAuB,SAAA,CACjC,CAAC,EASYE,EAAgCH,EAAAA,EAAE,KAAK,CAClD,iBACA,yBACA,aACF,CAAC,EAcYI,EAA0DJ,EAAAA,EAAE,KAAK,IAC5EA,EAAAA,EAAE,OAAO,CACP,SAAUA,EAAAA,EAAE,OAAA,EAAS,SAAA,EACrB,KAAMA,EAAAA,EAAE,OAAA,EAAS,SAAA,EACjB,QAASA,EAAAA,EAAE,MAAMA,EAAAA,EAAE,KAAK,IAAMI,CAAwB,CAAC,EAAE,SAAA,CAAS,CACnE,CACH,EAKaC,EAA4BL,EAAAA,EAAE,OAAO,CAChD,KAAMG,EACN,KAAMC,CACR,CAAC,EAKYE,EAA+BN,EAAAA,EAAE,OAAO,CACnD,QAASA,EAAAA,EAAE,OAAO,CAChB,SAAUA,EAAAA,EAAE,OAAA,EAAS,IAAI,EAAG,8BAA8B,CAAA,CAC3D,CACH,CAAC,EAKYO,EAAoBP,EAAAA,EAAE,OAAO,CACxC,KAAMA,EAAAA,EAAE,OAAA,EAAS,IAAI,EAAG,wBAAwB,EAChD,MAAOA,EAAAA,EAAE,OAAA,EAAS,IAAI,EAAG,yBAAyB,EAClD,UAAWA,EAAAA,EAAE,MAAMK,CAAyB,EAAE,SAAA,EAAW,QAAQ,EAAE,EACnE,YAAaC,EAA6B,SAAA,CAC5C,CAAC,EAMYE,EAAuBR,EAAAA,EAAE,OAAO,CAC3C,GAAIA,EAAAA,EAAE,OAAA,EAAS,IAAI,EAAG,sCAAsC,EAC5D,KAAMA,EAAAA,EAAE,OAAA,EAAS,IAAI,EAAG,wCAAwC,EAChE,KAAMA,EAAAA,EAAE,OAAA,EAAS,SAAA,EACjB,MAAOA,EAAAA,EAAE,OAAA,EAAS,SAAA,EAAW,QAAQ,MAAM,EAC3C,MAAOA,EAAAA,EAAE,MAAME,CAAgB,EAAE,SAAA,EAAW,QAAQ,EAAE,EACtD,OAAQF,EAAAA,EAAE,MAAMO,CAAiB,EAAE,SAAA,EAAW,QAAQ,CAAA,CAAE,CAC1D,CAAC,EA0BM,SAASE,EAAaC,EAAwC,CACnE,OAAOA,CACT,CAWO,SAASC,EAAuBC,EAAwC,CAC7E,MAAMC,EAASL,EAAqB,UAAUI,CAAG,EACjD,OAAIC,EAAO,QACF,CACL,QAAS,GACT,KAAMA,EAAO,IAAA,EAIV,CACL,QAAS,GACT,OAAQA,EAAO,MAAM,OAAO,IAAKC,IAAW,CAC1C,KAAMA,EAAM,KAAK,KAAK,GAAG,GAAK,OAC9B,QAASA,EAAM,OAAA,EACf,CAAA,CAEN"}
|
package/dist/manifest.d.ts
CHANGED
|
@@ -81,19 +81,6 @@ export declare const widgetEventArgumentNameSchema: z.ZodEnum<{
|
|
|
81
81
|
SelectedObject: "SelectedObject";
|
|
82
82
|
MultipleSelectedObject: "MultipleSelectedObject";
|
|
83
83
|
CurrentMenu: "CurrentMenu";
|
|
84
|
-
CurrentPageObject: "CurrentPageObject";
|
|
85
|
-
AllData: "AllData";
|
|
86
|
-
DragObject: "DragObject";
|
|
87
|
-
MultipleDragObject: "MultipleDragObject";
|
|
88
|
-
EditData: "EditData";
|
|
89
|
-
EditObject: "EditObject";
|
|
90
|
-
SelectedResource: "SelectedResource";
|
|
91
|
-
TargetObject: "TargetObject";
|
|
92
|
-
TargetResource: "TargetResource";
|
|
93
|
-
TargetDatetime: "TargetDatetime";
|
|
94
|
-
TargetStarttime: "TargetStarttime";
|
|
95
|
-
TargetEndtime: "TargetEndtime";
|
|
96
|
-
AcceptData: "AcceptData";
|
|
97
84
|
}>;
|
|
98
85
|
/**
|
|
99
86
|
* Recursive schema for event argument types (3.2):
|
|
@@ -115,19 +102,6 @@ export declare const widgetEventArgumentSchema: z.ZodObject<{
|
|
|
115
102
|
SelectedObject: "SelectedObject";
|
|
116
103
|
MultipleSelectedObject: "MultipleSelectedObject";
|
|
117
104
|
CurrentMenu: "CurrentMenu";
|
|
118
|
-
CurrentPageObject: "CurrentPageObject";
|
|
119
|
-
AllData: "AllData";
|
|
120
|
-
DragObject: "DragObject";
|
|
121
|
-
MultipleDragObject: "MultipleDragObject";
|
|
122
|
-
EditData: "EditData";
|
|
123
|
-
EditObject: "EditObject";
|
|
124
|
-
SelectedResource: "SelectedResource";
|
|
125
|
-
TargetObject: "TargetObject";
|
|
126
|
-
TargetResource: "TargetResource";
|
|
127
|
-
TargetDatetime: "TargetDatetime";
|
|
128
|
-
TargetStarttime: "TargetStarttime";
|
|
129
|
-
TargetEndtime: "TargetEndtime";
|
|
130
|
-
AcceptData: "AcceptData";
|
|
131
105
|
}>;
|
|
132
106
|
type: z.ZodType<WidgetArgumentType, unknown, z.core.$ZodTypeInternals<WidgetArgumentType, unknown>>;
|
|
133
107
|
}, z.core.$strip>;
|
|
@@ -150,19 +124,6 @@ export declare const widgetEventSchema: z.ZodObject<{
|
|
|
150
124
|
SelectedObject: "SelectedObject";
|
|
151
125
|
MultipleSelectedObject: "MultipleSelectedObject";
|
|
152
126
|
CurrentMenu: "CurrentMenu";
|
|
153
|
-
CurrentPageObject: "CurrentPageObject";
|
|
154
|
-
AllData: "AllData";
|
|
155
|
-
DragObject: "DragObject";
|
|
156
|
-
MultipleDragObject: "MultipleDragObject";
|
|
157
|
-
EditData: "EditData";
|
|
158
|
-
EditObject: "EditObject";
|
|
159
|
-
SelectedResource: "SelectedResource";
|
|
160
|
-
TargetObject: "TargetObject";
|
|
161
|
-
TargetResource: "TargetResource";
|
|
162
|
-
TargetDatetime: "TargetDatetime";
|
|
163
|
-
TargetStarttime: "TargetStarttime";
|
|
164
|
-
TargetEndtime: "TargetEndtime";
|
|
165
|
-
AcceptData: "AcceptData";
|
|
166
127
|
}>;
|
|
167
128
|
type: z.ZodType<WidgetArgumentType, unknown, z.core.$ZodTypeInternals<WidgetArgumentType, unknown>>;
|
|
168
129
|
}, z.core.$strip>>>>;
|
|
@@ -214,19 +175,6 @@ export declare const widgetManifestSchema: z.ZodObject<{
|
|
|
214
175
|
SelectedObject: "SelectedObject";
|
|
215
176
|
MultipleSelectedObject: "MultipleSelectedObject";
|
|
216
177
|
CurrentMenu: "CurrentMenu";
|
|
217
|
-
CurrentPageObject: "CurrentPageObject";
|
|
218
|
-
AllData: "AllData";
|
|
219
|
-
DragObject: "DragObject";
|
|
220
|
-
MultipleDragObject: "MultipleDragObject";
|
|
221
|
-
EditData: "EditData";
|
|
222
|
-
EditObject: "EditObject";
|
|
223
|
-
SelectedResource: "SelectedResource";
|
|
224
|
-
TargetObject: "TargetObject";
|
|
225
|
-
TargetResource: "TargetResource";
|
|
226
|
-
TargetDatetime: "TargetDatetime";
|
|
227
|
-
TargetStarttime: "TargetStarttime";
|
|
228
|
-
TargetEndtime: "TargetEndtime";
|
|
229
|
-
AcceptData: "AcceptData";
|
|
230
178
|
}>;
|
|
231
179
|
type: z.ZodType<WidgetArgumentType, unknown, z.core.$ZodTypeInternals<WidgetArgumentType, unknown>>;
|
|
232
180
|
}, z.core.$strip>>>>;
|
package/dist/manifest.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;EAoBjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;iBAIjC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAI3B,CAAC;AAMH;;GAEG;AACH,eAAO,MAAM,6BAA6B
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;EAoBjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;iBAIjC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAI3B,CAAC;AAMH;;GAEG;AACH,eAAO,MAAM,6BAA6B;;;;EAIxC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAMlE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;;iBAGpC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,4BAA4B;;;;iBAIvC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;iBAK5B,CAAC;AAMH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAO/B,CAAC;AAMH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AACpF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC5E,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAClF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAM3E;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAEnE;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,wBAAwB,CAgB7E"}
|
package/dist/manifest.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z as e } from "zod";
|
|
2
|
-
const
|
|
2
|
+
const o = e.enum([
|
|
3
3
|
"input",
|
|
4
4
|
"checkbox",
|
|
5
5
|
"color-picker",
|
|
@@ -19,58 +19,45 @@ const r = e.enum([
|
|
|
19
19
|
"data-node",
|
|
20
20
|
"data-node-fields",
|
|
21
21
|
"context-menu"
|
|
22
|
-
]),
|
|
23
|
-
type:
|
|
22
|
+
]), r = e.object({
|
|
23
|
+
type: o,
|
|
24
24
|
group: e.string().optional(),
|
|
25
25
|
label: e.string().min(1, "Property config label is required")
|
|
26
|
-
}),
|
|
26
|
+
}), s = e.object({
|
|
27
27
|
name: e.string().min(1, "Property name is required"),
|
|
28
28
|
defaultValue: e.any().optional().default(null),
|
|
29
|
-
config:
|
|
30
|
-
}),
|
|
29
|
+
config: r.optional()
|
|
30
|
+
}), c = e.enum([
|
|
31
31
|
"SelectedObject",
|
|
32
32
|
"MultipleSelectedObject",
|
|
33
|
-
"CurrentMenu"
|
|
34
|
-
|
|
35
|
-
"AllData",
|
|
36
|
-
"DragObject",
|
|
37
|
-
"MultipleDragObject",
|
|
38
|
-
"EditData",
|
|
39
|
-
"EditObject",
|
|
40
|
-
"SelectedResource",
|
|
41
|
-
"TargetObject",
|
|
42
|
-
"TargetResource",
|
|
43
|
-
"TargetDatetime",
|
|
44
|
-
"TargetStarttime",
|
|
45
|
-
"TargetEndtime",
|
|
46
|
-
"AcceptData"
|
|
47
|
-
]), i = e.lazy(
|
|
33
|
+
"CurrentMenu"
|
|
34
|
+
]), a = e.lazy(
|
|
48
35
|
() => e.object({
|
|
49
36
|
bindProp: e.string().optional(),
|
|
50
37
|
name: e.string().optional(),
|
|
51
|
-
generic: e.array(e.lazy(() =>
|
|
38
|
+
generic: e.array(e.lazy(() => a)).optional()
|
|
52
39
|
})
|
|
53
40
|
), d = e.object({
|
|
54
|
-
name:
|
|
55
|
-
type:
|
|
56
|
-
}),
|
|
41
|
+
name: c,
|
|
42
|
+
type: a
|
|
43
|
+
}), m = e.object({
|
|
57
44
|
options: e.object({
|
|
58
45
|
bindProp: e.string().min(1, "options.bindProp is required")
|
|
59
46
|
})
|
|
60
|
-
}),
|
|
47
|
+
}), l = e.object({
|
|
61
48
|
name: e.string().min(1, "Event name is required"),
|
|
62
49
|
label: e.string().min(1, "Event label is required"),
|
|
63
50
|
arguments: e.array(d).optional().default([]),
|
|
64
|
-
contextmenu:
|
|
51
|
+
contextmenu: m.optional()
|
|
65
52
|
}), u = e.object({
|
|
66
53
|
id: e.string().min(1, "'id' is required and cannot be empty"),
|
|
67
54
|
name: e.string().min(1, "'name' is required and cannot be empty"),
|
|
68
55
|
icon: e.string().optional(),
|
|
69
56
|
entry: e.string().optional().default("dist"),
|
|
70
|
-
props: e.array(
|
|
71
|
-
events: e.array(
|
|
57
|
+
props: e.array(s).optional().default([]),
|
|
58
|
+
events: e.array(l).optional().default([])
|
|
72
59
|
});
|
|
73
|
-
function
|
|
60
|
+
function g(t) {
|
|
74
61
|
return t;
|
|
75
62
|
}
|
|
76
63
|
function b(t) {
|
|
@@ -80,23 +67,23 @@ function b(t) {
|
|
|
80
67
|
data: n.data
|
|
81
68
|
} : {
|
|
82
69
|
success: !1,
|
|
83
|
-
errors: n.error.issues.map((
|
|
84
|
-
path:
|
|
85
|
-
message:
|
|
70
|
+
errors: n.error.issues.map((i) => ({
|
|
71
|
+
path: i.path.join(".") || "root",
|
|
72
|
+
message: i.message
|
|
86
73
|
}))
|
|
87
74
|
};
|
|
88
75
|
}
|
|
89
76
|
export {
|
|
90
|
-
|
|
77
|
+
g as defineWidget,
|
|
91
78
|
b as validateWidgetManifest,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
79
|
+
a as widgetArgumentTypeSchema,
|
|
80
|
+
o as widgetConfigTypeSchema,
|
|
81
|
+
c as widgetEventArgumentNameSchema,
|
|
95
82
|
d as widgetEventArgumentSchema,
|
|
96
|
-
|
|
97
|
-
|
|
83
|
+
m as widgetEventContextMenuSchema,
|
|
84
|
+
l as widgetEventSchema,
|
|
98
85
|
u as widgetManifestSchema,
|
|
99
|
-
|
|
100
|
-
|
|
86
|
+
r as widgetPropConfigSchema,
|
|
87
|
+
s as widgetPropSchema
|
|
101
88
|
};
|
|
102
89
|
//# sourceMappingURL=manifest.js.map
|
package/dist/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sources":["../src/manifest.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ==========================================\n// 1. Props Configuration Schemas\n// ==========================================\n\nexport const widgetConfigTypeSchema = z.enum([\n 'input',\n 'checkbox',\n 'color-picker',\n 'date',\n 'data-time-range',\n 'datetime',\n 'input-number',\n 'monaco-editor',\n 'radio',\n 'select',\n 'tree-select',\n 'time',\n 'textarea',\n 'switch',\n 'slider',\n 'select-cascader',\n 'data-node',\n 'data-node-fields',\n 'context-menu',\n]);\n\nexport const widgetPropConfigSchema = z.object({\n type: widgetConfigTypeSchema,\n group: z.string().optional(),\n label: z.string().min(1, 'Property config label is required'),\n});\n\nexport const widgetPropSchema = z.object({\n name: z.string().min(1, 'Property name is required'),\n defaultValue: z.any().optional().default(null),\n config: widgetPropConfigSchema.optional(),\n});\n\n// ==========================================\n// 2. Events & Arguments Configuration Schemas\n// ==========================================\n\n/**\n * Supported standard event argument names (3.3)\n */\nexport const widgetEventArgumentNameSchema = z.enum([\n 'SelectedObject',\n 'MultipleSelectedObject',\n 'CurrentMenu',\n
|
|
1
|
+
{"version":3,"file":"manifest.js","sources":["../src/manifest.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ==========================================\n// 1. Props Configuration Schemas\n// ==========================================\n\nexport const widgetConfigTypeSchema = z.enum([\n 'input',\n 'checkbox',\n 'color-picker',\n 'date',\n 'data-time-range',\n 'datetime',\n 'input-number',\n 'monaco-editor',\n 'radio',\n 'select',\n 'tree-select',\n 'time',\n 'textarea',\n 'switch',\n 'slider',\n 'select-cascader',\n 'data-node',\n 'data-node-fields',\n 'context-menu',\n]);\n\nexport const widgetPropConfigSchema = z.object({\n type: widgetConfigTypeSchema,\n group: z.string().optional(),\n label: z.string().min(1, 'Property config label is required'),\n});\n\nexport const widgetPropSchema = z.object({\n name: z.string().min(1, 'Property name is required'),\n defaultValue: z.any().optional().default(null),\n config: widgetPropConfigSchema.optional(),\n});\n\n// ==========================================\n// 2. Events & Arguments Configuration Schemas\n// ==========================================\n\n/**\n * Supported standard event argument names (3.3)\n */\nexport const widgetEventArgumentNameSchema = z.enum([\n 'SelectedObject',\n 'MultipleSelectedObject',\n 'CurrentMenu',\n]);\n\n/**\n * Recursive schema for event argument types (3.2):\n * 1. Entity type bound to property: { bindProp: 'dataSourceNode' }\n * 2. Generic collection type: { name: 'List', generic: [{ bindProp: 'dataSourceNode' }] }\n * 3. Fixed internal platform type: { name: 'CurrentMenu' }\n */\nexport type WidgetArgumentType = {\n bindProp?: string;\n name?: string;\n generic?: WidgetArgumentType[];\n};\n\nexport const widgetArgumentTypeSchema: z.ZodType<WidgetArgumentType> = z.lazy(() =>\n z.object({\n bindProp: z.string().optional(),\n name: z.string().optional(),\n generic: z.array(z.lazy(() => widgetArgumentTypeSchema)).optional(),\n })\n);\n\n/**\n * Event Argument configuration item (3.2)\n */\nexport const widgetEventArgumentSchema = z.object({\n name: widgetEventArgumentNameSchema,\n type: widgetArgumentTypeSchema,\n});\n\n/**\n * Context menu binding configuration for event (3.4)\n */\nexport const widgetEventContextMenuSchema = z.object({\n options: z.object({\n bindProp: z.string().min(1, 'options.bindProp is required'),\n }),\n});\n\n/**\n * Event configuration item (3.1)\n */\nexport const widgetEventSchema = z.object({\n name: z.string().min(1, 'Event name is required'),\n label: z.string().min(1, 'Event label is required'),\n arguments: z.array(widgetEventArgumentSchema).optional().default([]),\n contextmenu: widgetEventContextMenuSchema.optional(),\n});\n\n// ==========================================\n// 3. Widget Manifest Root Schema\n// ==========================================\n\nexport const widgetManifestSchema = z.object({\n id: z.string().min(1, \"'id' is required and cannot be empty\"),\n name: z.string().min(1, \"'name' is required and cannot be empty\"),\n icon: z.string().optional(),\n entry: z.string().optional().default('dist'),\n props: z.array(widgetPropSchema).optional().default([]),\n events: z.array(widgetEventSchema).optional().default([]),\n});\n\n// ==========================================\n// 4. Inferred TypeScript Types\n// ==========================================\n\nexport type WidgetConfigType = z.infer<typeof widgetConfigTypeSchema>;\nexport type WidgetPropConfig = z.infer<typeof widgetPropConfigSchema>;\nexport type WidgetProp = z.infer<typeof widgetPropSchema>;\n\nexport type WidgetEventArgumentName = z.infer<typeof widgetEventArgumentNameSchema>;\nexport type WidgetEventArgument = z.infer<typeof widgetEventArgumentSchema>;\nexport type WidgetEventContextMenu = z.infer<typeof widgetEventContextMenuSchema>;\nexport type WidgetEvent = z.infer<typeof widgetEventSchema>;\n\nexport type WidgetManifest = z.input<typeof widgetManifestSchema>;\nexport type ResolvedWidgetManifest = z.output<typeof widgetManifestSchema>;\n\n// ==========================================\n// 5. Helper & Validation Functions\n// ==========================================\n\n/**\n * Type-helper for defining widget manifest in `.goodo/manifest.ts`.\n * Provides full IDE autocomplete and compile-time type validation.\n */\nexport function defineWidget(config: WidgetManifest): WidgetManifest {\n return config;\n}\n\nexport interface ManifestValidationResult {\n success: boolean;\n data?: ResolvedWidgetManifest;\n errors?: Array<{ path: string; message: string }>;\n}\n\n/**\n * Validates raw manifest data using Zod schema for Node.js environments (e.g. CLI, backend).\n */\nexport function validateWidgetManifest(raw: unknown): ManifestValidationResult {\n const result = widgetManifestSchema.safeParse(raw);\n if (result.success) {\n return {\n success: true,\n data: result.data,\n };\n }\n\n return {\n success: false,\n errors: result.error.issues.map((issue) => ({\n path: issue.path.join('.') || 'root',\n message: issue.message,\n })),\n };\n}"],"names":["widgetConfigTypeSchema","z","widgetPropConfigSchema","widgetPropSchema","widgetEventArgumentNameSchema","widgetArgumentTypeSchema","widgetEventArgumentSchema","widgetEventContextMenuSchema","widgetEventSchema","widgetManifestSchema","defineWidget","config","validateWidgetManifest","raw","result","issue"],"mappings":";AAMO,MAAMA,IAAyBC,EAAE,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC,GAEYC,IAAyBD,EAAE,OAAO;AAAA,EAC7C,MAAMD;AAAA,EACN,OAAOC,EAAE,OAAA,EAAS,SAAA;AAAA,EAClB,OAAOA,EAAE,OAAA,EAAS,IAAI,GAAG,mCAAmC;AAC9D,CAAC,GAEYE,IAAmBF,EAAE,OAAO;AAAA,EACvC,MAAMA,EAAE,OAAA,EAAS,IAAI,GAAG,2BAA2B;AAAA,EACnD,cAAcA,EAAE,IAAA,EAAM,SAAA,EAAW,QAAQ,IAAI;AAAA,EAC7C,QAAQC,EAAuB,SAAA;AACjC,CAAC,GASYE,IAAgCH,EAAE,KAAK;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AACF,CAAC,GAcYI,IAA0DJ,EAAE;AAAA,EAAK,MAC5EA,EAAE,OAAO;AAAA,IACP,UAAUA,EAAE,OAAA,EAAS,SAAA;AAAA,IACrB,MAAMA,EAAE,OAAA,EAAS,SAAA;AAAA,IACjB,SAASA,EAAE,MAAMA,EAAE,KAAK,MAAMI,CAAwB,CAAC,EAAE,SAAA;AAAA,EAAS,CACnE;AACH,GAKaC,IAA4BL,EAAE,OAAO;AAAA,EAChD,MAAMG;AAAA,EACN,MAAMC;AACR,CAAC,GAKYE,IAA+BN,EAAE,OAAO;AAAA,EACnD,SAASA,EAAE,OAAO;AAAA,IAChB,UAAUA,EAAE,OAAA,EAAS,IAAI,GAAG,8BAA8B;AAAA,EAAA,CAC3D;AACH,CAAC,GAKYO,IAAoBP,EAAE,OAAO;AAAA,EACxC,MAAMA,EAAE,OAAA,EAAS,IAAI,GAAG,wBAAwB;AAAA,EAChD,OAAOA,EAAE,OAAA,EAAS,IAAI,GAAG,yBAAyB;AAAA,EAClD,WAAWA,EAAE,MAAMK,CAAyB,EAAE,SAAA,EAAW,QAAQ,EAAE;AAAA,EACnE,aAAaC,EAA6B,SAAA;AAC5C,CAAC,GAMYE,IAAuBR,EAAE,OAAO;AAAA,EAC3C,IAAIA,EAAE,OAAA,EAAS,IAAI,GAAG,sCAAsC;AAAA,EAC5D,MAAMA,EAAE,OAAA,EAAS,IAAI,GAAG,wCAAwC;AAAA,EAChE,MAAMA,EAAE,OAAA,EAAS,SAAA;AAAA,EACjB,OAAOA,EAAE,OAAA,EAAS,SAAA,EAAW,QAAQ,MAAM;AAAA,EAC3C,OAAOA,EAAE,MAAME,CAAgB,EAAE,SAAA,EAAW,QAAQ,EAAE;AAAA,EACtD,QAAQF,EAAE,MAAMO,CAAiB,EAAE,SAAA,EAAW,QAAQ,CAAA,CAAE;AAC1D,CAAC;AA0BM,SAASE,EAAaC,GAAwC;AACnE,SAAOA;AACT;AAWO,SAASC,EAAuBC,GAAwC;AAC7E,QAAMC,IAASL,EAAqB,UAAUI,CAAG;AACjD,SAAIC,EAAO,UACF;AAAA,IACL,SAAS;AAAA,IACT,MAAMA,EAAO;AAAA,EAAA,IAIV;AAAA,IACL,SAAS;AAAA,IACT,QAAQA,EAAO,MAAM,OAAO,IAAI,CAACC,OAAW;AAAA,MAC1C,MAAMA,EAAM,KAAK,KAAK,GAAG,KAAK;AAAA,MAC9B,SAASA,EAAM;AAAA,IAAA,EACf;AAAA,EAAA;AAEN;"}
|