cds-caching 0.3.0 → 0.3.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 +12 -3
- package/package.json +1 -1
- package/srv/CachingService.js +36 -3
- package/srv/util.js +22 -4
package/README.md
CHANGED
|
@@ -460,12 +460,21 @@ Templates support the following properties:
|
|
|
460
460
|
|
|
461
461
|
|
|
462
462
|
```javascript
|
|
463
|
-
|
|
464
|
-
// Store with tags
|
|
463
|
+
// Store with static tag
|
|
465
464
|
await cache.set("key", "value", {
|
|
466
465
|
tags: [{ value: "user-123" }]
|
|
467
466
|
})
|
|
468
467
|
|
|
468
|
+
// Store with template tag (will generate a tag like "tenant-global-user-anonymous")
|
|
469
|
+
await cache.set("key", "value", {
|
|
470
|
+
tags: [{ template: "tenant-{tenant}-user-{user}" }]
|
|
471
|
+
})
|
|
472
|
+
|
|
473
|
+
// Store with data-based tag
|
|
474
|
+
await cache.set("key", { id: 123, name: "Product" }, {
|
|
475
|
+
tags: [{ data: "id", prefix: "product-" }]
|
|
476
|
+
})
|
|
477
|
+
|
|
469
478
|
// Invalidate by tag
|
|
470
479
|
await cache.deleteByTag('user-123')
|
|
471
480
|
```
|
|
@@ -796,4 +805,4 @@ Contributions are welcome! Please read our contributing guidelines and submit pu
|
|
|
796
805
|
|
|
797
806
|
### License
|
|
798
807
|
|
|
799
|
-
This project is licensed under the
|
|
808
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
package/package.json
CHANGED
package/srv/CachingService.js
CHANGED
|
@@ -21,7 +21,7 @@ class CachingService extends cds.Service {
|
|
|
21
21
|
this.options = this.options || {
|
|
22
22
|
store: null,
|
|
23
23
|
compression: null,
|
|
24
|
-
credentials: {
|
|
24
|
+
credentials: {}
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
let store;
|
|
@@ -74,6 +74,9 @@ class CachingService extends cds.Service {
|
|
|
74
74
|
if (typeof event.data.value === "object") {
|
|
75
75
|
event.data.value = JSON.stringify(event.data.value);
|
|
76
76
|
}
|
|
77
|
+
|
|
78
|
+
console.log(event.data);
|
|
79
|
+
|
|
77
80
|
await this.cache.set(event.data.key, event.data.value, (event.data.ttl || 0))
|
|
78
81
|
});
|
|
79
82
|
|
|
@@ -239,7 +242,7 @@ class CachingService extends cds.Service {
|
|
|
239
242
|
return cachedValue;
|
|
240
243
|
}
|
|
241
244
|
const response = await next();
|
|
242
|
-
req.cacheOptions.tags = this.resolveTags(req.cacheOptions.tags, response, req.params);
|
|
245
|
+
req.cacheOptions.tags = this.resolveTags(req.cacheOptions.tags, response, { ...req.params, user: req.user.id, tenant: req.tenant, locale: req.locale, hash: this.createKey(req, { template: '{hash}' }) });
|
|
243
246
|
await this.set(req.cacheKey, response, req.cacheOptions);
|
|
244
247
|
return response;
|
|
245
248
|
case "cds.ql":
|
|
@@ -259,7 +262,7 @@ class CachingService extends cds.Service {
|
|
|
259
262
|
return this.get(query.cacheKey);
|
|
260
263
|
}
|
|
261
264
|
const data = await srv.run(query);
|
|
262
|
-
options.tags = this.resolveTags(options.tags, data, query.params);
|
|
265
|
+
options.tags = this.resolveTags(options.tags, data, { ...query.params, hash: this.createKey(query, { template: '{hash}' }) });
|
|
263
266
|
await this.set(query.cacheKey, data, options);
|
|
264
267
|
return data;
|
|
265
268
|
} else {
|
|
@@ -393,6 +396,36 @@ class CachingService extends cds.Service {
|
|
|
393
396
|
return [tag];
|
|
394
397
|
}
|
|
395
398
|
|
|
399
|
+
// Handle template-based tags
|
|
400
|
+
if (config.template) {
|
|
401
|
+
const createHash = (data) => crypto.createHash('md5').update(JSON.stringify(data)).digest('hex');
|
|
402
|
+
|
|
403
|
+
const hashParts = [
|
|
404
|
+
...(data ? [data] : []),
|
|
405
|
+
...(params ? [params] : [])
|
|
406
|
+
];
|
|
407
|
+
|
|
408
|
+
const contextVars = {
|
|
409
|
+
tenant: params.tenant || 'global',
|
|
410
|
+
user: params.user || 'anonymous',
|
|
411
|
+
locale: params.locale || 'en',
|
|
412
|
+
hash: createHash(hashParts)
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
const value = config.template.replace(
|
|
416
|
+
/\{(tenant|user|locale|hash)\}/g,
|
|
417
|
+
(match, variable) => contextVars[variable]
|
|
418
|
+
);
|
|
419
|
+
|
|
420
|
+
const tag = [
|
|
421
|
+
config.prefix,
|
|
422
|
+
value,
|
|
423
|
+
config.suffix
|
|
424
|
+
].filter(Boolean).join('');
|
|
425
|
+
|
|
426
|
+
return [tag];
|
|
427
|
+
}
|
|
428
|
+
|
|
396
429
|
// Handle data-based tags
|
|
397
430
|
if (config.data && dataArray.length) {
|
|
398
431
|
return dataArray.flatMap(item => {
|
package/srv/util.js
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
const cds = require("@sap/cds")
|
|
2
2
|
|
|
3
|
+
const extractCacheProperties = (entity, prefix) => {
|
|
4
|
+
const result = {};
|
|
5
|
+
for (const key of Object.keys(entity)) {
|
|
6
|
+
if (key.startsWith(`@cache.${prefix}.`)) {
|
|
7
|
+
const subKey = key.substring(`@cache.${prefix}.`.length);
|
|
8
|
+
result[subKey] = entity[key];
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
// If there are no subproperties but the main property exists, use it directly
|
|
12
|
+
if (Object.keys(result).length === 0 && entity[`@cache.${prefix}`]) {
|
|
13
|
+
return entity[`@cache.${prefix}`];
|
|
14
|
+
}
|
|
15
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
16
|
+
};
|
|
17
|
+
|
|
3
18
|
const bindFunction = async (service, action, isBound = false) => {
|
|
4
19
|
const cache = await cds.connect.to(action['@cache.service'] || "caching");
|
|
5
20
|
cache.addCachableFunction(action.name.split('.').pop(), action, isBound);
|
|
@@ -9,8 +24,8 @@ const bindFunction = async (service, action, isBound = false) => {
|
|
|
9
24
|
const cache = await cds.connect.to(action['@cache.service'] || "caching");
|
|
10
25
|
const data = await cache.run(req, next, {
|
|
11
26
|
ttl: action['@cache.ttl'],
|
|
12
|
-
tags: action['@cache.tags'],
|
|
13
|
-
key: action
|
|
27
|
+
tags: action['@cache.tags'],
|
|
28
|
+
key: extractCacheProperties(action, 'key')
|
|
14
29
|
});
|
|
15
30
|
return data;
|
|
16
31
|
})
|
|
@@ -21,10 +36,13 @@ const bindEntity = async (service, entity) => {
|
|
|
21
36
|
service.prepend(function () {
|
|
22
37
|
service.on('READ', entity.name, async (req, next) => {
|
|
23
38
|
const cache = await cds.connect.to(entity['@cache.service'] || "caching");
|
|
39
|
+
|
|
40
|
+
console.log(entity);
|
|
41
|
+
|
|
24
42
|
const data = await cache.run(req, next, {
|
|
25
43
|
ttl: entity['@cache.ttl'],
|
|
26
|
-
tags: entity['@cache.tags'],
|
|
27
|
-
key: entity
|
|
44
|
+
tags: entity['@cache.tags'],
|
|
45
|
+
key: extractCacheProperties(entity, 'key')
|
|
28
46
|
});
|
|
29
47
|
return data;
|
|
30
48
|
})
|