@knaus94/prisma-extension-cache-manager 1.2.0 → 1.2.2
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/README.md +75 -1
- package/dist/index.js +8 -20
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1 +1,75 @@
|
|
|
1
|
-
# prisma-extension-cache-manager
|
|
1
|
+
# @knaus94/prisma-extension-cache-manager
|
|
2
|
+
|
|
3
|
+
A caching extension for [Prisma](https://www.prisma.io/), compatible with [cache-manager](https://www.npmjs.com/package/cache-manager).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- [cache-manager](https://www.npmjs.com/package/cache-manager) compatibility
|
|
8
|
+
- Only model queries can be cacheable (no $query or $queryRaw)
|
|
9
|
+
- In-memory cache is recommended, since types like Date or Prisma.Decimal would be lost if using JSON serialization (maybe will try to use some binary serialization in the future)
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Install:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
npm i @knaus94/prisma-extension-cache-manager
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { PrismaClient } from "@prisma/client";
|
|
23
|
+
import * as cm from "cache-manager";
|
|
24
|
+
import cacheExtension from "@knaus94/prisma-extension-cache-manager";
|
|
25
|
+
|
|
26
|
+
async function main() {
|
|
27
|
+
const cache = await cm.caching("memory", {
|
|
28
|
+
ttl: 10000,
|
|
29
|
+
max: 200,
|
|
30
|
+
});
|
|
31
|
+
const prisma = new PrismaClient().$extends(cacheExtension({ cache }));
|
|
32
|
+
await prisma.user.findUniqueOrThrow({
|
|
33
|
+
where: {
|
|
34
|
+
email: user.email,
|
|
35
|
+
},
|
|
36
|
+
cache: true, // using cache default settings
|
|
37
|
+
});
|
|
38
|
+
await prisma.user.findMany({
|
|
39
|
+
cache: 5000, // setting ttl in milliseconds
|
|
40
|
+
});
|
|
41
|
+
await prisma.user.count({
|
|
42
|
+
cache: {
|
|
43
|
+
ttl: 2000,
|
|
44
|
+
key: "user_count", // custom cache key
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
await prisma.user.update({
|
|
48
|
+
data: {},
|
|
49
|
+
cache: {
|
|
50
|
+
ttl: 2000,
|
|
51
|
+
key: (result) => `user-${user.id}`, // custom cache key by result (There will be no reading from the cache, only a write down)
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
await prisma.user.create({
|
|
55
|
+
data: {},
|
|
56
|
+
unchace: `user_count`, // delete key from cache
|
|
57
|
+
});
|
|
58
|
+
await prisma.user.create({
|
|
59
|
+
data: {},
|
|
60
|
+
cache: {
|
|
61
|
+
ttl: 2000,
|
|
62
|
+
key: (result) => `user-${user.id}`, // custom cache key by result (There will be no reading from the cache, only a write down)
|
|
63
|
+
},
|
|
64
|
+
unchace: [`user_count`, `users`], // delete keys from cache
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
main().catch(console.error);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Learn more
|
|
72
|
+
|
|
73
|
+
- [Docs — Client extensions](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions)
|
|
74
|
+
- [Docs — Shared extensions](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions/shared-extensions)
|
|
75
|
+
- [Preview announcement blog post](https://www.prisma.io/blog/client-extensions-preview-8t3w27xkrxxn#introduction)
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,7 @@ exports.default = ({ cache }) => {
|
|
|
23
23
|
async $allOperations({ model, operation, args, query }) {
|
|
24
24
|
if (!types_1.CACHE_OPERATIONS.includes(operation))
|
|
25
25
|
return query(args);
|
|
26
|
-
const
|
|
26
|
+
const isWriteOperation = [
|
|
27
27
|
"create",
|
|
28
28
|
"upsert",
|
|
29
29
|
"update",
|
|
@@ -50,7 +50,7 @@ exports.default = ({ cache }) => {
|
|
|
50
50
|
.catch(() => false);
|
|
51
51
|
}
|
|
52
52
|
const useCache = cacheOption !== undefined &&
|
|
53
|
-
["boolean", "object"].includes(typeof cacheOption);
|
|
53
|
+
["boolean", "object", "number"].includes(typeof cacheOption);
|
|
54
54
|
const useUncache = uncacheOption !== undefined &&
|
|
55
55
|
(typeof uncacheOption === "function" ||
|
|
56
56
|
typeof uncacheOption === "string" ||
|
|
@@ -61,12 +61,12 @@ exports.default = ({ cache }) => {
|
|
|
61
61
|
processUncache(result);
|
|
62
62
|
return result;
|
|
63
63
|
}
|
|
64
|
-
if (typeof cacheOption
|
|
64
|
+
if (["boolean", "number"].includes(typeof cacheOption)) {
|
|
65
65
|
const cacheKey = generateComposedKey({
|
|
66
66
|
model,
|
|
67
67
|
queryArgs,
|
|
68
68
|
});
|
|
69
|
-
if (!
|
|
69
|
+
if (!isWriteOperation) {
|
|
70
70
|
const cached = await cache.get(cacheKey);
|
|
71
71
|
if (cached) {
|
|
72
72
|
return typeof cached === "string" ? JSON.parse(cached) : cached;
|
|
@@ -75,7 +75,7 @@ exports.default = ({ cache }) => {
|
|
|
75
75
|
const result = await query(queryArgs);
|
|
76
76
|
if (useUncache)
|
|
77
77
|
processUncache(result);
|
|
78
|
-
await cache.set(cacheKey, JSON.stringify(result));
|
|
78
|
+
await cache.set(cacheKey, JSON.stringify(result), typeof cacheOption === "number" ? cacheOption : undefined);
|
|
79
79
|
return result;
|
|
80
80
|
}
|
|
81
81
|
const { key, ttl } = cacheOption;
|
|
@@ -84,13 +84,7 @@ exports.default = ({ cache }) => {
|
|
|
84
84
|
if (useUncache)
|
|
85
85
|
processUncache(result);
|
|
86
86
|
const customCacheKey = key(result);
|
|
87
|
-
|
|
88
|
-
if (ttl) {
|
|
89
|
-
await cache.set(customCacheKey, value, ttl);
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
await cache.set(customCacheKey, value);
|
|
93
|
-
}
|
|
87
|
+
await cache.set(customCacheKey, JSON.stringify(result), ttl);
|
|
94
88
|
return result;
|
|
95
89
|
}
|
|
96
90
|
const customCacheKey = key ||
|
|
@@ -98,7 +92,7 @@ exports.default = ({ cache }) => {
|
|
|
98
92
|
model,
|
|
99
93
|
queryArgs,
|
|
100
94
|
});
|
|
101
|
-
if (!
|
|
95
|
+
if (!isWriteOperation) {
|
|
102
96
|
const cached = await cache.get(customCacheKey);
|
|
103
97
|
if (cached) {
|
|
104
98
|
return typeof cached === "string" ? JSON.parse(cached) : cached;
|
|
@@ -107,13 +101,7 @@ exports.default = ({ cache }) => {
|
|
|
107
101
|
const result = await query(queryArgs);
|
|
108
102
|
if (useUncache)
|
|
109
103
|
processUncache(result);
|
|
110
|
-
|
|
111
|
-
if (ttl) {
|
|
112
|
-
await cache.set(customCacheKey, value, ttl);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
await cache.set(customCacheKey, value);
|
|
116
|
-
}
|
|
104
|
+
await cache.set(customCacheKey, JSON.stringify(result), ttl);
|
|
117
105
|
return result;
|
|
118
106
|
},
|
|
119
107
|
},
|
package/dist/types.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export interface CacheOptions<T, A, O extends RequiredArgsOperation | OptionalAr
|
|
|
23
23
|
ttl?: number;
|
|
24
24
|
}
|
|
25
25
|
export interface PrismaCacheArgs<T, A, O extends RequiredArgsOperation | OptionalArgsOperation> {
|
|
26
|
-
cache?: boolean | CacheOptions<T, A, O>;
|
|
26
|
+
cache?: boolean | number | CacheOptions<T, A, O>;
|
|
27
27
|
uncache?: ((result: Prisma.Result<T, A, O>) => string[] | string) | string | string[];
|
|
28
28
|
}
|
|
29
29
|
export interface PrismaRedisCacheConfig {
|