{"version":3,"file":"controller.mjs","sources":["../../../../src/frame/message/controller.ts"],"sourcesContent":["import type { MessageCommands } from './commands'\nimport type { AppFrame } from '../frame'\nimport type { LoggerInterface } from '../../logger'\nimport { LoggerFactory } from '../../logger'\nimport { Type } from '../../tools/type'\nimport { Text } from '../../tools/text'\nimport { omit } from '../../tools'\n\ninterface PromiseHandlers {\n  resolve: (value: any) => void\n  reject: (reason?: any) => void\n  timeoutId: any\n}\n\n/**\n * Parent Window Request Parameters\n * - `isRawValue?: boolean` if true then JSON.stringify will not be executed\n * - `isSafely?: boolean` auto completion mode Promise.resolve()\n * - `safelyTime?: number` after what time (900 ms) should it be automatically resolved Promise\n * - `callBack?: () => void` for placement event\n * - `requestId?: string` Unique request identifier for tracking. Used for query deduplication and debugging.\n */\nexport interface SendParams {\n  isRawValue?: boolean\n  isSafely?: boolean\n  safelyTime?: number\n  callBack?: (...args: any[]) => void\n  requestId?: string\n  // @todo add this\n  // singleOption: any\n  [index: string]: any\n}\n\n/**\n * Parent Window Communication Manager at B24\n */\nexport class MessageManager {\n  #appFrame: AppFrame\n  #callbackPromises: Map<string, PromiseHandlers>\n  #callbackSingletone: Map<string, (...args: any[]) => void>\n\n  protected _logger: LoggerInterface\n\n  private readonly runCallbackHandler: OmitThisParameter<(event: MessageEvent) => void>\n\n  constructor(appFrame: AppFrame) {\n    this._logger = LoggerFactory.createNullLogger()\n    this.#appFrame = appFrame\n\n    this.#callbackPromises = new Map()\n    this.#callbackSingletone = new Map()\n\n    this.runCallbackHandler = this._runCallback.bind(this)\n  }\n\n  setLogger(logger: LoggerInterface): void {\n    this._logger = logger\n  }\n\n  getLogger(): LoggerInterface {\n    return this._logger\n  }\n\n  // region Events ////\n  /**\n   * Subscribe to the onMessage event of the parent window\n   */\n  subscribe() {\n    window.addEventListener('message', this.runCallbackHandler)\n  }\n\n  /**\n   * Unsubscribe from the onMessage event of the parent window\n   */\n  unsubscribe(): void {\n    window.removeEventListener('message', this.runCallbackHandler)\n  }\n\n  // endregion ////\n\n  /**\n   * Send message to parent window\n   * The answer (if) we will get in _runCallback\n   *\n   * @param command\n   * @param params\n   */\n  async send(\n    command: string | MessageCommands,\n    params: null | SendParams = null\n  ): Promise<any> {\n    return new Promise((resolve, reject) => {\n      let cmd: string | object\n      const promiseHandler: PromiseHandlers = {\n        resolve,\n        reject,\n        timeoutId: null\n      }\n\n      const keyPromise = this.#setCallbackPromise(promiseHandler)\n      let paramsSend: null | string | Record<string, any> = null\n\n      const optionsSend = omit(params || {}, ['singleOption', 'callBack', 'isSafely', 'safelyTime', 'requestId'])\n      const { callBack, singleOption, requestId } = params || {}\n      if (callBack) {\n        this.#callbackSingletone.set(keyPromise, callBack)\n      }\n\n      if (singleOption) {\n        paramsSend = singleOption\n      } else if (Object.keys(optionsSend).length > 0) {\n        paramsSend = { ...optionsSend }\n      }\n\n      if (command.toString().includes(':')) {\n        cmd = {\n          method: command.toString(),\n          params: paramsSend || '',\n          callback: keyPromise,\n          appSid: this.#appFrame.getAppSid(),\n          requestId\n        }\n      } else {\n        cmd = command.toString()\n\n        if (\n          params?.isRawValue !== true\n          && paramsSend\n        ) {\n          paramsSend = JSON.stringify(paramsSend)\n        } else if (\n          params?.isRawValue === true\n          && paramsSend\n          && Type.isPlainObject(paramsSend)\n          && paramsSend['value']\n        ) {\n          paramsSend = paramsSend['value']\n        }\n\n        const listParams = [\n          paramsSend || '',\n          keyPromise,\n          this.#appFrame.getAppSid()\n        ]\n\n        cmd += ':' + listParams.filter(Boolean).join(':')\n      }\n\n      this.getLogger().debug(`send to ${this.#appFrame.getTargetOrigin()}`, {\n        cmd,\n        origin: this.#appFrame.getTargetOrigin()\n      })\n\n      parent.postMessage(cmd, this.#appFrame.getTargetOrigin())\n\n      if (params?.isSafely) {\n        const safelyTime = Number.parseInt(String(params?.safelyTime || 900))\n        this.#callbackPromises.get(keyPromise)!.timeoutId = window.setTimeout(\n          () => {\n            if (this.#callbackPromises.has(keyPromise)) {\n              this.getLogger().warning(`action ${command.toString()} stop by timeout`, {\n                command: command.toString(),\n                safelyTime\n              })\n\n              this.#callbackPromises.delete(keyPromise)\n              resolve({ isSafely: true })\n            }\n          },\n          safelyTime\n        )\n      }\n    })\n  }\n\n  /**\n   * Fulfilling a promise based on messages from the parent window\n   *\n   * @param event\n   * @private\n   */\n  public _runCallback(event: MessageEvent): void {\n    if (event.origin !== this.#appFrame.getTargetOrigin()) {\n      return\n    }\n\n    if (event.data) {\n      this.getLogger().debug(`get from ${event.origin}`, {\n        data: event.data,\n        origin: event.origin\n      })\n\n      const tmp = event.data.split(':')\n\n      const cmd: { id: string, args: any } = {\n        id: tmp[0],\n        args: tmp.slice(1).join(':')\n      }\n\n      if (cmd.args) {\n        cmd.args = JSON.parse(cmd.args)\n      }\n\n      if (this.#callbackPromises.has(cmd.id)) {\n        const promise = this.#callbackPromises.get(cmd.id) as PromiseHandlers\n        if (promise.timeoutId) {\n          clearTimeout(promise.timeoutId)\n        }\n\n        this.#callbackPromises.delete(cmd.id)\n\n        promise.resolve(cmd.args)\n        // promise.reject(cmd.args) ////\n      } else if (this.#callbackSingletone.has(cmd.id)) {\n        const callBack = this.#callbackSingletone.get(cmd.id) as (...args: any[]) => void\n        if (callBack) {\n          callBack.apply(globalThis, [cmd.args])\n        }\n      }\n    }\n  }\n\n  /**\n   * Storing a promise for a message from the parent window\n   *\n   * @param promiseHandler\n   * @private\n   *\n   * @memo We don't use Symbol here, because we need to pass it to the parent and then find and restore it.\n   */\n  #setCallbackPromise(promiseHandler: PromiseHandlers): string {\n    const key = Text.getUniqId()\n    this.#callbackPromises.set(key, promiseHandler)\n    return key\n  }\n}\n"],"names":[],"mappings":"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"}