@goatlab/node-backend 0.0.14 → 0.0.16

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.
@@ -1,718 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const Cache_1 = require("./Cache");
5
- const KeyvLrus_1 = require("./cache/KeyvLrus");
6
- const keyv_1 = require("keyv");
7
- const const_1 = require("./test/const");
8
- const js_utils_1 = require("@goatlab/js-utils");
9
- const connection = (0, const_1.getGlobalData)().redisUrl || 'redis://localhost:6379';
10
- const a = new Cache_1.Cache({
11
- connection,
12
- opts: { namespace: 'test-ns' }
13
- });
14
- (0, vitest_1.describe)('Cache (Memory)', () => {
15
- (0, vitest_1.it)('should initialize with Redis store when connection is provided', () => {
16
- const cache = new Cache_1.Cache({ connection, opts: { namespace: 'test-ns' } });
17
- (0, vitest_1.expect)(cache).toBeInstanceOf(Cache_1.Cache);
18
- // @ts-expect-error accessing private property for test
19
- (0, vitest_1.expect)(cache._ns).toBe('test-ns');
20
- // @ts-expect-error accessing private property for test
21
- (0, vitest_1.expect)(cache.usesLRUMemory).toBe(false);
22
- // @ts-expect-error accessing private property for test
23
- (0, vitest_1.expect)(cache.memoryCache).toBeInstanceOf(keyv_1.default);
24
- // @ts-expect-error accessing private property for test
25
- (0, vitest_1.expect)(cache.keyvLru).toBeInstanceOf(KeyvLrus_1.KeyvLru);
26
- });
27
- (0, vitest_1.it)('should initialize with LRU store when connection is not provided', () => {
28
- const cache = new Cache_1.Cache({
29
- connection: undefined,
30
- opts: { namespace: 'lru-ns' }
31
- });
32
- (0, vitest_1.expect)(cache).toBeInstanceOf(Cache_1.Cache);
33
- // @ts-expect-error accessing private property for test
34
- (0, vitest_1.expect)(cache._ns).toBe('lru-ns');
35
- // @ts-expect-error accessing private property for test
36
- (0, vitest_1.expect)(cache.usesLRUMemory).toBe(false);
37
- // @ts-expect-error accessing private property for test
38
- (0, vitest_1.expect)(cache.memoryCache).toBeInstanceOf(keyv_1.default);
39
- // @ts-expect-error accessing private property for test
40
- (0, vitest_1.expect)(cache.keyvLru).toBeInstanceOf(KeyvLrus_1.KeyvLru);
41
- });
42
- (0, vitest_1.it)('should set usesLRUMemory to true if provided in opts', () => {
43
- const cache = new Cache_1.Cache({
44
- connection: undefined,
45
- opts: { usesLRUMemory: true, namespace: 'lru-ns' }
46
- });
47
- // @ts-expect-error accessing private property for test
48
- (0, vitest_1.expect)(cache.usesLRUMemory).toBe(true);
49
- });
50
- (0, vitest_1.it)('should default namespace to empty string if not provided', () => {
51
- const cache = new Cache_1.Cache({ connection: undefined, opts: {} });
52
- // @ts-expect-error accessing private property for test
53
- (0, vitest_1.expect)(cache._ns).toBe('');
54
- });
55
- (0, vitest_1.it)('should handle undefined opts gracefully', () => {
56
- const cache = new Cache_1.Cache({ connection: undefined });
57
- // @ts-expect-error accessing private property for test
58
- (0, vitest_1.expect)(cache._ns).toBe('');
59
- // @ts-expect-error accessing private property for test
60
- (0, vitest_1.expect)(cache.usesLRUMemory).toBe(false);
61
- });
62
- (0, vitest_1.it)('should set and get values correctly', async () => {
63
- const cache = new Cache_1.Cache({
64
- connection: undefined,
65
- opts: { namespace: 'data-ns' }
66
- });
67
- await cache.set('foo', 'bar');
68
- const value = await cache.get('foo');
69
- (0, vitest_1.expect)(value).toBe('bar');
70
- });
71
- (0, vitest_1.it)('should delete values correctly', async () => {
72
- const cache = new Cache_1.Cache({
73
- connection: undefined,
74
- opts: { namespace: 'del-ns' }
75
- });
76
- await cache.set('foo', 'bar');
77
- const deleted = await cache.delete('foo');
78
- (0, vitest_1.expect)(deleted).toBe(true);
79
- const value = await cache.get('foo');
80
- (0, vitest_1.expect)(value).toBeUndefined();
81
- });
82
- (0, vitest_1.it)('should return true for has when value exists', async () => {
83
- const cache = new Cache_1.Cache({
84
- connection: undefined,
85
- opts: { namespace: 'has-ns' }
86
- });
87
- await cache.set('foo', 'bar');
88
- const exists = await cache.has('foo');
89
- (0, vitest_1.expect)(exists).toBe(true);
90
- });
91
- (0, vitest_1.it)('should return false for has when value does not exist', async () => {
92
- const cache = new Cache_1.Cache({
93
- connection: undefined,
94
- opts: { namespace: 'has-ns' }
95
- });
96
- const exists = await cache.has('not-exist');
97
- (0, vitest_1.expect)(exists).toBe(false);
98
- });
99
- (0, vitest_1.it)('should remember and cache value for given ms', async () => {
100
- const cache = new Cache_1.Cache({
101
- connection: undefined,
102
- opts: { namespace: 'remember-ns' }
103
- });
104
- let called = 0;
105
- const result = await cache.remember('foo', 1000, async () => {
106
- called++;
107
- return 'bar';
108
- });
109
- (0, vitest_1.expect)(result).toBe('bar');
110
- const result2 = await cache.remember('foo', 1000, async () => {
111
- called++;
112
- return 'baz';
113
- });
114
- (0, vitest_1.expect)(result2).toBe('bar');
115
- (0, vitest_1.expect)(called).toBe(1);
116
- });
117
- (0, vitest_1.it)('should rememberForever and cache value', async () => {
118
- const cache = new Cache_1.Cache({
119
- connection: undefined,
120
- opts: { namespace: 'forever-ns' }
121
- });
122
- let called = 0;
123
- const result = await cache.rememberForever('foo', async () => {
124
- called++;
125
- return 'bar';
126
- });
127
- (0, vitest_1.expect)(result).toBe('bar');
128
- const result2 = await cache.rememberForever('foo', async () => {
129
- called++;
130
- return 'baz';
131
- });
132
- (0, vitest_1.expect)(result2).toBe('bar');
133
- (0, vitest_1.expect)(called).toBe(1);
134
- });
135
- (0, vitest_1.it)('should pull value and delete it', async () => {
136
- const cache = new Cache_1.Cache({
137
- connection: undefined,
138
- opts: { namespace: 'pull-ns' }
139
- });
140
- await cache.set('foo', 'bar');
141
- const value = await cache.pull('foo');
142
- (0, vitest_1.expect)(value).toBe('bar');
143
- const after = await cache.get('foo');
144
- (0, vitest_1.expect)(after).toBeUndefined();
145
- });
146
- (0, vitest_1.it)('should forget value', async () => {
147
- const cache = new Cache_1.Cache({
148
- connection: undefined,
149
- opts: { namespace: 'forget-ns' }
150
- });
151
- await cache.set('foo', 'bar');
152
- const result = await cache.forget('foo');
153
- (0, vitest_1.expect)(result).toBe(true);
154
- const value = await cache.get('foo');
155
- (0, vitest_1.expect)(value).toBeUndefined();
156
- });
157
- (0, vitest_1.it)('should flush all values in namespace', async () => {
158
- const cache = new Cache_1.Cache({
159
- connection: undefined,
160
- opts: { namespace: 'flush-ns' }
161
- });
162
- await cache.set('foo', 'bar');
163
- await cache.set('baz', 'qux');
164
- await cache.flush();
165
- const foo = await cache.get('foo');
166
- const baz = await cache.get('baz');
167
- (0, vitest_1.expect)(foo).toBeUndefined();
168
- (0, vitest_1.expect)(baz).toBeUndefined();
169
- });
170
- (0, vitest_1.it)('should delete keys where key starts with value', async () => {
171
- const cache = new Cache_1.Cache({
172
- connection: undefined,
173
- opts: { namespace: 'starts-ns' }
174
- });
175
- await cache.set('start:1', 'a');
176
- await cache.set('start:2', 'b');
177
- await cache.set('other:3', 'c');
178
- await cache.deleteWhereStartsWith('start');
179
- const v1 = await cache.get('start:1');
180
- const v2 = await cache.get('start:2');
181
- const v3 = await cache.get('other:3');
182
- (0, vitest_1.expect)(v1).toBeUndefined();
183
- (0, vitest_1.expect)(v2).toBeUndefined();
184
- (0, vitest_1.expect)(v3).toBe('c');
185
- });
186
- (0, vitest_1.it)('should use LRU memory cache when usesLRUMemory is true', async () => {
187
- const cache = new Cache_1.Cache({
188
- connection: undefined,
189
- opts: { namespace: 'lru-mem', usesLRUMemory: true }
190
- });
191
- await cache.set('foo', 'bar');
192
- // manually set in memoryCache to test get from LRU
193
- // @ts-expect-error
194
- await cache.memoryCache.set('lru-mem:foo', 'baz');
195
- const value = await cache.get('foo');
196
- (0, vitest_1.expect)(value).toBe('baz');
197
- });
198
- });
199
- (0, vitest_1.describe)('Cache (Redis)', () => {
200
- let cache;
201
- (0, vitest_1.beforeEach)(async () => {
202
- cache = new Cache_1.Cache({
203
- connection,
204
- opts: { namespace: `redis-ns-${js_utils_1.Ids.nanoId(5)}` }
205
- });
206
- await cache.flush();
207
- });
208
- (0, vitest_1.afterEach)(async () => {
209
- await cache.flush();
210
- });
211
- (0, vitest_1.it)('should set and get values correctly with Redis', async () => {
212
- await cache.set('foo', 'bar');
213
- const value = await cache.get('foo');
214
- (0, vitest_1.expect)(value).toBe('bar');
215
- });
216
- (0, vitest_1.it)('should delete values correctly with Redis', async () => {
217
- await cache.set('foo', 'bar');
218
- const deleted = await cache.delete('foo');
219
- (0, vitest_1.expect)(deleted).toBe(true);
220
- const value = await cache.get('foo');
221
- (0, vitest_1.expect)(value).toBeUndefined();
222
- });
223
- (0, vitest_1.it)('should return true for has when value exists (Redis)', async () => {
224
- await cache.set('foo', 'bar');
225
- const exists = await cache.has('foo');
226
- (0, vitest_1.expect)(exists).toBe(true);
227
- });
228
- (0, vitest_1.it)('should return false for has when value does not exist (Redis)', async () => {
229
- const exists = await cache.has('not-exist');
230
- (0, vitest_1.expect)(exists).toBe(false);
231
- });
232
- (0, vitest_1.it)('should remember and cache value for given ms (Redis)', async () => {
233
- let called = 0;
234
- const result = await cache.remember('foo', 1000, async () => {
235
- called++;
236
- return 'bar';
237
- });
238
- (0, vitest_1.expect)(result).toBe('bar');
239
- const result2 = await cache.remember('foo', 1000, async () => {
240
- called++;
241
- return 'baz';
242
- });
243
- (0, vitest_1.expect)(result2).toBe('bar');
244
- (0, vitest_1.expect)(called).toBe(1);
245
- });
246
- (0, vitest_1.it)('should rememberForever and cache value (Redis)', async () => {
247
- let called = 0;
248
- const result = await cache.rememberForever('foo', async () => {
249
- called++;
250
- return 'bar';
251
- });
252
- (0, vitest_1.expect)(result).toBe('bar');
253
- const result2 = await cache.rememberForever('foo', async () => {
254
- called++;
255
- return 'baz';
256
- });
257
- (0, vitest_1.expect)(result2).toBe('bar');
258
- (0, vitest_1.expect)(called).toBe(1);
259
- });
260
- (0, vitest_1.it)('should pull value and delete it (Redis)', async () => {
261
- await cache.set('foo', 'bar');
262
- const value = await cache.pull('foo');
263
- (0, vitest_1.expect)(value).toBe('bar');
264
- const after = await cache.get('foo');
265
- (0, vitest_1.expect)(after).toBeUndefined();
266
- });
267
- (0, vitest_1.it)('should forget value (Redis)', async () => {
268
- await cache.set('foo', 'bar');
269
- const result = await cache.forget('foo');
270
- (0, vitest_1.expect)(result).toBe(true);
271
- const value = await cache.get('foo');
272
- (0, vitest_1.expect)(value).toBeUndefined();
273
- });
274
- (0, vitest_1.it)('should flush all values in namespace (Redis)', async () => {
275
- await cache.set('foo', 'bar');
276
- await cache.set('baz', 'qux');
277
- await cache.flush();
278
- const foo = await cache.get('foo');
279
- const baz = await cache.get('baz');
280
- (0, vitest_1.expect)(foo).toBeUndefined();
281
- (0, vitest_1.expect)(baz).toBeUndefined();
282
- });
283
- (0, vitest_1.it)('should delete keys where key starts with value (Redis)', async () => {
284
- await cache.set('start:1', 'a');
285
- await cache.set('start:2', 'b');
286
- await cache.set('other:3', 'c');
287
- await cache.deleteWhereStartsWith('start');
288
- const v1 = await cache.get('start:1');
289
- const v2 = await cache.get('start:2');
290
- const v3 = await cache.get('other:3');
291
- (0, vitest_1.expect)(v1).toBeUndefined();
292
- (0, vitest_1.expect)(v2).toBeUndefined();
293
- (0, vitest_1.expect)(v3).toBe('c');
294
- });
295
- (0, vitest_1.it)('should support array of keys for has (Redis)', async () => {
296
- await cache.set('foo', 'bar');
297
- await cache.set('baz', 'qux');
298
- const exists = await cache.has(['foo', 'baz', 'not-exist']);
299
- const notExists = await cache.has(['anotherKey']);
300
- (0, vitest_1.expect)(exists).toEqual([true, true, false]);
301
- (0, vitest_1.expect)(notExists).toEqual([false]);
302
- });
303
- (0, vitest_1.it)('should not cache empty or nullish values in remember (Redis)', async () => {
304
- let called = 0;
305
- const result = await cache.remember('foo', 1000, async () => {
306
- called++;
307
- return '';
308
- });
309
- (0, vitest_1.expect)(result).toBe('');
310
- const result2 = await cache.remember('foo', 1000, async () => {
311
- called++;
312
- return 'bar';
313
- });
314
- (0, vitest_1.expect)(result2).toBe('bar');
315
- (0, vitest_1.expect)(called).toBe(2);
316
- });
317
- });
318
- (0, vitest_1.describe)('Cache (Memory) - Namespace Isolation', () => {
319
- (0, vitest_1.it)('should isolate keys between different namespaces', async () => {
320
- const cacheA = new Cache_1.Cache({
321
- connection: undefined,
322
- opts: { namespace: 'nsA' }
323
- });
324
- const cacheB = new Cache_1.Cache({
325
- connection: undefined,
326
- opts: { namespace: 'nsB' }
327
- });
328
- await cacheA.set('foo', 'barA');
329
- await cacheB.set('foo', 'barB');
330
- (0, vitest_1.expect)(await cacheA.get('foo')).toBe('barA');
331
- (0, vitest_1.expect)(await cacheB.get('foo')).toBe('barB');
332
- await cacheA.delete('foo');
333
- (0, vitest_1.expect)(await cacheA.get('foo')).toBeUndefined();
334
- (0, vitest_1.expect)(await cacheB.get('foo')).toBe('barB');
335
- await cacheB.flush();
336
- (0, vitest_1.expect)(await cacheB.get('foo')).toBeUndefined();
337
- });
338
- (0, vitest_1.it)('should not affect other namespaces when using remember and rememberForever', async () => {
339
- const cacheA = new Cache_1.Cache({
340
- connection: undefined,
341
- opts: { namespace: 'nsA2' }
342
- });
343
- const cacheB = new Cache_1.Cache({
344
- connection: undefined,
345
- opts: { namespace: 'nsB2' }
346
- });
347
- let calledA = 0;
348
- let calledB = 0;
349
- const valA = await cacheA.remember('foo', 1000, async () => {
350
- calledA++;
351
- return 'A';
352
- });
353
- const valB = await cacheB.rememberForever('foo', async () => {
354
- calledB++;
355
- return 'B';
356
- });
357
- (0, vitest_1.expect)(valA).toBe('A');
358
- (0, vitest_1.expect)(valB).toBe('B');
359
- (0, vitest_1.expect)(await cacheA.get('foo')).toBe('A');
360
- (0, vitest_1.expect)(await cacheB.get('foo')).toBe('B');
361
- // Should not affect each other
362
- await cacheA.forget('foo');
363
- (0, vitest_1.expect)(await cacheA.get('foo')).toBeUndefined();
364
- (0, vitest_1.expect)(await cacheB.get('foo')).toBe('B');
365
- });
366
- (0, vitest_1.it)('should isolate deleteWhereStartsWith between namespaces', async () => {
367
- const cacheA = new Cache_1.Cache({
368
- connection: undefined,
369
- opts: { namespace: 'nsA3' }
370
- });
371
- const cacheB = new Cache_1.Cache({
372
- connection: undefined,
373
- opts: { namespace: 'nsB3' }
374
- });
375
- await cacheA.set('start:1', 'a');
376
- await cacheA.set('start:2', 'b');
377
- await cacheB.set('start:1', 'c');
378
- await cacheB.set('other:1', 'd');
379
- await cacheA.deleteWhereStartsWith('start');
380
- (0, vitest_1.expect)(await cacheA.get('start:1')).toBeUndefined();
381
- (0, vitest_1.expect)(await cacheA.get('start:2')).toBeUndefined();
382
- (0, vitest_1.expect)(await cacheB.get('start:1')).toBe('c');
383
- (0, vitest_1.expect)(await cacheB.get('other:1')).toBe('d');
384
- });
385
- });
386
- (0, vitest_1.describe)('Cache (Redis) - Namespace Isolation', () => {
387
- let cacheA;
388
- let cacheB;
389
- (0, vitest_1.beforeEach)(async () => {
390
- cacheA = new Cache_1.Cache({
391
- connection,
392
- opts: { namespace: `redis-nsA-${js_utils_1.Ids.nanoId(5)}` }
393
- });
394
- cacheB = new Cache_1.Cache({
395
- connection,
396
- opts: { namespace: `redis-nsB-${js_utils_1.Ids.nanoId(5)}` }
397
- });
398
- await cacheA.flush();
399
- await cacheB.flush();
400
- });
401
- (0, vitest_1.afterEach)(async () => {
402
- await cacheA.flush();
403
- await cacheB.flush();
404
- });
405
- (0, vitest_1.it)('should isolate keys between different namespaces (Redis)', async () => {
406
- await cacheA.set('foo', 'barA');
407
- await cacheB.set('foo', 'barB');
408
- (0, vitest_1.expect)(await cacheA.get('foo')).toBe('barA');
409
- (0, vitest_1.expect)(await cacheB.get('foo')).toBe('barB');
410
- await cacheA.delete('foo');
411
- (0, vitest_1.expect)(await cacheA.get('foo')).toBeUndefined();
412
- (0, vitest_1.expect)(await cacheB.get('foo')).toBe('barB');
413
- await cacheB.flush();
414
- (0, vitest_1.expect)(await cacheB.get('foo')).toBeUndefined();
415
- });
416
- (0, vitest_1.it)('should not affect other namespaces when using remember and rememberForever (Redis)', async () => {
417
- let calledA = 0;
418
- let calledB = 0;
419
- const valA = await cacheA.remember('foo', 1000, async () => {
420
- calledA++;
421
- return 'A';
422
- });
423
- const valB = await cacheB.rememberForever('foo', async () => {
424
- calledB++;
425
- return 'B';
426
- });
427
- (0, vitest_1.expect)(valA).toBe('A');
428
- (0, vitest_1.expect)(valB).toBe('B');
429
- (0, vitest_1.expect)(await cacheA.get('foo')).toBe('A');
430
- (0, vitest_1.expect)(await cacheB.get('foo')).toBe('B');
431
- await cacheA.forget('foo');
432
- (0, vitest_1.expect)(await cacheA.get('foo')).toBeUndefined();
433
- (0, vitest_1.expect)(await cacheB.get('foo')).toBe('B');
434
- });
435
- (0, vitest_1.it)('should isolate deleteWhereStartsWith between namespaces (Redis)', async () => {
436
- await cacheA.set('start:1', 'a');
437
- await cacheA.set('start:2', 'b');
438
- await cacheB.set('start:1', 'c');
439
- await cacheB.set('other:1', 'd');
440
- await cacheA.deleteWhereStartsWith('start');
441
- (0, vitest_1.expect)(await cacheA.get('start:1')).toBeUndefined();
442
- (0, vitest_1.expect)(await cacheA.get('start:2')).toBeUndefined();
443
- (0, vitest_1.expect)(await cacheB.get('start:1')).toBe('c');
444
- (0, vitest_1.expect)(await cacheB.get('other:1')).toBe('d');
445
- });
446
- (0, vitest_1.it)('should support all functions in parallel without collision (Redis)', async () => {
447
- await cacheA.set('foo', 'a');
448
- await cacheB.set('foo', 'b');
449
- await cacheA.set('bar', 'a2');
450
- await cacheB.set('bar', 'b2');
451
- (0, vitest_1.expect)(await cacheA.has('foo')).toBe(true);
452
- (0, vitest_1.expect)(await cacheB.has('foo')).toBe(true);
453
- (0, vitest_1.expect)(await cacheA.has(['foo', 'bar', 'baz'])).toEqual([true, true, false]);
454
- (0, vitest_1.expect)(await cacheB.has(['foo', 'bar', 'baz'])).toEqual([true, true, false]);
455
- (0, vitest_1.expect)(await cacheA.pull('foo')).toBe('a');
456
- (0, vitest_1.expect)(await cacheA.get('foo')).toBeUndefined();
457
- (0, vitest_1.expect)(await cacheB.get('foo')).toBe('b');
458
- await cacheB.forget('bar');
459
- (0, vitest_1.expect)(await cacheB.get('bar')).toBeUndefined();
460
- (0, vitest_1.expect)(await cacheA.get('bar')).toBe('a2');
461
- });
462
- });
463
- (0, vitest_1.describe)('Cache (Memory) - LRU Memory with Namespaces', () => {
464
- (0, vitest_1.it)('should isolate LRU memory cache between namespaces', async () => {
465
- const cacheA = new Cache_1.Cache({
466
- connection: undefined,
467
- opts: { namespace: 'lruA', usesLRUMemory: true }
468
- });
469
- const cacheB = new Cache_1.Cache({
470
- connection: undefined,
471
- opts: { namespace: 'lruB', usesLRUMemory: true }
472
- });
473
- await cacheA.set('foo', 'barA');
474
- await cacheB.set('foo', 'barB');
475
- // @ts-expect-error
476
- await cacheA.memoryCache.set('lruA:foo', 'bazA');
477
- // @ts-expect-error
478
- await cacheB.memoryCache.set('lruB:foo', 'bazB');
479
- (0, vitest_1.expect)(await cacheA.get('foo')).toBe('bazA');
480
- (0, vitest_1.expect)(await cacheB.get('foo')).toBe('bazB');
481
- });
482
- });
483
- const cache = new Cache_1.Cache({ opts: { namespace: 'test' }, connection: undefined });
484
- (0, vitest_1.describe)('CACHE - Keyv', () => {
485
- (0, vitest_1.test)('should return false if a key does not exist in the cache', async () => {
486
- const exists = await cache.has('key');
487
- (0, vitest_1.expect)(exists).toBe(false);
488
- });
489
- (0, vitest_1.test)('should check if a key exists in the cache', async () => {
490
- const id = js_utils_1.Ids.uuid();
491
- await cache.rememberForever(id, async () => 1);
492
- const exists = await cache.has(id);
493
- (0, vitest_1.expect)(exists).toBe(true);
494
- });
495
- (0, vitest_1.test)('should retrieve a value from the cache', async () => {
496
- const value = await cache.remember('key', 1000, async () => 123);
497
- (0, vitest_1.expect)(value).toBe(123);
498
- });
499
- (0, vitest_1.test)('should retrieve and delete a value from the cache', async () => {
500
- const id = js_utils_1.Ids.uuid();
501
- const givenValue = 123;
502
- const returnedValue = await cache.rememberForever(id, async () => givenValue);
503
- (0, vitest_1.expect)(returnedValue).toBe(givenValue);
504
- const value = await cache.pull(id);
505
- (0, vitest_1.expect)(value).toBe(givenValue);
506
- const exists = await cache.has(id);
507
- (0, vitest_1.expect)(exists).toBe(false);
508
- });
509
- (0, vitest_1.test)('should remove a value from the cache', async () => {
510
- const id = js_utils_1.Ids.uuid();
511
- await cache.rememberForever(id, async () => 123);
512
- const result = await cache.forget(id);
513
- (0, vitest_1.expect)(result).toBe(true);
514
- });
515
- (0, vitest_1.test)('should flush all values from the cache', async () => {
516
- const namespace = js_utils_1.Ids.uuid();
517
- const isolatedCache = new Cache_1.Cache({
518
- opts: { namespace },
519
- connection: undefined
520
- });
521
- const id1 = js_utils_1.Ids.uuid();
522
- const id2 = js_utils_1.Ids.uuid();
523
- const id3 = js_utils_1.Ids.uuid();
524
- await isolatedCache.rememberForever(id1, async () => id1);
525
- await isolatedCache.rememberForever(id2, async () => id2);
526
- await isolatedCache.rememberForever(id3, async () => id3);
527
- await cache.flush();
528
- const exists = await cache.has(id3);
529
- (0, vitest_1.expect)(exists).toBe(false);
530
- });
531
- });
532
- (0, vitest_1.describe)('Cache#getValueWhereKeyStartsWith', () => {
533
- (0, vitest_1.it)('should return values for keys starting with a prefix (Memory)', async () => {
534
- const cache = new Cache_1.Cache({
535
- connection: undefined,
536
- opts: { namespace: 'gvwksw-ns' }
537
- });
538
- await cache.set('foo:1', 'a');
539
- await cache.set('foo:2', 'b');
540
- await cache.set('bar:1', 'c');
541
- const values = await cache.getValueWhereKeyStartsWith('foo');
542
- (0, vitest_1.expect)(values).toContain('a');
543
- (0, vitest_1.expect)(values).toContain('b');
544
- (0, vitest_1.expect)(values).not.toContain('c');
545
- (0, vitest_1.expect)(values.length).toBe(2);
546
- });
547
- (0, vitest_1.it)('should return an empty array if no keys match (Memory)', async () => {
548
- const cache = new Cache_1.Cache({
549
- connection: undefined,
550
- opts: { namespace: 'gvwksw-empty' }
551
- });
552
- await cache.set('foo:1', 'a');
553
- const values = await cache.getValueWhereKeyStartsWith('bar');
554
- (0, vitest_1.expect)(Array.isArray(values)).toBe(true);
555
- (0, vitest_1.expect)(values.length).toBe(0);
556
- });
557
- (0, vitest_1.it)('should isolate values between namespaces (Memory)', async () => {
558
- const cacheA = new Cache_1.Cache({
559
- connection: undefined,
560
- opts: { namespace: 'gvwksw-nsA' }
561
- });
562
- const cacheB = new Cache_1.Cache({
563
- connection: undefined,
564
- opts: { namespace: 'gvwksw-nsB' }
565
- });
566
- await cacheA.set('foo:1', 'a');
567
- await cacheB.set('foo:1', 'b');
568
- const valuesA = await cacheA.getValueWhereKeyStartsWith('foo');
569
- const valuesB = await cacheB.getValueWhereKeyStartsWith('foo');
570
- (0, vitest_1.expect)(valuesA).toEqual(['a']);
571
- (0, vitest_1.expect)(valuesB).toEqual(['b']);
572
- });
573
- (0, vitest_1.describe)('with Redis', () => {
574
- const connection = (0, const_1.getGlobalData)().redisUrl || 'redis://localhost:6379';
575
- let cache;
576
- (0, vitest_1.beforeEach)(async () => {
577
- cache = new Cache_1.Cache({
578
- connection,
579
- opts: { namespace: `gvwksw-redis-${js_utils_1.Ids.nanoId(5)}` }
580
- });
581
- await cache.flush();
582
- });
583
- (0, vitest_1.afterEach)(async () => {
584
- await cache.flush();
585
- });
586
- (0, vitest_1.it)('should return values for keys starting with a prefix (Redis)', async () => {
587
- await cache.set('foo:1', 'a');
588
- await cache.set('foo:2', 'b');
589
- await cache.set('bar:1', 'c');
590
- const values = await cache.getValueWhereKeyStartsWith('foo');
591
- (0, vitest_1.expect)(values).toContain('a');
592
- (0, vitest_1.expect)(values).toContain('b');
593
- (0, vitest_1.expect)(values).not.toContain('c');
594
- (0, vitest_1.expect)(values.length).toBe(2);
595
- });
596
- (0, vitest_1.it)('should return an empty array if no keys match (Redis)', async () => {
597
- await cache.set('foo:1', 'a');
598
- const values = await cache.getValueWhereKeyStartsWith('bar');
599
- (0, vitest_1.expect)(Array.isArray(values)).toBe(true);
600
- (0, vitest_1.expect)(values.length).toBe(0);
601
- });
602
- (0, vitest_1.it)('should isolate values between namespaces (Redis)', async () => {
603
- const cacheA = new Cache_1.Cache({
604
- connection,
605
- opts: { namespace: `gvwksw-redisA-${js_utils_1.Ids.nanoId(5)}` }
606
- });
607
- const cacheB = new Cache_1.Cache({
608
- connection,
609
- opts: { namespace: `gvwksw-redisB-${js_utils_1.Ids.nanoId(5)}` }
610
- });
611
- await cacheA.set('foo:1', 'a');
612
- await cacheB.set('foo:1', 'b');
613
- const valuesA = await cacheA.getValueWhereKeyStartsWith('foo');
614
- const valuesB = await cacheB.getValueWhereKeyStartsWith('foo');
615
- (0, vitest_1.expect)(valuesA).toEqual(['a']);
616
- (0, vitest_1.expect)(valuesB).toEqual(['b']);
617
- });
618
- });
619
- (0, vitest_1.describe)('Cache#getValueWhereKeyStartsWith - complex objects', () => {
620
- (0, vitest_1.it)('should return complex objects for keys starting with a prefix (Memory)', async () => {
621
- const cache = new Cache_1.Cache({
622
- connection: undefined,
623
- opts: { namespace: 'gvwksw-complex' }
624
- });
625
- const obj1 = { a: 1, b: [1, 2, 3], c: { d: 'test' } };
626
- const obj2 = { x: 42, y: { z: [4, 5] } };
627
- await cache.set('foo:1', obj1);
628
- await cache.set('foo:2', obj2);
629
- await cache.set('bar:1', { not: 'included' });
630
- const values = await cache.getValueWhereKeyStartsWith('foo');
631
- (0, vitest_1.expect)(values).toEqual(vitest_1.expect.arrayContaining([obj1, obj2]));
632
- (0, vitest_1.expect)(values).not.toContainEqual({ not: 'included' });
633
- (0, vitest_1.expect)(values.length).toBe(2);
634
- (0, vitest_1.expect)(values[0]).toHaveProperty('a');
635
- (0, vitest_1.expect)(values[1]).toHaveProperty('x');
636
- });
637
- (0, vitest_1.it)('should return an empty array if no complex objects match (Memory)', async () => {
638
- const cache = new Cache_1.Cache({
639
- connection: undefined,
640
- opts: { namespace: 'gvwksw-complex-empty' }
641
- });
642
- await cache.set('foo:1', { a: 1 });
643
- const values = await cache.getValueWhereKeyStartsWith('bar');
644
- (0, vitest_1.expect)(Array.isArray(values)).toBe(true);
645
- (0, vitest_1.expect)(values.length).toBe(0);
646
- });
647
- (0, vitest_1.it)('should isolate complex objects between namespaces (Memory)', async () => {
648
- const cacheA = new Cache_1.Cache({
649
- connection: undefined,
650
- opts: { namespace: 'gvwksw-complexA' }
651
- });
652
- const cacheB = new Cache_1.Cache({
653
- connection: undefined,
654
- opts: { namespace: 'gvwksw-complexB' }
655
- });
656
- const objA = { foo: 'A', arr: [1, 2] };
657
- const objB = { foo: 'B', arr: [3, 4] };
658
- await cacheA.set('foo:1', objA);
659
- await cacheB.set('foo:1', objB);
660
- const valuesA = await cacheA.getValueWhereKeyStartsWith('foo');
661
- const valuesB = await cacheB.getValueWhereKeyStartsWith('foo');
662
- (0, vitest_1.expect)(valuesA).toEqual([objA]);
663
- (0, vitest_1.expect)(valuesB).toEqual([objB]);
664
- });
665
- (0, vitest_1.describe)('with Redis - complex objects', () => {
666
- const connection = (0, const_1.getGlobalData)().redisUrl || 'redis://localhost:6379';
667
- let cache;
668
- (0, vitest_1.beforeEach)(async () => {
669
- cache = new Cache_1.Cache({
670
- connection,
671
- opts: { namespace: `gvwksw-redis-complex-${js_utils_1.Ids.nanoId(5)}` }
672
- });
673
- await cache.flush();
674
- });
675
- (0, vitest_1.afterEach)(async () => {
676
- await cache.flush();
677
- });
678
- // it('should return complex objects for keys starting with a prefix (Redis)', async () => {
679
- // const obj1 = { a: 1, b: [1, 2, 3], c: { d: 'test' } }
680
- // const obj2 = { x: 42, y: { z: [4, 5] } }
681
- // await cache.set('foo:1', obj1)
682
- // await cache.set('foo:2', obj2)
683
- // await cache.set('bar:1', { not: 'included' })
684
- // const values = await cache.getValueWhereKeyStartsWith('foo')
685
- // expect(values).toEqual(expect.arrayContaining([obj1, obj2]))
686
- // expect(values).not.toContainEqual({ not: 'included' })
687
- // expect(values.length).toBe(2)
688
- // expect(values[0]).toEqual(expect.objectContaining(obj1))
689
- // expect(values[1]).toEqual(expect.objectContaining(obj2))
690
- // })
691
- (0, vitest_1.it)('should return an empty array if no complex objects match (Redis)', async () => {
692
- await cache.set('foo:1', { a: 1 });
693
- const values = await cache.getValueWhereKeyStartsWith('bar');
694
- (0, vitest_1.expect)(Array.isArray(values)).toBe(true);
695
- (0, vitest_1.expect)(values.length).toBe(0);
696
- });
697
- (0, vitest_1.it)('should isolate complex objects between namespaces (Redis)', async () => {
698
- const cacheA = new Cache_1.Cache({
699
- connection,
700
- opts: { namespace: `gvwksw-redis-complexA-${js_utils_1.Ids.nanoId(5)}` }
701
- });
702
- const cacheB = new Cache_1.Cache({
703
- connection,
704
- opts: { namespace: `gvwksw-redis-complexB-${js_utils_1.Ids.nanoId(5)}` }
705
- });
706
- const objA = { foo: 'A', arr: [1, 2] };
707
- const objB = { foo: 'B', arr: [3, 4] };
708
- await cacheA.set('foo:1', objA);
709
- await cacheB.set('foo:1', objB);
710
- const valuesA = await cacheA.getValueWhereKeyStartsWith('foo');
711
- const valuesB = await cacheB.getValueWhereKeyStartsWith('foo');
712
- (0, vitest_1.expect)(valuesA).toEqual([objA]);
713
- (0, vitest_1.expect)(valuesB).toEqual([objB]);
714
- });
715
- });
716
- });
717
- });
718
- //# sourceMappingURL=Cache.test.js.map