{"version":3,"sources":["../src/index.ts"],"names":["reject"],"mappings":"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","sourcesContent":["import type {\n  GoogleMapsLoaderOptions,\n  GoogleMapsLibraries,\n  GoogleMapsLibrary,\n  ScriptOptions,\n  GoogleMapsLoaderStatus,\n} from './types';\n\nexport type {\n  GoogleMapsLoaderOptions,\n  GoogleMapsLoaderStatus,\n  GoogleMapsLibrary,\n  GoogleMapsLibraries,\n  ScriptOptions,\n};\n\ndeclare class GoogleMapsLoader {\n  /** @returns current status of {@link google.maps} script loading */\n  static getStatus(): GoogleMapsLoaderStatus;\n  /** @returns current status of a specific {@link library} loading */\n  static getStatus(library: GoogleMapsLibrary): GoogleMapsLoaderStatus;\n\n  /**\n   * @returns promise of {@link google.maps} script loading completion\n   *\n   * **Resolves** if {@link GoogleMapsLoader.load load} is successful\n   *\n   * **Rejects**\n   *\n   * - if {@link google.maps} was loaded outside of this library\n   * - if no `options` were set\n   * - if script loading failed\n   */\n  static getCompletion(): Promise<void>;\n  /**\n   * @returns promise of loading the provided {@link library}\n   */\n  static getCompletion<L extends GoogleMapsLibrary>(\n    library: L\n  ): Promise<GoogleMapsLibraries[L]>;\n  /**\n   * @returns promise of loading provided {@link libraries}\n   */\n  static getCompletion<const A extends GoogleMapsLibrary[]>(\n    ...libraries: A\n  ): Promise<{\n    [Index in keyof A]: GoogleMapsLibraries[A[Index]];\n  }>;\n\n  /**\n   * Can be called multiple times, only on the first call it starts loading {@link google.maps} script with the given `options`\n   */\n  static load(): Promise<void>;\n  /**\n   * loads {@link google.maps} script and a provided {@link library}\n   */\n  static load<L extends GoogleMapsLibrary>(\n    library: L\n  ): Promise<GoogleMapsLibraries[L]>;\n  /**\n   * loads {@link google.maps} script and provided {@link libraries}\n   */\n  static load<const A extends GoogleMapsLibrary[]>(\n    ...libraries: A\n  ): Promise<{\n    [Index in keyof A]: GoogleMapsLibraries[A[Index]];\n  }>;\n\n  /**\n   * @returns provided {@link library} or `undefined` if it's not loaded yet\n   */\n  static get<L extends GoogleMapsLibrary>(\n    library: L\n  ): GoogleMapsLibraries[L] | undefined;\n\n  /**\n   * @returns error for {@link google.maps} script or `undefined`\n   */\n  static getError(): Error | undefined;\n  /**\n   * @returns error for the provided {@link library} or `undefined`\n   */\n  static getError(\n    library: GoogleMapsLibrary\n  ):\n    | Error\n    | google.maps.MapsServerError\n    | google.maps.MapsNetworkError\n    | google.maps.MapsRequestError\n    | undefined;\n}\n\ntype Identity<T> = T;\n\ninterface GoogleMapsLoader extends Identity<typeof GoogleMapsLoader> {\n  /**\n   * Sets options for the {@link GoogleMapsLoader}\n   * @param options - options for {@link google.maps} script loading\n   * @param scriptOptions - options for script element\n   * @param callbackName - name for callback, which will be called when {@link google.maps} script loading ends, defaults to `\"__gmlcb\"`\n   */\n  (\n    options: GoogleMapsLoaderOptions,\n    scriptOptions?: ScriptOptions,\n    callbackName?: string\n  ): GoogleMapsLoader;\n}\n\nconst enum Status {\n  NONE,\n  LOADING,\n  LOADED,\n  ERROR,\n}\n\nconst googleMapsLoader = (() => {\n  let options: GoogleMapsLoaderOptions;\n\n  let scriptOptions: ScriptOptions;\n\n  let callbackName: string;\n\n  const GoogleMapsLoader = (\n    _options: GoogleMapsLoaderOptions,\n    _scriptProps?: ScriptOptions,\n    _callbackName?: string\n  ) => {\n    options = _options;\n\n    scriptOptions = _scriptProps || {};\n\n    callbackName = _callbackName || '__gmlcb';\n\n    return GoogleMapsLoader;\n  };\n\n  const completion = new Promise<void>((resolve, reject) => {\n    type Data = [\n      status: Status,\n      promise: Promise<any>,\n      lib: any,\n      error: any,\n      load: () => void,\n    ];\n\n    let status = Status.NONE;\n\n    let error: Error | undefined;\n\n    const statuses = ['none', 'loading', 'loaded', 'error'] as const;\n\n    const store = new Map<GoogleMapsLibrary, Data>();\n\n    const handleOnline = (cb: () => void, ifOnline?: () => void) => {\n      if (navigator.onLine) {\n        (ifOnline || cb)();\n      } else {\n        window.addEventListener('online', cb, { once: true });\n      }\n    };\n\n    const initData = (key: GoogleMapsLibrary) => {\n      let load!: () => void;\n\n      const data: Data = [\n        Status.NONE,\n        new Promise((res, rej) => {\n          load = () => {\n            const reject = (err: any) => {\n              handleOnline(load, () => {\n                data[0] = Status.ERROR;\n\n                data[3] = err;\n\n                rej(err);\n              });\n            };\n\n            completion.then(() => {\n              google.maps.importLibrary(key).then((value) => {\n                data[0] = Status.LOADED;\n\n                data[2] = value;\n\n                res(value);\n              }, reject);\n            }, reject);\n          };\n        }),\n        undefined,\n        undefined,\n        load,\n      ];\n\n      store.set(key, data);\n\n      return data;\n    };\n\n    const createCompletionGetter =\n      (\n        getCompletion: (key: GoogleMapsLibrary) => Promise<any>,\n        onetime?: () => undefined\n      ) =>\n      (...libraries: GoogleMapsLibrary[]) => {\n        if (onetime) {\n          onetime = onetime();\n        }\n\n        const l = libraries.length;\n\n        return l\n          ? l > 1\n            ? Promise.all(libraries.map(getCompletion))\n            : getCompletion(libraries[0])\n          : completion;\n      };\n\n    (GoogleMapsLoader as GoogleMapsLoader).get = (key) =>\n      store.has(key) ? store.get(key)![2] : undefined;\n\n    (GoogleMapsLoader as GoogleMapsLoader).getError = (\n      key?: GoogleMapsLibrary\n    ) => (key ? (store.has(key) ? store.get(key)![3] : undefined) : error);\n\n    (GoogleMapsLoader as GoogleMapsLoader).getStatus = (\n      key?: GoogleMapsLibrary\n    ) =>\n      statuses[\n        key ? (store.has(key) ? store.get(key)![0] : Status.NONE) : status\n      ];\n\n    (GoogleMapsLoader as GoogleMapsLoader).getCompletion =\n      createCompletionGetter((key) => (store.get(key) || initData(key))[1]);\n\n    (GoogleMapsLoader as GoogleMapsLoader).load = createCompletionGetter(\n      (key) => {\n        const data = store.get(key) || initData(key);\n\n        if (!data[0]) {\n          data[0] = Status.LOADING;\n\n          handleOnline(data.pop()!);\n        }\n\n        return data[1];\n      },\n      () => {\n        let errorMessage: string | undefined;\n\n        if (!options) {\n          errorMessage = 'no options was set';\n        } else if (window.google && google.maps) {\n          errorMessage = 'google.maps already loaded';\n        }\n\n        if (errorMessage) {\n          status = Status.ERROR;\n\n          reject((error = new Error(errorMessage)));\n        } else {\n          status = Status.LOADING;\n\n          const src = (\n            Object.keys(options) as Array<keyof GoogleMapsLoaderOptions>\n          ).reduce(\n            (acc, key) => `${acc}&${key}=${options[key]}`,\n            `https://maps.googleapis.com/maps/api/js?callback=${callbackName}&loading=async`\n          );\n\n          const createScript = () => {\n            const script = document.createElement('script');\n\n            script.type = 'text/javascript';\n\n            script.onerror = () => {\n              script.remove();\n\n              handleOnline(createScript, () => {\n                status = Status.ERROR;\n\n                reject((error = new Error('google.maps could not load')));\n              });\n            };\n\n            script.src = src;\n\n            for (const key in scriptOptions) {\n              // @ts-expect-error\n              script[key] = scriptOptions[key as keyof ScriptOptions]!;\n            }\n\n            document.head.appendChild(script);\n          };\n\n          window[callbackName as any] = (() => {\n            delete window[callbackName as any];\n\n            status = Status.LOADED;\n\n            resolve();\n          }) as any;\n\n          handleOnline(createScript);\n        }\n      }\n    );\n  });\n\n  return GoogleMapsLoader as GoogleMapsLoader;\n})();\n\nexport { googleMapsLoader as GoogleMapsLoader };\n"]}