UNPKG

@eastgold15/vscode-webview

Version:

优化 webview 页面与 vscode 扩展之间的 postMessage 通信

206 lines (205 loc) 5.95 kB
//#region \0@oxc-project+runtime@0.144.0/helpers/esm/typeof.js function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) { return typeof o; } : function(o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } //#endregion //#region \0@oxc-project+runtime@0.144.0/helpers/esm/toPrimitive.js function toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } //#endregion //#region \0@oxc-project+runtime@0.144.0/helpers/esm/toPropertyKey.js function toPropertyKey(t) { var i = toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } //#endregion //#region \0@oxc-project+runtime@0.144.0/helpers/esm/defineProperty.js function _defineProperty(e, r, t) { return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } //#endregion //#region src/index.ts const INTERVAL = 200; const TIMEOUT = 1e4; const TYPE_KEY = "type"; const DATA_KEY = "data"; const globalPostMessageOptions = { dataKey: DATA_KEY, interval: INTERVAL, timeout: TIMEOUT, typeKey: TYPE_KEY }; function isNil(v) { return typeof v === "undefined" || v === null; } /** * A utility wrapper around the acquireVsCodeApi() function, which enables * message passing and state management between the webview and extension * contexts. */ var WebviewApi = class { constructor(options) { _defineProperty(this, "webviewApi", void 0); _defineProperty(this, "_options", { interval: INTERVAL, timeout: TIMEOUT }); _defineProperty(this, "listeners", /* @__PURE__ */ new Map()); if (typeof acquireVsCodeApi !== "function") { console.error("acquireVsCodeApi is not a function"); return; } this.setOptions(options || {}); this.webviewApi = acquireVsCodeApi(); window.addEventListener("message", (event) => { const message = event.data || {}; const { typeKey, dataKey } = this._options; this._runListener(message[typeKey ?? TYPE_KEY], message[dataKey ?? DATA_KEY]); }); } /** * set the post message options * @param options */ setOptions(options) { this._options = { ...globalPostMessageOptions, ...this._options, ...options }; } _postMessage(type, data, options) { if (!this.webviewApi) return; this.webviewApi.postMessage({ [options.typeKey ?? TYPE_KEY]: type, [options.dataKey ?? DATA_KEY]: data }); } _runListener(type, result, error) { if (isNil(type) || this.listeners.size === 0) return; const listeners = this.listeners.get(type); if (listeners) { if (!isNil(result)) { var _listeners$; (_listeners$ = listeners[0]) === null || _listeners$ === void 0 || _listeners$.call(listeners, result); } if (!isNil(error)) { var _listeners$2; (_listeners$2 = listeners[1]) === null || _listeners$2 === void 0 || _listeners$2.call(listeners, error); } } } /** * Post a message to the owner of the webview * @param type the message type * @param data the message content * @param options */ post(type, data) { this._postMessage(type, data, this._options); } /** * Post a message to the owner of the webview, and return the response. The type of the message to be sent and received must be the same. * @param type the message type * @param data the message content * @param options */ postAndReceive(type, data, options) { return new Promise((resolve, reject) => { if (!this.webviewApi) { reject(/* @__PURE__ */ new Error("acquireVsCodeApi is not available")); return; } const opts = { ...this._options, ...options }; const post = () => { this._postMessage(type, data, opts); }; const intervalId = setInterval(post, opts.interval ?? INTERVAL); const _runListener = this._runListener; const timeoutId = setTimeout(() => { window.removeEventListener("message", receive); clearInterval(intervalId); _runListener(type, void 0, /* @__PURE__ */ new Error("Timeout")); reject(/* @__PURE__ */ new Error("Timeout")); }, opts.timeout ?? TIMEOUT); function receive(e) { if (!(e.origin.startsWith("vscode-webview://") && e.data) || e.data[opts.typeKey ?? TYPE_KEY] !== type) return; window.removeEventListener("message", receive); clearTimeout(timeoutId); clearInterval(intervalId); const res = e.data[opts.dataKey ?? DATA_KEY]; _runListener(type, res); resolve(res); } window.addEventListener("message", receive); post(); }); } /** * Register a listener for a message type * @param type the message type * @param success the success listener * @param fail the fail listener */ on(type, success, fail) { this.listeners.set(type, fail ? [success, fail] : [success]); } /** * Remove a listener for a message type * @param type the message type */ off(type) { this.listeners.delete(type); } /** * Post a message to the owner of the webview * @param message the message content */ postMessage(message) { this.webviewApi.postMessage(message); } /** * Get the persistent state stored for this webview. * * @return The current state or `undefined` if no state has been set. */ getState() { return this.webviewApi.getState(); } /** * Set the persistent state stored for this webview. * * @param newState New persisted state. This must be a JSON serializable object. Can be retrieved * using {@link getState}. * * @return The new state. */ setState(newState) { this.webviewApi.setState(newState); return newState; } }; //#endregion export { WebviewApi }; //# sourceMappingURL=index.mjs.map