{"version":3,"sources":["../src/index.ts","../src/useRead.ts","../src/useCache.ts","../src/contexts/CacheContext.ts","../src/Read.tsx","../src/cacheOptions.ts","../src/models/Subscribable.ts","../src/utils/isPlainObject.ts","../src/utils/hashCacheKey.ts","../src/Cache.ts","../src/CacheProvider.tsx"],"sourcesContent":["export { Read } from './Read'\nexport { useRead } from './useRead'\nexport { cacheOptions } from './cacheOptions'\nexport { Cache } from './Cache'\nexport { CacheProvider } from './CacheProvider'\nexport { useCache } from './useCache'\n","import { useSyncExternalStore } from 'react'\nimport type { ResolvedCached } from './Cache'\nimport type { CacheKey, CacheOptions } from './types'\nimport { useCache } from './useCache'\n\n/**\n * @experimental This is experimental feature.\n */\nexport function useRead<TData, TCacheKey extends CacheKey>(\n  options: CacheOptions<TData, TCacheKey>\n): ResolvedCached<TData, TCacheKey>['state'] {\n  const cache = useCache()\n  return useSyncExternalStore<ResolvedCached<TData, TCacheKey>>(\n    cache.subscribe,\n    () => cache.suspend<TData, TCacheKey>(options),\n    () => cache.suspend<TData, TCacheKey>(options)\n  ).state\n}\n","import { useContext } from 'react'\nimport type { Cache } from './Cache'\nimport { CacheContext } from './contexts'\n\n/**\n * @experimental This is experimental feature.\n */\nexport function useCache(): Cache {\n  const cache = useContext(CacheContext)\n  if (cache == null) {\n    throw new Error('CacheProvider should be in parent')\n  }\n  return cache\n}\n","import { createContext } from 'react'\nimport type { Cache } from '../Cache'\n\nexport const CacheContext = createContext<Cache | null>(null)\n","import type { ResolvedCached } from './Cache'\nimport type { CacheKey, CacheOptions } from './types'\nimport { useRead } from './useRead'\n\n/**\n * @experimental This is experimental feature.\n */\nexport interface ReadProps<TData, TCacheKey extends CacheKey> extends CacheOptions<TData, TCacheKey> {\n  children: (props: ResolvedCached<TData, TCacheKey>['state']) => JSX.Element\n}\n\n/**\n * @experimental This is experimental feature.\n */\nexport function Read<TData, TCacheKey extends CacheKey>({ children, ...options }: ReadProps<TData, TCacheKey>) {\n  return <>{children(useRead<TData, TCacheKey>(options))}</>\n}\n","import type { CacheKey, CacheOptions, DataTag } from './types'\n\n/**\n * @experimental This is experimental feature.\n */\nexport function cacheOptions<TData, TCacheKey extends CacheKey>(\n  options: CacheOptions<TData, TCacheKey>\n): CacheOptions<TData, TCacheKey> & {\n  cacheKey: DataTag<TCacheKey, TData>\n}\n\n/**\n * @experimental This is experimental feature.\n */\nexport function cacheOptions(options: unknown) {\n  return options\n}\n","type Listener = (...args: any[]) => unknown\n\ntype Unsubscribe = () => void\ntype Subscribe<TListener extends Listener> = (listener: TListener) => Unsubscribe\n\nexport class Subscribable<TListener extends Listener> {\n  protected listeners = new Set<TListener>()\n\n  public subscribe: Subscribe<TListener> = (listener) => {\n    this.listeners.add(listener)\n\n    const unsubscribe = (): void => {\n      this.listeners.delete(listener)\n    }\n    return unsubscribe\n  }\n\n  protected notify = (): void => this.listeners.forEach((listener) => listener())\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 { CacheKey } from '../types'\nimport { type PlainObject, isPlainObject } from './isPlainObject'\n\nexport const hashCacheKey = (key: CacheKey) =>\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 { Subscribable } from './models/Subscribable'\nimport type { CacheKey, CacheOptions } from './types'\nimport type { ExtractPartial } from './utility-types/ExtractPartial'\nimport { hashCacheKey } from './utils'\n\nconst enum CacheStatus {\n  Idle = 'idle',\n  Pending = 'pending',\n  Resolved = 'resolved',\n  Rejected = 'rejected',\n}\n\nexport type AllStatusCached<TData, TCacheKey extends CacheKey = CacheKey> =\n  | {\n      status: CacheStatus.Idle\n      promiseToSuspend: undefined\n      cacheKey: TCacheKey\n      hashedCacheKey: ReturnType<typeof hashCacheKey>\n      state: {\n        promise: undefined\n        data: undefined\n        error: undefined\n      }\n    }\n  | {\n      status: CacheStatus.Pending\n      promiseToSuspend: Promise<void>\n      cacheKey: TCacheKey\n      hashedCacheKey: ReturnType<typeof hashCacheKey>\n      state: {\n        promise: Promise<TData>\n        data: undefined\n        error: undefined\n      }\n    }\n  | {\n      status: CacheStatus.Resolved\n      promiseToSuspend: Promise<void>\n      cacheKey: TCacheKey\n      hashedCacheKey: ReturnType<typeof hashCacheKey>\n      state: {\n        promise: Promise<TData>\n        data: TData\n        error: undefined\n      }\n    }\n  | {\n      status: CacheStatus.Rejected\n      promiseToSuspend: Promise<void>\n      cacheKey: TCacheKey\n      hashedCacheKey: ReturnType<typeof hashCacheKey>\n      state: {\n        promise: Promise<TData>\n        data: undefined\n        error: unknown\n      }\n    }\n\nexport type IdleCached<TData, TCacheKey extends CacheKey = CacheKey> = ExtractPartial<\n  AllStatusCached<TData, TCacheKey>,\n  { status: CacheStatus.Idle }\n>\nexport type PendingCached<TData, TCacheKey extends CacheKey = CacheKey> = ExtractPartial<\n  AllStatusCached<TData, TCacheKey>,\n  { status: CacheStatus.Pending }\n>\nexport type ResolvedCached<TData, TCacheKey extends CacheKey = CacheKey> = ExtractPartial<\n  AllStatusCached<TData, TCacheKey>,\n  { status: CacheStatus.Resolved }\n>\nexport type RejectedCached<TData, TCacheKey extends CacheKey = CacheKey> = ExtractPartial<\n  AllStatusCached<TData, TCacheKey>,\n  { status: CacheStatus.Rejected }\n>\n\nexport type Cached<TData, TCacheKey extends CacheKey = CacheKey> =\n  | IdleCached<TData, TCacheKey>\n  | PendingCached<TData, TCacheKey>\n  | ResolvedCached<TData, TCacheKey>\n  | RejectedCached<TData, TCacheKey>\n\n/**\n * @experimental This is experimental feature.\n */\nexport class Cache extends Subscribable<() => void> {\n  private cache = new Map<ReturnType<typeof hashCacheKey>, Cached<unknown>>()\n\n  public reset = (options?: Pick<CacheOptions<unknown, CacheKey>, 'cacheKey'>) => {\n    if (typeof options?.cacheKey === 'undefined' || options.cacheKey.length === 0) {\n      this.cache.clear()\n      this.notify()\n      return\n    }\n\n    const hashedCacheKey = hashCacheKey(options.cacheKey)\n\n    if (this.cache.has(hashedCacheKey)) {\n      this.cache.delete(hashedCacheKey)\n    }\n\n    this.notify()\n  }\n\n  public remove = (options: Pick<CacheOptions<unknown, CacheKey>, 'cacheKey'>) => {\n    const hashedCacheKey = hashCacheKey(options.cacheKey)\n\n    if (this.cache.has(hashedCacheKey)) {\n      this.cache.delete(hashedCacheKey)\n    }\n  }\n\n  public clearError = (options?: Pick<CacheOptions<unknown, CacheKey>, 'cacheKey'>) => {\n    if (options?.cacheKey === undefined || options.cacheKey.length === 0) {\n      this.cache.forEach((cached, hashedCacheKey, cache) => {\n        cache.set(hashedCacheKey, {\n          ...cached,\n          status: CacheStatus.Idle,\n          promiseToSuspend: undefined,\n          state: {\n            promise: undefined,\n            error: undefined,\n            data: undefined,\n          },\n        })\n      })\n      return\n    }\n\n    const hashedCacheKey = hashCacheKey(options.cacheKey)\n    const cached = this.cache.get(hashedCacheKey)\n    if (cached) {\n      this.cache.set(hashedCacheKey, {\n        ...cached,\n        status: CacheStatus.Idle,\n        promiseToSuspend: undefined,\n        state: {\n          promise: undefined,\n          error: undefined,\n          data: undefined,\n        },\n      })\n    }\n  }\n\n  public suspend = <TData, TCacheKey extends CacheKey = CacheKey>({\n    cacheKey,\n    cacheFn,\n  }: CacheOptions<TData, TCacheKey>): ResolvedCached<TData, TCacheKey> => {\n    const hashedCacheKey = hashCacheKey(cacheKey)\n    const cached = this.cache.get(hashedCacheKey)\n    if (cached && cached.status !== CacheStatus.Idle) {\n      if (cached.status === CacheStatus.Rejected) {\n        throw cached.state.error\n      }\n      if (cached.status === CacheStatus.Resolved) {\n        return cached as ResolvedCached<TData, TCacheKey>\n      }\n      // eslint-disable-next-line @typescript-eslint/only-throw-error\n      throw cached.promiseToSuspend\n    }\n\n    const promise = cacheFn({ cacheKey })\n    const newCached: Cached<TData, TCacheKey> = {\n      cacheKey,\n      hashedCacheKey,\n      status: CacheStatus.Pending,\n      state: {\n        promise,\n        data: undefined,\n        error: undefined,\n      },\n      promiseToSuspend: promise.then(\n        (data) => {\n          newCached.status = CacheStatus.Resolved\n          newCached.state.data = data\n          newCached.state.error = undefined\n        },\n        (error: unknown) => {\n          newCached.status = CacheStatus.Rejected\n          newCached.state.data = undefined\n          newCached.state.error = error\n        }\n      ),\n    }\n\n    this.cache.set(hashedCacheKey, newCached)\n    // eslint-disable-next-line @typescript-eslint/only-throw-error\n    throw newCached.promiseToSuspend\n  }\n\n  public getData = (options: Pick<CacheOptions<unknown, CacheKey>, 'cacheKey'>) =>\n    this.cache.get(hashCacheKey(options.cacheKey))?.state.data\n  public getError = (options: Pick<CacheOptions<unknown, CacheKey>, 'cacheKey'>) =>\n    this.cache.get(hashCacheKey(options.cacheKey))?.state.error\n}\n","import { type PropsWithChildren } from 'react'\nimport type { Cache } from './Cache'\nimport { CacheContext } from './contexts'\n\ntype CacheProviderProps = PropsWithChildren<{ cache: Cache }>\n\n/**\n * @experimental This is experimental feature.\n */\nexport function CacheProvider({ cache, children }: CacheProviderProps) {\n  return <CacheContext.Provider value={cache}>{children}</CacheContext.Provider>\n}\n"],"mappings":"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","names":["import_react","import_react","cached","hashedCacheKey","import_jsx_runtime"]}