{"version":3,"file":"index.modern.mjs","sources":["../src/index.ts"],"sourcesContent":["import {\n  Obj,\n  MiddlewareFn,\n  OperationResult,\n  OperationContext,\n} from '@pql/client';\nimport { Observable, SubscriptionObserver } from '@pql/observable';\n\nexport interface ICacheStorage {\n  read(hash: any): Promise<any>;\n\n  write(hash: any, value: any): Promise<any>;\n\n  invalidate(hash: any): Promise<any>;\n\n  invalidateAll(): Promise<any>;\n}\n\n// type -> id -> hash\ninterface InvalidationMap {\n  [type: string]: {\n    [id: string]: string[];\n  };\n}\n\nfunction invalidateDepsFromInvalidationMap(\n  invalidationMap: InvalidationMap,\n  data: Obj,\n  hash: string\n): string[] {\n  const hashes: string[] = [];\n  if (typeof data.__typename === 'string' && data.id) {\n    const k = data.__typename;\n    const typeMap = invalidationMap[k] || (invalidationMap[k] = {});\n    (typeMap[data.id] || [])\n      .splice(0)\n      .map(hash => !hashes.includes(hash) && hashes.push(hash));\n  }\n\n  const values = Object.values(data);\n\n  while (values.length > 0) {\n    const val = values.pop();\n\n    if (Array.isArray(val)) values.push.apply(values, val);\n    else if (val && typeof val === 'object')\n      invalidateDepsFromInvalidationMap(invalidationMap, val, hash).map(\n        hash => !hashes.includes(hash) && hashes.push(hash)\n      );\n  }\n\n  return hashes;\n}\n\nfunction addDepsToInvalidationMap(\n  invalidationMap: InvalidationMap,\n  data: Obj,\n  hash: string\n) {\n  if (typeof data.__typename === 'string' && data.id) {\n    const k = data.__typename;\n    const typeMap = invalidationMap[k] || (invalidationMap[k] = {});\n    (typeMap[data.id] || (typeMap[data.id] = [])).push(hash);\n  }\n\n  const values = Object.values(data);\n\n  while (values.length > 0) {\n    const val = values.pop();\n\n    if (Array.isArray(val)) values.push.apply(values, val);\n    else if (val && typeof val === 'object')\n      addDepsToInvalidationMap(invalidationMap, val, hash);\n  }\n}\n\ninterface HashCacheMap {\n  [hash: string]: {\n    ctx: OperationContext<any>;\n    next: (ctx: OperationContext<any>) => Observable<OperationResult<any>>;\n    observers: SubscriptionObserver<OperationResult<any>>[];\n  };\n}\n\nexport function cache(storage: ICacheStorage): MiddlewareFn<any, any> {\n  const invalidationMap: InvalidationMap = {};\n  const hashCache: HashCacheMap = {};\n\n  function fetchQuery(hash: string) {\n    const { ctx, next, observers } = hashCache[hash];\n    next(ctx).subscribe({\n      next(res) {\n        const { data } = res;\n        if (data) {\n          storage.write(ctx.hash, data);\n          addDepsToInvalidationMap(invalidationMap, data, ctx.hash);\n        }\n        observers.map(obs => {\n          obs.next(res);\n        });\n      },\n      error(error) {\n        observers.map(obs => {\n          obs.next({ error, data: null });\n        });\n      },\n    });\n  }\n\n  return (ctx, next) => {\n    const { hash, skipCache, operationType } = ctx;\n    const isQuery = operationType === 'query';\n    const isSubscription = operationType === 'subscription';\n    const cache =\n      hashCache[hash] || (hashCache[hash] = { ctx, next, observers: [] });\n\n    return new Observable(observer => {\n      if (isQuery) cache.observers.push(observer);\n\n      const prom =\n        skipCache || !isQuery\n          ? Promise.resolve(undefined)\n          : storage.read(hash).catch(() => void 0);\n\n      prom.then(data => {\n        if (data) {\n          observer.next({ data, error: null });\n          return;\n        }\n\n        if (isQuery) {\n          fetchQuery(hash);\n        } else {\n          next(ctx)\n            .map(res => {\n              const { data } = res;\n              if (data) {\n                if (isSubscription) {\n                  addDepsToInvalidationMap(invalidationMap, data, hash);\n                } else {\n                  invalidateDepsFromInvalidationMap(\n                    invalidationMap,\n                    data,\n                    hash\n                  ).map(hash => {\n                    storage.invalidate(hash);\n                    fetchQuery(hash);\n                  });\n                }\n              }\n              return res;\n            })\n            .subscribe(observer);\n        }\n      });\n\n      return () => {\n        observer.complete();\n        isQuery && cache.observers.splice(cache.observers.indexOf(observer), 1);\n      };\n    });\n  };\n}\n\nexport class DefaultStorage implements ICacheStorage {\n  private cache: { [hash: string]: any };\n\n  constructor(initial?: { [hash: string]: any }) {\n    this.cache =\n      typeof initial === 'object' && !Array.isArray(initial) ? initial : {};\n  }\n\n  read(hash: any) {\n    return Promise.resolve(this.cache[hash]);\n  }\n\n  write(hash: any, value: any) {\n    return new Promise(resolve => {\n      this.cache[hash] = value;\n      resolve(hash);\n    });\n  }\n\n  invalidate(hash: any) {\n    return new Promise(resolve => {\n      delete this.cache[hash];\n      resolve(hash);\n    });\n  }\n\n  invalidateAll() {\n    return Promise.resolve((this.cache = {}));\n  }\n}\n"],"names":["invalidateDepsFromInvalidationMap","invalidationMap","data","hash","hashes","__typename","id","k","typeMap","splice","map","includes","push","values","Object","length","val","pop","Array","isArray","apply","addDepsToInvalidationMap","cache","storage","hashCache","fetchQuery","ctx","next","observers","subscribe","res","write","obs","error","skipCache","operationType","isQuery","isSubscription","Observable","observer","prom","Promise","resolve","undefined","read","then","invalidate","complete","indexOf","DefaultStorage","initial","value","invalidateAll"],"mappings":"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"}