{"version":3,"sources":["../../src/util/jsonp.ts"],"sourcesContent":["/**\n * MIT license\n */\n\n// Callback index.\nlet count = 0;\n\ntype CallbackId<Prefix extends string = string> = `${Prefix}${number}`;\n\ndeclare global {\n  interface Window {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    [key: CallbackId]: (data: any) => void;\n  }\n}\n\n/**\n * JSONP呼び出しのオプション設定\n */\nexport type JsonpOption = {\n  /**\n   * コールバック関数名のプレフィックス\n   * @default \"__jp\"\n   */\n  prefix?: string;\n  \n  /**\n   * コールバック関数名を指定するURLパラメータ名\n   * @default \"callback\"\n   */\n  param?: string;\n  \n  /**\n   * タイムアウト時間（ミリ秒）\n   * @default 15000\n   */\n  timeout?: number;\n};\n\nconst noop = function () { };\n\n/**\n * JSONPリクエストを実行してデータを取得します。\n * \n * @param url - リクエスト先のURL\n * @param options - JSONP呼び出しのオプション設定\n * @returns JSONPリクエストの結果をPromiseで返します\n * @throws {Error} タイムアウトが発生した場合、\"Timeout\"メッセージのエラーをスローします\n * \n * @example\n * ```typescript\n * // 基本的な使用方法\n * const data = await jsonp<ResponseType>('https://example.com/api');\n * \n * // オプション指定\n * const data = await jsonp<ResponseType>('https://example.com/api', {\n *   prefix: 'customPrefix',\n *   param: 'callbackParam',\n *   timeout: 10000\n * });\n * ```\n */\nexport function jsonp<T>(\n  url: string,\n  { prefix = \"__jp\", param = \"callback\", timeout = 15000 }: JsonpOption = {}\n): Promise<T> {\n  return new Promise(function (resolve, reject) {\n    // 最初のscriptタグを取得し、そのタグの直前に新しいscriptタグを挿入するための参照を取得\n    // これにより、ページの構造を大きく変えることなくscriptを追加できる\n    const targetChild = document.getElementsByTagName(\"script\").item(0);\n    const target = targetChild?.parentNode ?? document.head;\n\n    // ユニークなコールバック関数名を生成\n    const id: CallbackId = `${prefix}${count++}`;\n    \n    // リソース解放用の関数を定義\n    // スクリプトタグの削除、コールバック関数のクリーンアップ、タイマーのクリアを行う\n    const cleanup = function () {\n      // Remove the script tag.\n      if (script && script.parentNode) {\n        script.parentNode.removeChild(script);\n      }\n\n      // コールバック関数を空の関数に置き換えてメモリリークを防止\n      window[id] = noop;\n\n      if (timer) {\n        clearTimeout(timer);\n      }\n    };\n\n    // タイムアウト処理の設定\n    // 指定された時間内にレスポンスがない場合はエラーとして処理\n    const timer =\n      timeout > 0\n        ? setTimeout(() => {\n          cleanup();\n          reject(new Error(\"Timeout\"));\n        }, timeout)\n        : undefined;\n\n    // サーバーからのレスポンスを処理するコールバック関数\n    const callback = (data: T) => {\n      cleanup();\n      resolve(data);\n    };\n    \n    // グローバルスコープにコールバック関数を登録\n    // これによりJSONPのレスポンスから関数が呼び出せるようになる\n    window[id] = callback;\n\n    // JSONPリクエスト用のscriptタグを作成\n    const script = document.createElement(\"script\");\n    const urlObj = new URL(url);\n    \n    // URLにコールバック関数名をパラメータとして追加\n    urlObj.searchParams.set(param, id);\n    script.setAttribute(\"src\", urlObj.toString());\n    \n    // DOMにscriptタグを挿入し、リクエストを開始\n    target.insertBefore(script, targetChild);\n  });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,IAAI,QAAQ;AAkCZ,IAAM,OAAO,WAAY;AAAE;AAuBpB,SAAS,MACd,KACA,EAAE,SAAS,QAAQ,QAAQ,YAAY,UAAU,KAAM,IAAiB,CAAC,GAC7D;AACZ,SAAO,IAAI,QAAQ,SAAU,SAAS,QAAQ;AAG5C,UAAM,cAAc,SAAS,qBAAqB,QAAQ,EAAE,KAAK,CAAC;AAClE,UAAM,SAAS,aAAa,cAAc,SAAS;AAGnD,UAAM,KAAiB,GAAG,MAAM,GAAG,OAAO;AAI1C,UAAM,UAAU,WAAY;AAE1B,UAAI,UAAU,OAAO,YAAY;AAC/B,eAAO,WAAW,YAAY,MAAM;AAAA,MACtC;AAGA,aAAO,EAAE,IAAI;AAEb,UAAI,OAAO;AACT,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAIA,UAAM,QACJ,UAAU,IACN,WAAW,MAAM;AACjB,cAAQ;AACR,aAAO,IAAI,MAAM,SAAS,CAAC;AAAA,IAC7B,GAAG,OAAO,IACR;AAGN,UAAM,WAAW,CAAC,SAAY;AAC5B,cAAQ;AACR,cAAQ,IAAI;AAAA,IACd;AAIA,WAAO,EAAE,IAAI;AAGb,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,UAAM,SAAS,IAAI,IAAI,GAAG;AAG1B,WAAO,aAAa,IAAI,OAAO,EAAE;AACjC,WAAO,aAAa,OAAO,OAAO,SAAS,CAAC;AAG5C,WAAO,aAAa,QAAQ,WAAW;AAAA,EACzC,CAAC;AACH;","names":[]}