raffel 1.1.70 → 1.1.72

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.
Files changed (117) hide show
  1. package/dist/cache/defaults.d.ts +9 -0
  2. package/dist/cache/defaults.d.ts.map +1 -0
  3. package/dist/cache/defaults.js +9 -0
  4. package/dist/cache/defaults.js.map +1 -0
  5. package/dist/cache/expiration-wheel.d.ts +15 -0
  6. package/dist/cache/expiration-wheel.d.ts.map +1 -0
  7. package/dist/cache/expiration-wheel.js +65 -0
  8. package/dist/cache/expiration-wheel.js.map +1 -0
  9. package/dist/cache/fs-layer.d.ts +14 -0
  10. package/dist/cache/fs-layer.d.ts.map +1 -0
  11. package/dist/cache/fs-layer.js +190 -0
  12. package/dist/cache/fs-layer.js.map +1 -0
  13. package/dist/cache/index.d.ts +9 -0
  14. package/dist/cache/index.d.ts.map +1 -1
  15. package/dist/cache/index.js +4 -0
  16. package/dist/cache/index.js.map +1 -1
  17. package/dist/cache/key.d.ts +11 -0
  18. package/dist/cache/key.d.ts.map +1 -0
  19. package/dist/cache/key.js +41 -0
  20. package/dist/cache/key.js.map +1 -0
  21. package/dist/cache/redis-layer.d.ts +30 -0
  22. package/dist/cache/redis-layer.d.ts.map +1 -0
  23. package/dist/cache/redis-layer.js +108 -0
  24. package/dist/cache/redis-layer.js.map +1 -0
  25. package/dist/cache/server-runtime.d.ts +74 -0
  26. package/dist/cache/server-runtime.d.ts.map +1 -0
  27. package/dist/cache/server-runtime.js +220 -0
  28. package/dist/cache/server-runtime.js.map +1 -0
  29. package/dist/cache/tiered.d.ts +86 -0
  30. package/dist/cache/tiered.d.ts.map +1 -0
  31. package/dist/cache/tiered.js +681 -0
  32. package/dist/cache/tiered.js.map +1 -0
  33. package/dist/cache/write-behind-queue.d.ts +34 -0
  34. package/dist/cache/write-behind-queue.d.ts.map +1 -0
  35. package/dist/cache/write-behind-queue.js +115 -0
  36. package/dist/cache/write-behind-queue.js.map +1 -0
  37. package/dist/http/app.d.ts.map +1 -1
  38. package/dist/http/app.js +1 -0
  39. package/dist/http/app.js.map +1 -1
  40. package/dist/http/cache.d.ts +22 -0
  41. package/dist/http/cache.d.ts.map +1 -0
  42. package/dist/http/cache.js +183 -0
  43. package/dist/http/cache.js.map +1 -0
  44. package/dist/http/index.d.ts +2 -0
  45. package/dist/http/index.d.ts.map +1 -1
  46. package/dist/http/index.js +1 -0
  47. package/dist/http/index.js.map +1 -1
  48. package/dist/index.d.ts +2 -2
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +1 -1
  51. package/dist/index.js.map +1 -1
  52. package/dist/server/builder/operation-registrar.d.ts +3 -0
  53. package/dist/server/builder/operation-registrar.d.ts.map +1 -1
  54. package/dist/server/builder/operation-registrar.js +7 -2
  55. package/dist/server/builder/operation-registrar.js.map +1 -1
  56. package/dist/server/builder/programmatic-registration.d.ts +2 -0
  57. package/dist/server/builder/programmatic-registration.d.ts.map +1 -1
  58. package/dist/server/builder/programmatic-registration.js +13 -2
  59. package/dist/server/builder/programmatic-registration.js.map +1 -1
  60. package/dist/server/builder.d.ts.map +1 -1
  61. package/dist/server/builder.js +17 -3
  62. package/dist/server/builder.js.map +1 -1
  63. package/dist/server/discovery-utils.d.ts +2 -1
  64. package/dist/server/discovery-utils.d.ts.map +1 -1
  65. package/dist/server/discovery-utils.js +10 -2
  66. package/dist/server/discovery-utils.js.map +1 -1
  67. package/dist/server/fs-routes/types.d.ts +3 -0
  68. package/dist/server/fs-routes/types.d.ts.map +1 -1
  69. package/dist/server/handler-builders.d.ts +2 -0
  70. package/dist/server/handler-builders.d.ts.map +1 -1
  71. package/dist/server/handler-builders.js +7 -0
  72. package/dist/server/handler-builders.js.map +1 -1
  73. package/dist/server/interceptor-utils.d.ts +2 -0
  74. package/dist/server/interceptor-utils.d.ts.map +1 -1
  75. package/dist/server/interceptor-utils.js +25 -1
  76. package/dist/server/interceptor-utils.js.map +1 -1
  77. package/dist/server/router-module.d.ts +3 -0
  78. package/dist/server/router-module.d.ts.map +1 -1
  79. package/dist/server/router-module.js +1 -0
  80. package/dist/server/router-module.js.map +1 -1
  81. package/dist/server/types/config-types.d.ts +3 -0
  82. package/dist/server/types/config-types.d.ts.map +1 -1
  83. package/dist/server/types/handler-types.d.ts +7 -0
  84. package/dist/server/types/handler-types.d.ts.map +1 -1
  85. package/dist/server/types/lifecycle-types.d.ts +2 -0
  86. package/dist/server/types/lifecycle-types.d.ts.map +1 -1
  87. package/dist/server/types/protocol-namespace-types.d.ts +3 -0
  88. package/dist/server/types/protocol-namespace-types.d.ts.map +1 -1
  89. package/dist/ui/cache/defaults.d.ts +9 -0
  90. package/dist/ui/cache/defaults.d.ts.map +1 -0
  91. package/dist/ui/cache/expiration-wheel.d.ts +15 -0
  92. package/dist/ui/cache/expiration-wheel.d.ts.map +1 -0
  93. package/dist/ui/cache/fs-layer.d.ts +14 -0
  94. package/dist/ui/cache/fs-layer.d.ts.map +1 -0
  95. package/dist/ui/cache/key.d.ts +11 -0
  96. package/dist/ui/cache/key.d.ts.map +1 -0
  97. package/dist/ui/cache/server-runtime.d.ts +74 -0
  98. package/dist/ui/cache/server-runtime.d.ts.map +1 -0
  99. package/dist/ui/cache/tiered.d.ts +86 -0
  100. package/dist/ui/cache/tiered.d.ts.map +1 -0
  101. package/dist/ui/cache/write-behind-queue.d.ts +34 -0
  102. package/dist/ui/cache/write-behind-queue.d.ts.map +1 -0
  103. package/dist/ui/server/fs-routes/types.d.ts +3 -0
  104. package/dist/ui/server/fs-routes/types.d.ts.map +1 -1
  105. package/dist/ui/validation/index.d.ts +1 -1
  106. package/dist/ui/validation/index.d.ts.map +1 -1
  107. package/dist/ui/validation/schema.d.ts +7 -0
  108. package/dist/ui/validation/schema.d.ts.map +1 -1
  109. package/dist/validation/index.d.ts +1 -1
  110. package/dist/validation/index.d.ts.map +1 -1
  111. package/dist/validation/index.js +1 -1
  112. package/dist/validation/index.js.map +1 -1
  113. package/dist/validation/schema.d.ts +7 -0
  114. package/dist/validation/schema.d.ts.map +1 -1
  115. package/dist/validation/schema.js +36 -2
  116. package/dist/validation/schema.js.map +1 -1
  117. package/package.json +5 -1
