{"version":3,"sources":["../src/useAwait.ts","../src/utils/isPlainObject.ts","../src/utils/hashKey.ts","../src/AwaitClient.ts"],"sourcesContent":["import { useMemo, useSyncExternalStore } from 'react'\nimport { awaitClient } from './AwaitClient'\nimport type { AwaitOptions, Awaited, Key } from './types'\n\n/**\n * @experimental This is experimental feature.\n */\nexport const useAwait = <TData, TKey extends Key>(options: AwaitOptions<TData, TKey>): Awaited<TData> => {\n  const syncData = () => awaitClient.suspend(options)\n  const data = useSyncExternalStore<TData>(\n    (sync) => awaitClient.subscribe(options.key, sync).unsubscribe,\n    syncData,\n    syncData\n  )\n\n  return useMemo(\n    () => ({\n      key: options.key,\n      data,\n      reset: () => awaitClient.reset(options.key),\n    }),\n    [data, options.key]\n  )\n}\n","export type PlainObject = Record<string, any>\n\nexport const isPlainObject = (value: any): value is PlainObject => {\n  if (!hasObjectPrototype(value)) {\n    return false\n  }\n\n  // If has modified constructor\n  const ctor = value.constructor\n  if (typeof ctor === 'undefined') {\n    return true\n  }\n\n  // If has modified prototype\n  const prot = ctor.prototype\n  if (!hasObjectPrototype(prot)) {\n    return false\n  }\n\n  // If constructor does not have an Object-specific method\n  if (!Object.prototype.hasOwnProperty.call(prot, 'isPrototypeOf')) {\n    return false\n  }\n\n  // Most likely a plain Object\n  return true\n}\n\nconst hasObjectPrototype = (value: any) => Object.prototype.toString.call(value) === '[object Object]'\n","import type { Key } from '../types'\nimport { type PlainObject, isPlainObject } from './isPlainObject'\n\nexport const hashKey = (key: Key) =>\n  JSON.stringify(key, (_, val: unknown) =>\n    isPlainObject(val)\n      ? Object.keys(val)\n          .sort()\n          .reduce((acc: PlainObject, cur) => {\n            acc[cur] = val[cur]\n            return acc\n          }, {})\n      : val\n  )\n","import type { AwaitOptions, Key } from './types'\nimport { hashKey } from './utils'\n\ntype Sync = (...args: unknown[]) => unknown\n\ntype AwaitState<TKey extends Key = Key> = {\n  promise?: Promise<unknown>\n  key: TKey\n  hashedKey: ReturnType<typeof hashKey>\n  error?: unknown\n  data?: unknown\n}\n\nclass AwaitClient {\n  private cache = new Map<ReturnType<typeof hashKey>, AwaitState>()\n  private syncsMap = new Map<ReturnType<typeof hashKey>, Sync[]>()\n\n  public reset = (key?: Key) => {\n    if (key === undefined || key.length === 0) {\n      this.cache.clear()\n      this.syncSubscribers()\n      return\n    }\n\n    const hashedKey = hashKey(key)\n\n    if (this.cache.has(hashedKey)) {\n      // TODO: reset with key index hierarchy\n      this.cache.delete(hashedKey)\n    }\n\n    this.syncSubscribers(key)\n  }\n\n  public clearError = (key?: Key) => {\n    if (key === undefined || key.length === 0) {\n      this.cache.forEach((value, key, map) => {\n        map.set(key, { ...value, promise: undefined, error: undefined })\n      })\n      return\n    }\n\n    const hashedKey = hashKey(key)\n    const awaitState = this.cache.get(hashedKey)\n    if (awaitState) {\n      // TODO: clearError with key index hierarchy\n      this.cache.set(hashedKey, { ...awaitState, promise: undefined, error: undefined })\n    }\n  }\n\n  public suspend = <TData, TKey extends Key = Key>({ key, fn }: AwaitOptions<TData, TKey>): TData => {\n    const hashedKey = hashKey(key)\n    const awaitState = this.cache.get(hashedKey)\n\n    if (awaitState?.error) {\n      // eslint-disable-next-line @typescript-eslint/no-throw-literal\n      throw awaitState.error\n    }\n    if (awaitState?.data) {\n      return awaitState.data as TData\n    }\n\n    if (awaitState?.promise) {\n      // eslint-disable-next-line @typescript-eslint/no-throw-literal\n      throw awaitState.promise\n    }\n\n    const newAwaitState: AwaitState<TKey> = {\n      key,\n      hashedKey,\n      promise: fn({ key })\n        .then((data) => {\n          newAwaitState.data = data\n        })\n        .catch((error: unknown) => {\n          newAwaitState.error = error\n        }),\n    }\n\n    this.cache.set(hashedKey, newAwaitState)\n    // eslint-disable-next-line @typescript-eslint/no-throw-literal\n    throw newAwaitState.promise\n  }\n\n  public getData = (key: Key) => this.cache.get(hashKey(key))?.data\n  public getError = (key: Key) => this.cache.get(hashKey(key))?.error\n\n  public subscribe(key: Key, syncSubscriber: Sync) {\n    const hashedKey = hashKey(key)\n    const syncs = this.syncsMap.get(hashedKey)\n    this.syncsMap.set(hashedKey, [...(syncs ?? []), syncSubscriber])\n\n    const subscribed = {\n      unsubscribe: () => this.unsubscribe(key, syncSubscriber),\n    }\n    return subscribed\n  }\n\n  public unsubscribe(key: Key, syncSubscriber: Sync) {\n    const hashedKey = hashKey(key)\n    const syncs = this.syncsMap.get(hashedKey)\n\n    if (syncs) {\n      this.syncsMap.set(\n        hashedKey,\n        syncs.filter((sync) => sync !== syncSubscriber)\n      )\n    }\n  }\n\n  private syncSubscribers = (key?: Key) => {\n    const hashedKey = key ? hashKey(key) : undefined\n\n    return hashedKey\n      ? this.syncsMap.get(hashedKey)?.forEach((sync) => sync())\n      : this.syncsMap.forEach((syncs) => syncs.forEach((sync) => sync()))\n  }\n}\n\n/**\n * @experimental This is experimental feature.\n */\nexport const awaitClient = new AwaitClient()\n"],"mappings":"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","names":["key"]}