@prisma/orm-extension-middleware-cache 8.0.0-rc.18-dev.20 → 8.0.0-rc.18-dev.21

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/dist/index.d.mts CHANGED
@@ -225,7 +225,7 @@ declare function deriveKeyFromContentHash(exec: ExecutionPlan, ctx: ActivityCont
225
225
  * @example
226
226
  * ```typescript
227
227
  * const cache = createCacheMiddleware();
228
- * const db = postgres<Contract>({ contractJson, url, middleware: [cache] });
228
+ * const db = postgres({ contract, url, middleware: [cache] });
229
229
  *
230
230
  * const user = await db.orm.public.User.first(
231
231
  * { id: 1 },
package/dist/index.mjs CHANGED
@@ -259,7 +259,7 @@ function valueToStore(miss, result) {
259
259
  * @example
260
260
  * ```typescript
261
261
  * const cache = createCacheMiddleware();
262
- * const db = postgres<Contract>({ contractJson, url, middleware: [cache] });
262
+ * const db = postgres({ contract, url, middleware: [cache] });
263
263
  *
264
264
  * const user = await db.orm.public.User.first(
265
265
  * { id: 1 },
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../3-extensions/middleware-cache/dist/index.mjs"],"sourcesContent":["import { defineAnnotation } from \"@internal/framework-components/runtime\";\nimport { blindCast } from \"@internal/utils/casts\";\nimport { structuredError } from \"@internal/utils/structured-error\";\n//#region src/cache-annotation.ts\n/**\n* Marks a read for the cache middleware. It applies to reads only: a write terminal refuses it at\n* compile time and at run time. The middleware reads it from a statement plan's `meta.annotations.cache`, or from the annotations of a client activity, such as an ORM read, which is then cached as a whole.\n*\n* `TMeta` types `meta` for this call only. Nothing ties it to the store's `TMeta`, so a store\n* package should export a wrapper typed with its own meta, such as\n* `(o: CacheAnnotationOptions<TagMeta>) => cacheAnnotation<TagMeta>(o)`.\n*\n* @example\n* ```typescript\n* import { cacheAnnotation } from '@internal/middleware-cache';\n*\n* // ORM read terminal — accepts the read-only annotation via the meta callback.\n* const user = await db.orm.public.User.first(\n* { id },\n* (meta) => meta.annotate(cacheAnnotation({ key: `user-${id}` })),\n* );\n*\n* // SQL DSL select builder — chainable.\n* const plan = db.sql\n* .from(tables.user)\n* .annotate(cacheAnnotation({}))\n* .select({ id: tables.user.columns.id })\n* .build();\n* ```\n*/\nconst cacheAnnotation = withTypedMeta(defineAnnotation()({\n\tnamespace: \"cache\",\n\tapplicableTo: [\"read\"]\n}));\nfunction withTypedMeta(handle) {\n\tfunction cacheAnnotationWithMeta(options) {\n\t\treturn handle(options);\n\t}\n\treturn Object.freeze(Object.assign(cacheAnnotationWithMeta, {\n\t\tnamespace: handle.namespace,\n\t\tapplicableTo: handle.applicableTo,\n\t\tread: handle.read\n\t}));\n}\n//#endregion\n//#region src/cache-store.ts\nconst typedArraySlice = Reflect.get(Object.getPrototypeOf(Uint8Array.prototype), \"slice\");\n/**\n* A copy of the plain structure of `value`: plain and null-prototype objects, arrays, `Map`, `Set`,\n* `Date`, `RegExp`, `ArrayBuffer`, typed arrays and `DataView` are copied, and every other value,\n* such as a class instance or a function, is kept by reference. A typed array is copied with\n* `TypedArray.prototype.slice`, which keeps its class, so a `Buffer` copies to a `Buffer` with its\n* own memory; a `DataView` copies to a plain `DataView`; an array copies to its elements only, with\n* holes read as `undefined`. Shared references and cycles are kept.\n*/\nfunction copyValue(value, copies = /* @__PURE__ */ new Map()) {\n\tif (typeof value !== \"object\" || value === null) return value;\n\tconst known = copies.get(value);\n\tif (known !== void 0) return blindCast(known);\n\tconst copy = copyObject(value, copies);\n\tcopies.set(value, copy);\n\treturn blindCast(copy);\n}\nfunction copyObject(value, copies) {\n\tif (value instanceof DataView) {\n\t\tconst start = value.byteOffset;\n\t\treturn new DataView(value.buffer.slice(start, start + value.byteLength));\n\t}\n\tif (ArrayBuffer.isView(value)) return typedArraySlice.call(value);\n\tconst prototype = Object.getPrototypeOf(value);\n\tif (prototype === ArrayBuffer.prototype && value instanceof ArrayBuffer) return value.slice(0);\n\tif (prototype === Date.prototype && value instanceof Date) return new Date(value.getTime());\n\tif (prototype === RegExp.prototype && value instanceof RegExp) return new RegExp(value.source, value.flags);\n\tif (prototype === Map.prototype && value instanceof Map) {\n\t\tconst copy = /* @__PURE__ */ new Map();\n\t\tcopies.set(value, copy);\n\t\tfor (const [key, entry] of value) copy.set(copyValue(key, copies), copyValue(entry, copies));\n\t\treturn copy;\n\t}\n\tif (prototype === Set.prototype && value instanceof Set) {\n\t\tconst copy = /* @__PURE__ */ new Set();\n\t\tcopies.set(value, copy);\n\t\tfor (const entry of value) copy.add(copyValue(entry, copies));\n\t\treturn copy;\n\t}\n\tif (prototype === Array.prototype && Array.isArray(value)) {\n\t\tconst copy = [];\n\t\tcopies.set(value, copy);\n\t\tfor (const entry of value) copy.push(copyValue(entry, copies));\n\t\treturn copy;\n\t}\n\tif (prototype !== Object.prototype && prototype !== null) return value;\n\tconst copy = Object.create(prototype);\n\tcopies.set(value, copy);\n\tfor (const key of Reflect.ownKeys(value)) if (Object.prototype.propertyIsEnumerable.call(value, key)) copy[key] = copyValue(Reflect.get(value, key), copies);\n\treturn copy;\n}\n/** Statement rows hold driver values, such as BSON `ObjectId`s, that this package cannot copy. So the array and each row object are copied, each row keeping its prototype, and the driver's values are kept by reference and shared with every hit. */\nfunction copyRows(rows) {\n\treturn rows.map((row) => {\n\t\tconst copy = Object.create(Object.getPrototypeOf(row));\n\t\treturn Object.assign(copy, row);\n\t});\n}\nfunction copyStored(value) {\n\tswitch (value.kind) {\n\t\tcase \"statement-rows\": return {\n\t\t\tkind: \"statement-rows\",\n\t\t\trows: copyRows(value.rows)\n\t\t};\n\t\tcase \"call-result\": return {\n\t\t\tkind: \"call-result\",\n\t\t\tresult: copyValue(value.result)\n\t\t};\n\t}\n}\nfunction metaUnsupported() {\n\treturn structuredError(\"RUNTIME.CACHE_STORE_META_UNSUPPORTED\", \"The in-memory cache store cannot remove entries by meta because it does not index meta\", { fix: \"Invalidate by keys, or supply a CacheStore that indexes meta in set and unset.\" });\n}\nfunction invalidOption(argument, received, expected) {\n\treturn structuredError(\"RUNTIME.ARGUMENT_INVALID\", `createInMemoryCacheStore: ${argument} must be ${expected}`, {\n\t\tfix: `Pass ${argument} as ${expected}, or leave it unset for the default.`,\n\t\tmeta: {\n\t\t\thelper: \"createInMemoryCacheStore\",\n\t\t\targument,\n\t\t\treceived\n\t\t}\n\t});\n}\n/**\n* The default cache store: a least-recently-used map of `CachedValue` with one lifetime for every value, local to the process. Statement rows are copied one level deep on `set` and `get`: the array, and each row object with its prototype. The driver's values in them are kept by reference and shared with every hit; the runtime decodes them on each hit, and a codec that returns its wire value unchanged, such as a date or byte-array codec, hands that shared object to the caller. A call result has its plain structure copied on `set` and on every `get`: plain and null-prototype objects, arrays (their elements only; holes read as `undefined`), `Map`, `Set`, `Date`, `RegExp`, `ArrayBuffer`, typed arrays (a subclass such as Node's `Buffer` keeps its class) and `DataView` (copied as a plain `DataView`). Every other value in it, such as a class instance (a Temporal value, a BSON value, an error) or a function, is shared by reference. So after `set` returns, a change to the plain structure of the value `set` was given, or of a value `get` returned, reaches no later `get`; a change made to a shared value, or made before `set`, does. It never refuses a value: `set` returns `false` only when the version moved. A key's version is kept for `ttlMs` after the `unset` that moved it (see `InMemoryCacheStoreOptions`). It ignores `meta` in `get` and `set`, and its `unset` rejects any `meta`, including `null`, before changing anything. It throws `RUNTIME.ARGUMENT_INVALID` for a `maxEntries` or `ttlMs` outside the ranges above.\n*/\nfunction createInMemoryCacheStore(options) {\n\tconst maxEntries = options?.maxEntries ?? 1e3;\n\tconst ttlMs = options?.ttlMs ?? 6e4;\n\tconst clock = options?.clock ?? Date.now;\n\tif (!Number.isInteger(maxEntries) || maxEntries <= 0) throw invalidOption(\"maxEntries\", maxEntries, \"a positive integer\");\n\tif (!(ttlMs > 0)) throw invalidOption(\"ttlMs\", ttlMs, \"a positive number of milliseconds, or Infinity\");\n\tconst records = /* @__PURE__ */ new Map();\n\tconst versions = /* @__PURE__ */ new Map();\n\tfunction forgetExpiredVersions() {\n\t\tconst now = clock();\n\t\tfor (const [key, record] of versions) {\n\t\t\tif (now < record.expiresAt) return;\n\t\t\tversions.delete(key);\n\t\t}\n\t}\n\tfunction versionOf(key) {\n\t\tforgetExpiredVersions();\n\t\treturn versions.get(key)?.version ?? 0;\n\t}\n\tfunction liveRecord(key) {\n\t\tconst record = records.get(key);\n\t\tif (record === void 0) return;\n\t\trecords.delete(key);\n\t\tif (clock() >= record.expiresAt) return;\n\t\trecords.set(key, record);\n\t\treturn record;\n\t}\n\tasync function get(target) {\n\t\tconst record = liveRecord(target.key);\n\t\treturn {\n\t\t\tkey: target.key,\n\t\t\tmeta: target.meta,\n\t\t\tversion: versionOf(target.key),\n\t\t\tdata: record === void 0 ? { empty: true } : {\n\t\t\t\tempty: false,\n\t\t\t\tvalue: copyStored(record.value)\n\t\t\t}\n\t\t};\n\t}\n\tasync function set(entry, value) {\n\t\tif (entry.version !== versionOf(entry.key)) return false;\n\t\trecords.delete(entry.key);\n\t\trecords.set(entry.key, {\n\t\t\tvalue: copyStored(value),\n\t\t\texpiresAt: clock() + ttlMs\n\t\t});\n\t\tfor (const leastRecentlyUsed of records.keys()) {\n\t\t\tif (records.size <= maxEntries) break;\n\t\t\trecords.delete(leastRecentlyUsed);\n\t\t}\n\t\treturn true;\n\t}\n\tasync function unset(target) {\n\t\tif (target.meta !== void 0) throw metaUnsupported();\n\t\tfor (const key of target.keys ?? []) {\n\t\t\trecords.delete(key);\n\t\t\tconst version = versionOf(key) + 1;\n\t\t\tversions.delete(key);\n\t\t\tversions.set(key, {\n\t\t\t\tversion,\n\t\t\t\texpiresAt: clock() + ttlMs\n\t\t\t});\n\t\t}\n\t}\n\treturn {\n\t\tget,\n\t\tset,\n\t\tunset\n\t};\n}\n//#endregion\n//#region src/cache-middleware.ts\n/**\n* The default `deriveKey`: the family runtime's content hash of the plan, which covers the\n* statement, its parameters and the storage hash.\n*/\nfunction deriveKeyFromContentHash(exec, ctx) {\n\treturn ctx.contentHash(exec);\n}\nconst pendingMiss = Symbol(\"cache.pendingMiss\");\nfunction pendingOf(ctx) {\n\tconst miss = ctx.state(pendingMiss)[\"miss\"];\n\treturn isPendingMiss(miss) ? miss : void 0;\n}\nfunction isPendingMiss(value) {\n\treturn typeof value === \"object\" && value !== null && \"entry\" in value && \"buffer\" in value;\n}\nfunction hasTag(value, tag) {\n\treturn value.kind === tag;\n}\nfunction cacheable(ctx) {\n\treturn ctx.scope === \"runtime\" && !ctx.inTransaction();\n}\n/** The value a pending miss stores when its activity ends this way, or `undefined` to store nothing. */\nfunction valueToStore(miss, result) {\n\tif (result.outcome !== \"succeeded\") return void 0;\n\tif (result.kind === \"statement\") return result.source === \"driver\" && miss.buffer !== void 0 ? {\n\t\tkind: \"statement-rows\",\n\t\trows: miss.buffer\n\t} : void 0;\n\tif (result.kind === \"transaction\") return void 0;\n\treturn result.source === \"client\" && result.result !== void 0 ? {\n\t\tkind: \"call-result\",\n\t\tresult: result.result\n\t} : void 0;\n}\n/**\n* Creates a read-through cache middleware that works with every family runtime.\n*\n* It caches an activity that carries `cacheAnnotation` without `bypass` and runs in runtime scope,\n* outside any transaction: never on a held connection, whose session may change what a read\n* returns, and never inside a transaction, which must read its own uncommitted writes. Two kinds\n* of activity are cached:\n*\n* - A statement whose plan carries the annotation, such as an annotated SQL builder query. Its key\n* is the annotation's `key`, else `deriveKey(exec, ctx)`; its value is the raw rows.\n* - A client activity that carries the annotation, such as an annotated ORM read. Its key is the\n* annotation's `key`, else `await activity.contentHash()`; its value is the result the client\n* ended the activity with. It is served as a whole, so a hit sends no statement.\n*\n* The middleware tags each stored value `statement-rows` or `call-result` and serves `statement-rows` only to a statement and `call-result` only to a client activity; under the same key, a value with the other tag is a miss, and the read stores its own value in its place. A key therefore belongs to one query and one terminal method: an ORM call served another method's result under a shared key fails with `ORM.INTERCEPTED_RESULT_INVALID` or returns the wrong shape.\n*\n* - `intercept.onQuery` and `intercept.onActivity` — on a hit, return the stored rows or result,\n* and nothing runs. On a miss, record the pending entry.\n* - `onRow` — collects each row of a statement miss.\n* - `activityEnded` — when the driver completed the statement, or the client ended the call\n* `succeeded` with a result (`null` is a result), calls `store.set(entry, value)` with the entry\n* `store.get` returned, which stores only if the key's version has not moved. If an `unset` moved\n* it meanwhile, `set` returns `false` and the middleware logs `middleware.cache.store-skipped`.\n*\n* @example\n* ```typescript\n* const cache = createCacheMiddleware();\n* const db = postgres<Contract>({ contractJson, url, middleware: [cache] });\n*\n* const user = await db.orm.public.User.first(\n* { id: 1 },\n* (meta) => meta.annotate(cacheAnnotation({ key: 'user-1' })),\n* );\n* await db.orm.public.User.where({ id: 1 }).update({ name: 'Alicia' });\n* await cache.invalidate({ keys: ['user-1'] });\n* ```\n*/\nfunction createCacheMiddleware(options) {\n\tconst store = options?.store ?? createInMemoryCacheStore();\n\tconst deriveKey = options?.deriveKey ?? deriveKeyFromContentHash;\n\tasync function lookUp(tag, key, meta, ctx, buffer) {\n\t\tconst entry = await store.get({\n\t\t\tkey,\n\t\t\tmeta\n\t\t});\n\t\tif (!entry.data.empty && hasTag(entry.data.value, tag)) {\n\t\t\tctx.log.debug?.({\n\t\t\t\tevent: \"middleware.cache.hit\",\n\t\t\t\tmiddleware: \"cache\",\n\t\t\t\tkey\n\t\t\t});\n\t\t\treturn entry.data.value;\n\t\t}\n\t\tctx.state(pendingMiss)[\"miss\"] = {\n\t\t\tentry,\n\t\t\tbuffer\n\t\t};\n\t\tctx.log.debug?.({\n\t\t\tevent: \"middleware.cache.miss\",\n\t\t\tmiddleware: \"cache\",\n\t\t\tkey\n\t\t});\n\t}\n\tasync function onQuery(exec, ctx) {\n\t\tif (!cacheable(ctx)) return;\n\t\tconst annotation = cacheAnnotation.read(exec);\n\t\tif (annotation === void 0 || annotation.bypass === true) return;\n\t\tconst value = await lookUp(\"statement-rows\", annotation.key ?? await deriveKey(exec, ctx), annotation.meta, ctx, []);\n\t\treturn value === void 0 ? void 0 : { rows: value.rows };\n\t}\n\tasync function onActivity(activity, ctx) {\n\t\tif (!cacheable(ctx)) return;\n\t\tconst annotation = cacheAnnotation.read(activity);\n\t\tif (annotation === void 0 || annotation.bypass === true) return;\n\t\tconst value = await lookUp(\"call-result\", annotation.key ?? await activity.contentHash(), annotation.meta, ctx, void 0);\n\t\treturn value === void 0 ? void 0 : { result: value.result };\n\t}\n\tasync function onRow(row, _exec, ctx) {\n\t\tpendingOf(ctx)?.buffer?.push(row);\n\t}\n\tasync function activityEnded(_activity, result, ctx) {\n\t\tconst miss = pendingOf(ctx);\n\t\tif (miss === void 0) return;\n\t\tdelete ctx.state(pendingMiss)[\"miss\"];\n\t\tconst value = valueToStore(miss, result);\n\t\tif (value === void 0) return;\n\t\tconst stored = await store.set(miss.entry, value);\n\t\tctx.log.debug?.({\n\t\t\tevent: stored ? \"middleware.cache.store\" : \"middleware.cache.store-skipped\",\n\t\t\tmiddleware: \"cache\",\n\t\t\tkey: miss.entry.key\n\t\t});\n\t}\n\tasync function invalidate(target) {\n\t\tconst keys = target.keys !== void 0 && target.keys.length > 0 ? target.keys : void 0;\n\t\tif (keys === void 0 && target.meta === void 0) return;\n\t\tawait store.unset({\n\t\t\tkeys,\n\t\t\tmeta: target.meta\n\t\t});\n\t}\n\treturn {\n\t\tname: \"cache\",\n\t\tintercept: {\n\t\t\tonQuery,\n\t\t\tonActivity\n\t\t},\n\t\tonRow,\n\t\tactivityEnded,\n\t\tinvalidate\n\t};\n}\n//#endregion\nexport { cacheAnnotation, createCacheMiddleware, createInMemoryCacheStore, deriveKeyFromContentHash };\n\n//# sourceMappingURL=index.mjs.map"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../3-extensions/middleware-cache/dist/index.mjs"],"sourcesContent":["import { defineAnnotation } from \"@internal/framework-components/runtime\";\nimport { blindCast } from \"@internal/utils/casts\";\nimport { structuredError } from \"@internal/utils/structured-error\";\n//#region src/cache-annotation.ts\n/**\n* Marks a read for the cache middleware. It applies to reads only: a write terminal refuses it at\n* compile time and at run time. The middleware reads it from a statement plan's `meta.annotations.cache`, or from the annotations of a client activity, such as an ORM read, which is then cached as a whole.\n*\n* `TMeta` types `meta` for this call only. Nothing ties it to the store's `TMeta`, so a store\n* package should export a wrapper typed with its own meta, such as\n* `(o: CacheAnnotationOptions<TagMeta>) => cacheAnnotation<TagMeta>(o)`.\n*\n* @example\n* ```typescript\n* import { cacheAnnotation } from '@internal/middleware-cache';\n*\n* // ORM read terminal — accepts the read-only annotation via the meta callback.\n* const user = await db.orm.public.User.first(\n* { id },\n* (meta) => meta.annotate(cacheAnnotation({ key: `user-${id}` })),\n* );\n*\n* // SQL DSL select builder — chainable.\n* const plan = db.sql\n* .from(tables.user)\n* .annotate(cacheAnnotation({}))\n* .select({ id: tables.user.columns.id })\n* .build();\n* ```\n*/\nconst cacheAnnotation = withTypedMeta(defineAnnotation()({\n\tnamespace: \"cache\",\n\tapplicableTo: [\"read\"]\n}));\nfunction withTypedMeta(handle) {\n\tfunction cacheAnnotationWithMeta(options) {\n\t\treturn handle(options);\n\t}\n\treturn Object.freeze(Object.assign(cacheAnnotationWithMeta, {\n\t\tnamespace: handle.namespace,\n\t\tapplicableTo: handle.applicableTo,\n\t\tread: handle.read\n\t}));\n}\n//#endregion\n//#region src/cache-store.ts\nconst typedArraySlice = Reflect.get(Object.getPrototypeOf(Uint8Array.prototype), \"slice\");\n/**\n* A copy of the plain structure of `value`: plain and null-prototype objects, arrays, `Map`, `Set`,\n* `Date`, `RegExp`, `ArrayBuffer`, typed arrays and `DataView` are copied, and every other value,\n* such as a class instance or a function, is kept by reference. A typed array is copied with\n* `TypedArray.prototype.slice`, which keeps its class, so a `Buffer` copies to a `Buffer` with its\n* own memory; a `DataView` copies to a plain `DataView`; an array copies to its elements only, with\n* holes read as `undefined`. Shared references and cycles are kept.\n*/\nfunction copyValue(value, copies = /* @__PURE__ */ new Map()) {\n\tif (typeof value !== \"object\" || value === null) return value;\n\tconst known = copies.get(value);\n\tif (known !== void 0) return blindCast(known);\n\tconst copy = copyObject(value, copies);\n\tcopies.set(value, copy);\n\treturn blindCast(copy);\n}\nfunction copyObject(value, copies) {\n\tif (value instanceof DataView) {\n\t\tconst start = value.byteOffset;\n\t\treturn new DataView(value.buffer.slice(start, start + value.byteLength));\n\t}\n\tif (ArrayBuffer.isView(value)) return typedArraySlice.call(value);\n\tconst prototype = Object.getPrototypeOf(value);\n\tif (prototype === ArrayBuffer.prototype && value instanceof ArrayBuffer) return value.slice(0);\n\tif (prototype === Date.prototype && value instanceof Date) return new Date(value.getTime());\n\tif (prototype === RegExp.prototype && value instanceof RegExp) return new RegExp(value.source, value.flags);\n\tif (prototype === Map.prototype && value instanceof Map) {\n\t\tconst copy = /* @__PURE__ */ new Map();\n\t\tcopies.set(value, copy);\n\t\tfor (const [key, entry] of value) copy.set(copyValue(key, copies), copyValue(entry, copies));\n\t\treturn copy;\n\t}\n\tif (prototype === Set.prototype && value instanceof Set) {\n\t\tconst copy = /* @__PURE__ */ new Set();\n\t\tcopies.set(value, copy);\n\t\tfor (const entry of value) copy.add(copyValue(entry, copies));\n\t\treturn copy;\n\t}\n\tif (prototype === Array.prototype && Array.isArray(value)) {\n\t\tconst copy = [];\n\t\tcopies.set(value, copy);\n\t\tfor (const entry of value) copy.push(copyValue(entry, copies));\n\t\treturn copy;\n\t}\n\tif (prototype !== Object.prototype && prototype !== null) return value;\n\tconst copy = Object.create(prototype);\n\tcopies.set(value, copy);\n\tfor (const key of Reflect.ownKeys(value)) if (Object.prototype.propertyIsEnumerable.call(value, key)) copy[key] = copyValue(Reflect.get(value, key), copies);\n\treturn copy;\n}\n/** Statement rows hold driver values, such as BSON `ObjectId`s, that this package cannot copy. So the array and each row object are copied, each row keeping its prototype, and the driver's values are kept by reference and shared with every hit. */\nfunction copyRows(rows) {\n\treturn rows.map((row) => {\n\t\tconst copy = Object.create(Object.getPrototypeOf(row));\n\t\treturn Object.assign(copy, row);\n\t});\n}\nfunction copyStored(value) {\n\tswitch (value.kind) {\n\t\tcase \"statement-rows\": return {\n\t\t\tkind: \"statement-rows\",\n\t\t\trows: copyRows(value.rows)\n\t\t};\n\t\tcase \"call-result\": return {\n\t\t\tkind: \"call-result\",\n\t\t\tresult: copyValue(value.result)\n\t\t};\n\t}\n}\nfunction metaUnsupported() {\n\treturn structuredError(\"RUNTIME.CACHE_STORE_META_UNSUPPORTED\", \"The in-memory cache store cannot remove entries by meta because it does not index meta\", { fix: \"Invalidate by keys, or supply a CacheStore that indexes meta in set and unset.\" });\n}\nfunction invalidOption(argument, received, expected) {\n\treturn structuredError(\"RUNTIME.ARGUMENT_INVALID\", `createInMemoryCacheStore: ${argument} must be ${expected}`, {\n\t\tfix: `Pass ${argument} as ${expected}, or leave it unset for the default.`,\n\t\tmeta: {\n\t\t\thelper: \"createInMemoryCacheStore\",\n\t\t\targument,\n\t\t\treceived\n\t\t}\n\t});\n}\n/**\n* The default cache store: a least-recently-used map of `CachedValue` with one lifetime for every value, local to the process. Statement rows are copied one level deep on `set` and `get`: the array, and each row object with its prototype. The driver's values in them are kept by reference and shared with every hit; the runtime decodes them on each hit, and a codec that returns its wire value unchanged, such as a date or byte-array codec, hands that shared object to the caller. A call result has its plain structure copied on `set` and on every `get`: plain and null-prototype objects, arrays (their elements only; holes read as `undefined`), `Map`, `Set`, `Date`, `RegExp`, `ArrayBuffer`, typed arrays (a subclass such as Node's `Buffer` keeps its class) and `DataView` (copied as a plain `DataView`). Every other value in it, such as a class instance (a Temporal value, a BSON value, an error) or a function, is shared by reference. So after `set` returns, a change to the plain structure of the value `set` was given, or of a value `get` returned, reaches no later `get`; a change made to a shared value, or made before `set`, does. It never refuses a value: `set` returns `false` only when the version moved. A key's version is kept for `ttlMs` after the `unset` that moved it (see `InMemoryCacheStoreOptions`). It ignores `meta` in `get` and `set`, and its `unset` rejects any `meta`, including `null`, before changing anything. It throws `RUNTIME.ARGUMENT_INVALID` for a `maxEntries` or `ttlMs` outside the ranges above.\n*/\nfunction createInMemoryCacheStore(options) {\n\tconst maxEntries = options?.maxEntries ?? 1e3;\n\tconst ttlMs = options?.ttlMs ?? 6e4;\n\tconst clock = options?.clock ?? Date.now;\n\tif (!Number.isInteger(maxEntries) || maxEntries <= 0) throw invalidOption(\"maxEntries\", maxEntries, \"a positive integer\");\n\tif (!(ttlMs > 0)) throw invalidOption(\"ttlMs\", ttlMs, \"a positive number of milliseconds, or Infinity\");\n\tconst records = /* @__PURE__ */ new Map();\n\tconst versions = /* @__PURE__ */ new Map();\n\tfunction forgetExpiredVersions() {\n\t\tconst now = clock();\n\t\tfor (const [key, record] of versions) {\n\t\t\tif (now < record.expiresAt) return;\n\t\t\tversions.delete(key);\n\t\t}\n\t}\n\tfunction versionOf(key) {\n\t\tforgetExpiredVersions();\n\t\treturn versions.get(key)?.version ?? 0;\n\t}\n\tfunction liveRecord(key) {\n\t\tconst record = records.get(key);\n\t\tif (record === void 0) return;\n\t\trecords.delete(key);\n\t\tif (clock() >= record.expiresAt) return;\n\t\trecords.set(key, record);\n\t\treturn record;\n\t}\n\tasync function get(target) {\n\t\tconst record = liveRecord(target.key);\n\t\treturn {\n\t\t\tkey: target.key,\n\t\t\tmeta: target.meta,\n\t\t\tversion: versionOf(target.key),\n\t\t\tdata: record === void 0 ? { empty: true } : {\n\t\t\t\tempty: false,\n\t\t\t\tvalue: copyStored(record.value)\n\t\t\t}\n\t\t};\n\t}\n\tasync function set(entry, value) {\n\t\tif (entry.version !== versionOf(entry.key)) return false;\n\t\trecords.delete(entry.key);\n\t\trecords.set(entry.key, {\n\t\t\tvalue: copyStored(value),\n\t\t\texpiresAt: clock() + ttlMs\n\t\t});\n\t\tfor (const leastRecentlyUsed of records.keys()) {\n\t\t\tif (records.size <= maxEntries) break;\n\t\t\trecords.delete(leastRecentlyUsed);\n\t\t}\n\t\treturn true;\n\t}\n\tasync function unset(target) {\n\t\tif (target.meta !== void 0) throw metaUnsupported();\n\t\tfor (const key of target.keys ?? []) {\n\t\t\trecords.delete(key);\n\t\t\tconst version = versionOf(key) + 1;\n\t\t\tversions.delete(key);\n\t\t\tversions.set(key, {\n\t\t\t\tversion,\n\t\t\t\texpiresAt: clock() + ttlMs\n\t\t\t});\n\t\t}\n\t}\n\treturn {\n\t\tget,\n\t\tset,\n\t\tunset\n\t};\n}\n//#endregion\n//#region src/cache-middleware.ts\n/**\n* The default `deriveKey`: the family runtime's content hash of the plan, which covers the\n* statement, its parameters and the storage hash.\n*/\nfunction deriveKeyFromContentHash(exec, ctx) {\n\treturn ctx.contentHash(exec);\n}\nconst pendingMiss = Symbol(\"cache.pendingMiss\");\nfunction pendingOf(ctx) {\n\tconst miss = ctx.state(pendingMiss)[\"miss\"];\n\treturn isPendingMiss(miss) ? miss : void 0;\n}\nfunction isPendingMiss(value) {\n\treturn typeof value === \"object\" && value !== null && \"entry\" in value && \"buffer\" in value;\n}\nfunction hasTag(value, tag) {\n\treturn value.kind === tag;\n}\nfunction cacheable(ctx) {\n\treturn ctx.scope === \"runtime\" && !ctx.inTransaction();\n}\n/** The value a pending miss stores when its activity ends this way, or `undefined` to store nothing. */\nfunction valueToStore(miss, result) {\n\tif (result.outcome !== \"succeeded\") return void 0;\n\tif (result.kind === \"statement\") return result.source === \"driver\" && miss.buffer !== void 0 ? {\n\t\tkind: \"statement-rows\",\n\t\trows: miss.buffer\n\t} : void 0;\n\tif (result.kind === \"transaction\") return void 0;\n\treturn result.source === \"client\" && result.result !== void 0 ? {\n\t\tkind: \"call-result\",\n\t\tresult: result.result\n\t} : void 0;\n}\n/**\n* Creates a read-through cache middleware that works with every family runtime.\n*\n* It caches an activity that carries `cacheAnnotation` without `bypass` and runs in runtime scope,\n* outside any transaction: never on a held connection, whose session may change what a read\n* returns, and never inside a transaction, which must read its own uncommitted writes. Two kinds\n* of activity are cached:\n*\n* - A statement whose plan carries the annotation, such as an annotated SQL builder query. Its key\n* is the annotation's `key`, else `deriveKey(exec, ctx)`; its value is the raw rows.\n* - A client activity that carries the annotation, such as an annotated ORM read. Its key is the\n* annotation's `key`, else `await activity.contentHash()`; its value is the result the client\n* ended the activity with. It is served as a whole, so a hit sends no statement.\n*\n* The middleware tags each stored value `statement-rows` or `call-result` and serves `statement-rows` only to a statement and `call-result` only to a client activity; under the same key, a value with the other tag is a miss, and the read stores its own value in its place. A key therefore belongs to one query and one terminal method: an ORM call served another method's result under a shared key fails with `ORM.INTERCEPTED_RESULT_INVALID` or returns the wrong shape.\n*\n* - `intercept.onQuery` and `intercept.onActivity` — on a hit, return the stored rows or result,\n* and nothing runs. On a miss, record the pending entry.\n* - `onRow` — collects each row of a statement miss.\n* - `activityEnded` — when the driver completed the statement, or the client ended the call\n* `succeeded` with a result (`null` is a result), calls `store.set(entry, value)` with the entry\n* `store.get` returned, which stores only if the key's version has not moved. If an `unset` moved\n* it meanwhile, `set` returns `false` and the middleware logs `middleware.cache.store-skipped`.\n*\n* @example\n* ```typescript\n* const cache = createCacheMiddleware();\n* const db = postgres({ contract, url, middleware: [cache] });\n*\n* const user = await db.orm.public.User.first(\n* { id: 1 },\n* (meta) => meta.annotate(cacheAnnotation({ key: 'user-1' })),\n* );\n* await db.orm.public.User.where({ id: 1 }).update({ name: 'Alicia' });\n* await cache.invalidate({ keys: ['user-1'] });\n* ```\n*/\nfunction createCacheMiddleware(options) {\n\tconst store = options?.store ?? createInMemoryCacheStore();\n\tconst deriveKey = options?.deriveKey ?? deriveKeyFromContentHash;\n\tasync function lookUp(tag, key, meta, ctx, buffer) {\n\t\tconst entry = await store.get({\n\t\t\tkey,\n\t\t\tmeta\n\t\t});\n\t\tif (!entry.data.empty && hasTag(entry.data.value, tag)) {\n\t\t\tctx.log.debug?.({\n\t\t\t\tevent: \"middleware.cache.hit\",\n\t\t\t\tmiddleware: \"cache\",\n\t\t\t\tkey\n\t\t\t});\n\t\t\treturn entry.data.value;\n\t\t}\n\t\tctx.state(pendingMiss)[\"miss\"] = {\n\t\t\tentry,\n\t\t\tbuffer\n\t\t};\n\t\tctx.log.debug?.({\n\t\t\tevent: \"middleware.cache.miss\",\n\t\t\tmiddleware: \"cache\",\n\t\t\tkey\n\t\t});\n\t}\n\tasync function onQuery(exec, ctx) {\n\t\tif (!cacheable(ctx)) return;\n\t\tconst annotation = cacheAnnotation.read(exec);\n\t\tif (annotation === void 0 || annotation.bypass === true) return;\n\t\tconst value = await lookUp(\"statement-rows\", annotation.key ?? await deriveKey(exec, ctx), annotation.meta, ctx, []);\n\t\treturn value === void 0 ? void 0 : { rows: value.rows };\n\t}\n\tasync function onActivity(activity, ctx) {\n\t\tif (!cacheable(ctx)) return;\n\t\tconst annotation = cacheAnnotation.read(activity);\n\t\tif (annotation === void 0 || annotation.bypass === true) return;\n\t\tconst value = await lookUp(\"call-result\", annotation.key ?? await activity.contentHash(), annotation.meta, ctx, void 0);\n\t\treturn value === void 0 ? void 0 : { result: value.result };\n\t}\n\tasync function onRow(row, _exec, ctx) {\n\t\tpendingOf(ctx)?.buffer?.push(row);\n\t}\n\tasync function activityEnded(_activity, result, ctx) {\n\t\tconst miss = pendingOf(ctx);\n\t\tif (miss === void 0) return;\n\t\tdelete ctx.state(pendingMiss)[\"miss\"];\n\t\tconst value = valueToStore(miss, result);\n\t\tif (value === void 0) return;\n\t\tconst stored = await store.set(miss.entry, value);\n\t\tctx.log.debug?.({\n\t\t\tevent: stored ? \"middleware.cache.store\" : \"middleware.cache.store-skipped\",\n\t\t\tmiddleware: \"cache\",\n\t\t\tkey: miss.entry.key\n\t\t});\n\t}\n\tasync function invalidate(target) {\n\t\tconst keys = target.keys !== void 0 && target.keys.length > 0 ? target.keys : void 0;\n\t\tif (keys === void 0 && target.meta === void 0) return;\n\t\tawait store.unset({\n\t\t\tkeys,\n\t\t\tmeta: target.meta\n\t\t});\n\t}\n\treturn {\n\t\tname: \"cache\",\n\t\tintercept: {\n\t\t\tonQuery,\n\t\t\tonActivity\n\t\t},\n\t\tonRow,\n\t\tactivityEnded,\n\t\tinvalidate\n\t};\n}\n//#endregion\nexport { cacheAnnotation, createCacheMiddleware, createInMemoryCacheStore, deriveKeyFromContentHash };\n\n//# sourceMappingURL=index.mjs.map"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/orm-extension-middleware-cache",
3
- "version": "8.0.0-rc.18-dev.20",
3
+ "version": "8.0.0-rc.18-dev.21",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -9,12 +9,12 @@
9
9
  "dist"
10
10
  ],
11
11
  "dependencies": {
12
- "@prisma/orm-framework": "8.0.0-rc.18-dev.20"
12
+ "@prisma/orm-framework": "8.0.0-rc.18-dev.21"
13
13
  },
14
14
  "devDependencies": {
15
- "@internal/middleware-cache": "8.0.0-rc.18-dev.20",
16
- "@repo/tsconfig": "8.0.0-rc.18-dev.20",
17
- "@repo/tsdown": "8.0.0-rc.18-dev.20",
15
+ "@internal/middleware-cache": "8.0.0-rc.18-dev.21",
16
+ "@repo/tsconfig": "8.0.0-rc.18-dev.21",
17
+ "@repo/tsdown": "8.0.0-rc.18-dev.21",
18
18
  "tsdown": "0.22.14",
19
19
  "typescript": "5.9.3"
20
20
  },