diff --git a/examples/prisma-next-demo/src/orm-client/find-user-by-id-cached.ts b/examples/prisma-next-demo/src/orm-client/find-user-by-id-cached.ts index ee70dea1bf..159fe42d90 100644 --- a/examples/prisma-next-demo/src/orm-client/find-user-by-id-cached.ts +++ b/examples/prisma-next-demo/src/orm-client/find-user-by-id-cached.ts @@ -20,9 +20,10 @@ * a write terminal (`create`, `update`, `delete`) is a type error * *and* a runtime error — it cannot be smuggled through with a cast * on one side without failing on the other. - * - On a cache hit, telemetry's `afterExecute` event reports - * `source: 'middleware'`. Telemetry is wired in front of the cache - * in `db.ts`, so observability still works for cached reads. + * - On a cache hit, every registered middleware's `afterExecute` still + * fires and reports `source: 'middleware'` — the `slowQueryWarning` + * middleware in `db.ts` observes cached reads too — so observability + * is preserved even though the driver is skipped. * - Schema migrations rotate `meta.storageHash`, which feeds * `contentHash`, so cached entries from a previous schema cannot * accidentally serve queries against the new schema. diff --git a/examples/prisma-next-demo/src/prisma/db.ts b/examples/prisma-next-demo/src/prisma/db.ts index 30d63ebce0..619d5683e5 100644 --- a/examples/prisma-next-demo/src/prisma/db.ts +++ b/examples/prisma-next-demo/src/prisma/db.ts @@ -10,8 +10,12 @@ export const db = postgres({ contractJson, extensions: [pgvector], middleware: [ - // Cache first so its `intercept` short-circuits before any downstream - // middleware (`lints`, `budgets`) fires on a hit. The cache stores + // Cache first: interceptors are consulted in registration order and + // the first non-`undefined` result wins, so the cache gets first + // claim. A hit skips only the driver call and per-row `onRow` hooks: + // every middleware's `beforeExecute` (`lints`, `budgets`) has already + // run before any `intercept` is consulted, and `afterExecute` still + // fires for all of them with `source: 'middleware'`. The cache stores // raw rows; the runtime still runs `decodeRow` on the hit path, so // consumers see decoded values in both cases. createCacheMiddleware({ maxEntries: 1_000 }), diff --git a/packages/3-extensions/middleware-cache/src/cache-middleware.ts b/packages/3-extensions/middleware-cache/src/cache-middleware.ts index 74ebb32b02..f205d54b6d 100644 --- a/packages/3-extensions/middleware-cache/src/cache-middleware.ts +++ b/packages/3-extensions/middleware-cache/src/cache-middleware.ts @@ -100,12 +100,13 @@ async function resolveCacheKey( * The middleware uses three hooks: * * - `intercept` — on each execution, checks the cache. On a hit, returns - * the cached raw rows; the runtime skips `beforeExecute`, `runDriver`, - * and `onRow`, and yields the cached rows to the consumer (which, in - * the SQL runtime, sees them after the standard `decodeRow` pass — - * i.e. the cache stores wire-format values). On a miss, records a - * pending buffer keyed on the `exec` object identity and returns - * `undefined` (passthrough). + * the cached raw rows; the runtime skips `runDriver` and `onRow` + * (`beforeExecute` is not affected — it has already run for every + * middleware before any `intercept` is consulted) and yields the + * cached rows to the consumer (which, in the SQL runtime, sees them + * after the standard `decodeRow` pass — i.e. the cache stores + * wire-format values). On a miss, records a pending buffer keyed on + * the `exec` object identity and returns `undefined` (passthrough). * - `onRow` — on the miss path, appends each row yielded by the driver * to the pending buffer. * - `afterExecute` — on the miss path, commits the buffer to the store diff --git a/skills/extension-author/prisma-next-extension-upgrade/upgrades/0.14-to-0.15/instructions.md b/skills/extension-author/prisma-next-extension-upgrade/upgrades/0.14-to-0.15/instructions.md index 255405f1f0..a8c5acd078 100644 --- a/skills/extension-author/prisma-next-extension-upgrade/upgrades/0.14-to-0.15/instructions.md +++ b/skills/extension-author/prisma-next-extension-upgrade/upgrades/0.14-to-0.15/instructions.md @@ -774,3 +774,13 @@ updated to the shipped forms. No code, API, contract shape, or emitted artefact changes. No extension-author action required. Incidental docs-only diff. --> + + diff --git a/skills/upgrade/prisma-next-upgrade/upgrades/0.14-to-0.15/instructions.md b/skills/upgrade/prisma-next-upgrade/upgrades/0.14-to-0.15/instructions.md index 28876ddf44..745965f9c9 100644 --- a/skills/upgrade/prisma-next-upgrade/upgrades/0.14-to-0.15/instructions.md +++ b/skills/upgrade/prisma-next-upgrade/upgrades/0.14-to-0.15/instructions.md @@ -316,3 +316,15 @@ vitest `retry` config that absorbs a known intermittent PGlite (WASM) abort. A re-emit picks up any contract shape. No user action required. Incidental substrate diff only. --> + +