/**
 * A higher-order function to conditionally cache the results of function calls.
 * The underlying function dictates whether its return value should be cached,
 * signaling so by wrapping the value in either a fulfilled or rejected promise.
 *
 * @param {Object} options
 *        Options for an LRU cache object from 'lru-cache'.
 * @param {Function} fn
 *        A unary, promise-returning function.
 * @return {Function}
 *        A version of `fn` which consults an LRU cache before invoking `fn`; call this
 *        the "cached function".
 *
 *        The promise returned by the cached function fulfills if either
 *          a) cache hit, or
 *          b) cache miss + successful cache refresh.
 *        Rejects otherwise, in the case of a cache miss + failed refreshing attempt.
 *
 *        When a cache miss occurs, `fn` is
 *        called (synchronously), and its return value is cached if and only if it
 *        fulfills. If a cache miss occurs and `fn(key)` rejects, the promise returned
 *        by the cached function rejects with the same value; the cached function has
 *        no built-in facility for retrying.
 *
 *        The underlying `fn` is invoked once for every cache miss. If it's likely that
 *        the cached function may be called many times in quick succession with the
 *        same value, ensure `fn` behaves as you want it to. `utils.batch_concurrent`
 *        may be of use to you here.
 *
 *        Promises returned from this function bear a "cache access ID", the value
 *        on their Symbol(CacheAccessId) property. This is so that callers need not
 *        be aware that they're calling a cached function, but _can_ still get
 *        information about the cache access (like whether it was a hit or not).
 *
 *        This function has a property, Symbol(CacheAccesses), on which that metadata
 *        about cache accesses is stored. This metadata store is a WeakMap keyed on
 *        the cache access IDs above. E.g.,
 *          const result = cachedFn('myKey');
 *          const cacheAccessId = result[CacheAccessId];
 *          await result;
 *          const wasCacheHit = cachedFn[Cache].get(cacheAccessId).hit;
 */
export function cache(options: Object, fn: Function): Function;
export const CacheAccesses: unique symbol;
export const CacheAccessId: unique symbol;
export const Cache: unique symbol;
