{"version":3,"file":"dataloader.mjs","names":[],"sources":["../src/dataloader.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * DataLoader - A generic utility for batching and caching data fetches.\n *\n * Vendored from: https://github.com/graphql/dataloader\n * Commit: a10773043d41a56bde4219c155fcf5633e6c9bcb\n * License: MIT\n * Copyright (c) GraphQL Contributors\n */\n\n/**\n * A `DataLoader` creates a public API for loading data from a particular\n * data back-end with unique keys such as the `id` column of a SQL table or\n * document name in a MongoDB database, given a batch loading function.\n *\n * Each `DataLoader` instance contains a unique memoized cache. Use caution when\n * used in long-lived applications or those which serve many users with\n * different access permissions and consider creating a new instance per\n * web request.\n */\nexport class DataLoader<K, V, C = K> {\n\tconstructor(batchLoadFn: DataLoader.BatchLoadFn<K, V>, options?: DataLoader.Options<K, V, C>) {\n\t\tif (typeof batchLoadFn !== 'function') {\n\t\t\tthrow new TypeError(\n\t\t\t\t'DataLoader must be constructed with a function which accepts ' +\n\t\t\t\t\t`Array<key> and returns Promise<Array<value>>, but got: ${batchLoadFn}.`,\n\t\t\t);\n\t\t}\n\t\tthis._batchLoadFn = batchLoadFn;\n\t\tthis._maxBatchSize = getValidMaxBatchSize(options);\n\t\tthis._batchScheduleFn = getValidBatchScheduleFn(options);\n\t\tthis._cacheKeyFn = getValidCacheKeyFn(options);\n\t\tthis._cacheMap = getValidCacheMap(options);\n\t\tthis._batch = null;\n\t\tthis.name = getValidName(options);\n\t}\n\n\t// Private\n\t_batchLoadFn: DataLoader.BatchLoadFn<K, V>;\n\t_maxBatchSize: number;\n\t_batchScheduleFn: (cb: () => void) => void;\n\t_cacheKeyFn: (key: K) => C;\n\t_cacheMap: DataLoader.CacheMap<C, Promise<V>> | null;\n\t_batch: Batch<K, V> | null;\n\n\t/**\n\t * Loads a key, returning a `Promise` for the value represented by that key.\n\t */\n\tload(key: K): Promise<V> {\n\t\tif (key === null || key === undefined) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`The loader.load() function must be called with a value, but got: ${String(key)}.`,\n\t\t\t);\n\t\t}\n\n\t\tconst batch = getCurrentBatch(this);\n\t\tconst cacheMap = this._cacheMap;\n\t\tlet cacheKey: C;\n\n\t\t// If caching and there is a cache-hit, return cached Promise.\n\t\tif (cacheMap) {\n\t\t\tcacheKey = this._cacheKeyFn(key);\n\t\t\tconst cachedPromise = cacheMap.get(cacheKey);\n\t\t\tif (cachedPromise) {\n\t\t\t\tconst cacheHits = batch.cacheHits || (batch.cacheHits = []);\n\t\t\t\treturn new Promise((resolve) => {\n\t\t\t\t\tcacheHits.push(() => {\n\t\t\t\t\t\tresolve(cachedPromise);\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise, produce a new Promise for this key, and enqueue it to be\n\t\t// dispatched along with the current batch.\n\t\tbatch.keys.push(key);\n\t\tconst promise = new Promise<V>((resolve, reject) => {\n\t\t\tbatch.callbacks.push({ resolve, reject });\n\t\t});\n\n\t\t// If caching, cache this promise.\n\t\tif (cacheMap) {\n\t\t\tcacheMap.set(cacheKey!, promise);\n\t\t}\n\n\t\treturn promise;\n\t}\n\n\t/**\n\t * Loads multiple keys, promising an array of values:\n\t *\n\t *     var [ a, b ] = await myLoader.loadMany([ 'a', 'b' ]);\n\t *\n\t * This is similar to the more verbose:\n\t *\n\t *     var [ a, b ] = await Promise.all([\n\t *       myLoader.load('a'),\n\t *       myLoader.load('b')\n\t *     ]);\n\t *\n\t * However it is different in the case where any load fails. Where\n\t * Promise.all() would reject, loadMany() always resolves, however each result\n\t * is either a value or an Error instance.\n\t *\n\t *     var [ a, b, c ] = await myLoader.loadMany([ 'a', 'b', 'badkey' ]);\n\t *     // c instanceof Error\n\t *\n\t */\n\tloadMany(keys: ReadonlyArray<K>): Promise<Array<V | Error>> {\n\t\tif (!isArrayLike(keys)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`The loader.loadMany() function must be called with Array<key>, but got: ${keys}.`,\n\t\t\t);\n\t\t}\n\t\t// Support ArrayLike by using only minimal property access\n\t\tconst loadPromises = [];\n\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\tloadPromises.push(this.load(keys[i]).catch((error) => error));\n\t\t}\n\t\treturn Promise.all(loadPromises);\n\t}\n\n\t/**\n\t * Clears the value at `key` from the cache, if it exists. Returns itself for\n\t * method chaining.\n\t */\n\tclear(key: K): this {\n\t\tconst cacheMap = this._cacheMap;\n\t\tif (cacheMap) {\n\t\t\tconst cacheKey = this._cacheKeyFn(key);\n\t\t\tcacheMap.delete(cacheKey);\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Clears the entire cache. To be used when some event results in unknown\n\t * invalidations across this particular `DataLoader`. Returns itself for\n\t * method chaining.\n\t */\n\tclearAll(): this {\n\t\tconst cacheMap = this._cacheMap;\n\t\tif (cacheMap) {\n\t\t\tcacheMap.clear();\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds the provided key and value to the cache. If the key already\n\t * exists, no change is made. Returns itself for method chaining.\n\t *\n\t * To prime the cache with an error at a key, provide an Error instance.\n\t */\n\tprime(key: K, value: V | Promise<V> | Error): this {\n\t\tconst cacheMap = this._cacheMap;\n\t\tif (cacheMap) {\n\t\t\tconst cacheKey = this._cacheKeyFn(key);\n\n\t\t\t// Only add the key if it does not already exist.\n\t\t\tif (cacheMap.get(cacheKey) === undefined) {\n\t\t\t\t// Cache a rejected promise if the value is an Error, in order to match\n\t\t\t\t// the behavior of load(key).\n\t\t\t\tlet promise;\n\t\t\t\tif (value instanceof Error) {\n\t\t\t\t\tpromise = Promise.reject(value);\n\t\t\t\t\t// Since this is a case where an Error is intentionally being primed\n\t\t\t\t\t// for a given key, we want to disable unhandled promise rejection.\n\t\t\t\t\tpromise.catch(() => {});\n\t\t\t\t} else {\n\t\t\t\t\tpromise = Promise.resolve(value);\n\t\t\t\t}\n\t\t\t\tcacheMap.set(cacheKey, promise);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * The name given to this `DataLoader` instance. Useful for APM tools.\n\t *\n\t * Is `null` if not set in the constructor.\n\t */\n\tname: string | null;\n}\n\n// Private: Enqueue a Job to be executed after all \"PromiseJobs\" Jobs.\n//\n// ES6 JavaScript uses the concepts Job and JobQueue to schedule work to occur\n// after the current execution context has completed:\n// http://www.ecma-international.org/ecma-262/6.0/#sec-jobs-and-job-queues\n//\n// Node.js uses the `process.nextTick` mechanism to implement the concept of a\n// Job, maintaining a global FIFO JobQueue for all Jobs, which is flushed after\n// the current call stack ends.\n//\n// When calling `then` on a Promise, it enqueues a Job on a specific\n// \"PromiseJobs\" JobQueue which is flushed in Node as a single Job on the\n// global JobQueue.\n//\n// DataLoader batches all loads which occur in a single frame of execution, but\n// should include in the batch all loads which occur during the flushing of the\n// \"PromiseJobs\" JobQueue after that same execution frame.\n//\n// In order to avoid the DataLoader dispatch Job occuring before \"PromiseJobs\",\n// A Promise Job is created with the sole purpose of enqueuing a global Job,\n// ensuring that it always occurs after \"PromiseJobs\" ends.\n//\n// Node.js's job queue is unique. Browsers do not have an equivalent mechanism\n// for enqueuing a job to be performed after promise microtasks and before the\n// next macrotask. For browser environments, a macrotask is used (via\n// setImmediate or setTimeout) at a potential performance penalty.\nconst enqueuePostPromiseJob: (fn: () => void) => void =\n\t// @ts-ignore\n\ttypeof process === 'object' && typeof process.nextTick === 'function'\n\t\t? function (fn) {\n\t\t\t\tif (!resolvedPromise) {\n\t\t\t\t\tresolvedPromise = Promise.resolve();\n\t\t\t\t}\n\t\t\t\tresolvedPromise.then(() => {\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tprocess.nextTick(fn);\n\t\t\t\t});\n\t\t\t}\n\t\t: // @ts-ignore\n\t\t\ttypeof setImmediate === 'function'\n\t\t\t? function (fn) {\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tsetImmediate(fn);\n\t\t\t\t}\n\t\t\t: function (fn) {\n\t\t\t\t\tsetTimeout(fn);\n\t\t\t\t};\n\n// Private: cached resolved Promise instance\nlet resolvedPromise: Promise<void> | undefined;\n\n// Private: Describes a batch of requests\ntype Batch<K, V> = {\n\thasDispatched: boolean;\n\tkeys: Array<K>;\n\tcallbacks: Array<{\n\t\tresolve: (value: V) => void;\n\t\treject: (error: Error) => void;\n\t}>;\n\tcacheHits?: Array<() => void>;\n};\n\n// Private: Either returns the current batch, or creates and schedules a\n// dispatch of a new batch for the given loader.\nfunction getCurrentBatch<K, V>(loader: DataLoader<K, V, any>): Batch<K, V> {\n\t// If there is an existing batch which has not yet dispatched and is within\n\t// the limit of the batch size, then return it.\n\tconst existingBatch = loader._batch;\n\tif (\n\t\texistingBatch !== null &&\n\t\t!existingBatch.hasDispatched &&\n\t\texistingBatch.keys.length < loader._maxBatchSize\n\t) {\n\t\treturn existingBatch;\n\t}\n\n\t// Otherwise, create a new batch for this loader.\n\tconst newBatch = { hasDispatched: false, keys: [], callbacks: [] };\n\n\t// Store it on the loader so it may be reused.\n\tloader._batch = newBatch;\n\n\t// Then schedule a task to dispatch this batch of requests.\n\tloader._batchScheduleFn(() => {\n\t\tdispatchBatch(loader, newBatch);\n\t});\n\n\treturn newBatch;\n}\n\nfunction dispatchBatch<K, V>(loader: DataLoader<K, V, any>, batch: Batch<K, V>) {\n\t// Mark this batch as having been dispatched.\n\tbatch.hasDispatched = true;\n\n\t// If there's nothing to load, resolve any cache hits and return early.\n\tif (batch.keys.length === 0) {\n\t\tresolveCacheHits(batch);\n\t\treturn;\n\t}\n\n\t// Call the provided batchLoadFn for this loader with the batch's keys and\n\t// with the loader as the `this` context.\n\tlet batchPromise;\n\ttry {\n\t\tbatchPromise = loader._batchLoadFn(batch.keys);\n\t} catch (e) {\n\t\treturn failedDispatch(\n\t\t\tloader,\n\t\t\tbatch,\n\t\t\tnew TypeError(\n\t\t\t\t'DataLoader must be constructed with a function which accepts ' +\n\t\t\t\t\t'Array<key> and returns Promise<Array<value>>, but the function ' +\n\t\t\t\t\t`errored synchronously: ${String(e)}.`,\n\t\t\t),\n\t\t);\n\t}\n\n\t// Assert the expected response from batchLoadFn\n\tif (!batchPromise || typeof batchPromise.then !== 'function') {\n\t\treturn failedDispatch(\n\t\t\tloader,\n\t\t\tbatch,\n\t\t\tnew TypeError(\n\t\t\t\t'DataLoader must be constructed with a function which accepts ' +\n\t\t\t\t\t'Array<key> and returns Promise<Array<value>>, but the function did ' +\n\t\t\t\t\t`not return a Promise: ${String(batchPromise)}.`,\n\t\t\t),\n\t\t);\n\t}\n\n\t// Await the resolution of the call to batchLoadFn.\n\tPromise.resolve(batchPromise)\n\t\t.then((values) => {\n\t\t\t// Assert the expected resolution from batchLoadFn.\n\t\t\tif (!isArrayLike(values)) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'DataLoader must be constructed with a function which accepts ' +\n\t\t\t\t\t\t'Array<key> and returns Promise<Array<value>>, but the function did ' +\n\t\t\t\t\t\t`not return a Promise of an Array: ${String(values)}.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (values.length !== batch.keys.length) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'DataLoader must be constructed with a function which accepts ' +\n\t\t\t\t\t\t'Array<key> and returns Promise<Array<value>>, but the function did ' +\n\t\t\t\t\t\t'not return a Promise of an Array of the same length as the Array ' +\n\t\t\t\t\t\t'of keys.' +\n\t\t\t\t\t\t`\\n\\nKeys:\\n${String(batch.keys)}` +\n\t\t\t\t\t\t`\\n\\nValues:\\n${String(values)}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Resolve all cache hits in the same micro-task as freshly loaded values.\n\t\t\tresolveCacheHits(batch);\n\n\t\t\t// Step through values, resolving or rejecting each Promise in the batch.\n\t\t\tfor (let i = 0; i < batch.callbacks.length; i++) {\n\t\t\t\tconst value = values[i];\n\t\t\t\tif (value instanceof Error) {\n\t\t\t\t\tbatch.callbacks[i].reject(value);\n\t\t\t\t} else {\n\t\t\t\t\tbatch.callbacks[i].resolve(value);\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\t.catch((error: unknown) => {\n\t\t\tfailedDispatch(loader, batch, error as Error);\n\t\t});\n}\n\n// Private: do not cache individual loads if the entire batch dispatch fails,\n// but still reject each request so they do not hang.\nfunction failedDispatch<K, V>(loader: DataLoader<K, V, any>, batch: Batch<K, V>, error: Error) {\n\t// Cache hits are resolved, even though the batch failed.\n\tresolveCacheHits(batch);\n\tfor (let i = 0; i < batch.keys.length; i++) {\n\t\tloader.clear(batch.keys[i]);\n\t\tbatch.callbacks[i].reject(error);\n\t}\n}\n\n// Private: Resolves the Promises for any cache hits in this batch.\nfunction resolveCacheHits(batch: Batch<any, any>) {\n\tif (batch.cacheHits) {\n\t\tfor (let i = 0; i < batch.cacheHits.length; i++) {\n\t\t\tbatch.cacheHits[i]();\n\t\t}\n\t}\n}\n\n// Private: given the DataLoader's options, produce a valid max batch size.\nfunction getValidMaxBatchSize<K, V, C>(options?: DataLoader.Options<K, V, C>): number {\n\tconst shouldBatch = !options || options.batch !== false;\n\tif (!shouldBatch) {\n\t\treturn 1;\n\t}\n\tconst maxBatchSize = options && options.maxBatchSize;\n\tif (maxBatchSize === undefined) {\n\t\treturn Infinity;\n\t}\n\tif (typeof maxBatchSize !== 'number' || maxBatchSize < 1) {\n\t\tthrow new TypeError(`maxBatchSize must be a positive number: ${maxBatchSize}`);\n\t}\n\treturn maxBatchSize;\n}\n\n// Private\nfunction getValidBatchScheduleFn<K, V, C>(\n\toptions?: DataLoader.Options<K, V, C>,\n): (cb: () => void) => void {\n\tconst batchScheduleFn = options && options.batchScheduleFn;\n\tif (batchScheduleFn === undefined) {\n\t\treturn enqueuePostPromiseJob;\n\t}\n\tif (typeof batchScheduleFn !== 'function') {\n\t\tthrow new TypeError(`batchScheduleFn must be a function: ${batchScheduleFn}`);\n\t}\n\treturn batchScheduleFn;\n}\n\n// Private: given the DataLoader's options, produce a cache key function.\nfunction getValidCacheKeyFn<K, V, C>(options?: DataLoader.Options<K, V, C>): (key: K) => C {\n\tconst cacheKeyFn = options && options.cacheKeyFn;\n\tif (cacheKeyFn === undefined) {\n\t\treturn (key: K) => key as unknown as C;\n\t}\n\tif (typeof cacheKeyFn !== 'function') {\n\t\tthrow new TypeError(`cacheKeyFn must be a function: ${cacheKeyFn}`);\n\t}\n\treturn cacheKeyFn;\n}\n\n// Private: given the DataLoader's options, produce a CacheMap to be used.\nfunction getValidCacheMap<K, V, C>(\n\toptions?: DataLoader.Options<K, V, C>,\n): DataLoader.CacheMap<C, Promise<V>> | null {\n\tconst shouldCache = !options || options.cache !== false;\n\tif (!shouldCache) {\n\t\treturn null;\n\t}\n\tconst cacheMap = options && options.cacheMap;\n\tif (cacheMap === undefined) {\n\t\treturn new Map();\n\t}\n\tif (cacheMap !== null) {\n\t\tconst cacheFunctions = ['get', 'set', 'delete', 'clear'] as const;\n\t\tconst missingFunctions = cacheFunctions.filter(\n\t\t\t(fnName) => cacheMap && typeof cacheMap[fnName] !== 'function',\n\t\t);\n\t\tif (missingFunctions.length !== 0) {\n\t\t\tthrow new TypeError('Custom cacheMap missing methods: ' + missingFunctions.join(', '));\n\t\t}\n\t}\n\treturn cacheMap;\n}\n\nfunction getValidName<K, V, C>(options?: DataLoader.Options<K, V, C>): string | null {\n\tif (options && options.name) {\n\t\treturn options.name;\n\t}\n\n\treturn null;\n}\n\nfunction isArrayLike(x: unknown): x is ArrayLike<unknown> {\n\treturn (\n\t\ttypeof x === 'object' &&\n\t\tx !== null &&\n\t\t'length' in x &&\n\t\ttypeof x.length === 'number' &&\n\t\t(x.length === 0 || (x.length > 0 && Object.prototype.hasOwnProperty.call(x, x.length - 1)))\n\t);\n}\n\nexport declare namespace DataLoader {\n\t// If a custom cache is provided, it must be of this type (a subset of ES6 Map).\n\texport type CacheMap<K, V> = {\n\t\tget(key: K): V | void;\n\t\tset(key: K, value: V): any;\n\t\tdelete(key: K): any;\n\t\tclear(): any;\n\t};\n\n\t// A Function, which when given an Array of keys, returns a Promise of an Array\n\t// of values or Errors.\n\texport type BatchLoadFn<K, V> = (keys: ReadonlyArray<K>) => PromiseLike<ArrayLike<V | Error>>;\n\n\t// Optionally turn off batching or caching or provide a cache key function or a\n\t// custom cache instance.\n\texport type Options<K, V, C = K> = {\n\t\t/**\n\t\t * Default `true`. Set to `false` to disable batching, invoking\n\t\t * `batchLoadFn` with a single load key. This is equivalent to setting\n\t\t * `maxBatchSize` to `1`.\n\t\t */\n\t\tbatch?: boolean;\n\n\t\t/**\n\t\t * Default `Infinity`. Limits the number of items that get passed in to the\n\t\t * `batchLoadFn`. May be set to `1` to disable batching.\n\t\t */\n\t\tmaxBatchSize?: number;\n\n\t\t/**\n\t\t * Default see https://github.com/graphql/dataloader#batch-scheduling.\n\t\t * A function to schedule the later execution of a batch. The function is\n\t\t * expected to call the provided callback in the immediate future.\n\t\t */\n\t\tbatchScheduleFn?: (callback: () => void) => void;\n\n\t\t/**\n\t\t * Default `true`. Set to `false` to disable memoization caching, creating a\n\t\t * new Promise and new key in the `batchLoadFn` for every load of the same\n\t\t * key. This is equivalent to setting `cacheMap` to `null`.\n\t\t */\n\t\tcache?: boolean;\n\n\t\t/**\n\t\t * Default `key => key`. Produces cache key for a given load key. Useful\n\t\t * when keys are objects and two objects should be considered equivalent.\n\t\t */\n\t\tcacheKeyFn?: (key: K) => C;\n\n\t\t/**\n\t\t * Default `new Map()`. Instance of `Map` (or an object with a similar API)\n\t\t * to be used as cache. May be set to `null` to disable caching.\n\t\t */\n\t\tcacheMap?: CacheMap<C, Promise<V>> | null;\n\n\t\t/**\n\t\t * The name given to this `DataLoader` instance. Useful for APM tools.\n\t\t *\n\t\t * Is `null` if not set in the constructor.\n\t\t */\n\t\tname?: string | null;\n\t};\n}\n"],"mappings":"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"}