diff --git a/src/index.ts b/src/index.ts index eeb4ed8..400f4cc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1682,6 +1682,15 @@ export class LRUCache { if (v !== oldVal) { if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) { oldVal.__abortController.abort(new Error('replaced')) + const { __staleWhileFetching: s } = oldVal + if (s !== undefined && !noDisposeOnSet) { + if (this.#hasDispose) { + this.#dispose?.(s as V, k, 'set') + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([s as V, k, 'set']) + } + } } else if (!noDisposeOnSet) { if (this.#hasDispose) { this.#dispose?.(oldVal as V, k, 'set') diff --git a/test/fetch.ts b/test/fetch.ts index b0fa33e..984e78d 100644 --- a/test/fetch.ts +++ b/test/fetch.ts @@ -2,7 +2,7 @@ if (typeof performance === 'undefined') { global.performance = require('perf_hooks').performance } import t from 'tap' -import { LRUCache, BackgroundFetch } from '../' +import { BackgroundFetch, LRUCache } from '../' import { expose } from './fixtures/expose' const fn: LRUCache.Fetcher = async (_, v) => @@ -720,7 +720,10 @@ t.test('allowStaleOnFetchAbort', async t => { const p = c.fetch(1, { signal: ac.signal }) ac.abort(new Error('gimme the stale value')) t.equal(await p, 10) - t.equal(c.get(1, { allowStale: true, noDeleteOnStaleGet: true }), 10) + t.equal( + c.get(1, { allowStale: true, noDeleteOnStaleGet: true }), + 10 + ) const p2 = c.fetch(1) c.set(1, 100) t.equal(await p2, 10) @@ -844,3 +847,22 @@ t.test('has false for pending fetch without stale val', async t => { t.equal(c.has(1), true) } }) + +t.test('properly dispose when using fetch', async t => { + const disposes: [number, number, string][] = [] + const disposeAfters: [number, number, string][] = [] + let i = 0 + const c = new LRUCache({ + max: 3, + ttl: 10, + dispose: (key, val, reason) => disposes.push([key, val, reason]), + disposeAfter: (key, val, reason) => + disposeAfters.push([key, val, reason]), + fetchMethod: async () => Promise.resolve(i++), + }) + t.equal(await c.fetch(1), 0) + clock.advance(20) + t.equal(await c.fetch(1), 1) + t.strictSame(disposes, [[0, 1, 'set']]) + t.strictSame(disposeAfters, [[0, 1, 'set']]) +})