{"version":3,"sources":["../src/ParentHandler.ts","../src/utils/index.ts","../src/RequestManager/RequestManager.ts","../src/WebViewRequester.ts"],"sourcesContent":["import {\n  AsyncPostMessageRequest,\n  AsyncPostMessageResponse,\n  Promises,\n} from \"./RequestManager/types\";\n\ntype Unsubscribe = () => void;\n\nexport const handleWebViewRequest = <PromisesInterface extends Promises>(\n  target: { postMessage: typeof window.postMessage },\n  handler: (\n    request: AsyncPostMessageRequest<PromisesInterface>\n  ) => Promise<AsyncPostMessageResponse<PromisesInterface>>\n): Unsubscribe => {\n  const handleMessage = async (\n    event: MessageEvent<AsyncPostMessageRequest<PromisesInterface>>\n  ) => {\n    // Execute the business logic.\n    const response = await handler(event.data);\n\n    // Send the response back to the iFrame so it can resolve.\n    target.postMessage(response, \"*\");\n  };\n\n  window.addEventListener(\"message\", handleMessage);\n\n  return () => {\n    window.removeEventListener(\"message\", handleMessage);\n  };\n};\n","/**\n * Generates an alphanumeric unique identifier.\n *\n * @returns {string} The alphanumeric unique identifier.\n */\nexport const generateAlphaNumericUniqueId = (): string => {\n  // Generate a random number between 0 and 35.\n  const randomNumber = Math.floor(Math.random() * 36);\n\n  // Get the current timestamp.\n  const timestamp = Date.now();\n\n  // Combine the random number and timestamp to create a unique identifier.\n  const uniqueId = `${randomNumber}-${timestamp}`;\n\n  // Convert the unique identifier to a base-36 string.\n  const alphaNumericUniqueId = uniqueId.replace(/[\\W_]/g, \"\");\n\n  // Return the alpha numeric unique identifier.\n  return alphaNumericUniqueId;\n};\n","import { generateAlphaNumericUniqueId } from \"../utils\";\nimport {\n  AsyncPostMessageRequest,\n  AsyncPostMessageResponse,\n  CallbackType,\n  Promises,\n  UidType,\n} from \"./types\";\n\n/**\n * A class for managing async postMessage requests and their promise wrappers. Each instance\n * stores a map of callbacks for each unique ID. It does not wrap the `postMessage` API. Instead,\n * it allows the client to set the listener and postMessage methods on their own.\n */\nexport class RequestManager<PromisesInterface extends Promises> {\n  /**\n   * Map of callbacks for each promise's unique ID.\n   */\n  private callbacks: Map<UidType, CallbackType>;\n\n  constructor() {\n    this.callbacks = new Map();\n  }\n\n  /**\n   * Send a strongly typed async postMessage request.\n   *\n   * @param functionName The name of the function to call\n   * @param args The arguments to pass to the function\n   * @param options Options for the request. Defaults to a timeout of 10 seconds. If `0` is passed\n   * as the timeout, the request will not timeout.\n   * @returns A promise that resolves with the return value of the function\n   */\n  public send = <FnNameType extends keyof PromisesInterface & string>(\n    functionName: FnNameType,\n    args: Parameters<PromisesInterface[FnNameType]>,\n    options?: { timeoutMs: number }\n  ): Promise<ReturnType<PromisesInterface[FnNameType]>> => {\n    // Generate a unique ID for this request.\n    const uid = generateAlphaNumericUniqueId();\n\n    const promise = new Promise<ReturnType<PromisesInterface[FnNameType]>>(\n      (resolve, reject) => {\n        this.callbacks.set(uid, { resolve, reject });\n        const message: AsyncPostMessageRequest<PromisesInterface> = {\n          uid,\n          functionName,\n          args,\n        };\n        this.postMessage(message);\n\n        // Set a timeout for the request (defaults to 10 seconds).\n        const timeout = options?.timeoutMs ?? 10000;\n        if (timeout > 0) {\n          setTimeout(() => {\n            reject(new Error(`${functionName} timed out (id: ${uid})`));\n            this.callbacks.delete(uid);\n          }, timeout);\n        }\n      }\n    );\n\n    return promise;\n  };\n\n  /**\n   * Handler for postMessages to the client.\n   *\n   * @param message Message payload received by the webview.\n   */\n  public onResponse(\n    message: AsyncPostMessageResponse<PromisesInterface>\n  ): void {\n    const callback = this.callbacks.get(message.uid);\n\n    // If the callback is not defined, do nothing as it means the request timed out.\n    if (!callback) {\n      return;\n    }\n\n    this.callbacks.delete(message.uid);\n    if (message.error) {\n      callback.reject(new Error(message.error));\n    } else {\n      callback.resolve(message.response);\n    }\n  }\n\n  /**\n   * Send a strongly typed async postMessage request to the target. This should be set by the\n   * client.\n   *\n   * @param _message Message payload to send to the target.\n   */\n  public postMessage(\n    _message: AsyncPostMessageRequest<PromisesInterface>\n  ): void {\n    console.warn(\"[AsyncPostMessage] postMessage unimplemented\");\n  }\n}\n","import { RequestManager } from \"./RequestManager/RequestManager\";\nimport { AsyncPostMessageResponse, Promises } from \"./RequestManager/types\";\n\n/**\n * The Singleton class defines the `getInstance` method that lets clients access\n * the unique singleton instance.\n */\nexport class WebViewRequester<PromisesInterface extends Promises = any> {\n  private static instance: WebViewRequester;\n\n  private requestManager: RequestManager<PromisesInterface>;\n\n  /**\n   * The Singleton's constructor should always be private to prevent direct\n   * construction calls with the `new` operator.\n   */\n  private constructor() {\n    // Setup instance of RequestManager that will be used by all calls.\n    this.requestManager = new RequestManager();\n\n    // Listen for messages from the parent.\n    window.addEventListener(\n      \"message\",\n      (event: MessageEvent<AsyncPostMessageResponse<PromisesInterface>>) => {\n        if (!event.data) {\n          return;\n        }\n        this.requestManager.onResponse(event.data);\n      }\n    );\n\n    // Setup data pipeline to send messages to the parent.\n    this.requestManager.postMessage = (message) => {\n      window.parent.postMessage(message, \"*\");\n    };\n  }\n\n  /**\n   * The static method that controls the access to the global AsyncPostMessage instance.\n   *\n   * We use a singleton so that the client does not need to worry about creating multiple\n   * instances of the `AsyncPostMessage` class.\n   */\n  public static getInstance = <\n    PromisesInterface extends Promises\n  >(): WebViewRequester<PromisesInterface> => {\n    if (!WebViewRequester.instance) {\n      WebViewRequester.instance = new WebViewRequester();\n    }\n\n    return WebViewRequester.instance;\n  };\n\n  /**\n   * Execute a strongly typed promise that is executed in the parent process.\n   */\n  public execute = <FnNameType extends keyof PromisesInterface & string>(\n    functionName: FnNameType,\n    args: Parameters<PromisesInterface[FnNameType]>,\n    options?: { timeoutMs: number }\n  ): Promise<ReturnType<PromisesInterface[FnNameType]>> => {\n    return this.requestManager.send(functionName, args, options);\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAQO,IAAM,uBAAuB,CAClC,QACA,YAGgB;AAChB,QAAM,gBAAgB,CACpB,UACG;AAEH,UAAM,WAAW,MAAM,QAAQ,MAAM,IAAI;AAGzC,WAAO,YAAY,UAAU,GAAG;AAAA,EAClC;AAEA,SAAO,iBAAiB,WAAW,aAAa;AAEhD,SAAO,MAAM;AACX,WAAO,oBAAoB,WAAW,aAAa;AAAA,EACrD;AACF;;;ACxBO,IAAM,+BAA+B,MAAc;AAExD,QAAM,eAAe,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAGlD,QAAM,YAAY,KAAK,IAAI;AAG3B,QAAM,WAAW,GAAG,YAAY,IAAI,SAAS;AAG7C,QAAM,uBAAuB,SAAS,QAAQ,UAAU,EAAE;AAG1D,SAAO;AACT;;;ACNO,IAAM,iBAAN,MAAyD;AAAA,EAM9D,cAAc;AAad;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAO,OAAO,CACZ,cACA,MACA,YACuD;AAEvD,YAAM,MAAM,6BAA6B;AAEzC,YAAM,UAAU,IAAI;AAAA,QAClB,CAAC,SAAS,WAAW;AA1C3B;AA2CQ,eAAK,UAAU,IAAI,KAAK,EAAE,SAAS,OAAO,CAAC;AAC3C,gBAAM,UAAsD;AAAA,YAC1D;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,eAAK,YAAY,OAAO;AAGxB,gBAAM,WAAU,wCAAS,cAAT,YAAsB;AACtC,cAAI,UAAU,GAAG;AACf,uBAAW,MAAM;AACf,qBAAO,IAAI,MAAM,GAAG,YAAY,mBAAmB,GAAG,GAAG,CAAC;AAC1D,mBAAK,UAAU,OAAO,GAAG;AAAA,YAC3B,GAAG,OAAO;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AA1CE,SAAK,YAAY,oBAAI,IAAI;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgDO,WACL,SACM;AACN,UAAM,WAAW,KAAK,UAAU,IAAI,QAAQ,GAAG;AAG/C,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,SAAK,UAAU,OAAO,QAAQ,GAAG;AACjC,QAAI,QAAQ,OAAO;AACjB,eAAS,OAAO,IAAI,MAAM,QAAQ,KAAK,CAAC;AAAA,IAC1C,OAAO;AACL,eAAS,QAAQ,QAAQ,QAAQ;AAAA,IACnC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,YACL,UACM;AACN,YAAQ,KAAK,8CAA8C;AAAA,EAC7D;AACF;;;AC5FO,IAAM,oBAAN,MAAM,kBAA2D;AAAA;AAAA;AAAA;AAAA;AAAA,EAS9D,cAAc;AAwCtB;AAAA;AAAA;AAAA,SAAO,UAAU,CACf,cACA,MACA,YACuD;AACvD,aAAO,KAAK,eAAe,KAAK,cAAc,MAAM,OAAO;AAAA,IAC7D;AA5CE,SAAK,iBAAiB,IAAI,eAAe;AAGzC,WAAO;AAAA,MACL;AAAA,MACA,CAAC,UAAqE;AACpE,YAAI,CAAC,MAAM,MAAM;AACf;AAAA,QACF;AACA,aAAK,eAAe,WAAW,MAAM,IAAI;AAAA,MAC3C;AAAA,IACF;AAGA,SAAK,eAAe,cAAc,CAAC,YAAY;AAC7C,aAAO,OAAO,YAAY,SAAS,GAAG;AAAA,IACxC;AAAA,EACF;AA4BF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAxDa,kBAoCG,cAAc,MAEgB;AAC1C,MAAI,CAAC,kBAAiB,UAAU;AAC9B,sBAAiB,WAAW,IAAI,kBAAiB;AAAA,EACnD;AAEA,SAAO,kBAAiB;AAC1B;AA5CK,IAAM,mBAAN;","names":[]}