[PR #646] [MERGED] feat: implement cacheForRequest() per-request factory cache #743

Closed
opened 2026-05-06 13:09:54 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/646
Author: @JamesbbBriz
Created: 3/22/2026
Status: Merged
Merged: 3/28/2026
Merged by: @james-elicx

Base: mainHead: feat/cache-for-request


📝 Commits (3)

  • e781265 feat: add cacheForRequest() — per-request factory cache
  • eb667a9 fix: address review feedback for cacheForRequest
  • 01a76b1 fix: add void operator to suppress no-floating-promises lint warnings

📊 Changes

7 files changed (+224 additions, -3 deletions)

View changed files

📝 packages/vinext/package.json (+4 -0)
packages/vinext/src/cache.ts (+11 -0)
📝 packages/vinext/src/index.ts (+1 -0)
packages/vinext/src/shims/cache-for-request.ts (+89 -0)
📝 packages/vinext/src/shims/unified-request-context.ts (+10 -3)
tests/cache-for-request.test.ts (+108 -0)
📝 tests/unified-request-context.test.ts (+1 -0)

📄 Description

Summary

Implements cacheForRequest() from RFC #623 — a per-request factory cache that lazily initializes values on first call and returns the cached result for subsequent calls within the same request.

API

import { cacheForRequest } from "vinext/cache-for-request";

const getPrisma = cacheForRequest(() => {
  const pool = new Pool({ connectionString: env.HYPERDRIVE.connectionString });
  return new PrismaClient({ adapter: new PrismaPg(pool) });
});

// In any server code:
const prisma = getPrisma(); // first call creates, subsequent calls reuse

Key design decisions:

  • Factory function reference = cache key (no string keys, no cross-module collision)
  • Async factories cache the Promise itself (concurrent-safe: two await getDb() share one invocation)
  • Outside request scope: factory runs every time, no caching (safe for tests/build-time)

Changes

File Change
shims/cache-for-request.ts New — cacheForRequest() implementation (17 lines of logic)
shims/unified-request-context.ts Add requestCache: WeakMap<Function, unknown> field + shallow-clone comment sync
package.json Add "./cache-for-request" export

Blast radius

Zero. New file + one new field with new WeakMap() default (~0.1μs per request). No existing behavior changes.

Test plan

Tested with Prisma v7 + Hyperdrive on Workers. Happy to add unit tests — let me know the preferred test file location.

Addresses #623 · Relates to #537


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/646 **Author:** [@JamesbbBriz](https://github.com/JamesbbBriz) **Created:** 3/22/2026 **Status:** ✅ Merged **Merged:** 3/28/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `feat/cache-for-request` --- ### 📝 Commits (3) - [`e781265`](https://github.com/cloudflare/vinext/commit/e7812657367ab704fb3989dfc25c68c14ad09d1f) feat: add cacheForRequest() — per-request factory cache - [`eb667a9`](https://github.com/cloudflare/vinext/commit/eb667a9b6b70823a17ddf613eaeba3d3fb0c33ee) fix: address review feedback for cacheForRequest - [`01a76b1`](https://github.com/cloudflare/vinext/commit/01a76b136e525afac6e986c994e58300833b6210) fix: add void operator to suppress no-floating-promises lint warnings ### 📊 Changes **7 files changed** (+224 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/package.json` (+4 -0) ➕ `packages/vinext/src/cache.ts` (+11 -0) 📝 `packages/vinext/src/index.ts` (+1 -0) ➕ `packages/vinext/src/shims/cache-for-request.ts` (+89 -0) 📝 `packages/vinext/src/shims/unified-request-context.ts` (+10 -3) ➕ `tests/cache-for-request.test.ts` (+108 -0) 📝 `tests/unified-request-context.test.ts` (+1 -0) </details> ### 📄 Description ## Summary Implements `cacheForRequest()` from RFC #623 — a per-request factory cache that lazily initializes values on first call and returns the cached result for subsequent calls within the same request. ## API ```ts import { cacheForRequest } from "vinext/cache-for-request"; const getPrisma = cacheForRequest(() => { const pool = new Pool({ connectionString: env.HYPERDRIVE.connectionString }); return new PrismaClient({ adapter: new PrismaPg(pool) }); }); // In any server code: const prisma = getPrisma(); // first call creates, subsequent calls reuse ``` **Key design decisions:** - Factory function reference = cache key (no string keys, no cross-module collision) - Async factories cache the Promise itself (concurrent-safe: two `await getDb()` share one invocation) - Outside request scope: factory runs every time, no caching (safe for tests/build-time) ## Changes | File | Change | |------|--------| | `shims/cache-for-request.ts` | New — `cacheForRequest()` implementation (17 lines of logic) | | `shims/unified-request-context.ts` | Add `requestCache: WeakMap<Function, unknown>` field + shallow-clone comment sync | | `package.json` | Add `"./cache-for-request"` export | ## Blast radius Zero. New file + one new field with `new WeakMap()` default (~0.1μs per request). No existing behavior changes. ## Test plan Tested with Prisma v7 + Hyperdrive on Workers. Happy to add unit tests — let me know the preferred test file location. Addresses #623 · Relates to #537 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:09:54 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#743
No description provided.