@cogitator-ai/redis 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +474 -24
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,7 +8,20 @@ Unified Redis client for Cogitator with standalone and cluster support.
|
|
|
8
8
|
pnpm add @cogitator-ai/redis ioredis
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Unified Interface** - Same API for standalone and cluster modes
|
|
14
|
+
- **Auto-Detection** - Automatically detect standalone vs cluster
|
|
15
|
+
- **Environment Config** - Configure via environment variables
|
|
16
|
+
- **TLS Support** - Secure connections with TLS
|
|
17
|
+
- **NAT Mapping** - Support for cluster nodes behind NAT
|
|
18
|
+
- **Key Prefixing** - Automatic key prefixing with hash tags for cluster
|
|
19
|
+
- **Retry Strategy** - Built-in exponential backoff
|
|
20
|
+
- **Pub/Sub** - Publish/subscribe support
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
12
25
|
|
|
13
26
|
### Standalone Mode
|
|
14
27
|
|
|
@@ -21,6 +34,8 @@ const redis = await createRedisClient({
|
|
|
21
34
|
|
|
22
35
|
await redis.set('key', 'value');
|
|
23
36
|
const value = await redis.get('key');
|
|
37
|
+
|
|
38
|
+
await redis.quit();
|
|
24
39
|
```
|
|
25
40
|
|
|
26
41
|
### Cluster Mode
|
|
@@ -29,48 +44,483 @@ const value = await redis.get('key');
|
|
|
29
44
|
import { createRedisClient } from '@cogitator-ai/redis';
|
|
30
45
|
|
|
31
46
|
const redis = await createRedisClient({
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
},
|
|
47
|
+
mode: 'cluster',
|
|
48
|
+
nodes: [
|
|
49
|
+
{ host: 'redis-1', port: 6379 },
|
|
50
|
+
{ host: 'redis-2', port: 6379 },
|
|
51
|
+
{ host: 'redis-3', port: 6379 },
|
|
52
|
+
],
|
|
53
|
+
keyPrefix: '{cogitator}:',
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
await redis.set('key', 'value');
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Creating Clients
|
|
62
|
+
|
|
63
|
+
### Factory Function
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { createRedisClient } from '@cogitator-ai/redis';
|
|
67
|
+
|
|
68
|
+
// Standalone with URL
|
|
69
|
+
const client1 = await createRedisClient({
|
|
70
|
+
url: 'redis://localhost:6379',
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Standalone with host/port
|
|
74
|
+
const client2 = await createRedisClient({
|
|
75
|
+
host: 'localhost',
|
|
76
|
+
port: 6379,
|
|
77
|
+
password: 'secret',
|
|
78
|
+
db: 1,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Cluster mode
|
|
82
|
+
const client3 = await createRedisClient({
|
|
83
|
+
mode: 'cluster',
|
|
84
|
+
nodes: [
|
|
85
|
+
{ host: 'node1', port: 6379 },
|
|
86
|
+
{ host: 'node2', port: 6379 },
|
|
87
|
+
{ host: 'node3', port: 6379 },
|
|
88
|
+
],
|
|
39
89
|
});
|
|
40
90
|
```
|
|
41
91
|
|
|
42
|
-
### Environment
|
|
92
|
+
### From Environment Variables
|
|
43
93
|
|
|
44
94
|
```typescript
|
|
45
|
-
import { createConfigFromEnv } from '@cogitator-ai/redis';
|
|
95
|
+
import { createRedisClient, createConfigFromEnv } from '@cogitator-ai/redis';
|
|
46
96
|
|
|
47
|
-
// Reads from REDIS_URL, REDIS_HOST, REDIS_PORT, REDIS_PASSWORD
|
|
48
|
-
// REDIS_CLUSTER_NODES for cluster mode
|
|
49
97
|
const config = createConfigFromEnv();
|
|
50
98
|
const redis = await createRedisClient(config);
|
|
51
99
|
```
|
|
52
100
|
|
|
53
|
-
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Configuration
|
|
104
|
+
|
|
105
|
+
### Standalone Configuration
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
interface RedisStandaloneConfig {
|
|
109
|
+
mode?: 'standalone';
|
|
110
|
+
|
|
111
|
+
// Connection
|
|
112
|
+
url?: string; // Redis URL (e.g., redis://localhost:6379)
|
|
113
|
+
host?: string; // Host (alternative to url)
|
|
114
|
+
port?: number; // Port (alternative to url)
|
|
115
|
+
db?: number; // Database number
|
|
116
|
+
|
|
117
|
+
// Authentication
|
|
118
|
+
password?: string; // Redis password
|
|
119
|
+
|
|
120
|
+
// Options
|
|
121
|
+
keyPrefix?: string; // Prefix for all keys
|
|
122
|
+
tls?: boolean; // Enable TLS
|
|
123
|
+
maxRetriesPerRequest?: number; // Max retries (default: 3)
|
|
124
|
+
lazyConnect?: boolean; // Don't connect immediately
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Cluster Configuration
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
interface RedisClusterConfig {
|
|
132
|
+
mode: 'cluster';
|
|
133
|
+
nodes: { host: string; port: number }[];
|
|
134
|
+
|
|
135
|
+
// Authentication
|
|
136
|
+
password?: string;
|
|
137
|
+
|
|
138
|
+
// Options
|
|
139
|
+
keyPrefix?: string; // Use {hashtag}: format for cluster
|
|
140
|
+
tls?: boolean;
|
|
141
|
+
maxRetriesPerRequest?: number;
|
|
142
|
+
lazyConnect?: boolean;
|
|
143
|
+
|
|
144
|
+
// Cluster-specific
|
|
145
|
+
scaleReads?: 'master' | 'slave' | 'all'; // Where to read from
|
|
146
|
+
natMap?: Record<string, { host: string; port: number }>; // NAT mapping
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Configuration Options
|
|
151
|
+
|
|
152
|
+
| Option | Standalone | Cluster | Description |
|
|
153
|
+
| ---------------------- | :--------: | :-----: | ----------------------- |
|
|
154
|
+
| `url` | ✓ | - | Redis connection URL |
|
|
155
|
+
| `host` | ✓ | - | Redis host |
|
|
156
|
+
| `port` | ✓ | - | Redis port |
|
|
157
|
+
| `db` | ✓ | - | Database number |
|
|
158
|
+
| `nodes` | - | ✓ | Cluster nodes array |
|
|
159
|
+
| `password` | ✓ | ✓ | Authentication password |
|
|
160
|
+
| `keyPrefix` | ✓ | ✓ | Key prefix |
|
|
161
|
+
| `tls` | ✓ | ✓ | Enable TLS |
|
|
162
|
+
| `maxRetriesPerRequest` | ✓ | ✓ | Max retry attempts |
|
|
163
|
+
| `lazyConnect` | ✓ | ✓ | Lazy connection |
|
|
164
|
+
| `scaleReads` | - | ✓ | Read from replicas |
|
|
165
|
+
| `natMap` | - | ✓ | NAT address mapping |
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## RedisClient Interface
|
|
170
|
+
|
|
171
|
+
The unified client interface works identically for both modes.
|
|
172
|
+
|
|
173
|
+
### Key-Value Operations
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
await redis.get('key');
|
|
177
|
+
|
|
178
|
+
await redis.set('key', 'value');
|
|
179
|
+
|
|
180
|
+
await redis.setex('key', 3600, 'value');
|
|
181
|
+
|
|
182
|
+
await redis.del('key1', 'key2');
|
|
183
|
+
|
|
184
|
+
await redis.expire('key', 3600);
|
|
185
|
+
|
|
186
|
+
await redis.mget('key1', 'key2', 'key3');
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Sorted Sets
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
await redis.zadd('leaderboard', 100, 'player1');
|
|
193
|
+
await redis.zadd('leaderboard', 200, 'player2');
|
|
194
|
+
|
|
195
|
+
const top3 = await redis.zrange('leaderboard', 0, 2);
|
|
196
|
+
|
|
197
|
+
const highScores = await redis.zrangebyscore('leaderboard', 100, 500);
|
|
198
|
+
|
|
199
|
+
await redis.zrem('leaderboard', 'player1');
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Sets
|
|
54
203
|
|
|
55
204
|
```typescript
|
|
56
|
-
|
|
205
|
+
const members = await redis.smembers('myset');
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Pub/Sub
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
const subscriber = redis.duplicate();
|
|
212
|
+
|
|
213
|
+
await subscriber.subscribe('channel', (channel, message) => {
|
|
214
|
+
console.log(`Received on ${channel}: ${message}`);
|
|
215
|
+
});
|
|
57
216
|
|
|
58
|
-
|
|
59
|
-
|
|
217
|
+
await redis.publish('channel', 'hello');
|
|
218
|
+
|
|
219
|
+
await subscriber.unsubscribe('channel');
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Events
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
redis.on('connect', () => console.log('Connected'));
|
|
226
|
+
redis.on('ready', () => console.log('Ready'));
|
|
227
|
+
redis.on('error', (err) => console.error('Error:', err));
|
|
228
|
+
redis.on('close', () => console.log('Closed'));
|
|
229
|
+
redis.on('reconnecting', () => console.log('Reconnecting...'));
|
|
230
|
+
redis.on('end', () => console.log('Connection ended'));
|
|
60
231
|
```
|
|
61
232
|
|
|
233
|
+
### Utility Methods
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
await redis.ping();
|
|
237
|
+
|
|
238
|
+
const info = await redis.info();
|
|
239
|
+
const memoryInfo = await redis.info('memory');
|
|
240
|
+
|
|
241
|
+
const allKeys = await redis.keys('myapp:*');
|
|
242
|
+
|
|
243
|
+
const sub = redis.duplicate();
|
|
244
|
+
|
|
245
|
+
await redis.quit();
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
62
250
|
## Environment Variables
|
|
63
251
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
252
|
+
| Variable | Description |
|
|
253
|
+
| --------------------- | ------------------------------- |
|
|
254
|
+
| `REDIS_URL` | Redis connection URL |
|
|
255
|
+
| `REDIS_HOST` | Redis host (default: localhost) |
|
|
256
|
+
| `REDIS_PORT` | Redis port (default: 6379) |
|
|
257
|
+
| `REDIS_PASSWORD` | Redis password |
|
|
258
|
+
| `REDIS_CLUSTER_NODES` | JSON array of cluster nodes |
|
|
259
|
+
| `REDIS_KEY_PREFIX` | Key prefix |
|
|
260
|
+
|
|
261
|
+
### Environment Examples
|
|
70
262
|
|
|
71
|
-
|
|
263
|
+
**Standalone:**
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
REDIS_URL=redis://localhost:6379
|
|
267
|
+
REDIS_PASSWORD=secret
|
|
268
|
+
REDIS_KEY_PREFIX=myapp:
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Cluster:**
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
REDIS_CLUSTER_NODES='[{"host":"10.0.0.1","port":6379},{"host":"10.0.0.2","port":6379}]'
|
|
275
|
+
REDIS_PASSWORD=secret
|
|
276
|
+
REDIS_KEY_PREFIX={myapp}:
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Auto-Detection
|
|
282
|
+
|
|
283
|
+
Automatically detect if Redis is running in cluster mode:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
import { createRedisClient, detectRedisMode } from '@cogitator-ai/redis';
|
|
287
|
+
|
|
288
|
+
const mode = await detectRedisMode({
|
|
289
|
+
host: 'localhost',
|
|
290
|
+
port: 6379,
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
console.log(`Redis mode: ${mode}`);
|
|
294
|
+
|
|
295
|
+
const config =
|
|
296
|
+
mode === 'cluster'
|
|
297
|
+
? { mode: 'cluster', nodes: [{ host: 'localhost', port: 6379 }] }
|
|
298
|
+
: { host: 'localhost', port: 6379 };
|
|
299
|
+
|
|
300
|
+
const redis = await createRedisClient(config);
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Cluster Key Routing
|
|
306
|
+
|
|
307
|
+
In cluster mode, use hash tags to ensure related keys route to the same slot:
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
const redis = await createRedisClient({
|
|
311
|
+
mode: 'cluster',
|
|
312
|
+
nodes: [...],
|
|
313
|
+
keyPrefix: '{myapp}:', // Hash tag prefix
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// All these keys route to the same slot because of {myapp}
|
|
317
|
+
await redis.set('users:123', '...'); // → {myapp}:users:123
|
|
318
|
+
await redis.set('sessions:456', '...'); // → {myapp}:sessions:456
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Hash Tag Rules
|
|
322
|
+
|
|
323
|
+
- Use `{hashtag}:` format for prefixes
|
|
324
|
+
- Content inside `{}` determines slot routing
|
|
325
|
+
- Keys with same hash tag go to same node
|
|
326
|
+
- Required for multi-key operations in cluster
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## TLS Configuration
|
|
331
|
+
|
|
332
|
+
### Standalone with TLS
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
const redis = await createRedisClient({
|
|
336
|
+
url: 'rediss://secure.redis.host:6379', // Note: rediss://
|
|
337
|
+
tls: true,
|
|
338
|
+
});
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Cluster with TLS
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
const redis = await createRedisClient({
|
|
345
|
+
mode: 'cluster',
|
|
346
|
+
nodes: [
|
|
347
|
+
{ host: 'secure-1.redis.host', port: 6379 },
|
|
348
|
+
{ host: 'secure-2.redis.host', port: 6379 },
|
|
349
|
+
],
|
|
350
|
+
tls: true,
|
|
351
|
+
password: 'secret',
|
|
352
|
+
});
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## NAT Mapping
|
|
358
|
+
|
|
359
|
+
For cluster nodes behind NAT/load balancer:
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
const redis = await createRedisClient({
|
|
363
|
+
mode: 'cluster',
|
|
364
|
+
nodes: [{ host: 'external.host', port: 6379 }],
|
|
365
|
+
natMap: {
|
|
366
|
+
'10.0.0.1:6379': { host: 'external-1.host', port: 6379 },
|
|
367
|
+
'10.0.0.2:6379': { host: 'external-2.host', port: 6379 },
|
|
368
|
+
'10.0.0.3:6379': { host: 'external-3.host', port: 6379 },
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## Examples
|
|
376
|
+
|
|
377
|
+
### Connection Pooling Pattern
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
import { createRedisClient, createConfigFromEnv } from '@cogitator-ai/redis';
|
|
381
|
+
import type { RedisClient } from '@cogitator-ai/redis';
|
|
382
|
+
|
|
383
|
+
let client: RedisClient | null = null;
|
|
384
|
+
|
|
385
|
+
async function getRedis(): Promise<RedisClient> {
|
|
386
|
+
if (!client) {
|
|
387
|
+
const config = createConfigFromEnv();
|
|
388
|
+
client = await createRedisClient(config);
|
|
389
|
+
}
|
|
390
|
+
return client;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
async function closeRedis(): Promise<void> {
|
|
394
|
+
if (client) {
|
|
395
|
+
await client.quit();
|
|
396
|
+
client = null;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Caching Pattern
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
import { createRedisClient } from '@cogitator-ai/redis';
|
|
405
|
+
|
|
406
|
+
const redis = await createRedisClient({
|
|
407
|
+
url: 'redis://localhost:6379',
|
|
408
|
+
keyPrefix: 'cache:',
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
async function getOrFetch<T>(
|
|
412
|
+
key: string,
|
|
413
|
+
fetcher: () => Promise<T>,
|
|
414
|
+
ttl: number = 3600
|
|
415
|
+
): Promise<T> {
|
|
416
|
+
const cached = await redis.get(key);
|
|
417
|
+
if (cached) {
|
|
418
|
+
return JSON.parse(cached);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const data = await fetcher();
|
|
422
|
+
await redis.setex(key, ttl, JSON.stringify(data));
|
|
423
|
+
return data;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const user = await getOrFetch('user:123', () => fetchUserFromDb(123), 600);
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Pub/Sub Pattern
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
import { createRedisClient } from '@cogitator-ai/redis';
|
|
433
|
+
|
|
434
|
+
const redis = await createRedisClient({ url: 'redis://localhost:6379' });
|
|
435
|
+
|
|
436
|
+
const publisher = redis;
|
|
437
|
+
const subscriber = redis.duplicate();
|
|
438
|
+
|
|
439
|
+
interface Event {
|
|
440
|
+
type: string;
|
|
441
|
+
payload: unknown;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
async function publish(event: Event): Promise<void> {
|
|
445
|
+
await publisher.publish('events', JSON.stringify(event));
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
async function subscribe(handler: (event: Event) => void): Promise<void> {
|
|
449
|
+
await subscriber.subscribe('events', (channel, message) => {
|
|
450
|
+
const event = JSON.parse(message);
|
|
451
|
+
handler(event);
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
await subscribe((event) => {
|
|
456
|
+
console.log('Received event:', event);
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
await publish({ type: 'user.created', payload: { id: 123 } });
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### Health Check
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
import { createRedisClient } from '@cogitator-ai/redis';
|
|
466
|
+
|
|
467
|
+
async function checkRedisHealth(): Promise<boolean> {
|
|
468
|
+
const redis = await createRedisClient({
|
|
469
|
+
url: 'redis://localhost:6379',
|
|
470
|
+
lazyConnect: true,
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
try {
|
|
474
|
+
const result = await redis.ping();
|
|
475
|
+
return result === 'PONG';
|
|
476
|
+
} catch {
|
|
477
|
+
return false;
|
|
478
|
+
} finally {
|
|
479
|
+
await redis.quit();
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### Graceful Shutdown
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
import { createRedisClient, createConfigFromEnv } from '@cogitator-ai/redis';
|
|
488
|
+
|
|
489
|
+
const redis = await createRedisClient(createConfigFromEnv());
|
|
490
|
+
|
|
491
|
+
process.on('SIGTERM', async () => {
|
|
492
|
+
console.log('Shutting down...');
|
|
493
|
+
await redis.quit();
|
|
494
|
+
process.exit(0);
|
|
495
|
+
});
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## Type Reference
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
import type {
|
|
504
|
+
RedisMode,
|
|
505
|
+
RedisNodeConfig,
|
|
506
|
+
RedisCommonOptions,
|
|
507
|
+
RedisStandaloneConfig,
|
|
508
|
+
RedisClusterConfig,
|
|
509
|
+
RedisConfig,
|
|
510
|
+
RedisClient,
|
|
511
|
+
QueueMetrics,
|
|
512
|
+
} from '@cogitator-ai/redis';
|
|
513
|
+
|
|
514
|
+
import {
|
|
515
|
+
createRedisClient,
|
|
516
|
+
detectRedisMode,
|
|
517
|
+
parseClusterNodesEnv,
|
|
518
|
+
createConfigFromEnv,
|
|
519
|
+
isClusterConfig,
|
|
520
|
+
} from '@cogitator-ai/redis';
|
|
521
|
+
```
|
|
72
522
|
|
|
73
|
-
|
|
523
|
+
---
|
|
74
524
|
|
|
75
525
|
## License
|
|
76
526
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cogitator-ai/redis",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Unified Redis client for Cogitator with standalone and cluster support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@types/node": "^25.0.0",
|
|
19
|
-
"@cogitator-ai/types": "0.
|
|
19
|
+
"@cogitator-ai/types": "0.5.0"
|
|
20
20
|
},
|
|
21
21
|
"optionalDependencies": {
|
|
22
22
|
"ioredis": "^5.4.1"
|