@prisma/orm-mongo 8.0.0-rc.14-dev.8 → 8.0.0-rc.14-dev.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/orm-mongo",
|
|
3
|
-
"version": "8.0.0-rc.14-dev.
|
|
3
|
+
"version": "8.0.0-rc.14-dev.9",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -10,18 +10,18 @@
|
|
|
10
10
|
"skills"
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@prisma/orm-family-mongo": "8.0.0-rc.14-dev.
|
|
14
|
-
"@prisma/orm-framework": "8.0.0-rc.14-dev.
|
|
15
|
-
"@prisma/orm-target-mongo": "8.0.0-rc.14-dev.
|
|
16
|
-
"@prisma/orm-toolchain": "8.0.0-rc.14-dev.
|
|
13
|
+
"@prisma/orm-family-mongo": "8.0.0-rc.14-dev.9",
|
|
14
|
+
"@prisma/orm-framework": "8.0.0-rc.14-dev.9",
|
|
15
|
+
"@prisma/orm-target-mongo": "8.0.0-rc.14-dev.9",
|
|
16
|
+
"@prisma/orm-toolchain": "8.0.0-rc.14-dev.9",
|
|
17
17
|
"mongodb-connection-string-url": "^7.0.1",
|
|
18
18
|
"pathe": "^2.0.3",
|
|
19
19
|
"tinyglobby": "^0.2.17"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@internal/mongo": "8.0.0-rc.14-dev.
|
|
23
|
-
"@repo/tsconfig": "8.0.0-rc.14-dev.
|
|
24
|
-
"@repo/tsdown": "8.0.0-rc.14-dev.
|
|
22
|
+
"@internal/mongo": "8.0.0-rc.14-dev.9",
|
|
23
|
+
"@repo/tsconfig": "8.0.0-rc.14-dev.9",
|
|
24
|
+
"@repo/tsdown": "8.0.0-rc.14-dev.9",
|
|
25
25
|
"tsdown": "0.22.14",
|
|
26
26
|
"typescript": "5.9.3"
|
|
27
27
|
},
|
package/skills/prisma-8/SKILL.md
CHANGED
|
@@ -236,29 +236,43 @@ For the full option surface, read the source: `packages/2-sql/5-runtime/src/midd
|
|
|
236
236
|
|
|
237
237
|
## Workflow — Cache middleware
|
|
238
238
|
|
|
239
|
-
The concept: `@prisma/orm-extension-middleware-cache` ships an opt-in read cache built on the `interceptQuery` hook. On a hit the driver is never called; on a miss the rows are buffered and
|
|
239
|
+
The concept: `@prisma/orm-extension-middleware-cache` ships an opt-in read cache built on the `interceptQuery` hook. On a hit the driver is never called; on a miss the rows are buffered and stored when the query completes. Only a plan carrying `cacheAnnotation` is cached; `cacheAnnotation({ bypass: true })` skips the cache for one call. Cache keys default to the runtime's content hash of the plan (`key` overrides), and queries inside a transaction or pinned connection bypass the cache. How long an entry lives is the store's policy: the default store keeps up to 1000 entries for 60 seconds each, and `createInMemoryCacheStore({ maxEntries, ttlMs })` changes that (`ttlMs: Infinity` never expires). `CacheStore` is the interface for a Redis-style backend. The cache never sees writes: after the write commits, call `cache.invalidate({ keys })` for reads annotated with a `key`. `cacheAnnotation({ meta })` hands any value to the store with the entry, and `cache.invalidate({ meta })` hands one to its `unset`; only a custom store that indexes `meta` can act on it, and the default store throws `RUNTIME.CACHE_STORE_META_UNSUPPORTED`.
|
|
240
240
|
|
|
241
241
|
```typescript
|
|
242
|
-
import {
|
|
243
|
-
|
|
242
|
+
import {
|
|
243
|
+
cacheAnnotation,
|
|
244
|
+
createCacheMiddleware,
|
|
245
|
+
createInMemoryCacheStore,
|
|
246
|
+
} from '@prisma/orm-extension-middleware-cache';
|
|
247
|
+
|
|
248
|
+
export const cache = createCacheMiddleware({
|
|
249
|
+
store: createInMemoryCacheStore({ maxEntries: 1_000, ttlMs: 60_000 }),
|
|
250
|
+
});
|
|
244
251
|
export const db = postgres<Contract>({
|
|
245
252
|
contractJson,
|
|
246
253
|
url: process.env['DATABASE_URL']!,
|
|
247
|
-
middleware: [
|
|
254
|
+
middleware: [cache, lints(), budgets({ maxRows: 10_000 })],
|
|
248
255
|
});
|
|
249
256
|
|
|
250
|
-
// Cached for
|
|
251
|
-
const user = await db.orm.public.User.first({ id: 1 }, (meta) =>
|
|
257
|
+
// Cached for the store's 60 s; an identical read in that window is served without a driver call.
|
|
258
|
+
const user = await db.orm.public.User.first({ id: 1 }, (meta) =>
|
|
259
|
+
meta.annotate(cacheAnnotation({ key: 'user-1' })),
|
|
260
|
+
);
|
|
252
261
|
// Un-annotated queries always hit the database.
|
|
262
|
+
|
|
263
|
+
// After a write to user 1 has committed (outside the transaction, never inside it):
|
|
264
|
+
await cache.invalidate({ keys: ['user-1'] });
|
|
253
265
|
```
|
|
254
266
|
|
|
255
|
-
**
|
|
267
|
+
**Invalidate after the commit, not inside the transaction.** A read from another request can refill the cache with the old rows before the commit lands. A read that missed before the `invalidate` and finishes after it does not store its rows: the store moves the key's version on `unset`, and the read's `set` is conditional on the version it saw. This holds across processes that share a store.
|
|
268
|
+
|
|
269
|
+
**The cache key carries no identity.** The default key is the runtime's content hash of the plan — contract hash, SQL text, and bound parameters — so two callers issuing the same statement share one entry regardless of who they are. Never annotate a read whose rows depend on the caller (per-user, per-tenant, or RLS-filtered data) on the plain `postgres()` façade unless the identity is part of the key: `cacheAnnotation({ key: `user:${userId}:profile` })`, or a `where` clause that binds the identity as a parameter (the parameter is in the hash). Queries that run on a pinned connection or inside a transaction bypass the cache entirely (`ctx.scope !== 'runtime'`), which is why a Supabase `RoleBoundDb` read — executed on a connection with the role bound via `set_config` — is never served from cache; the plain façade has no such protection.
|
|
256
270
|
|
|
257
271
|
## Workflow — Compose multiple middleware
|
|
258
272
|
|
|
259
273
|
```typescript
|
|
260
274
|
middleware: [
|
|
261
|
-
createCacheMiddleware(
|
|
275
|
+
createCacheMiddleware(), // first — gets first claim on an interceptQuery hit
|
|
262
276
|
lints({ severities: { noLimit: 'error' } }),
|
|
263
277
|
budgets({ maxLatencyMs: 5_000 }),
|
|
264
278
|
slowQueryWarning({ thresholdMs: 250 }), // afterQuery fires for cache hits too (source: 'middleware')
|