{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { WebviewApi as VsCodeWebviewApi } from \"vscode-webview\";\n\nexport type PostMessageOptions = PostMessageAsyncOptions &\n  PostMessageDataOptions;\n\nexport interface PostMessageAsyncOptions {\n  /**\n   * the millisecond of try interval time\n   * @default 200\n   */\n  interval?: number;\n  /**\n   * the millisecond of post timeout\n   * @default 10000\n   */\n  timeout?: number;\n}\n\nexport interface PostMessageDataOptions {\n  /**\n   *  the name of data in the message, default 'data'\n   */\n  dataKey?: string;\n  /**\n   *  the name of key in the message, default 'type'\n   */\n  typeKey?: string;\n}\n\nconst INTERVAL = 200;\nconst TIMEOUT = 10_000;\nconst TYPE_KEY = \"type\";\nconst DATA_KEY = \"data\";\n\nconst globalPostMessageOptions: PostMessageOptions = {\n  dataKey: DATA_KEY,\n  interval: INTERVAL,\n  timeout: TIMEOUT,\n  typeKey: TYPE_KEY,\n};\n\nfunction isNil(v: any) {\n  return typeof v === \"undefined\" || v === null;\n}\n\nexport type PostMessageListener<T> = (data: T) => void | Promise<void>;\n\n/**\n * A utility wrapper around the acquireVsCodeApi() function, which enables\n * message passing and state management between the webview and extension\n * contexts.\n */\nexport class WebviewApi<StateType = any> {\n  private readonly webviewApi!: VsCodeWebviewApi<StateType>;\n  private _options: PostMessageOptions = {\n    interval: INTERVAL,\n    timeout: TIMEOUT,\n  };\n\n  private readonly listeners: Map<string | number, PostMessageListener<any>[]> =\n    new Map();\n\n  constructor(options?: PostMessageOptions) {\n    if (typeof acquireVsCodeApi !== \"function\") {\n      console.error(\"acquireVsCodeApi is not a function\");\n      return;\n    }\n\n    this.setOptions(options || {});\n    this.webviewApi = acquireVsCodeApi();\n\n    window.addEventListener(\"message\", (event) => {\n      const message = event.data || {};\n      const { typeKey, dataKey } = this._options;\n      this._runListener(\n        message[typeKey ?? TYPE_KEY],\n        message[dataKey ?? DATA_KEY]\n      );\n    });\n  }\n\n  /**\n   * set the post message options\n   * @param options\n   */\n  public setOptions(options: PostMessageOptions) {\n    this._options = {\n      ...globalPostMessageOptions,\n      ...this._options,\n      ...options,\n    };\n  }\n\n  private _postMessage(\n    type: string | number,\n    data: any | undefined,\n    options: PostMessageOptions\n  ) {\n    if (!this.webviewApi) {\n      return;\n    }\n\n    this.webviewApi.postMessage({\n      [options.typeKey ?? TYPE_KEY]: type,\n      [options.dataKey ?? DATA_KEY]: data,\n    });\n  }\n\n  private _runListener(type: string | number, result: any, error?: any) {\n    if (isNil(type) || this.listeners.size === 0) {\n      return;\n    }\n    const listeners = this.listeners.get(type);\n    if (listeners) {\n      if (!isNil(result)) {\n        listeners[0]?.(result);\n      }\n      if (!isNil(error)) {\n        listeners[1]?.(error);\n      }\n    }\n  }\n\n  /**\n   * Post a message to the owner of the webview\n   * @param type the message type\n   * @param data the message content\n   * @param options\n   */\n\n  public post(type: string | number, data: any | undefined) {\n    this._postMessage(type, data, this._options);\n  }\n\n  /**\n   * 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.\n   * @param type the message type\n   * @param data the message content\n   * @param options\n   */\n  public postAndReceive<T>(\n    type: string | number,\n    data: any | undefined,\n    options?: PostMessageAsyncOptions\n  ): Promise<T> {\n    return new Promise((resolve, reject) => {\n      if (!this.webviewApi) {\n        reject(new Error(\"acquireVsCodeApi is not available\"));\n        return;\n      }\n\n      const opts = { ...this._options, ...options };\n      const post = () => {\n        this._postMessage(type, data, opts);\n      };\n\n      const intervalId = setInterval(post, opts.interval ?? INTERVAL);\n\n      const _runListener = this._runListener;\n\n      const timeoutId = setTimeout(() => {\n        window.removeEventListener(\"message\", receive);\n        clearInterval(intervalId);\n\n        _runListener(type, undefined, new Error(\"Timeout\"));\n\n        reject(new Error(\"Timeout\"));\n      }, opts.timeout ?? TIMEOUT);\n\n      function receive(e: MessageEvent<any>) {\n        if (\n          !(e.origin.startsWith(\"vscode-webview://\") && e.data) ||\n          e.data[opts.typeKey ?? TYPE_KEY] !== type\n        ) {\n          return;\n        }\n\n        window.removeEventListener(\"message\", receive);\n        clearTimeout(timeoutId);\n        clearInterval(intervalId);\n\n        const res = e.data[opts.dataKey ?? DATA_KEY];\n        _runListener(type, res);\n        resolve(res);\n      }\n\n      window.addEventListener(\"message\", receive);\n      post();\n    });\n  }\n\n  /**\n   * Register a listener for a message type\n   * @param type the message type\n   * @param success the success listener\n   * @param fail the fail listener\n   */\n  on<T>(\n    type: string | number,\n    success: PostMessageListener<T>,\n    fail?: PostMessageListener<any>\n  ) {\n    this.listeners.set(type, fail ? [success, fail] : [success]);\n  }\n\n  /**\n   * Remove a listener for a message type\n   * @param type the message type\n   */\n  off(type: string | number) {\n    this.listeners.delete(type);\n  }\n\n  /**\n   * Post a message to the owner of the webview\n   * @param message the message content\n   */\n  postMessage<T = any>(message: T) {\n    this.webviewApi.postMessage(message);\n  }\n\n  /**\n   * Get the persistent state stored for this webview.\n   *\n   * @return The current state or `undefined` if no state has been set.\n   */\n  getState(): StateType | undefined {\n    return this.webviewApi.getState();\n  }\n\n  /**\n   * Set the persistent state stored for this webview.\n   *\n   * @param newState New persisted state. This must be a JSON serializable object. Can be retrieved\n   * using {@link getState}.\n   *\n   * @return The new state.\n   */\n  setState<T extends StateType | undefined>(newState: T): T {\n    this.webviewApi.setState(newState);\n    return newState;\n  }\n}\n"],"mappings":"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"}