From cda02280f09b0230bd44eafcc4a710d9a5ec84b0 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 13 Oct 2020 13:04:55 -0400 Subject: [PATCH] Support optimistic.forget to remove Entry objects from Cache (#84) --- src/index.ts | 7 +++++++ src/tests/api.ts | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/index.ts b/src/index.ts index bee5f54..0fd24ec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -53,6 +53,8 @@ export type OptimisticWrapperFunction< dirty: (...args: TKeyArgs) => void; // Examine the current value without recomputing it. peek: (...args: TKeyArgs) => TResult | undefined; + // Remove the entry from the cache, dirtying any parent entries. + forget: (...args: TKeyArgs) => boolean; }; export type OptimisticWrapOptions< @@ -149,5 +151,10 @@ export function wrap< } }; + optimistic.forget = function () { + const key = makeCacheKey.apply(null, arguments as any); + return key !== void 0 && cache.delete(key); + }; + return optimistic as OptimisticWrapperFunction; } diff --git a/src/tests/api.ts b/src/tests/api.ts index 9b35686..80a9cca 100644 --- a/src/tests/api.ts +++ b/src/tests/api.ts @@ -579,4 +579,44 @@ describe("optimism", function () { // Since 6 < 7, its value is still cached. assert.strictEqual(sumFirst.peek(6), 6 * 7 / 2); }); + + it("allows forgetting entries", function () { + const ns: number[] = []; + const sumFirst = wrap(function (n: number): number { + ns.push(n); + return n < 1 ? 0 : n + sumFirst(n - 1); + }); + + function inclusiveDescendingRange(n: number, limit = 0) { + const range: number[] = []; + while (n >= limit) range.push(n--); + return range; + } + + assert.strictEqual(sumFirst(10), 55); + assert.deepStrictEqual(ns, inclusiveDescendingRange(10)); + + assert.strictEqual(sumFirst.forget(6), true); + assert.strictEqual(sumFirst(4), 10); + assert.deepStrictEqual(ns, inclusiveDescendingRange(10)); + + assert.strictEqual(sumFirst(11), 66); + assert.deepStrictEqual(ns, [ + ...inclusiveDescendingRange(10), + ...inclusiveDescendingRange(11, 6), + ]); + + assert.strictEqual(sumFirst.forget(3), true); + assert.strictEqual(sumFirst(7), 28); + assert.deepStrictEqual(ns, [ + ...inclusiveDescendingRange(10), + ...inclusiveDescendingRange(11, 6), + ...inclusiveDescendingRange(7, 3), + ]); + + assert.strictEqual(sumFirst.forget(123), false); + assert.strictEqual(sumFirst.forget(-1), false); + assert.strictEqual(sumFirst.forget("7" as any), false); + assert.strictEqual((sumFirst.forget as any)(6, 4), false); + }); });