@@ -0,0 +1,9 @@
1
+ export declare const DEFAULT_L1_MAX_MEMORY_BYTES: number;
2
+ export declare const DEFAULT_L1_MAX_ENTRIES = 10000;
3
+ export declare const DEFAULT_L2_MAX_SIZE_BYTES: number;
4
+ export declare const DEFAULT_L2_MAX_FILES = 50000;
5
+ export declare const DEFAULT_CACHE_READ_TIMEOUT_MS = 250;
6
+ export declare const DEFAULT_CACHE_OPERATION_TIMEOUT_MS = 1000;
7
+ export declare const DEFAULT_CACHE_CIRCUIT_FAILURE_THRESHOLD = 3;
8
+ export declare const DEFAULT_CACHE_CIRCUIT_COOLDOWN_MS = 10000;
9
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/cache/defaults.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,QAAmB,CAAA;AAC3D,eAAO,MAAM,sBAAsB,QAAS,CAAA;AAC5C,eAAO,MAAM,yBAAyB,QAAmB,CAAA;AACzD,eAAO,MAAM,oBAAoB,QAAS,CAAA;AAC1C,eAAO,MAAM,6BAA6B,MAAM,CAAA;AAChD,eAAO,MAAM,kCAAkC,OAAQ,CAAA;AACvD,eAAO,MAAM,uCAAuC,IAAI,CAAA;AACxD,eAAO,MAAM,iCAAiC,QAAS,CAAA"}
@@ -0,0 +1,9 @@
1
+ export const DEFAULT_L1_MAX_MEMORY_BYTES = 16 * 1024 * 1024;
2
+ export const DEFAULT_L1_MAX_ENTRIES = 10_000;
3
+ export const DEFAULT_L2_MAX_SIZE_BYTES = 64 * 1024 * 1024;
4
+ export const DEFAULT_L2_MAX_FILES = 50_000;
5
+ export const DEFAULT_CACHE_READ_TIMEOUT_MS = 250;
6
+ export const DEFAULT_CACHE_OPERATION_TIMEOUT_MS = 1_000;
7
+ export const DEFAULT_CACHE_CIRCUIT_FAILURE_THRESHOLD = 3;
8
+ export const DEFAULT_CACHE_CIRCUIT_COOLDOWN_MS = 10_000;
9
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/cache/defaults.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AAC3D,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAA;AAC5C,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AACzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAA;AAC1C,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAA;AAChD,MAAM,CAAC,MAAM,kCAAkC,GAAG,KAAK,CAAA;AACvD,MAAM,CAAC,MAAM,uCAAuC,GAAG,CAAC,CAAA;AACxD,MAAM,CAAC,MAAM,iCAAiC,GAAG,MAAM,CAAA"}
@@ -0,0 +1,15 @@
1
+ export declare class ExpirationWheel {
2
+ private readonly resolutionMs;
3
+ private readonly onExpire;
4
+ private readonly slots;
5
+ private readonly scheduled;
6
+ private readonly timer;
7
+ private currentTick;
8
+ constructor(resolutionMs: number, onExpire: (key: string, version: number) => void, wheelSize?: number);
9
+ schedule(key: string, expiresAt: number, version: number): void;
10
+ cancel(key: string): void;
11
+ shutdown(): void;
12
+ private advance;
13
+ private expire;
14
+ }
15
+ //# sourceMappingURL=expiration-wheel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expiration-wheel.d.ts","sourceRoot":"","sources":["../../src/cache/expiration-wheel.ts"],"names":[],"mappings":"AAMA,qBAAa,eAAe;IAOxB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqC;IAC/D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IACtD,OAAO,CAAC,WAAW,CAAQ;gBAGR,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,EACjE,SAAS,SAAM;IAQjB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAQ/D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAOzB,QAAQ,IAAI,IAAI;IAMhB,OAAO,CAAC,OAAO;IAuBf,OAAO,CAAC,MAAM;CAKf"}
@@ -0,0 +1,65 @@
1
+ export class ExpirationWheel {
2
+ resolutionMs;
3
+ onExpire;
4
+ slots;
5
+ scheduled = new Map();
6
+ timer;
7
+ currentTick;
8
+ constructor(resolutionMs, onExpire, wheelSize = 256) {
9
+ this.resolutionMs = resolutionMs;
10
+ this.onExpire = onExpire;
11
+ this.slots = Array.from({ length: wheelSize }, () => new Set());
12
+ this.currentTick = Math.floor(Date.now() / resolutionMs);
13
+ this.timer = setInterval(() => this.advance(), resolutionMs);
14
+ this.timer.unref();
15
+ }
16
+ schedule(key, expiresAt, version) {
17
+ this.cancel(key);
18
+ const dueTick = Math.ceil(expiresAt / this.resolutionMs);
19
+ const slot = dueTick % this.slots.length;
20
+ this.slots[slot].add(key);
21
+ this.scheduled.set(key, { dueTick, slot, version });
22
+ }
23
+ cancel(key) {
24
+ const expiry = this.scheduled.get(key);
25
+ if (!expiry)
26
+ return;
27
+ this.slots[expiry.slot].delete(key);
28
+ this.scheduled.delete(key);
29
+ }
30
+ shutdown() {
31
+ clearInterval(this.timer);
32
+ this.scheduled.clear();
33
+ for (const slot of this.slots)
34
+ slot.clear();
35
+ }
36
+ advance() {
37
+ const targetTick = Math.floor(Date.now() / this.resolutionMs);
38
+ const elapsed = targetTick - this.currentTick;
39
+ if (elapsed <= 0)
40
+ return;
41
+ if (elapsed > this.slots.length) {
42
+ this.currentTick = targetTick;
43
+ for (const [key, expiry] of this.scheduled) {
44
+ if (expiry.dueTick <= targetTick)
45
+ this.expire(key, expiry);
46
+ }
47
+ return;
48
+ }
49
+ while (this.currentTick < targetTick) {
50
+ this.currentTick++;
51
+ const slotIndex = this.currentTick % this.slots.length;
52
+ for (const key of [...this.slots[slotIndex]]) {
53
+ const expiry = this.scheduled.get(key);
54
+ if (expiry && expiry.dueTick <= this.currentTick)
55
+ this.expire(key, expiry);
56
+ }
57
+ }
58
+ }
59
+ expire(key, expiry) {
60
+ this.slots[expiry.slot].delete(key);
61
+ this.scheduled.delete(key);
62
+ this.onExpire(key, expiry.version);
63
+ }
64
+ }
65
+ //# sourceMappingURL=expiration-wheel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expiration-wheel.js","sourceRoot":"","sources":["../../src/cache/expiration-wheel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type CacheCircuitBreakerOptions, type CacheLayer } from './tiered.js';
2
+ export interface FileSystemCacheLayerOptions {
3
+ id: string;
4
+ directory: string;
5
+ ttlMs: number;
6
+ maxSizeBytes?: number;
7
+ maxFiles?: number;
8
+ expirationResolutionMs?: number;
9
+ readTimeoutMs?: number;
10
+ operationTimeoutMs?: number;
11
+ circuitBreaker?: CacheCircuitBreakerOptions;
12
+ }
13
+ export declare function createFileSystemCacheLayer(options: FileSystemCacheLayerOptions): CacheLayer;
14
+ //# sourceMappingURL=fs-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-layer.d.ts","sourceRoot":"","sources":["../../src/cache/fs-layer.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EAEhB,MAAM,aAAa,CAAA;AAUpB,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,cAAc,CAAC,EAAE,0BAA0B,CAAA;CAC5C;AAmBD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,GAAG,UAAU,CAgL3F"}
@@ -0,0 +1,190 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { mkdir, readFile, readdir, rename, unlink, writeFile } from 'node:fs/promises';
3
+ import { dirname, join } from 'node:path';
4
+ import { ExpirationWheel } from './expiration-wheel.js';
5
+ import { isCacheRecord, } from './tiered.js';
6
+ import { DEFAULT_CACHE_CIRCUIT_COOLDOWN_MS, DEFAULT_CACHE_CIRCUIT_FAILURE_THRESHOLD, DEFAULT_CACHE_OPERATION_TIMEOUT_MS, DEFAULT_CACHE_READ_TIMEOUT_MS, DEFAULT_L2_MAX_FILES, DEFAULT_L2_MAX_SIZE_BYTES, } from './defaults.js';
7
+ function hashedPath(directory, key) {
8
+ const hash = createHash('sha256').update(key).digest('hex');
9
+ return join(directory, hash.slice(0, 2), `${hash.slice(2)}.cache`);
10
+ }
11
+ export function createFileSystemCacheLayer(options) {
12
+ if (options.ttlMs <= 0)
13
+ throw new Error('Filesystem cache ttlMs must be greater than zero');
14
+ if (options.maxFiles !== undefined && options.maxFiles <= 0) {
15
+ throw new Error('Filesystem cache maxFiles must be greater than zero');
16
+ }
17
+ if (options.maxSizeBytes !== undefined && options.maxSizeBytes <= 0) {
18
+ throw new Error('Filesystem cache maxSizeBytes must be greater than zero');
19
+ }
20
+ const maxSizeBytes = options.maxSizeBytes ?? DEFAULT_L2_MAX_SIZE_BYTES;
21
+ const maxFiles = options.maxFiles ?? DEFAULT_L2_MAX_FILES;
22
+ const index = new Map();
23
+ let totalSizeBytes = 0;
24
+ let hits = 0;
25
+ let misses = 0;
26
+ const wheel = new ExpirationWheel(options.expirationResolutionMs ?? 1_000, (key, version) => {
27
+ if (index.get(key)?.version === version)
28
+ void remove(key);
29
+ });
30
+ let initializationError;
31
+ const ready = initialize().catch((error) => {
32
+ initializationError = error;
33
+ });
34
+ async function ensureReady() {
35
+ await ready;
36
+ if (initializationError)
37
+ throw initializationError;
38
+ }
39
+ async function initialize() {
40
+ await mkdir(options.directory, { recursive: true });
41
+ const recovered = [];
42
+ for (const shard of await readdir(options.directory, { withFileTypes: true })) {
43
+ if (!shard.isDirectory())
44
+ continue;
45
+ const shardPath = join(options.directory, shard.name);
46
+ for (const file of await readdir(shardPath, { withFileTypes: true })) {
47
+ if (!file.isFile() || !file.name.endsWith('.cache'))
48
+ continue;
49
+ const filePath = join(shardPath, file.name);
50
+ try {
51
+ const content = await readFile(filePath);
52
+ const stored = JSON.parse(content.toString('utf8'));
53
+ if (typeof stored.key !== 'string' || !isCacheRecord(stored.record)) {
54
+ throw new Error('Invalid cache record');
55
+ }
56
+ const expiresAt = stored.record.staleUntil ?? stored.record.expiresAt;
57
+ if (Date.now() >= expiresAt) {
58
+ await unlink(filePath);
59
+ continue;
60
+ }
61
+ recovered.push([
62
+ stored.key,
63
+ {
64
+ path: filePath,
65
+ sizeBytes: content.byteLength,
66
+ createdAt: stored.record.createdAt,
67
+ version: stored.record.version,
68
+ },
69
+ expiresAt,
70
+ ]);
71
+ }
72
+ catch {
73
+ await unlink(filePath).catch(() => undefined);
74
+ }
75
+ }
76
+ }
77
+ recovered.sort((left, right) => left[1].createdAt - right[1].createdAt);
78
+ for (const [key, metadata, expiresAt] of recovered) {
79
+ index.set(key, metadata);
80
+ totalSizeBytes += metadata.sizeBytes;
81
+ wheel.schedule(key, expiresAt, metadata.version);
82
+ }
83
+ await enforceLimits(0);
84
+ }
85
+ async function remove(key) {
86
+ const metadata = index.get(key);
87
+ if (!metadata)
88
+ return;
89
+ index.delete(key);
90
+ totalSizeBytes -= metadata.sizeBytes;
91
+ wheel.cancel(key);
92
+ await unlink(metadata.path).catch(() => undefined);
93
+ }
94
+ async function enforceLimits(incomingBytes) {
95
+ if (incomingBytes > maxSizeBytes)
96
+ return false;
97
+ while (totalSizeBytes + incomingBytes > maxSizeBytes || index.size >= maxFiles) {
98
+ const oldest = index.keys().next().value;
99
+ if (oldest === undefined)
100
+ break;
101
+ await remove(oldest);
102
+ }
103
+ return totalSizeBytes + incomingBytes <= maxSizeBytes;
104
+ }
105
+ return {
106
+ id: options.id,
107
+ ttlMs: options.ttlMs,
108
+ readTimeoutMs: options.readTimeoutMs ?? DEFAULT_CACHE_READ_TIMEOUT_MS,
109
+ operationTimeoutMs: options.operationTimeoutMs ?? DEFAULT_CACHE_OPERATION_TIMEOUT_MS,
110
+ circuitBreaker: options.circuitBreaker ?? {
111
+ failureThreshold: DEFAULT_CACHE_CIRCUIT_FAILURE_THRESHOLD,
112
+ cooldownMs: DEFAULT_CACHE_CIRCUIT_COOLDOWN_MS,
113
+ },
114
+ async get(key) {
115
+ await ensureReady();
116
+ const filePath = hashedPath(options.directory, key);
117
+ try {
118
+ const stored = JSON.parse(await readFile(filePath, 'utf8'));
119
+ if (typeof stored.key !== 'string' || !isCacheRecord(stored.record)) {
120
+ throw new Error('Invalid cache record');
121
+ }
122
+ const expiresAt = stored.record.staleUntil ?? stored.record.expiresAt;
123
+ if (stored.key !== key || Date.now() >= expiresAt) {
124
+ await remove(key);
125
+ misses++;
126
+ return undefined;
127
+ }
128
+ hits++;
129
+ return stored.record;
130
+ }
131
+ catch {
132
+ await remove(key);
133
+ misses++;
134
+ return undefined;
135
+ }
136
+ },
137
+ async set(key, record, ttlMs, staleMs = 0) {
138
+ await ensureReady();
139
+ const expiresAt = Date.now() + ttlMs;
140
+ const stored = {
141
+ key,
142
+ record: {
143
+ ...record,
144
+ expiresAt,
145
+ staleUntil: staleMs > 0 ? expiresAt + staleMs : undefined,
146
+ },
147
+ };
148
+ const encoded = Buffer.from(JSON.stringify(stored));
149
+ await remove(key);
150
+ if (!(await enforceLimits(encoded.byteLength)))
151
+ return;
152
+ const filePath = hashedPath(options.directory, key);
153
+ await mkdir(dirname(filePath), { recursive: true });
154
+ const temporaryPath = `${filePath}.${randomUUID()}.tmp`;
155
+ try {
156
+ await writeFile(temporaryPath, encoded);
157
+ await rename(temporaryPath, filePath);
158
+ }
159
+ finally {
160
+ await unlink(temporaryPath).catch(() => undefined);
161
+ }
162
+ index.set(key, {
163
+ path: filePath,
164
+ sizeBytes: encoded.byteLength,
165
+ createdAt: record.createdAt,
166
+ version: record.version,
167
+ });
168
+ totalSizeBytes += encoded.byteLength;
169
+ wheel.schedule(key, stored.record.staleUntil ?? expiresAt, record.version);
170
+ },
171
+ async delete(key) {
172
+ await ensureReady();
173
+ await remove(key);
174
+ },
175
+ async clearNamespace(namespace) {
176
+ await ensureReady();
177
+ await Promise.all([...index.keys()]
178
+ .filter((key) => key.startsWith(`${namespace}:`))
179
+ .map((key) => remove(key)));
180
+ },
181
+ stats() {
182
+ return { totalItems: index.size, storageUsageBytes: totalSizeBytes, hits, misses };
183
+ },
184
+ async shutdown() {
185
+ await ready;
186
+ wheel.shutdown();
187
+ },
188
+ };
189
+ }
190
+ //# sourceMappingURL=fs-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-layer.js","sourceRoot":"","sources":["../../src/cache/fs-layer.ts"],"names":[],"mappings":"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"}
@@ -54,4 +54,13 @@
54
54
  export type { CacheDriver, CacheEntry, CacheGetResult, CacheStats, MemoryStats, CompressionStats, EvictionPolicy, CompressionConfig, MemoryDriverOptions, FileDriverOptions, RedisDriverOptions, RedisLikeClient, CacheDriverType, CacheDriverConfig, EvictionInfo, PressureInfo, } from './types.js';
