{"version":3,"sources":["../../src/slot.ts","../../src/context.ts","../../src/cache.ts","../../src/helpers.ts","../../src/entry.ts","../../src/dep.ts","../../src/index.ts"],"names":["currentContext","MISSING_VALUE","idCounter","globalKey","host","Array","Slot","id","Date","now","Math","random","toString","slice","join","hasValue","parent","this","slots","value","getValue","withValue","callback","args","thisArg","__proto__","apply","bind","context","saved","arguments","noContext","Object","defineProperty","enumerable","writable","configurable","defaultDispose","max","dispose","map","Map","newest","oldest","has","key","get","node","getNode","older","newer","set","clean","size","delete","parentEntrySlot","prototype","toArray","collection","array","forEach","item","push","maybeUnsubscribe","entryOrDep","unsubscribe","emptySetPool","assert","condition","optionalMessage","Error","valueGet","length","fn","parents","Set","childValues","dirtyChildren","dirty","recomputing","deps","Entry","count","peek","mightBeDirty","rememberParent","recompute","entry","forgetChildren","recomputeNewValue","subscribe","e","setDirty","maybeSubscribe","reportClean","setClean","reallyRecompute","reportDirty","eachParent","child","forgetChild","forget","dependOn","dep","add","pop","forgetDeps","clear","reportDirtyChild","reportCleanChild","parentCount","i","parentWasClean","childValue","a","b","len","valueIs","removeDirtyChild","dc","_value","EntryMethods","options","depsByKey","depend","entryMethodName","call","makeDefaultMakeCacheKeyFunction","keyTrie","WeakMap","lookupArray","caches","wrap","originalFunction","create","cache","Cache","pow","keyArgs","makeCacheKey","optimistic","dirtyKey","peekKey","forgetKey","getKey","freeze"],"mappings":"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","file":"static/js/optimism.a5427703.chunk.js","sourcesContent":["type Context = {\n parent: Context | null;\n slots: { [slotId: string]: any };\n}\n\n// This currentContext variable will only be used if the makeSlotClass\n// function is called, which happens only if this is the first copy of the\n// @wry/context package to be imported.\nlet currentContext: Context | null = null;\n\n// This unique internal object is used to denote the absence of a value\n// for a given Slot, and is never exposed to outside code.\nconst MISSING_VALUE: any = {};\n\nlet idCounter = 1;\n\n// Although we can't do anything about the cost of duplicated code from\n// accidentally bundling multiple copies of the @wry/context package, we can\n// avoid creating the Slot class more than once using makeSlotClass.\nconst makeSlotClass = () => class Slot {\n // If you have a Slot object, you can find out its slot.id, but you cannot\n // guess the slot.id of a Slot you don't have access to, thanks to the\n // randomized suffix.\n public readonly id = [\n \"slot\",\n idCounter++,\n Date.now(),\n Math.random().toString(36).slice(2),\n ].join(\":\");\n\n public hasValue() {\n for (let context = currentContext; context; context = context.parent) {\n // We use the Slot object iself as a key to its value, which means the\n // value cannot be obtained without a reference to the Slot object.\n if (this.id in context.slots) {\n const value = context.slots[this.id];\n if (value === MISSING_VALUE) break;\n if (context !== currentContext) {\n // Cache the value in currentContext.slots so the next lookup will\n // be faster. This caching is safe because the tree of contexts and\n // the values of the slots are logically immutable.\n currentContext!.slots[this.id] = value;\n }\n return true;\n }\n }\n if (currentContext) {\n // If a value was not found for this Slot, it's never going to be found\n // no matter how many times we look it up, so we might as well cache\n // the absence of the value, too.\n currentContext.slots[this.id] = MISSING_VALUE;\n }\n return false;\n }\n\n public getValue(): TValue | undefined {\n if (this.hasValue()) {\n return currentContext!.slots[this.id] as TValue;\n }\n }\n\n public withValue(\n value: TValue,\n callback: (this: TThis, ...args: TArgs) => TResult,\n // Given the prevalence of arrow functions, specifying arguments is likely\n // to be much more common than specifying `this`, hence this ordering:\n args?: TArgs,\n thisArg?: TThis,\n ): TResult {\n const slots = {\n __proto__: null,\n [this.id]: value,\n };\n const parent = currentContext;\n currentContext = { parent, slots };\n try {\n // Function.prototype.apply allows the arguments array argument to be\n // omitted or undefined, so args! is fine here.\n return callback.apply(thisArg!, args!);\n } finally {\n currentContext = parent;\n }\n }\n\n // Capture the current context and wrap a callback function so that it\n // reestablishes the captured context when called.\n static bind(\n callback: (this: TThis, ...args: TArgs) => TResult,\n ) {\n const context = currentContext;\n return function (this: TThis) {\n const saved = currentContext;\n try {\n currentContext = context;\n return callback.apply(this, arguments as any);\n } finally {\n currentContext = saved;\n }\n } as typeof callback;\n }\n\n // Immediately run a callback function without any captured context.\n static noContext(\n callback: (this: TThis, ...args: TArgs) => TResult,\n // Given the prevalence of arrow functions, specifying arguments is likely\n // to be much more common than specifying `this`, hence this ordering:\n args?: TArgs,\n thisArg?: TThis,\n ) {\n if (currentContext) {\n const saved = currentContext;\n try {\n currentContext = null;\n // Function.prototype.apply allows the arguments array argument to be\n // omitted or undefined, so args! is fine here.\n return callback.apply(thisArg!, args!);\n } finally {\n currentContext = saved;\n }\n } else {\n return callback.apply(thisArg!, args!);\n }\n }\n};\n\n// We store a single global implementation of the Slot class as a permanent\n// non-enumerable symbol property of the Array constructor. This obfuscation\n// does nothing to prevent access to the Slot class, but at least it ensures\n// the implementation (i.e. currentContext) cannot be tampered with, and all\n// copies of the @wry/context package (hopefully just one) will share the\n// same Slot implementation. Since the first copy of the @wry/context package\n// to be imported wins, this technique imposes a very high cost for any\n// future breaking changes to the Slot class.\nconst globalKey = \"@wry/context:Slot\";\nconst host = Array as any;\n\nexport const Slot: ReturnType = host[globalKey] || function () {\n const Slot = makeSlotClass();\n try {\n Object.defineProperty(host, globalKey, {\n value: host[globalKey] = Slot,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n } finally {\n return Slot;\n }\n}();\n","import { AnyEntry } from \"./entry\";\nimport { Slot } from \"@wry/context\";\n\nexport const parentEntrySlot = new Slot();\n\nexport {\n bind as bindContext,\n noContext,\n setTimeout,\n asyncFromGen,\n} from \"@wry/context\";\n","interface Node {\n key: K;\n value: V;\n newer: Node | null;\n older: Node | null;\n}\n\nfunction defaultDispose() {}\n\nexport class Cache {\n private map = new Map>();\n private newest: Node | null = null;\n private oldest: Node | null = null;\n\n constructor(\n private max = Infinity,\n public dispose: (value: V, key: K) => void = defaultDispose,\n ) {}\n\n public has(key: K): boolean {\n return this.map.has(key);\n }\n\n public get(key: K): V | undefined {\n const node = this.getNode(key);\n return node && node.value;\n }\n\n private getNode(key: K): Node | undefined {\n const node = this.map.get(key);\n\n if (node && node !== this.newest) {\n const { older, newer } = node;\n\n if (newer) {\n newer.older = older;\n }\n\n if (older) {\n older.newer = newer;\n }\n\n node.older = this.newest;\n node.older!.newer = node;\n\n node.newer = null;\n this.newest = node;\n\n if (node === this.oldest) {\n this.oldest = newer;\n }\n }\n\n return node;\n }\n\n public set(key: K, value: V): V {\n let node = this.getNode(key);\n if (node) {\n return node.value = value;\n }\n\n node = {\n key,\n value,\n newer: null,\n older: this.newest\n };\n\n if (this.newest) {\n this.newest.newer = node;\n }\n\n this.newest = node;\n this.oldest = this.oldest || node;\n\n this.map.set(key, node);\n\n return node.value;\n }\n\n public clean() {\n while (this.oldest && this.map.size > this.max) {\n this.delete(this.oldest.key);\n }\n }\n\n public delete(key: K): boolean {\n const node = this.map.get(key);\n if (node) {\n if (node === this.newest) {\n this.newest = node.older;\n }\n\n if (node === this.oldest) {\n this.oldest = node.newer;\n }\n\n if (node.newer) {\n node.newer.older = node.older;\n }\n\n if (node.older) {\n node.older.newer = node.newer;\n }\n\n this.map.delete(key);\n this.dispose(node.value, key);\n\n return true;\n }\n\n return false;\n }\n}\n","export const {\n hasOwnProperty,\n} = Object.prototype;\n\nexport const {\n // This Array.from polyfill is restricted to working with Set for now,\n // but we can improve the polyfill and add other input types, as needed. Note\n // that this fallback implementation will only be used if the host environment\n // does not support a native Array.from function. In most modern JS runtimes,\n // the toArray function exported here will be === Array.from.\n from: toArray = (collection: Set) => {\n const array: any[] = [];\n collection.forEach(item => array.push(item));\n return array;\n },\n} = Array;\n\nexport type Unsubscribable = {\n unsubscribe?: void | (() => any);\n}\n\nexport function maybeUnsubscribe(entryOrDep: Unsubscribable) {\n const { unsubscribe } = entryOrDep;\n if (typeof unsubscribe === \"function\") {\n entryOrDep.unsubscribe = void 0;\n unsubscribe();\n }\n}\n","import { parentEntrySlot } from \"./context\";\nimport { OptimisticWrapOptions } from \"./index\";\nimport { Dep } from \"./dep\";\nimport { maybeUnsubscribe, toArray, Unsubscribable } from \"./helpers\";\n\nconst emptySetPool: Set[] = [];\nconst POOL_TARGET_SIZE = 100;\n\n// Since this package might be used browsers, we should avoid using the\n// Node built-in assert module.\nfunction assert(condition: any, optionalMessage?: string) {\n if (! condition) {\n throw new Error(optionalMessage || \"assertion failure\");\n }\n}\n\n// Since exceptions are cached just like normal values, we need an efficient\n// way of representing unknown, ordinary, and exceptional values.\ntype Value =\n | [] // unknown\n | [T] // known value\n | [void, any]; // known exception\n\nfunction valueIs(a: Value, b: Value) {\n const len = a.length;\n return (\n // Unknown values are not equal to each other.\n len > 0 &&\n // Both values must be ordinary (or both exceptional) to be equal.\n len === b.length &&\n // The underlying value or exception must be the same.\n a[len - 1] === b[len - 1]\n );\n}\n\nfunction valueGet(value: Value): T {\n switch (value.length) {\n case 0: throw new Error(\"unknown value\");\n case 1: return value[0];\n case 2: throw value[1];\n }\n}\n\nfunction valueCopy(value: Value): Value {\n return value.slice(0) as Value;\n}\n\nexport type AnyEntry = Entry;\n\nexport class Entry {\n public static count = 0;\n\n public subscribe: OptimisticWrapOptions[\"subscribe\"];\n public unsubscribe: Unsubscribable[\"unsubscribe\"];\n\n public readonly parents = new Set();\n public readonly childValues = new Map>();\n\n // When this Entry has children that are dirty, this property becomes\n // a Set containing other Entry objects, borrowed from emptySetPool.\n // When the set becomes empty, it gets recycled back to emptySetPool.\n public dirtyChildren: Set | null = null;\n\n public dirty = true;\n public recomputing = false;\n public readonly value: Value = [];\n\n constructor(\n public readonly fn: (...args: TArgs) => TValue,\n ) {\n ++Entry.count;\n }\n\n public peek(): TValue | undefined {\n if (this.value.length === 1 && !mightBeDirty(this)) {\n rememberParent(this);\n return this.value[0];\n }\n }\n\n // This is the most important method of the Entry API, because it\n // determines whether the cached this.value can be returned immediately,\n // or must be recomputed. The overall performance of the caching system\n // depends on the truth of the following observations: (1) this.dirty is\n // usually false, (2) this.dirtyChildren is usually null/empty, and thus\n // (3) valueGet(this.value) is usually returned without recomputation.\n public recompute(args: TArgs): TValue {\n assert(! this.recomputing, \"already recomputing\");\n rememberParent(this);\n return mightBeDirty(this)\n ? reallyRecompute(this, args)\n : valueGet(this.value);\n }\n\n public setDirty() {\n if (this.dirty) return;\n this.dirty = true;\n this.value.length = 0;\n reportDirty(this);\n // We can go ahead and unsubscribe here, since any further dirty\n // notifications we receive will be redundant, and unsubscribing may\n // free up some resources, e.g. file watchers.\n maybeUnsubscribe(this);\n }\n\n public dispose() {\n this.setDirty();\n\n // Sever any dependency relationships with our own children, so those\n // children don't retain this parent Entry in their child.parents sets,\n // thereby preventing it from being fully garbage collected.\n forgetChildren(this);\n\n // Because this entry has been kicked out of the cache (in index.js),\n // we've lost the ability to find out if/when this entry becomes dirty,\n // whether that happens through a subscription, because of a direct call\n // to entry.setDirty(), or because one of its children becomes dirty.\n // Because of this loss of future information, we have to assume the\n // worst (that this entry might have become dirty very soon), so we must\n // immediately mark this entry's parents as dirty. Normally we could\n // just call entry.setDirty() rather than calling parent.setDirty() for\n // each parent, but that would leave this entry in parent.childValues\n // and parent.dirtyChildren, which would prevent the child from being\n // truly forgotten.\n eachParent(this, (parent, child) => {\n parent.setDirty();\n forgetChild(parent, this);\n });\n }\n\n public forget() {\n // The code that creates Entry objects in index.ts will replace this method\n // with one that actually removes the Entry from the cache, which will also\n // trigger the entry.dispose method.\n this.dispose();\n }\n\n private deps: Set> | null = null;\n\n public dependOn(dep: Dep) {\n dep.add(this);\n if (! this.deps) {\n this.deps = emptySetPool.pop() || new Set>();\n }\n this.deps.add(dep);\n }\n\n public forgetDeps() {\n if (this.deps) {\n toArray(this.deps).forEach(dep => dep.delete(this));\n this.deps.clear();\n emptySetPool.push(this.deps);\n this.deps = null;\n }\n }\n}\n\nfunction rememberParent(child: AnyEntry) {\n const parent = parentEntrySlot.getValue();\n if (parent) {\n child.parents.add(parent);\n\n if (! parent.childValues.has(child)) {\n parent.childValues.set(child, []);\n }\n\n if (mightBeDirty(child)) {\n reportDirtyChild(parent, child);\n } else {\n reportCleanChild(parent, child);\n }\n\n return parent;\n }\n}\n\nfunction reallyRecompute(entry: AnyEntry, args: any[]) {\n forgetChildren(entry);\n\n // Set entry as the parent entry while calling recomputeNewValue(entry).\n parentEntrySlot.withValue(entry, recomputeNewValue, [entry, args]);\n\n if (maybeSubscribe(entry, args)) {\n // If we successfully recomputed entry.value and did not fail to\n // (re)subscribe, then this Entry is no longer explicitly dirty.\n setClean(entry);\n }\n\n return valueGet(entry.value);\n}\n\nfunction recomputeNewValue(entry: AnyEntry, args: any[]) {\n entry.recomputing = true;\n // Set entry.value as unknown.\n entry.value.length = 0;\n try {\n // If entry.fn succeeds, entry.value will become a normal Value.\n entry.value[0] = entry.fn.apply(null, args);\n } catch (e) {\n // If entry.fn throws, entry.value will become exceptional.\n entry.value[1] = e;\n }\n // Either way, this line is always reached.\n entry.recomputing = false;\n}\n\nfunction mightBeDirty(entry: AnyEntry) {\n return entry.dirty || !!(entry.dirtyChildren && entry.dirtyChildren.size);\n}\n\nfunction setClean(entry: AnyEntry) {\n entry.dirty = false;\n\n if (mightBeDirty(entry)) {\n // This Entry may still have dirty children, in which case we can't\n // let our parents know we're clean just yet.\n return;\n }\n\n reportClean(entry);\n}\n\nfunction reportDirty(child: AnyEntry) {\n eachParent(child, reportDirtyChild);\n}\n\nfunction reportClean(child: AnyEntry) {\n eachParent(child, reportCleanChild);\n}\n\nfunction eachParent(\n child: AnyEntry,\n callback: (parent: AnyEntry, child: AnyEntry) => any,\n) {\n const parentCount = child.parents.size;\n if (parentCount) {\n const parents = toArray(child.parents);\n for (let i = 0; i < parentCount; ++i) {\n callback(parents[i], child);\n }\n }\n}\n\n// Let a parent Entry know that one of its children may be dirty.\nfunction reportDirtyChild(parent: AnyEntry, child: AnyEntry) {\n // Must have called rememberParent(child) before calling\n // reportDirtyChild(parent, child).\n assert(parent.childValues.has(child));\n assert(mightBeDirty(child));\n const parentWasClean = !mightBeDirty(parent);\n\n if (! parent.dirtyChildren) {\n parent.dirtyChildren = emptySetPool.pop() || new Set;\n\n } else if (parent.dirtyChildren.has(child)) {\n // If we already know this child is dirty, then we must have already\n // informed our own parents that we are dirty, so we can terminate\n // the recursion early.\n return;\n }\n\n parent.dirtyChildren.add(child);\n\n // If parent was clean before, it just became (possibly) dirty (according to\n // mightBeDirty), since we just added child to parent.dirtyChildren.\n if (parentWasClean) {\n reportDirty(parent);\n }\n}\n\n// Let a parent Entry know that one of its children is no longer dirty.\nfunction reportCleanChild(parent: AnyEntry, child: AnyEntry) {\n // Must have called rememberChild(child) before calling\n // reportCleanChild(parent, child).\n assert(parent.childValues.has(child));\n assert(! mightBeDirty(child));\n\n const childValue = parent.childValues.get(child)!;\n if (childValue.length === 0) {\n parent.childValues.set(child, valueCopy(child.value));\n } else if (! valueIs(childValue, child.value)) {\n parent.setDirty();\n }\n\n removeDirtyChild(parent, child);\n\n if (mightBeDirty(parent)) {\n return;\n }\n\n reportClean(parent);\n}\n\nfunction removeDirtyChild(parent: AnyEntry, child: AnyEntry) {\n const dc = parent.dirtyChildren;\n if (dc) {\n dc.delete(child);\n if (dc.size === 0) {\n if (emptySetPool.length < POOL_TARGET_SIZE) {\n emptySetPool.push(dc);\n }\n parent.dirtyChildren = null;\n }\n }\n}\n\n// Removes all children from this entry and returns an array of the\n// removed children.\nfunction forgetChildren(parent: AnyEntry) {\n if (parent.childValues.size > 0) {\n parent.childValues.forEach((_value, child) => {\n forgetChild(parent, child);\n });\n }\n\n // Remove this parent Entry from any sets to which it was added by the\n // addToSet method.\n parent.forgetDeps();\n\n // After we forget all our children, this.dirtyChildren must be empty\n // and therefore must have been reset to null.\n assert(parent.dirtyChildren === null);\n}\n\nfunction forgetChild(parent: AnyEntry, child: AnyEntry) {\n child.parents.delete(parent);\n parent.childValues.delete(child);\n removeDirtyChild(parent, child);\n}\n\nfunction maybeSubscribe(entry: AnyEntry, args: any[]) {\n if (typeof entry.subscribe === \"function\") {\n try {\n maybeUnsubscribe(entry); // Prevent double subscriptions.\n entry.unsubscribe = entry.subscribe.apply(null, args);\n } catch (e) {\n // If this Entry has a subscribe function and it threw an exception\n // (or an unsubscribe function it previously returned now throws),\n // return false to indicate that we were not able to subscribe (or\n // unsubscribe), and this Entry should remain dirty.\n entry.setDirty();\n return false;\n }\n }\n\n // Returning true indicates either that there was no entry.subscribe\n // function or that it succeeded.\n return true;\n}\n","import { AnyEntry } from \"./entry\";\nimport { OptimisticWrapOptions } from \"./index\";\nimport { parentEntrySlot } from \"./context\";\nimport { hasOwnProperty, Unsubscribable, maybeUnsubscribe, toArray } from \"./helpers\";\n\ntype EntryMethodName = keyof typeof EntryMethods;\nconst EntryMethods = {\n setDirty: true, // Mark parent Entry as needing to be recomputed (default)\n dispose: true, // Detach parent Entry from parents and children, but leave in LRU cache\n forget: true, // Fully remove parent Entry from LRU cache and computation graph\n};\n\nexport type OptimisticDependencyFunction =\n ((key: TKey) => void) & {\n dirty: (key: TKey, entryMethodName?: EntryMethodName) => void;\n };\n\nexport type Dep = Set & {\n subscribe: OptimisticWrapOptions<[TKey]>[\"subscribe\"];\n} & Unsubscribable;\n\nexport function dep(options?: {\n subscribe: Dep[\"subscribe\"];\n}) {\n const depsByKey = new Map>();\n const subscribe = options && options.subscribe;\n\n function depend(key: TKey) {\n const parent = parentEntrySlot.getValue();\n if (parent) {\n let dep = depsByKey.get(key);\n if (!dep) {\n depsByKey.set(key, dep = new Set as Dep);\n }\n parent.dependOn(dep);\n if (typeof subscribe === \"function\") {\n maybeUnsubscribe(dep);\n dep.unsubscribe = subscribe(key);\n }\n }\n }\n\n depend.dirty = function dirty(\n key: TKey,\n entryMethodName?: EntryMethodName,\n ) {\n const dep = depsByKey.get(key);\n if (dep) {\n const m: EntryMethodName = (\n entryMethodName &&\n hasOwnProperty.call(EntryMethods, entryMethodName)\n ) ? entryMethodName : \"setDirty\";\n // We have to use toArray(dep).forEach instead of dep.forEach, because\n // modifying a Set while iterating over it can cause elements in the Set\n // to be removed from the Set before they've been iterated over.\n toArray(dep).forEach(entry => entry[m]());\n depsByKey.delete(key);\n maybeUnsubscribe(dep);\n }\n };\n\n return depend as OptimisticDependencyFunction;\n}\n","import { Trie } from \"@wry/trie\";\n\nimport { Cache } from \"./cache\";\nimport { Entry, AnyEntry } from \"./entry\";\nimport { parentEntrySlot } from \"./context\";\n\n// These helper functions are important for making optimism work with\n// asynchronous code. In order to register parent-child dependencies,\n// optimism needs to know about any currently active parent computations.\n// In ordinary synchronous code, the parent context is implicit in the\n// execution stack, but asynchronous code requires some extra guidance in\n// order to propagate context from one async task segment to the next.\nexport {\n bindContext,\n noContext,\n setTimeout,\n asyncFromGen,\n} from \"./context\";\n\n// A lighter-weight dependency, similar to OptimisticWrapperFunction, except\n// with only one argument, no makeCacheKey, no wrapped function to recompute,\n// and no result value. Useful for representing dependency leaves in the graph\n// of computation. Subscriptions are supported.\nexport { dep, OptimisticDependencyFunction } from \"./dep\";\n\nfunction makeDefaultMakeCacheKeyFunction<\n TKeyArgs extends any[],\n TCacheKey = any,\n>(): (...args: TKeyArgs) => TCacheKey {\n const keyTrie = new Trie(typeof WeakMap === \"function\");\n return function () {\n return keyTrie.lookupArray(arguments);\n };\n}\n\n// The defaultMakeCacheKey function is remarkably powerful, because it gives\n// a unique object for any shallow-identical list of arguments. If you need\n// to implement a custom makeCacheKey function, you may find it helpful to\n// delegate the final work to defaultMakeCacheKey, which is why we export it\n// here. However, you may want to avoid defaultMakeCacheKey if your runtime\n// does not support WeakMap, or you have the ability to return a string key.\n// In those cases, just write your own custom makeCacheKey functions.\nexport const defaultMakeCacheKey = makeDefaultMakeCacheKeyFunction();\n\n// If you're paranoid about memory leaks, or you want to avoid using WeakMap\n// under the hood, but you still need the behavior of defaultMakeCacheKey,\n// import this constructor to create your own tries.\nexport { Trie as KeyTrie }\n\nexport type OptimisticWrapperFunction<\n TArgs extends any[],\n TResult,\n TKeyArgs extends any[] = TArgs,\n TCacheKey = any,\n> = ((...args: TArgs) => TResult) & {\n // Get the current number of Entry objects in the LRU cache.\n readonly size: number;\n\n // \"Dirty\" any cached Entry stored for the given arguments, marking that Entry\n // and its ancestors as potentially needing to be recomputed. The .dirty(...)\n // method of an optimistic function takes the same parameter types as the\n // original function by default, unless a keyArgs function is configured, and\n // then it matters that .dirty takes TKeyArgs instead of TArgs.\n dirty: (...args: TKeyArgs) => void;\n // A version of .dirty that accepts a key returned by .getKey.\n dirtyKey: (key: TCacheKey) => void;\n\n // Examine the current value without recomputing it.\n peek: (...args: TKeyArgs) => TResult | undefined;\n // A version of .peek that accepts a key returned by .getKey.\n peekKey: (key: TCacheKey) => TResult | undefined;\n\n // Completely remove the entry from the cache, dirtying any parent entries.\n forget: (...args: TKeyArgs) => boolean;\n // A version of .forget that accepts a key returned by .getKey.\n forgetKey: (key: TCacheKey) => boolean;\n\n // In order to use the -Key version of the above functions, you need a key\n // rather than the arguments used to compute the key. These two functions take\n // TArgs or TKeyArgs and return the corresponding TCacheKey. If no keyArgs\n // function has been configured, TArgs will be the same as TKeyArgs, and thus\n // getKey and makeCacheKey will be synonymous.\n getKey: (...args: TArgs) => TCacheKey;\n\n // This property is equivalent to the makeCacheKey function provided in the\n // OptimisticWrapOptions, or (if no options.makeCacheKey function is provided)\n // a default implementation of makeCacheKey.\n makeCacheKey: (...args: TKeyArgs) => TCacheKey;\n};\n\nexport type OptimisticWrapOptions<\n TArgs extends any[],\n TKeyArgs extends any[] = TArgs,\n TCacheKey = any,\n> = {\n // The maximum number of cache entries that should be retained before the\n // cache begins evicting the oldest ones.\n max?: number;\n // Transform the raw arguments to some other type of array, which will then\n // be passed to makeCacheKey.\n keyArgs?: (...args: TArgs) => TKeyArgs;\n // The makeCacheKey function takes the same arguments that were passed to\n // the wrapper function and returns a single value that can be used as a key\n // in a Map to identify the cached result.\n makeCacheKey?: (...args: TKeyArgs) => TCacheKey;\n // If provided, the subscribe function should either return an unsubscribe\n // function or return nothing.\n subscribe?: (...args: TArgs) => void | (() => any);\n};\n\nconst caches = new Set>();\n\nexport function wrap<\n TArgs extends any[],\n TResult,\n TKeyArgs extends any[] = TArgs,\n TCacheKey = any,\n>(\n originalFunction: (...args: TArgs) => TResult,\n options: OptimisticWrapOptions = Object.create(null),\n) {\n const cache = new Cache>(\n options.max || Math.pow(2, 16),\n entry => entry.dispose(),\n );\n\n const keyArgs = options.keyArgs;\n const makeCacheKey = options.makeCacheKey ||\n makeDefaultMakeCacheKeyFunction();\n\n const optimistic = function (): TResult {\n const key = makeCacheKey.apply(\n null,\n keyArgs ? keyArgs.apply(null, arguments as any) : arguments as any\n );\n\n if (key === void 0) {\n return originalFunction.apply(null, arguments as any);\n }\n\n let entry = cache.get(key)!;\n if (!entry) {\n cache.set(key, entry = new Entry(originalFunction));\n entry.subscribe = options.subscribe;\n // Give the Entry the ability to trigger cache.delete(key), even though\n // the Entry itself does not know about key or cache.\n entry.forget = () => cache.delete(key);\n }\n\n const value = entry.recompute(\n Array.prototype.slice.call(arguments) as TArgs,\n );\n\n // Move this entry to the front of the least-recently used queue,\n // since we just finished computing its value.\n cache.set(key, entry);\n\n caches.add(cache);\n\n // Clean up any excess entries in the cache, but only if there is no\n // active parent entry, meaning we're not in the middle of a larger\n // computation that might be flummoxed by the cleaning.\n if (! parentEntrySlot.hasValue()) {\n caches.forEach(cache => cache.clean());\n caches.clear();\n }\n\n return value;\n } as OptimisticWrapperFunction;\n\n Object.defineProperty(optimistic, \"size\", {\n get() {\n return cache[\"map\"].size;\n },\n configurable: false,\n enumerable: false,\n });\n\n function dirtyKey(key: TCacheKey) {\n const entry = cache.get(key);\n if (entry) {\n entry.setDirty();\n }\n }\n optimistic.dirtyKey = dirtyKey;\n optimistic.dirty = function dirty() {\n dirtyKey(makeCacheKey.apply(null, arguments as any));\n };\n\n function peekKey(key: TCacheKey) {\n const entry = cache.get(key);\n if (entry) {\n return entry.peek();\n }\n }\n optimistic.peekKey = peekKey;\n optimistic.peek = function peek() {\n return peekKey(makeCacheKey.apply(null, arguments as any));\n };\n\n function forgetKey(key: TCacheKey) {\n return cache.delete(key);\n }\n optimistic.forgetKey = forgetKey;\n optimistic.forget = function forget() {\n return forgetKey(makeCacheKey.apply(null, arguments as any));\n };\n\n optimistic.makeCacheKey = makeCacheKey;\n optimistic.getKey = keyArgs ? function getKey() {\n return makeCacheKey.apply(null, keyArgs.apply(null, arguments as any));\n } : makeCacheKey as (...args: any[]) => TCacheKey;\n\n return Object.freeze(optimistic);\n}\n"],"sourceRoot":""}