From 1e67fa9274a3366f3f538d2b6982b508b51f339d Mon Sep 17 00:00:00 2001 From: Jacob Ley Date: Tue, 20 Oct 2026 03:33:37 +0000 Subject: [PATCH] fix: pass gracedEntry to background factories --- .changeset/graced-entry-background-factory.md | 5 ++++ .../bentocache/src/cache/factory_runner.ts | 2 +- .../tests/cache/factory_context.spec.ts | 29 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 .changeset/graced-entry-background-factory.md diff --git a/.changeset/graced-entry-background-factory.md b/.changeset/graced-entry-background-factory.md new file mode 100644 index 00000000..fa433c6d --- /dev/null +++ b/.changeset/graced-entry-background-factory.md @@ -0,0 +1,5 @@ +--- +'bentocache': patch +--- + +Pass `gracedEntry` to factories that refresh a stale value in the background (`timeout: 0`, the default). It was always `undefined` there, so a background refresh couldn't tell it had a stale value to fall back on. diff --git a/packages/bentocache/src/cache/factory_runner.ts b/packages/bentocache/src/cache/factory_runner.ts index 5a731134..84536bf7 100644 --- a/packages/bentocache/src/cache/factory_runner.ts +++ b/packages/bentocache/src/cache/factory_runner.ts @@ -137,7 +137,7 @@ export class FactoryRunner { * And immediately return the fallback value */ if (options.shouldSwr(hasGracedValue)) { - this.#runFactory({ key, factory, options, lockReleaser, isBackground: true }) + this.#runFactory({ key, factory, options, lockReleaser, isBackground: true, gracedValue }) throw new errors.E_FACTORY_SOFT_TIMEOUT(key) } diff --git a/packages/bentocache/tests/cache/factory_context.spec.ts b/packages/bentocache/tests/cache/factory_context.spec.ts index d2daa327..63780f02 100644 --- a/packages/bentocache/tests/cache/factory_context.spec.ts +++ b/packages/bentocache/tests/cache/factory_context.spec.ts @@ -120,4 +120,33 @@ test.group('Factory Context', () => { assert.deepEqual(r1, 'bar') }) + + test('can access graced entry when refreshing in the background', async ({ assert }) => { + const { cache } = new CacheFactory() + .withL1L2Config() + .merge({ grace: '2m', timeout: 0 }) + .create() + + await cache.getOrSet({ + key: 'foo', + ttl: 100, + factory: () => 'bar', + }) + + await sleep(100) + + let gracedEntry: { value: any } | undefined + const r1 = await cache.getOrSet({ + key: 'foo', + factory: (ctx) => { + gracedEntry = ctx.gracedEntry + return 'baz' + }, + }) + + await sleep(50) + + assert.deepEqual(r1, 'bar') + assert.deepEqual(gracedEntry, { value: 'bar' }) + }) })