55
55
  export { createDriver, createDriverFromConfig, createDriverSync, DRIVER_TYPES, isValidDriverType, } from './factory.js';
56
56
  export { MemoryDriver, createMemoryDriver, FileDriver, createFileDriver, RedisDriver, createRedisDriver, } from './drivers/index.js';
57
+ export { createTieredCache, createMemoryCacheLayer, createFileSystemCacheLayer, DEFAULT_CACHE_CIRCUIT_COOLDOWN_MS, DEFAULT_CACHE_CIRCUIT_FAILURE_THRESHOLD, DEFAULT_CACHE_OPERATION_TIMEOUT_MS, DEFAULT_CACHE_READ_TIMEOUT_MS, DEFAULT_L1_MAX_ENTRIES, DEFAULT_L1_MAX_MEMORY_BYTES, DEFAULT_L2_MAX_FILES, DEFAULT_L2_MAX_SIZE_BYTES, } from './tiered.js';
58
+ export { createRedisCacheLayer } from './redis-layer.js';
59
+ export { procedureCacheKey, procedureCacheKeyFor } from './key.js';
60
+ export type { CacheLayer, CacheCircuitBreakerOptions, CacheLayerStats, CacheLookup, CacheRecord, CacheWriteOptions, MemoryCacheLayerOptions, TieredCache, TieredCacheOptions, } from './tiered.js';
61
+ export type { FileSystemCacheLayerOptions } from './fs-layer.js';
62
+ export type { RedisCacheLayerClient, RedisCacheLayerOptions } from './redis-layer.js';
63
+ export type { CacheIdentityScope } from './key.js';
64
+ export type { CacheRule, FileSystemLayerConfig, MemoryLayerConfig, ProviderLayerConfig, RouteCacheConfig, ServerCacheConfig, ServerCacheController, ServerCacheLayerConfig, } from './server-runtime.js';
65
+ export type { WriteBehindQueueOptions, WriteBehindQueueStats } from './write-behind-queue.js';
57
66
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAGH,YAAY,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,iBAAiB,GAClB,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAGH,YAAY,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,iBAAiB,GAClB,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,0BAA0B,EAC1B,iCAAiC,EACjC,uCAAuC,EACvC,kCAAkC,EAClC,6BAA6B,EAC7B,sBAAsB,EACtB,2BAA2B,EAC3B,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAClE,YAAY,EACV,UAAU,EACV,0BAA0B,EAC1B,eAAe,EACf,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,uBAAuB,EACvB,WAAW,EACX,kBAAkB,GACnB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAA;AAChE,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AACrF,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAClD,YAAY,EACV,SAAS,EACT,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA"}
@@ -55,4 +55,8 @@
55
55
  export { createDriver, createDriverFromConfig, createDriverSync, DRIVER_TYPES, isValidDriverType, } from './factory.js';
