diff --git a/packages/babel-core/src/config/caching.js b/packages/babel-core/src/config/caching.js index fa071dbbe8..47414fbc68 100644 --- a/packages/babel-core/src/config/caching.js +++ b/packages/babel-core/src/config/caching.js @@ -14,15 +14,19 @@ type SimpleCacheConfiguratorObj = { invalidate: (handler: () => T) => T, }; -type CacheEntry = Array<[ResultT, () => boolean]>; +type CacheEntry = Array< + [ResultT, (SideChannel) => boolean], +>; + +export type { CacheConfigurator }; /** * Given a function with a single argument, cache its results based on its argument and how it * configures its caching behavior. Cached values are stored strongly. */ -export function makeStrongCache( - handler: (ArgT, CacheConfigurator) => ResultT, -): ArgT => ResultT { +export function makeStrongCache( + handler: (ArgT, CacheConfigurator) => ResultT, +): (ArgT, SideChannel) => ResultT { return makeCachedFunction(new Map(), handler); } @@ -31,30 +35,41 @@ export function makeStrongCache( * configures its caching behavior. Cached values are stored weakly and the function argument must be * an object type. */ -export function makeWeakCache | $ReadOnlyArray<*>, ResultT>( - handler: (ArgT, CacheConfigurator) => ResultT, -): ArgT => ResultT { +export function makeWeakCache< + ArgT: {} | Array<*> | $ReadOnlyArray<*>, + ResultT, + SideChannel, +>( + handler: (ArgT, CacheConfigurator) => ResultT, +): (ArgT, SideChannel) => ResultT { return makeCachedFunction(new WeakMap(), handler); } -type CacheMap = - | Map> - | WeakMap>; +type CacheMap = + | Map> + | WeakMap>; -function makeCachedFunction>( +function makeCachedFunction< + ArgT, + ResultT, + SideChannel, + Cache: CacheMap, +>( callCache: Cache, - handler: (ArgT, CacheConfigurator) => ResultT, -): ArgT => ResultT { - return function cachedFunction(arg) { - let cachedValue: CacheEntry | void = callCache.get(arg); + handler: (ArgT, CacheConfigurator) => ResultT, +): (ArgT, SideChannel) => ResultT { + return function cachedFunction(arg, data) { + let cachedValue: CacheEntry | void = callCache.get( + arg, + ); if (cachedValue) { for (const [value, valid] of cachedValue) { - if (valid()) return value; + if (valid(data)) return value; } } - const cache = new CacheConfigurator(); + const cache = new CacheConfigurator(data); const value = handler(arg, cache); @@ -84,7 +99,7 @@ function makeCachedFunction>( }; } -class CacheConfigurator { +class CacheConfigurator { _active: boolean = true; _never: boolean = false; _forever: boolean = false; @@ -92,7 +107,13 @@ class CacheConfigurator { _configured: boolean = false; - _pairs: Array<[mixed, () => mixed]> = []; + _pairs: Array<[mixed, (SideChannel) => mixed]> = []; + + _data: SideChannel; + + constructor(data: SideChannel) { + this._data = data; + } simple() { return makeSimpleConfigurator(this); @@ -127,7 +148,7 @@ class CacheConfigurator { this._configured = true; } - using(handler: () => T): T { + using(handler: SideChannel => T): T { if (!this._active) { throw new Error("Cannot change caching after evaluation has completed."); } @@ -138,12 +159,12 @@ class CacheConfigurator { } this._configured = true; - const key = handler(); + const key = handler(this._data); this._pairs.push([key, handler]); return key; } - invalidate(handler: () => T): T { + invalidate(handler: SideChannel => T): T { if (!this._active) { throw new Error("Cannot change caching after evaluation has completed."); } @@ -155,14 +176,14 @@ class CacheConfigurator { this._invalidate = true; this._configured = true; - const key = handler(); + const key = handler(this._data); this._pairs.push([key, handler]); return key; } - validator(): () => boolean { + validator(): SideChannel => boolean { const pairs = this._pairs; - return () => pairs.every(([key, fn]) => key === fn()); + return (data: SideChannel) => pairs.every(([key, fn]) => key === fn(data)); } deactivate() { @@ -175,7 +196,7 @@ class CacheConfigurator { } function makeSimpleConfigurator( - cache: CacheConfigurator, + cache: CacheConfigurator, ): SimpleCacheConfigurator { function cacheFn(val) { if (typeof val === "boolean") { @@ -188,8 +209,8 @@ function makeSimpleConfigurator( } cacheFn.forever = () => cache.forever(); cacheFn.never = () => cache.never(); - cacheFn.using = cb => cache.using(cb); - cacheFn.invalidate = cb => cache.invalidate(cb); + cacheFn.using = cb => cache.using(() => cb()); + cacheFn.invalidate = cb => cache.invalidate(() => cb()); return (cacheFn: any); }