@nestjs-redisx/cache 1.0.0
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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/cache/api/decorators/cached.decorator.d.ts +152 -0
- package/dist/cache/api/decorators/cached.decorator.d.ts.map +1 -0
- package/dist/cache/api/decorators/invalidate-tags.decorator.d.ts +44 -0
- package/dist/cache/api/decorators/invalidate-tags.decorator.d.ts.map +1 -0
- package/dist/cache/application/ports/cache-service.port.d.ts +120 -0
- package/dist/cache/application/ports/cache-service.port.d.ts.map +1 -0
- package/dist/cache/application/ports/l1-cache-store.port.d.ts +56 -0
- package/dist/cache/application/ports/l1-cache-store.port.d.ts.map +1 -0
- package/dist/cache/application/ports/l2-cache-store.port.d.ts +98 -0
- package/dist/cache/application/ports/l2-cache-store.port.d.ts.map +1 -0
- package/dist/cache/application/services/cache-decorator-initializer.service.d.ts +25 -0
- package/dist/cache/application/services/cache-decorator-initializer.service.d.ts.map +1 -0
- package/dist/cache/application/services/cache.service.d.ts +106 -0
- package/dist/cache/application/services/cache.service.d.ts.map +1 -0
- package/dist/cache/application/services/warmup.service.d.ts +25 -0
- package/dist/cache/application/services/warmup.service.d.ts.map +1 -0
- package/dist/cache/domain/services/serializer.service.d.ts +29 -0
- package/dist/cache/domain/services/serializer.service.d.ts.map +1 -0
- package/dist/cache/domain/value-objects/cache-entry.vo.d.ts +69 -0
- package/dist/cache/domain/value-objects/cache-entry.vo.d.ts.map +1 -0
- package/dist/cache/domain/value-objects/cache-key.vo.d.ts +45 -0
- package/dist/cache/domain/value-objects/cache-key.vo.d.ts.map +1 -0
- package/dist/cache/domain/value-objects/tag.vo.d.ts +36 -0
- package/dist/cache/domain/value-objects/tag.vo.d.ts.map +1 -0
- package/dist/cache/domain/value-objects/tags.vo.d.ts +57 -0
- package/dist/cache/domain/value-objects/tags.vo.d.ts.map +1 -0
- package/dist/cache/domain/value-objects/ttl.vo.d.ts +58 -0
- package/dist/cache/domain/value-objects/ttl.vo.d.ts.map +1 -0
- package/dist/cache/infrastructure/adapters/l1-memory-store.adapter.d.ts +36 -0
- package/dist/cache/infrastructure/adapters/l1-memory-store.adapter.d.ts.map +1 -0
- package/dist/cache/infrastructure/adapters/l2-redis-store.adapter.d.ts +41 -0
- package/dist/cache/infrastructure/adapters/l2-redis-store.adapter.d.ts.map +1 -0
- package/dist/cache.plugin.d.ts +17 -0
- package/dist/cache.plugin.d.ts.map +1 -0
- package/dist/cache.service.d.ts +234 -0
- package/dist/cache.service.d.ts.map +1 -0
- package/dist/decorators/cache-evict.decorator.d.ts +97 -0
- package/dist/decorators/cache-evict.decorator.d.ts.map +1 -0
- package/dist/decorators/cache-put.decorator.d.ts +95 -0
- package/dist/decorators/cache-put.decorator.d.ts.map +1 -0
- package/dist/decorators/cache.interceptor.d.ts +63 -0
- package/dist/decorators/cache.interceptor.d.ts.map +1 -0
- package/dist/decorators/cacheable.decorator.d.ts +88 -0
- package/dist/decorators/cacheable.decorator.d.ts.map +1 -0
- package/dist/decorators/key-generator.util.d.ts +69 -0
- package/dist/decorators/key-generator.util.d.ts.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4199 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +4152 -0
- package/dist/index.mjs.map +1 -0
- package/dist/invalidation/application/ports/event-invalidation.port.d.ts +28 -0
- package/dist/invalidation/application/ports/event-invalidation.port.d.ts.map +1 -0
- package/dist/invalidation/application/ports/invalidation-registry.port.d.ts +36 -0
- package/dist/invalidation/application/ports/invalidation-registry.port.d.ts.map +1 -0
- package/dist/invalidation/application/services/event-invalidation.service.d.ts +30 -0
- package/dist/invalidation/application/services/event-invalidation.service.d.ts.map +1 -0
- package/dist/invalidation/application/services/invalidation-registry.service.d.ts +17 -0
- package/dist/invalidation/application/services/invalidation-registry.service.d.ts.map +1 -0
- package/dist/invalidation/domain/entities/invalidation-rule.entity.d.ts +60 -0
- package/dist/invalidation/domain/entities/invalidation-rule.entity.d.ts.map +1 -0
- package/dist/invalidation/domain/value-objects/event-pattern.vo.d.ts +27 -0
- package/dist/invalidation/domain/value-objects/event-pattern.vo.d.ts.map +1 -0
- package/dist/invalidation/domain/value-objects/tag-template.vo.d.ts +34 -0
- package/dist/invalidation/domain/value-objects/tag-template.vo.d.ts.map +1 -0
- package/dist/invalidation/infrastructure/adapters/amqp-event-source.adapter.d.ts +51 -0
- package/dist/invalidation/infrastructure/adapters/amqp-event-source.adapter.d.ts.map +1 -0
- package/dist/invalidation/infrastructure/decorators/invalidate-on.decorator.d.ts +69 -0
- package/dist/invalidation/infrastructure/decorators/invalidate-on.decorator.d.ts.map +1 -0
- package/dist/key-builder.d.ts +199 -0
- package/dist/key-builder.d.ts.map +1 -0
- package/dist/serializers/index.d.ts +19 -0
- package/dist/serializers/index.d.ts.map +1 -0
- package/dist/serializers/json.serializer.d.ts +51 -0
- package/dist/serializers/json.serializer.d.ts.map +1 -0
- package/dist/serializers/msgpack.serializer.d.ts +67 -0
- package/dist/serializers/msgpack.serializer.d.ts.map +1 -0
- package/dist/serializers/serializer.interface.d.ts +36 -0
- package/dist/serializers/serializer.interface.d.ts.map +1 -0
- package/dist/shared/constants/index.d.ts +73 -0
- package/dist/shared/constants/index.d.ts.map +1 -0
- package/dist/shared/errors/index.d.ts +46 -0
- package/dist/shared/errors/index.d.ts.map +1 -0
- package/dist/shared/types/context-provider.interface.d.ts +58 -0
- package/dist/shared/types/context-provider.interface.d.ts.map +1 -0
- package/dist/shared/types/index.d.ts +259 -0
- package/dist/shared/types/index.d.ts.map +1 -0
- package/dist/stampede/application/ports/stampede-protection.port.d.ts +33 -0
- package/dist/stampede/application/ports/stampede-protection.port.d.ts.map +1 -0
- package/dist/stampede/infrastructure/stampede-protection.service.d.ts +30 -0
- package/dist/stampede/infrastructure/stampede-protection.service.d.ts.map +1 -0
- package/dist/strategies/eviction-strategy.interface.d.ts +39 -0
- package/dist/strategies/eviction-strategy.interface.d.ts.map +1 -0
- package/dist/strategies/fifo.strategy.d.ts +86 -0
- package/dist/strategies/fifo.strategy.d.ts.map +1 -0
- package/dist/strategies/index.d.ts +19 -0
- package/dist/strategies/index.d.ts.map +1 -0
- package/dist/strategies/lfu.strategy.d.ts +87 -0
- package/dist/strategies/lfu.strategy.d.ts.map +1 -0
- package/dist/strategies/lru.strategy.d.ts +78 -0
- package/dist/strategies/lru.strategy.d.ts.map +1 -0
- package/dist/swr/application/ports/swr-manager.port.d.ts +83 -0
- package/dist/swr/application/ports/swr-manager.port.d.ts.map +1 -0
- package/dist/swr/infrastructure/swr-manager.service.d.ts +30 -0
- package/dist/swr/infrastructure/swr-manager.service.d.ts.map +1 -0
- package/dist/tags/application/ports/tag-index.port.d.ts +55 -0
- package/dist/tags/application/ports/tag-index.port.d.ts.map +1 -0
- package/dist/tags/infrastructure/repositories/tag-index.repository.d.ts +37 -0
- package/dist/tags/infrastructure/repositories/tag-index.repository.d.ts.map +1 -0
- package/dist/tags/infrastructure/scripts/lua-scripts.d.ts +25 -0
- package/dist/tags/infrastructure/scripts/lua-scripts.d.ts.map +1 -0
- package/dist/tags/infrastructure/services/lua-script-loader.service.d.ts +44 -0
- package/dist/tags/infrastructure/services/lua-script-loader.service.d.ts.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anti-stampede protection using local singleflight + distributed Redis lock.
|
|
3
|
+
*
|
|
4
|
+
* Two layers of protection:
|
|
5
|
+
* 1. Local singleflight — coalesces concurrent requests within the same process
|
|
6
|
+
* 2. Distributed lock — prevents duplicate loading across multiple instances
|
|
7
|
+
*/
|
|
8
|
+
import { IRedisDriver } from '@nestjs-redisx/core';
|
|
9
|
+
import { ICachePluginOptions, IStampedeResult, IStampedeStats } from '../../shared/types';
|
|
10
|
+
import { IStampedeProtection } from '../application/ports/stampede-protection.port';
|
|
11
|
+
export declare class StampedeProtectionService implements IStampedeProtection {
|
|
12
|
+
private readonly options;
|
|
13
|
+
private readonly driver;
|
|
14
|
+
private readonly logger;
|
|
15
|
+
private readonly flights;
|
|
16
|
+
private readonly lockTimeout;
|
|
17
|
+
private readonly waitTimeout;
|
|
18
|
+
private prevented;
|
|
19
|
+
constructor(options: ICachePluginOptions, driver: IRedisDriver);
|
|
20
|
+
protect<T>(key: string, loader: () => Promise<T>): Promise<IStampedeResult<T>>;
|
|
21
|
+
clearKey(key: string): Promise<void>;
|
|
22
|
+
clearAll(): Promise<void>;
|
|
23
|
+
getStats(): IStampedeStats;
|
|
24
|
+
private waitForFlight;
|
|
25
|
+
private executeLoader;
|
|
26
|
+
private tryAcquireLock;
|
|
27
|
+
private releaseLock;
|
|
28
|
+
private generateLockValue;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=stampede-protection.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stampede-protection.service.d.ts","sourceRoot":"","sources":["../../../src/stampede/infrastructure/stampede-protection.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAgB,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAIjE,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AAyBpF,qBACa,yBAA0B,YAAW,mBAAmB;IASjE,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8C;IACrE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,SAAS,CAAK;gBAIH,OAAO,EAAE,mBAAmB,EAE5B,MAAM,EAAE,YAAY;IAMjC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IA2E9E,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASpC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B,QAAQ,IAAI,cAAc;YAsBZ,aAAa;YA4Bb,aAAa;YA6Bb,cAAc;YAUd,WAAW;IAQzB,OAAO,CAAC,iBAAiB;CAG1B"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eviction strategy interface for cache management.
|
|
3
|
+
* Defines how items should be evicted when cache reaches capacity.
|
|
4
|
+
*/
|
|
5
|
+
export interface IEvictionStrategy<K = string, _V = unknown> {
|
|
6
|
+
/**
|
|
7
|
+
* Records access to a key (for LRU, etc.)
|
|
8
|
+
*
|
|
9
|
+
* @param key - Cache key that was accessed
|
|
10
|
+
*/
|
|
11
|
+
recordAccess(key: K): void;
|
|
12
|
+
/**
|
|
13
|
+
* Records insertion of a new key
|
|
14
|
+
*
|
|
15
|
+
* @param key - Cache key that was inserted
|
|
16
|
+
*/
|
|
17
|
+
recordInsert(key: K): void;
|
|
18
|
+
/**
|
|
19
|
+
* Records deletion of a key
|
|
20
|
+
*
|
|
21
|
+
* @param key - Cache key that was deleted
|
|
22
|
+
*/
|
|
23
|
+
recordDelete(key: K): void;
|
|
24
|
+
/**
|
|
25
|
+
* Selects key to evict based on strategy
|
|
26
|
+
*
|
|
27
|
+
* @returns Key to evict, or undefined if no candidates
|
|
28
|
+
*/
|
|
29
|
+
selectVictim(): K | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Clears all tracking data
|
|
32
|
+
*/
|
|
33
|
+
clear(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Gets current size of tracked keys
|
|
36
|
+
*/
|
|
37
|
+
size(): number;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=eviction-strategy.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eviction-strategy.interface.d.ts","sourceRoot":"","sources":["../../src/strategies/eviction-strategy.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,MAAM,EAAE,EAAE,GAAG,OAAO;IACzD;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;IAE3B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;IAE3B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;IAE3B;;;;OAIG;IACH,YAAY,IAAI,CAAC,GAAG,SAAS,CAAC;IAE9B;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,IAAI,IAAI,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First In First Out (FIFO) eviction strategy.
|
|
3
|
+
*
|
|
4
|
+
* Evicts the oldest inserted item when cache is full.
|
|
5
|
+
* Does not consider access patterns - only insertion order matters.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const strategy = new FifoStrategy<string>();
|
|
10
|
+
*
|
|
11
|
+
* strategy.recordInsert('key1');
|
|
12
|
+
* strategy.recordInsert('key2');
|
|
13
|
+
* strategy.recordAccess('key1'); // Access doesn't affect order in FIFO
|
|
14
|
+
*
|
|
15
|
+
* const victim = strategy.selectVictim(); // Returns 'key1' (first inserted)
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import { IEvictionStrategy } from './eviction-strategy.interface';
|
|
19
|
+
export declare class FifoStrategy<K = string> implements IEvictionStrategy<K> {
|
|
20
|
+
/**
|
|
21
|
+
* Queue maintaining keys in insertion order.
|
|
22
|
+
* First element is oldest (next to evict).
|
|
23
|
+
*/
|
|
24
|
+
private readonly queue;
|
|
25
|
+
/**
|
|
26
|
+
* Set for O(1) existence checks
|
|
27
|
+
*/
|
|
28
|
+
private readonly keySet;
|
|
29
|
+
constructor();
|
|
30
|
+
/**
|
|
31
|
+
* Records access to a key.
|
|
32
|
+
* In FIFO, access doesn't affect eviction order, so this is a no-op.
|
|
33
|
+
*
|
|
34
|
+
* @param _key - Key that was accessed
|
|
35
|
+
*/
|
|
36
|
+
recordAccess(_key: K): void;
|
|
37
|
+
/**
|
|
38
|
+
* Records insertion of a new key.
|
|
39
|
+
*
|
|
40
|
+
* @param key - Key that was inserted
|
|
41
|
+
*/
|
|
42
|
+
recordInsert(key: K): void;
|
|
43
|
+
/**
|
|
44
|
+
* Records deletion of a key.
|
|
45
|
+
*
|
|
46
|
+
* @param key - Key that was deleted
|
|
47
|
+
*/
|
|
48
|
+
recordDelete(key: K): void;
|
|
49
|
+
/**
|
|
50
|
+
* Selects the oldest inserted key for eviction.
|
|
51
|
+
*
|
|
52
|
+
* @returns Oldest key (first in queue), or undefined if empty
|
|
53
|
+
*/
|
|
54
|
+
selectVictim(): K | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Clears all tracking data.
|
|
57
|
+
*/
|
|
58
|
+
clear(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Gets current number of tracked keys.
|
|
61
|
+
*
|
|
62
|
+
* @returns Number of keys
|
|
63
|
+
*/
|
|
64
|
+
size(): number;
|
|
65
|
+
/**
|
|
66
|
+
* Gets all keys in FIFO order (oldest to newest).
|
|
67
|
+
*
|
|
68
|
+
* @returns Array of keys in insertion order
|
|
69
|
+
*/
|
|
70
|
+
getKeys(): K[];
|
|
71
|
+
/**
|
|
72
|
+
* Gets keys that should be evicted to reach target size.
|
|
73
|
+
*
|
|
74
|
+
* @param targetSize - Desired size after eviction
|
|
75
|
+
* @returns Array of keys to evict (oldest first)
|
|
76
|
+
*/
|
|
77
|
+
getVictims(targetSize: number): K[];
|
|
78
|
+
/**
|
|
79
|
+
* Checks if a key is tracked.
|
|
80
|
+
*
|
|
81
|
+
* @param key - Key to check
|
|
82
|
+
* @returns True if key is tracked
|
|
83
|
+
*/
|
|
84
|
+
has(key: K): boolean;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=fifo.strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fifo.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/fifo.strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,qBAAa,YAAY,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,iBAAiB,CAAC,CAAC,CAAC;IACnE;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAM;IAE5B;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAOhC;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAK3B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;IAQ1B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;IAW1B;;;;OAIG;IACH,YAAY,IAAI,CAAC,GAAG,SAAS;IAI7B;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;;;OAIG;IACH,IAAI,IAAI,MAAM;IAId;;;;OAIG;IACH,OAAO,IAAI,CAAC,EAAE;IAId;;;;;OAKG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,EAAE;IAUnC;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;CAGrB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache eviction strategies.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { LruStrategy, FifoStrategy } from '@nestjs-redisx/cache';
|
|
7
|
+
*
|
|
8
|
+
* const lru = new LruStrategy<string>();
|
|
9
|
+
* lru.recordInsert('key1');
|
|
10
|
+
* lru.recordInsert('key2');
|
|
11
|
+
* lru.recordAccess('key1');
|
|
12
|
+
* const victim = lru.selectVictim(); // Returns 'key2'
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export type { IEvictionStrategy } from './eviction-strategy.interface';
|
|
16
|
+
export { LruStrategy } from './lru.strategy';
|
|
17
|
+
export { FifoStrategy } from './fifo.strategy';
|
|
18
|
+
export { LfuStrategy } from './lfu.strategy';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/strategies/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,YAAY,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Least Frequently Used (LFU) eviction strategy.
|
|
3
|
+
*
|
|
4
|
+
* Evicts the least frequently accessed item when cache is full.
|
|
5
|
+
* Tracks access frequency for each key, with insertion order as tiebreaker.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const strategy = new LfuStrategy<string>();
|
|
10
|
+
*
|
|
11
|
+
* strategy.recordInsert('key1');
|
|
12
|
+
* strategy.recordInsert('key2');
|
|
13
|
+
* strategy.recordAccess('key1'); // key1 frequency = 2
|
|
14
|
+
* strategy.recordAccess('key1'); // key1 frequency = 3
|
|
15
|
+
*
|
|
16
|
+
* const victim = strategy.selectVictim(); // Returns 'key2' (frequency = 1)
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import { IEvictionStrategy } from './eviction-strategy.interface';
|
|
20
|
+
export declare class LfuStrategy<K = string> implements IEvictionStrategy<K> {
|
|
21
|
+
private readonly entries;
|
|
22
|
+
private insertCounter;
|
|
23
|
+
constructor();
|
|
24
|
+
/**
|
|
25
|
+
* Records access to a key, incrementing its frequency counter.
|
|
26
|
+
*
|
|
27
|
+
* @param key - Key that was accessed
|
|
28
|
+
*/
|
|
29
|
+
recordAccess(key: K): void;
|
|
30
|
+
/**
|
|
31
|
+
* Records insertion of a new key with initial frequency of 1.
|
|
32
|
+
*
|
|
33
|
+
* @param key - Key that was inserted
|
|
34
|
+
*/
|
|
35
|
+
recordInsert(key: K): void;
|
|
36
|
+
/**
|
|
37
|
+
* Records deletion of a key.
|
|
38
|
+
*
|
|
39
|
+
* @param key - Key that was deleted
|
|
40
|
+
*/
|
|
41
|
+
recordDelete(key: K): void;
|
|
42
|
+
/**
|
|
43
|
+
* Selects the least frequently used key for eviction.
|
|
44
|
+
* When frequencies are equal, the oldest inserted key is selected.
|
|
45
|
+
*
|
|
46
|
+
* @returns Least frequently used key, or undefined if empty
|
|
47
|
+
*/
|
|
48
|
+
selectVictim(): K | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Clears all tracking data.
|
|
51
|
+
*/
|
|
52
|
+
clear(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Gets current number of tracked keys.
|
|
55
|
+
*
|
|
56
|
+
* @returns Number of keys
|
|
57
|
+
*/
|
|
58
|
+
size(): number;
|
|
59
|
+
/**
|
|
60
|
+
* Gets all keys sorted by frequency (lowest first), then by insertion order.
|
|
61
|
+
*
|
|
62
|
+
* @returns Array of keys sorted by eviction priority
|
|
63
|
+
*/
|
|
64
|
+
getKeys(): K[];
|
|
65
|
+
/**
|
|
66
|
+
* Gets keys that should be evicted to reach target size.
|
|
67
|
+
*
|
|
68
|
+
* @param targetSize - Desired size after eviction
|
|
69
|
+
* @returns Array of keys to evict
|
|
70
|
+
*/
|
|
71
|
+
getVictims(targetSize: number): K[];
|
|
72
|
+
/**
|
|
73
|
+
* Checks if a key is tracked.
|
|
74
|
+
*
|
|
75
|
+
* @param key - Key to check
|
|
76
|
+
* @returns True if key is tracked
|
|
77
|
+
*/
|
|
78
|
+
has(key: K): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Gets the frequency count for a key.
|
|
81
|
+
*
|
|
82
|
+
* @param key - Key to check
|
|
83
|
+
* @returns Frequency count, or 0 if key not tracked
|
|
84
|
+
*/
|
|
85
|
+
getFrequency(key: K): number;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=lfu.strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lfu.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/lfu.strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAQlE,qBAAa,WAAW,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,iBAAiB,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,aAAa,CAAS;;IAO9B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;IAO1B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;IAW1B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;IAI1B;;;;;OAKG;IACH,YAAY,IAAI,CAAC,GAAG,SAAS;IAgB7B;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;;;OAIG;IACH,IAAI,IAAI,MAAM;IAId;;;;OAIG;IACH,OAAO,IAAI,CAAC,EAAE;IAMd;;;;;OAKG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,EAAE;IAWnC;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAIpB;;;;;OAKG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,MAAM;CAG7B"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Least Recently Used (LRU) eviction strategy.
|
|
3
|
+
*
|
|
4
|
+
* Evicts the least recently accessed item when cache is full.
|
|
5
|
+
* Uses a Map to maintain insertion order and updates order on access.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const strategy = new LruStrategy<string>();
|
|
10
|
+
*
|
|
11
|
+
* strategy.recordInsert('key1');
|
|
12
|
+
* strategy.recordInsert('key2');
|
|
13
|
+
* strategy.recordAccess('key1'); // key1 is now most recent
|
|
14
|
+
*
|
|
15
|
+
* const victim = strategy.selectVictim(); // Returns 'key2' (least recent)
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import { IEvictionStrategy } from './eviction-strategy.interface';
|
|
19
|
+
export declare class LruStrategy<K = string> implements IEvictionStrategy<K> {
|
|
20
|
+
/**
|
|
21
|
+
* Map maintaining keys in LRU order.
|
|
22
|
+
* JavaScript Map maintains insertion order, so we use delete+set to move to end.
|
|
23
|
+
*/
|
|
24
|
+
private readonly keyOrder;
|
|
25
|
+
/**
|
|
26
|
+
* Timestamp counter for tracking access order
|
|
27
|
+
*/
|
|
28
|
+
private timestamp;
|
|
29
|
+
constructor();
|
|
30
|
+
/**
|
|
31
|
+
* Records access to a key, moving it to most recently used position.
|
|
32
|
+
*
|
|
33
|
+
* @param key - Key that was accessed
|
|
34
|
+
*/
|
|
35
|
+
recordAccess(key: K): void;
|
|
36
|
+
/**
|
|
37
|
+
* Records insertion of a new key.
|
|
38
|
+
*
|
|
39
|
+
* @param key - Key that was inserted
|
|
40
|
+
*/
|
|
41
|
+
recordInsert(key: K): void;
|
|
42
|
+
/**
|
|
43
|
+
* Records deletion of a key.
|
|
44
|
+
*
|
|
45
|
+
* @param key - Key that was deleted
|
|
46
|
+
*/
|
|
47
|
+
recordDelete(key: K): void;
|
|
48
|
+
/**
|
|
49
|
+
* Selects the least recently used key for eviction.
|
|
50
|
+
*
|
|
51
|
+
* @returns Least recently used key, or undefined if empty
|
|
52
|
+
*/
|
|
53
|
+
selectVictim(): K | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Clears all tracking data.
|
|
56
|
+
*/
|
|
57
|
+
clear(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Gets current number of tracked keys.
|
|
60
|
+
*
|
|
61
|
+
* @returns Number of keys
|
|
62
|
+
*/
|
|
63
|
+
size(): number;
|
|
64
|
+
/**
|
|
65
|
+
* Gets all keys in LRU order (oldest to newest).
|
|
66
|
+
*
|
|
67
|
+
* @returns Array of keys sorted by access time
|
|
68
|
+
*/
|
|
69
|
+
getKeys(): K[];
|
|
70
|
+
/**
|
|
71
|
+
* Gets keys that should be evicted to reach target size.
|
|
72
|
+
*
|
|
73
|
+
* @param targetSize - Desired size after eviction
|
|
74
|
+
* @returns Array of keys to evict
|
|
75
|
+
*/
|
|
76
|
+
getVictims(targetSize: number): K[];
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=lru.strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lru.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/lru.strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,qBAAa,WAAW,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,iBAAiB,CAAC,CAAC,CAAC;IAClE;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAE1C;;OAEG;IACH,OAAO,CAAC,SAAS,CAAS;;IAO1B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;IAM1B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;IAK1B;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;IAI1B;;;;OAIG;IACH,YAAY,IAAI,CAAC,GAAG,SAAS;IAmB7B;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;;;OAIG;IACH,IAAI,IAAI,MAAM;IAId;;;;OAIG;IACH,OAAO,IAAI,CAAC,EAAE;IAMd;;;;;OAKG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,EAAE;CAUpC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stale-While-Revalidate manager interface.
|
|
3
|
+
*/
|
|
4
|
+
import { SwrEntry } from '../../../shared/types';
|
|
5
|
+
export interface ISwrManager {
|
|
6
|
+
/**
|
|
7
|
+
* Gets value from SWR cache.
|
|
8
|
+
* Returns value with staleness flag.
|
|
9
|
+
*
|
|
10
|
+
* @param key - Cache key
|
|
11
|
+
* @returns SWR entry or null if not found
|
|
12
|
+
*/
|
|
13
|
+
get<T>(key: string): Promise<SwrEntry<T> | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Sets value in SWR cache with metadata.
|
|
16
|
+
*
|
|
17
|
+
* @param key - Cache key
|
|
18
|
+
* @param value - Value to cache
|
|
19
|
+
* @param staleTimeSeconds - Time after which value is stale
|
|
20
|
+
*/
|
|
21
|
+
set<T>(key: string, value: T, staleTimeSeconds: number): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Deletes SWR entry.
|
|
24
|
+
*
|
|
25
|
+
* @param key - Cache key
|
|
26
|
+
*/
|
|
27
|
+
delete(key: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Checks if an entry is stale (past staleAt timestamp).
|
|
30
|
+
*
|
|
31
|
+
* @param entry - SWR entry to check
|
|
32
|
+
* @returns True if entry is stale
|
|
33
|
+
*/
|
|
34
|
+
isStale<T>(entry: SwrEntry<T>): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Checks if an entry has expired completely (past expiresAt timestamp).
|
|
37
|
+
*
|
|
38
|
+
* @param entry - SWR entry to check
|
|
39
|
+
* @returns True if entry has expired
|
|
40
|
+
*/
|
|
41
|
+
isExpired<T>(entry: SwrEntry<T>): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Schedules background revalidation for a key.
|
|
44
|
+
*
|
|
45
|
+
* @param key - Cache key
|
|
46
|
+
* @param loader - Function to load fresh value
|
|
47
|
+
* @param onSuccess - Callback when revalidation succeeds
|
|
48
|
+
* @param onError - Optional callback when revalidation fails
|
|
49
|
+
*/
|
|
50
|
+
scheduleRevalidation<T>(key: string, loader: () => Promise<T>, onSuccess: (value: T) => Promise<void>, onError?: (error: Error) => void): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Checks if revalidation can be started for a key.
|
|
53
|
+
* Returns false if revalidation is already in progress.
|
|
54
|
+
*
|
|
55
|
+
* @param key - Cache key
|
|
56
|
+
* @returns True if revalidation can proceed
|
|
57
|
+
*/
|
|
58
|
+
shouldRevalidate(key: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Creates an SWR entry with metadata.
|
|
61
|
+
*
|
|
62
|
+
* @param value - Value to cache
|
|
63
|
+
* @param freshTtl - Time in seconds until value becomes stale
|
|
64
|
+
* @param staleTtl - Optional time in seconds for stale period (defaults to config)
|
|
65
|
+
* @returns SWR entry with timestamps
|
|
66
|
+
*/
|
|
67
|
+
createSwrEntry<T>(value: T, freshTtl: number, staleTtl?: number): SwrEntry<T>;
|
|
68
|
+
/**
|
|
69
|
+
* Gets SWR manager statistics.
|
|
70
|
+
*
|
|
71
|
+
* @returns Stats object with active revalidations count
|
|
72
|
+
*/
|
|
73
|
+
getStats(): {
|
|
74
|
+
activeRevalidations: number;
|
|
75
|
+
enabled: boolean;
|
|
76
|
+
staleTtl: number;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Clears all pending revalidations.
|
|
80
|
+
*/
|
|
81
|
+
clearRevalidations(): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=swr-manager.port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swr-manager.port.d.ts","sourceRoot":"","sources":["../../../../src/swr/application/ports/swr-manager.port.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEjD;;;;;;OAMG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvE;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC;;;;;OAKG;IACH,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAExC;;;;;OAKG;IACH,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAE1C;;;;;;;OAOG;IACH,oBAAoB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExJ;;;;;;OAMG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAEvC;;;;;;;OAOG;IACH,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE9E;;;;OAIG;IACH,QAAQ,IAAI;QACV,mBAAmB,EAAE,MAAM,CAAC;QAC5B,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IAEF;;OAEG;IACH,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stale-While-Revalidate manager.
|
|
3
|
+
* Serves stale data while revalidating in the background.
|
|
4
|
+
*/
|
|
5
|
+
import { ICachePluginOptions, SwrEntry } from '../../shared/types';
|
|
6
|
+
import { ISwrManager } from '../application/ports/swr-manager.port';
|
|
7
|
+
export declare class SwrManagerService implements ISwrManager {
|
|
8
|
+
private readonly options;
|
|
9
|
+
private readonly logger;
|
|
10
|
+
private readonly jobs;
|
|
11
|
+
private readonly staleTtl;
|
|
12
|
+
private readonly enabled;
|
|
13
|
+
constructor(options: ICachePluginOptions);
|
|
14
|
+
get<T>(_key: string): Promise<SwrEntry<T> | null>;
|
|
15
|
+
set<T>(_key: string, _value: T, _staleTimeSeconds: number): Promise<void>;
|
|
16
|
+
delete(_key: string): Promise<void>;
|
|
17
|
+
isStale<T>(entry: SwrEntry<T>): boolean;
|
|
18
|
+
isExpired<T>(entry: SwrEntry<T>): boolean;
|
|
19
|
+
shouldRevalidate(key: string): boolean;
|
|
20
|
+
scheduleRevalidation<T>(key: string, loader: () => Promise<T>, onSuccess: (value: T) => Promise<void>, onError?: (error: Error) => void): Promise<void>;
|
|
21
|
+
createSwrEntry<T>(value: T, freshTtl: number, staleTtl?: number): SwrEntry<T>;
|
|
22
|
+
getStats(): {
|
|
23
|
+
activeRevalidations: number;
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
staleTtl: number;
|
|
26
|
+
};
|
|
27
|
+
clearRevalidations(): Promise<void>;
|
|
28
|
+
private executeRevalidation;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=swr-manager.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swr-manager.service.d.ts","sourceRoot":"","sources":["../../../src/swr/infrastructure/swr-manager.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAUpE,qBACa,iBAAkB,YAAW,WAAW;IAQjD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;IAC7D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgD;IACrE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAIf,OAAO,EAAE,mBAAmB;IAOzC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAMjD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO;IASvC,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO;IAKzC,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAMhC,oBAAoB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB7J,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC;IAa7E,QAAQ;;;;;IASF,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;YAI3B,mBAAmB;CAgBlC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tag index repository interface.
|
|
3
|
+
*/
|
|
4
|
+
export interface ITagIndex {
|
|
5
|
+
/**
|
|
6
|
+
* Adds cache key to tag indexes.
|
|
7
|
+
*
|
|
8
|
+
* @param key - Cache key (with full prefix)
|
|
9
|
+
* @param tags - Array of tags
|
|
10
|
+
*/
|
|
11
|
+
addKeyToTags(key: string, tags: string[]): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Removes cache key from specified tag indexes.
|
|
14
|
+
*
|
|
15
|
+
* @param key - Cache key
|
|
16
|
+
* @param tags - Tags to remove the key from
|
|
17
|
+
*/
|
|
18
|
+
removeKeyFromTags(key: string, tags: string[]): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Gets all cache keys associated with a tag.
|
|
21
|
+
*
|
|
22
|
+
* @param tag - Tag name
|
|
23
|
+
* @returns Array of cache keys
|
|
24
|
+
*/
|
|
25
|
+
getKeysByTag(tag: string): Promise<string[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Invalidates tag - deletes all associated cache keys and the tag index.
|
|
28
|
+
*
|
|
29
|
+
* @param tag - Tag name
|
|
30
|
+
* @returns Number of keys deleted
|
|
31
|
+
*/
|
|
32
|
+
invalidateTag(tag: string): Promise<number>;
|
|
33
|
+
/**
|
|
34
|
+
* Invalidates multiple tags.
|
|
35
|
+
*
|
|
36
|
+
* @param tags - Array of tag names
|
|
37
|
+
* @returns Total number of keys deleted
|
|
38
|
+
*/
|
|
39
|
+
invalidateTags(tags: string[]): Promise<number>;
|
|
40
|
+
/**
|
|
41
|
+
* Clears all tag indexes.
|
|
42
|
+
*/
|
|
43
|
+
clearAllTags(): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Gets statistics for a specific tag.
|
|
46
|
+
*
|
|
47
|
+
* @param tag - Tag name
|
|
48
|
+
* @returns Object with key count and existence flag
|
|
49
|
+
*/
|
|
50
|
+
getTagStats(tag: string): Promise<{
|
|
51
|
+
keyCount: number;
|
|
52
|
+
exists: boolean;
|
|
53
|
+
}>;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=tag-index.port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag-index.port.d.ts","sourceRoot":"","sources":["../../../../src/tags/application/ports/tag-index.port.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD;;;;;OAKG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D;;;;;OAKG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7C;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhD;;OAEG;IACH,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9B;;;;;OAKG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC1E"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tag index repository for tag-based cache invalidation.
|
|
3
|
+
* Maintains mapping of tags to cache keys.
|
|
4
|
+
*/
|
|
5
|
+
import { IRedisDriver } from '@nestjs-redisx/core';
|
|
6
|
+
import { ICachePluginOptions } from '../../../shared/types';
|
|
7
|
+
import { ITagIndex } from '../../application/ports/tag-index.port';
|
|
8
|
+
import { LuaScriptLoader } from '../services/lua-script-loader.service';
|
|
9
|
+
export declare class TagIndexRepository implements ITagIndex {
|
|
10
|
+
private readonly driver;
|
|
11
|
+
private readonly options;
|
|
12
|
+
private readonly luaLoader;
|
|
13
|
+
private readonly tagPrefix;
|
|
14
|
+
constructor(driver: IRedisDriver, options: ICachePluginOptions, luaLoader: LuaScriptLoader);
|
|
15
|
+
addKeyToTags(key: string, tags: string[]): Promise<void>;
|
|
16
|
+
removeKeyFromTags(key: string, tags: string[]): Promise<void>;
|
|
17
|
+
getKeysByTag(tag: string): Promise<string[]>;
|
|
18
|
+
invalidateTag(tag: string): Promise<number>;
|
|
19
|
+
invalidateTags(tags: string[]): Promise<number>;
|
|
20
|
+
clearAllTags(): Promise<void>;
|
|
21
|
+
getTagStats(tag: string): Promise<{
|
|
22
|
+
keyCount: number;
|
|
23
|
+
exists: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Validates tags using Tags value object.
|
|
27
|
+
*
|
|
28
|
+
* @param tags - Array of tag strings
|
|
29
|
+
* @returns Array of validated tag strings
|
|
30
|
+
* @throws CacheError if validation fails
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
private validateTags;
|
|
34
|
+
private buildTagKey;
|
|
35
|
+
private scanKeys;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=tag-index.repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag-index.repository.d.ts","sourceRoot":"","sources":["../../../../src/tags/infrastructure/repositories/tag-index.repository.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAgB,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAKxE,qBACa,kBAAmB,YAAW,SAAS;IAI1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACf,OAAO,CAAC,QAAQ,CAAC,OAAO;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS;IALvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGM,MAAM,EAAE,YAAY,EACZ,OAAO,EAAE,mBAAmB,EAC/B,SAAS,EAAE,eAAe;IAQlE,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BxD,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB7D,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAY5C,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuC3C,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAsB/C,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB7B,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IAc9E;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;YAIL,QAAQ;CAevB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline Lua scripts for tag-based cache invalidation.
|
|
3
|
+
*
|
|
4
|
+
* Scripts are stored as inline strings to avoid issues with file reading
|
|
5
|
+
* after build (dist directory doesn't contain .lua files).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Atomically adds a cache key to multiple tag sets.
|
|
9
|
+
*
|
|
10
|
+
* KEYS[1..N] = tag set keys
|
|
11
|
+
* ARGV[1] = cache key to add
|
|
12
|
+
* ARGV[2] = TTL for tag sets in seconds
|
|
13
|
+
*
|
|
14
|
+
* Returns: number of tag sets updated
|
|
15
|
+
*/
|
|
16
|
+
export declare const ADD_KEY_TO_TAGS_SCRIPT: string;
|
|
17
|
+
/**
|
|
18
|
+
* Atomically invalidates all cache keys for a tag.
|
|
19
|
+
*
|
|
20
|
+
* KEYS[1] = tag set key (e.g., "cache:_tag:users")
|
|
21
|
+
*
|
|
22
|
+
* Returns: number of deleted cache keys
|
|
23
|
+
*/
|
|
24
|
+
export declare const INVALIDATE_TAG_SCRIPT: string;
|
|
25
|
+
//# sourceMappingURL=lua-scripts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lua-scripts.d.ts","sourceRoot":"","sources":["../../../../src/tags/infrastructure/scripts/lua-scripts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,QAW3B,CAAC;AAET;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,QAuB1B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lua script loader service.
|
|
3
|
+
* Loads inline Lua scripts and registers them with Redis.
|
|
4
|
+
*
|
|
5
|
+
* Scripts are stored as inline strings to avoid issues with file reading
|
|
6
|
+
* after build (dist directory doesn't contain .lua files).
|
|
7
|
+
*/
|
|
8
|
+
import { OnModuleInit } from '@nestjs/common';
|
|
9
|
+
import { IRedisDriver } from '@nestjs-redisx/core';
|
|
10
|
+
export declare class LuaScriptLoader implements OnModuleInit {
|
|
11
|
+
private readonly driver;
|
|
12
|
+
private readonly logger;
|
|
13
|
+
private readonly scriptShas;
|
|
14
|
+
constructor(driver: IRedisDriver);
|
|
15
|
+
onModuleInit(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Loads all Lua scripts into Redis.
|
|
18
|
+
*/
|
|
19
|
+
private loadScripts;
|
|
20
|
+
/**
|
|
21
|
+
* Executes a Lua script by name using EVALSHA.
|
|
22
|
+
*
|
|
23
|
+
* @param scriptName - Name of the script
|
|
24
|
+
* @param keys - Redis keys to pass to the script
|
|
25
|
+
* @param args - Arguments to pass to the script
|
|
26
|
+
* @returns Script execution result
|
|
27
|
+
*/
|
|
28
|
+
evalSha(scriptName: string, keys: string[], args: (string | number)[]): Promise<unknown>;
|
|
29
|
+
/**
|
|
30
|
+
* Gets the SHA hash of a loaded script.
|
|
31
|
+
*
|
|
32
|
+
* @param scriptName - Name of the script
|
|
33
|
+
* @returns SHA hash or undefined if not loaded
|
|
34
|
+
*/
|
|
35
|
+
getSha(scriptName: string): string | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Checks if a script is loaded.
|
|
38
|
+
*
|
|
39
|
+
* @param scriptName - Name of the script
|
|
40
|
+
* @returns True if script is loaded
|
|
41
|
+
*/
|
|
42
|
+
isLoaded(scriptName: string): boolean;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=lua-script-loader.service.d.ts.map
|