56
56
  // Drivers (for direct import when needed)
57
57
  export { MemoryDriver, createMemoryDriver, FileDriver, createFileDriver, RedisDriver, createRedisDriver, } from './drivers/index.js';
58
+ // Hierarchical response cache (L1 memory → L2 filesystem → L3 provider)
59
+ export { createTieredCache, createMemoryCacheLayer, createFileSystemCacheLayer, DEFAULT_CACHE_CIRCUIT_COOLDOWN_MS, DEFAULT_CACHE_CIRCUIT_FAILURE_THRESHOLD, DEFAULT_CACHE_OPERATION_TIMEOUT_MS, DEFAULT_CACHE_READ_TIMEOUT_MS, DEFAULT_L1_MAX_ENTRIES, DEFAULT_L1_MAX_MEMORY_BYTES, DEFAULT_L2_MAX_FILES, DEFAULT_L2_MAX_SIZE_BYTES, } from './tiered.js';
60
+ export { createRedisCacheLayer } from './redis-layer.js';
61
+ export { procedureCacheKey, procedureCacheKeyFor } from './key.js';
58
62
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAsBH,UAAU;AACV,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAA;AAErB,0CAA0C;AAC1C,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,iBAAiB,GAClB,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAsBH,UAAU;AACV,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAA;AAErB,0CAA0C;AAC1C,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,iBAAiB,GAClB,MAAM,oBAAoB,CAAA;AAE3B,wEAAwE;AACxE,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,0BAA0B,EAC1B,iCAAiC,EACjC,uCAAuC,EACvC,kCAAkC,EAClC,6BAA6B,EAC7B,sBAAsB,EACtB,2BAA2B,EAC3B,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA"}
@@ -0,0 +1,11 @@
1
+ import type { Context, Envelope } from '../types/index.js';
2
+ export type CacheIdentityScope = 'auto' | 'public' | 'tenant' | 'principal';
3
+ export declare function procedureCacheKey(envelope: Envelope, ctx: Context, options?: {
4
+ scope?: CacheIdentityScope;
5
+ version?: string;
6
+ }): string | undefined;
7
+ export declare function procedureCacheKeyFor(procedure: string, input: unknown, ctx: Context, options?: {
8
+ scope?: CacheIdentityScope;
9
+ version?: string;
10
+ }): string | undefined;
11
+ //# sourceMappingURL=key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../src/cache/key.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE1D,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAA;AA6B3E,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7D,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7D,MAAM,GAAG,SAAS,CAMpB"}
@@ -0,0 +1,41 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { deriveAuthPrincipalId, deriveAuthTenantId } from '../auth/principal.js';
3
+ function stableJson(value) {
4
+ try {
5
+ return JSON.stringify(value, (_key, current) => {
6
+ if (!current || typeof current !== 'object' || Array.isArray(current))
7
+ return current;
8
+ return Object.fromEntries(Object.entries(current).sort(([left], [right]) => left.localeCompare(right)));
9
+ });
10
+ }
11
+ catch {
12
+ return undefined;
13
+ }
14
+ }
15
+ function identityFor(ctx, scope) {
16
+ if (scope === 'public')
17
+ return 'public';
18
+ const principal = deriveAuthPrincipalId(ctx.auth);
19
+ const tenant = deriveAuthTenantId(ctx.auth);
20
+ if (scope === 'tenant')
21
+ return tenant ? `tenant:${tenant}` : undefined;
22
+ if (scope === 'principal')
23
+ return principal
24
+ ? `tenant:${tenant ?? '-'}:principal:${principal}`
25
+ : undefined;
26
+ if (!ctx.auth.authenticated)
27
+ return 'anonymous';
28
+ return principal ? `tenant:${tenant ?? '-'}:principal:${principal}` : undefined;
29
+ }
30
+ export function procedureCacheKey(envelope, ctx, options = {}) {
31
+ return procedureCacheKeyFor(envelope.procedure, envelope.payload, ctx, options);
32
+ }
33
+ export function procedureCacheKeyFor(procedure, input, ctx, options = {}) {
34
+ const payload = stableJson(input);
35
+ const identity = identityFor(ctx, options.scope ?? 'auto');
36
+ if (payload === undefined || identity === undefined)
37
+ return undefined;
38
+ const digest = createHash('sha256').update(payload).digest('base64url');
39
+ return `procedure:${procedure}:v${options.version ?? '1'}:${identity}:${digest}`;
40
+ }
41
+ //# sourceMappingURL=key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/cache/key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAKhF,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;YAC7C,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;gBAAE,OAAO,OAAO,CAAA;YACrF,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAkC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAC1E,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAC1B,CACF,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAY,EAAE,KAAyB;IAC1D,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAA;IACvC,MAAM,SAAS,GAAG,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACjD,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC3C,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;IACtE,IAAI,KAAK,KAAK,WAAW;QAAE,OAAO,SAAS;YACzC,CAAC,CAAC,UAAU,MAAM,IAAI,GAAG,cAAc,SAAS,EAAE;YAClD,CAAC,CAAC,SAAS,CAAA;IACb,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa;QAAE,OAAO,WAAW,CAAA;IAC/C,OAAO,SAAS,CAAC,CAAC,CAAC,UAAU,MAAM,IAAI,GAAG,cAAc,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;AACjF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,QAAkB,EAClB,GAAY,EACZ,UAA4D,EAAE;IAE9D,OAAO,oBAAoB,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;AACjF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,SAAiB,EACjB,KAAc,EACd,GAAY,EACZ,UAA4D,EAAE;IAE9D,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;IACjC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,CAAA;IAC1D,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACrE,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IACvE,OAAO,aAAa,SAAS,KAAK,OAAO,CAAC,OAAO,IAAI,GAAG,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAA;AAClF,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { type CacheCircuitBreakerOptions, type CacheLayer } from './tiered.js';
2
+ export interface RedisCacheLayerClient {
3
+ get(key: string): Promise<string | null>;
4
+ set?(key: string, value: string, ...args: any[]): Promise<unknown>;
5
+ pSetEx?(key: string, milliseconds: number, value: string): Promise<unknown>;
6
+ del(key: string | string[]): Promise<number>;
7
+ scan?(cursor: string | number, ...args: any[]): Promise<[string | number, string[]] | {
8
+ cursor: string | number;
9
+ keys: string[];
10
+ }>;
11
+ keys?(pattern: string): Promise<string[]>;
12
+ quit?(): Promise<unknown>;
13
+ }
14
+ export interface RedisCacheLayerOptions {
15
+ id: string;
16
+ client: RedisCacheLayerClient;
17
+ ttlMs: number;
18
+ prefix?: string;
19
+ scanCount?: number;
20
+ closeOnShutdown?: boolean;
21
+ clientStyle?: 'ioredis' | 'node-redis';
22
+ allowBlockingClear?: boolean;
23
+ readTimeoutMs?: number;
24
+ operationTimeoutMs?: number;
25
+ circuitBreaker?: CacheCircuitBreakerOptions;
26
+ setWithTtl?: (client: RedisCacheLayerClient, key: string, value: string, ttlMs: number) => Promise<unknown>;
27
+ }
28
+ /** Redis/Valkey layer that delegates capacity and eviction to the provider. */
29
+ export declare function createRedisCacheLayer(options: RedisCacheLayerOptions): CacheLayer;
30
+ //# sourceMappingURL=redis-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-layer.d.ts","sourceRoot":"","sources":["../../src/cache/redis-layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EAEhB,MAAM,aAAa,CAAA;AAOpB,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACxC,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAClE,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC5C,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CACnD,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,GAC3B;QAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAC9C,CAAA;IACD,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACzC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,qBAAqB,CAAA;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,CAAA;IACtC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,cAAc,CAAC,EAAE,0BAA0B,CAAA;IAC3C,UAAU,CAAC,EAAE,CACX,MAAM,EAAE,qBAAqB,EAC7B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,KACV,OAAO,CAAC,OAAO,CAAC,CAAA;CACtB;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,UAAU,CAuGjF"}
@@ -0,0 +1,108 @@
1
+ import { isCacheRecord, } from './tiered.js';
2
+ import { DEFAULT_CACHE_CIRCUIT_COOLDOWN_MS, DEFAULT_CACHE_CIRCUIT_FAILURE_THRESHOLD, DEFAULT_CACHE_OPERATION_TIMEOUT_MS, } from './defaults.js';
3
+ /** Redis/Valkey layer that delegates capacity and eviction to the provider. */
4
+ export function createRedisCacheLayer(options) {
5
+ const prefix = options.prefix ?? 'raffel:cache:';
6
+ const fullKey = (key) => prefix + key;
7
+ let hits = 0;
8
+ let misses = 0;
9
+ async function setWithNativeTtl(key, value, ttlMs) {
10
+ if (options.setWithTtl) {
11
+ await options.setWithTtl(options.client, key, value, ttlMs);
12
+ return;
13
+ }
14
+ if (options.client.pSetEx) {
15
+ await options.client.pSetEx(key, ttlMs, value);
16
+ return;
17
+ }
18
+ if (!options.client.set)
19
+ throw new Error('Redis/Valkey client does not implement SET');
20
+ if (options.clientStyle === 'node-redis') {
21
+ await options.client.set(key, value, { PX: ttlMs });
22
+ return;
23
+ }
24
+ await options.client.set(key, value, 'PX', ttlMs);
25
+ }
26
+ return {
27
+ id: options.id,
28
+ ttlMs: options.ttlMs,
29
+ readTimeoutMs: options.readTimeoutMs ?? 100,
30
+ operationTimeoutMs: options.operationTimeoutMs ?? DEFAULT_CACHE_OPERATION_TIMEOUT_MS,
31
+ circuitBreaker: options.circuitBreaker ?? {
32
+ failureThreshold: DEFAULT_CACHE_CIRCUIT_FAILURE_THRESHOLD,
33
+ cooldownMs: DEFAULT_CACHE_CIRCUIT_COOLDOWN_MS,
34
+ },
35
+ async get(key) {
36
+ const providerKey = fullKey(key);
37
+ const encoded = await options.client.get(providerKey);
38
+ if (!encoded) {
39
+ misses++;
40
+ return undefined;
41
+ }
42
+ let record;
43
+ try {
44
+ record = JSON.parse(encoded);
45
+ if (!isCacheRecord(record))
46
+ throw new Error('Invalid cache record');
47
+ }
48
+ catch {
49
+ await options.client.del(providerKey);
50
+ misses++;
51
+ return undefined;
52
+ }
53
+ if (Date.now() >= (record.staleUntil ?? record.expiresAt)) {
54
+ await options.client.del(providerKey);
55
+ misses++;
56
+ return undefined;
57
+ }
58
+ hits++;
59
+ return record;
60
+ },
61
+ async set(key, record, ttlMs, staleMs = 0) {
62
+ const expiresAt = Date.now() + ttlMs;
63
+ const stored = {
64
+ ...record,
65
+ expiresAt,
66
+ staleUntil: staleMs > 0 ? expiresAt + staleMs : undefined,
67
+ };
68
+ await setWithNativeTtl(fullKey(key), JSON.stringify(stored), ttlMs + staleMs);
69
+ },
70
+ async delete(key) {
71
+ await options.client.del(fullKey(key));
72
+ },
73
+ async clearNamespace(namespace) {
74
+ const pattern = `${prefix}${namespace}:*`;
75
+ if (!options.client.scan) {
76
+ if (options.allowBlockingClear && options.client.keys) {
77
+ const keys = await options.client.keys(pattern);
78
+ if (keys.length > 0)
79
+ await options.client.del(keys);
80
+ return;
81
+ }
82
+ throw new Error('Redis/Valkey namespace invalidation requires SCAN support');
83
+ }
84
+ let cursor = '0';
85
+ do {
86
+ const result = options.clientStyle === 'node-redis' || options.client.pSetEx
87
+ ? await options.client.scan(cursor, {
88
+ MATCH: pattern,
89
+ COUNT: options.scanCount ?? 100,
90
+ })
91
+ : await options.client.scan(cursor, 'MATCH', pattern, 'COUNT', options.scanCount ?? 100);
92
+ const next = Array.isArray(result) ? result[0] : result.cursor;
93
+ const keys = Array.isArray(result) ? result[1] : result.keys;
94
+ cursor = String(next);
95
+ if (keys.length > 0)
96
+ await options.client.del(keys);
97
+ } while (cursor !== '0');
98
+ },
99
+ stats() {
100
+ return { totalItems: 0, hits, misses };
101
+ },
102
+ async shutdown() {
103
+ if (options.closeOnShutdown)
104
+ await options.client.quit?.();
105
+ },
106
+ };
107
+ }
108
+ //# sourceMappingURL=redis-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-layer.js","sourceRoot":"","sources":["../../src/cache/redis-layer.ts"],"names":[],"mappings":"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"}