@owlmeans/redis 0.1.1 → 0.1.3
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 +1 -1
- package/README.md +26 -486
- package/package.json +8 -6
- package/tsconfig.json +5 -4
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 OwlMeans Common — Fullstack typescript framework
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -1,517 +1,57 @@
|
|
|
1
1
|
# @owlmeans/redis
|
|
2
2
|
|
|
3
|
-
Redis service
|
|
3
|
+
Redis service for OwlMeans server contexts — connection management with cluster support.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- **Connection Pooling**: Efficient Redis connection management with proper cleanup
|
|
12
|
-
- **Multi-Layer Support**: Integration with OwlMeans context layer system for proper data isolation
|
|
13
|
-
- **Prefix Management**: Automatic key prefixing for namespace isolation
|
|
14
|
-
|
|
15
|
-
This package follows the OwlMeans "quadra" pattern as a server-side implementation complementing the basic `@owlmeans/redis-resource` package.
|
|
7
|
+
- `makeRedisService(alias?)` — creates a Redis connection service
|
|
8
|
+
- `appendRedis(context, alias?)` — registers the service in the context
|
|
9
|
+
- Reads connection config from `context.cfg.dbs[alias]`
|
|
10
|
+
- Used as the connection provider for `@owlmeans/redis-resource`
|
|
16
11
|
|
|
17
12
|
## Installation
|
|
18
13
|
|
|
19
14
|
```bash
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Dependencies
|
|
24
|
-
|
|
25
|
-
This package requires Redis client library and integrates with:
|
|
26
|
-
- `@owlmeans/redis-resource`: Base Redis resource definitions
|
|
27
|
-
- `@owlmeans/server-context`: Server context management
|
|
28
|
-
- `@owlmeans/resource`: Base resource service patterns
|
|
29
|
-
- `ioredis`: High-performance Redis client library
|
|
30
|
-
|
|
31
|
-
## Core Concepts
|
|
32
|
-
|
|
33
|
-
### Redis Service
|
|
34
|
-
|
|
35
|
-
The Redis service provides connection management and extends the base database service with Redis-specific functionality like clustering and prefix management.
|
|
36
|
-
|
|
37
|
-
### Connection Management
|
|
38
|
-
|
|
39
|
-
Manages Redis connections with support for clustering, sentinels, and proper connection lifecycle management including graceful shutdown.
|
|
40
|
-
|
|
41
|
-
### Layer Integration
|
|
42
|
-
|
|
43
|
-
Supports multi-layer data isolation through the OwlMeans context layer system, allowing service-specific and entity-specific Redis configurations.
|
|
44
|
-
|
|
45
|
-
## API Reference
|
|
46
|
-
|
|
47
|
-
### Types
|
|
48
|
-
|
|
49
|
-
#### `RedisMeta`
|
|
50
|
-
Metadata interface for Redis-specific configuration extending ioredis options.
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
interface RedisMeta extends RedisOptions {
|
|
54
|
-
masterNumber?: number // Master node count for cluster
|
|
55
|
-
slaveNumber?: number // Slave node count for cluster
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Factory Functions
|
|
60
|
-
|
|
61
|
-
#### `makeRedisService(alias?: string): RedisDbService`
|
|
62
|
-
|
|
63
|
-
Creates a Redis service instance with connection management and clustering capabilities.
|
|
64
|
-
|
|
65
|
-
**Parameters:**
|
|
66
|
-
- `alias` (optional): Service alias (default: `DEFAULT_ALIAS`)
|
|
67
|
-
|
|
68
|
-
**Returns:** `RedisDbService` instance
|
|
69
|
-
|
|
70
|
-
**Methods:**
|
|
71
|
-
- **`db(configAlias?: string): Promise<RedisDb>`**: Gets Redis database instance with prefix for the configuration
|
|
72
|
-
- **`initialize(configAlias?: string): Promise<void>`**: Initializes Redis connection with cluster setup
|
|
73
|
-
- **`reinitializeContext<T>(context: BasicContext<ServerConfig>): T`**: Reinitializes service with new context
|
|
74
|
-
|
|
75
|
-
**Example:**
|
|
76
|
-
```typescript
|
|
77
|
-
import { makeRedisService } from '@owlmeans/redis'
|
|
78
|
-
|
|
79
|
-
const redisService = makeRedisService('cache')
|
|
80
|
-
|
|
81
|
-
// Initialize with configuration
|
|
82
|
-
await redisService.initialize('prod-config')
|
|
83
|
-
|
|
84
|
-
// Get database instance with prefix
|
|
85
|
-
const db = await redisService.db('prod-config')
|
|
86
|
-
|
|
87
|
-
// Use Redis operations
|
|
88
|
-
await db.client.set('user:123', JSON.stringify(userData))
|
|
89
|
-
const user = await db.client.get('user:123')
|
|
15
|
+
bun add @owlmeans/redis
|
|
90
16
|
```
|
|
91
17
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
Convenience function to create and register a Redis service with a context.
|
|
95
|
-
|
|
96
|
-
**Parameters:**
|
|
97
|
-
- `context`: Server context instance
|
|
98
|
-
- `alias` (optional): Service alias (default: `DEFAULT_ALIAS`)
|
|
99
|
-
|
|
100
|
-
**Returns:** The context with Redis service registered
|
|
18
|
+
## Usage
|
|
101
19
|
|
|
102
|
-
**Example:**
|
|
103
20
|
```typescript
|
|
104
|
-
import { appendRedis } from '@owlmeans/redis'
|
|
105
|
-
import { makeServerContext } from '@owlmeans/server-context'
|
|
21
|
+
import { appendRedis, DEFAULT_ALIAS } from '@owlmeans/redis'
|
|
106
22
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
await contextWithRedis.configure().init()
|
|
111
|
-
|
|
112
|
-
// Access Redis service
|
|
113
|
-
const redisService = context.service('session-store')
|
|
23
|
+
// In context setup (backend/src/context.ts)
|
|
24
|
+
appendRedis<C, T>(context)
|
|
114
25
|
```
|
|
115
26
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
The Redis service provides a database interface with automatic prefixing:
|
|
119
|
-
|
|
120
|
-
#### `RedisDb`
|
|
121
|
-
Database instance with client and prefix management.
|
|
27
|
+
Config (`config.json`):
|
|
122
28
|
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
**Usage:**
|
|
131
|
-
```typescript
|
|
132
|
-
const db = await redisService.db('config-alias')
|
|
133
|
-
|
|
134
|
-
// Keys are automatically prefixed
|
|
135
|
-
await db.client.set('session:user123', sessionData)
|
|
136
|
-
await db.client.get('session:user123')
|
|
137
|
-
|
|
138
|
-
// Use Redis operations with prefix isolation
|
|
139
|
-
await db.client.hmset('user:profile', profileData)
|
|
140
|
-
const profile = await db.client.hgetall('user:profile')
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Cluster Support
|
|
144
|
-
|
|
145
|
-
The service automatically handles Redis cluster and sentinel configuration:
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
// Configuration with cluster hosts
|
|
149
|
-
const config = {
|
|
150
|
-
alias: 'cluster-config',
|
|
151
|
-
host: ['redis1.example.com', 'redis2.example.com', 'redis3.example.com'],
|
|
152
|
-
port: 6379,
|
|
153
|
-
database: 'app-cache',
|
|
154
|
-
// Additional cluster options in meta
|
|
155
|
-
meta: {
|
|
156
|
-
masterNumber: 3,
|
|
157
|
-
slaveNumber: 6,
|
|
158
|
-
enableReadyCheck: true,
|
|
159
|
-
maxRetriesPerRequest: 3
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Service automatically detects cluster and sets up connections
|
|
164
|
-
await redisService.initialize('cluster-config')
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Constants
|
|
168
|
-
|
|
169
|
-
#### `DEFAULT_ALIAS`
|
|
170
|
-
Default service alias for Redis services.
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
const DEFAULT_ALIAS = DEFAULT_DB_ALIAS // From @owlmeans/redis-resource
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
## Usage Examples
|
|
177
|
-
|
|
178
|
-
### Basic Redis Service Setup
|
|
179
|
-
|
|
180
|
-
```typescript
|
|
181
|
-
import { makeRedisService } from '@owlmeans/redis'
|
|
182
|
-
import { makeServerContext } from '@owlmeans/server-context'
|
|
183
|
-
|
|
184
|
-
// Create server context with Redis configuration
|
|
185
|
-
const context = makeServerContext({
|
|
186
|
-
service: 'my-app',
|
|
187
|
-
type: AppType.Backend,
|
|
188
|
-
layer: Layer.Service,
|
|
189
|
-
dbs: [{
|
|
190
|
-
alias: 'main-cache',
|
|
191
|
-
service: 'redis',
|
|
192
|
-
host: 'localhost',
|
|
193
|
-
port: 6379,
|
|
194
|
-
database: 'app-cache'
|
|
195
|
-
}]
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
// Create and register Redis service
|
|
199
|
-
const redisService = makeRedisService('redis')
|
|
200
|
-
context.registerService(redisService)
|
|
201
|
-
|
|
202
|
-
// Initialize context
|
|
203
|
-
await context.configure().init()
|
|
204
|
-
|
|
205
|
-
// Use Redis
|
|
206
|
-
const db = await redisService.db('main-cache')
|
|
207
|
-
await db.client.set('key', 'value')
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Using appendRedis Helper
|
|
211
|
-
|
|
212
|
-
```typescript
|
|
213
|
-
import { appendRedis } from '@owlmeans/redis'
|
|
214
|
-
|
|
215
|
-
const context = makeServerContext(config)
|
|
216
|
-
const contextWithRedis = appendRedis(context)
|
|
217
|
-
|
|
218
|
-
await contextWithRedis.configure().init()
|
|
219
|
-
|
|
220
|
-
const redisService = context.service('redis')
|
|
221
|
-
const db = await redisService.db()
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### Session Storage
|
|
225
|
-
|
|
226
|
-
```typescript
|
|
227
|
-
// Configure Redis for session storage
|
|
228
|
-
const sessionConfig = {
|
|
229
|
-
alias: 'session-store',
|
|
230
|
-
service: 'redis',
|
|
231
|
-
host: 'localhost',
|
|
232
|
-
port: 6379,
|
|
233
|
-
database: 'sessions'
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const redisService = makeRedisService('redis')
|
|
237
|
-
await redisService.initialize('session-store')
|
|
238
|
-
|
|
239
|
-
const db = await redisService.db('session-store')
|
|
240
|
-
|
|
241
|
-
// Store session data
|
|
242
|
-
const sessionId = 'sess_123456'
|
|
243
|
-
const sessionData = {
|
|
244
|
-
userId: 'user_789',
|
|
245
|
-
loginTime: Date.now(),
|
|
246
|
-
permissions: ['read', 'write']
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
await db.client.setex(`session:${sessionId}`, 3600, JSON.stringify(sessionData))
|
|
250
|
-
|
|
251
|
-
// Retrieve session data
|
|
252
|
-
const rawSession = await db.client.get(`session:${sessionId}`)
|
|
253
|
-
const session = JSON.parse(rawSession)
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
### Caching with TTL
|
|
257
|
-
|
|
258
|
-
```typescript
|
|
259
|
-
const cacheService = makeRedisService('cache')
|
|
260
|
-
await cacheService.initialize('cache-config')
|
|
261
|
-
|
|
262
|
-
const db = await cacheService.db('cache-config')
|
|
263
|
-
|
|
264
|
-
// Cache with expiration
|
|
265
|
-
await db.client.setex('user:profile:123', 300, JSON.stringify(userProfile)) // 5 minutes
|
|
266
|
-
|
|
267
|
-
// Cache with complex data structures
|
|
268
|
-
await db.client.hmset('stats:daily', {
|
|
269
|
-
visitors: 1234,
|
|
270
|
-
pageViews: 5678,
|
|
271
|
-
lastUpdated: Date.now()
|
|
272
|
-
})
|
|
273
|
-
await db.client.expire('stats:daily', 86400) // 24 hours
|
|
274
|
-
|
|
275
|
-
// Get cached data
|
|
276
|
-
const cachedProfile = await db.client.get('user:profile:123')
|
|
277
|
-
const stats = await db.client.hgetall('stats:daily')
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### Multi-Configuration Setup
|
|
281
|
-
|
|
282
|
-
```typescript
|
|
283
|
-
const context = makeServerContext({
|
|
284
|
-
service: 'multi-redis-app',
|
|
285
|
-
type: AppType.Backend,
|
|
286
|
-
layer: Layer.Service,
|
|
287
|
-
dbs: [
|
|
288
|
-
{
|
|
289
|
-
alias: 'session-store',
|
|
290
|
-
service: 'redis',
|
|
291
|
-
host: 'sessions.redis.example.com',
|
|
292
|
-
database: 'sessions',
|
|
293
|
-
meta: { db: 0 }
|
|
294
|
-
},
|
|
295
|
-
{
|
|
296
|
-
alias: 'cache-store',
|
|
297
|
-
service: 'redis',
|
|
298
|
-
host: 'cache.redis.example.com',
|
|
299
|
-
database: 'cache',
|
|
300
|
-
meta: { db: 1 }
|
|
301
|
-
}
|
|
302
|
-
]
|
|
303
|
-
})
|
|
304
|
-
|
|
305
|
-
const redisService = makeRedisService('redis')
|
|
306
|
-
context.registerService(redisService)
|
|
307
|
-
|
|
308
|
-
await context.configure().init()
|
|
309
|
-
|
|
310
|
-
// Use different Redis instances
|
|
311
|
-
const sessionDb = await redisService.db('session-store')
|
|
312
|
-
const cacheDb = await redisService.db('cache-store')
|
|
313
|
-
|
|
314
|
-
// Operations are isolated by configuration
|
|
315
|
-
await sessionDb.client.set('user:session', sessionData)
|
|
316
|
-
await cacheDb.client.set('user:profile', profileData)
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
### Cluster Configuration
|
|
320
|
-
|
|
321
|
-
```typescript
|
|
322
|
-
const clusterConfig = {
|
|
323
|
-
service: 'cluster-app',
|
|
324
|
-
type: AppType.Backend,
|
|
325
|
-
layer: Layer.Service,
|
|
326
|
-
dbs: [{
|
|
327
|
-
alias: 'cluster-cache',
|
|
328
|
-
service: 'redis',
|
|
329
|
-
host: [
|
|
330
|
-
'redis1.cluster.example.com',
|
|
331
|
-
'redis2.cluster.example.com',
|
|
332
|
-
'redis3.cluster.example.com'
|
|
333
|
-
],
|
|
334
|
-
port: 6379,
|
|
335
|
-
database: 'clustered-cache',
|
|
336
|
-
meta: {
|
|
337
|
-
enableReadyCheck: true,
|
|
338
|
-
maxRetriesPerRequest: 3,
|
|
339
|
-
retryDelayOnFailover: 100,
|
|
340
|
-
masterNumber: 3,
|
|
341
|
-
slaveNumber: 6
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"dbs": {
|
|
32
|
+
"redis": {
|
|
33
|
+
"host": "localhost",
|
|
34
|
+
"port": 6379
|
|
342
35
|
}
|
|
343
|
-
}]
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
const context = makeServerContext(clusterConfig)
|
|
347
|
-
const redisService = makeRedisService('redis')
|
|
348
|
-
context.registerService(redisService)
|
|
349
|
-
|
|
350
|
-
// Service automatically handles cluster setup
|
|
351
|
-
await context.configure().init()
|
|
352
|
-
|
|
353
|
-
const db = await redisService.db('cluster-cache')
|
|
354
|
-
// Operations work transparently across cluster
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
### Service Reinitialization
|
|
358
|
-
|
|
359
|
-
```typescript
|
|
360
|
-
// Original context
|
|
361
|
-
const originalContext = makeServerContext(config)
|
|
362
|
-
const redisService = makeRedisService()
|
|
363
|
-
originalContext.registerService(redisService)
|
|
364
|
-
|
|
365
|
-
// Later, reinitialize with new context
|
|
366
|
-
const newContext = makeServerContext(newConfig)
|
|
367
|
-
const reinitializedService = redisService.reinitializeContext(newContext)
|
|
368
|
-
|
|
369
|
-
// Service now uses new context configuration
|
|
370
|
-
await reinitializedService.initialize()
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
### Pub/Sub Operations
|
|
374
|
-
|
|
375
|
-
```typescript
|
|
376
|
-
const redisService = makeRedisService('pubsub')
|
|
377
|
-
await redisService.initialize('pubsub-config')
|
|
378
|
-
|
|
379
|
-
const db = await redisService.db('pubsub-config')
|
|
380
|
-
|
|
381
|
-
// Subscribe to channels
|
|
382
|
-
await db.client.subscribe('notifications')
|
|
383
|
-
db.client.on('message', (channel, message) => {
|
|
384
|
-
console.log(`Received from ${channel}: ${message}`)
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
// Publish messages
|
|
388
|
-
await db.client.publish('notifications', JSON.stringify({
|
|
389
|
-
type: 'user-login',
|
|
390
|
-
userId: '123',
|
|
391
|
-
timestamp: Date.now()
|
|
392
|
-
}))
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
## Configuration
|
|
396
|
-
|
|
397
|
-
Redis service configuration is handled through the server context's database configuration:
|
|
398
|
-
|
|
399
|
-
```typescript
|
|
400
|
-
interface DatabaseConfig {
|
|
401
|
-
alias: string // Configuration alias
|
|
402
|
-
service: string // Service name ('redis')
|
|
403
|
-
host: string | string[] // Redis host(s)
|
|
404
|
-
port?: number // Redis port
|
|
405
|
-
database: string // Database prefix/namespace
|
|
406
|
-
username?: string // Authentication username
|
|
407
|
-
password?: string // Authentication password
|
|
408
|
-
serviceSensitive?: boolean // Enable service-layer isolation
|
|
409
|
-
entitySensitive?: boolean // Enable entity-layer isolation
|
|
410
|
-
meta?: RedisMeta // Redis-specific options
|
|
411
|
-
}
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
### Redis-Specific Meta Options
|
|
415
|
-
|
|
416
|
-
```typescript
|
|
417
|
-
interface RedisMeta extends RedisOptions {
|
|
418
|
-
masterNumber?: number // Master node count for cluster
|
|
419
|
-
slaveNumber?: number // Slave node count for cluster
|
|
420
|
-
// Plus all ioredis options:
|
|
421
|
-
db?: number // Redis database number
|
|
422
|
-
connectTimeout?: number // Connection timeout
|
|
423
|
-
commandTimeout?: number // Command timeout
|
|
424
|
-
retryDelayOnFailover?: number // Failover retry delay
|
|
425
|
-
enableReadyCheck?: boolean // Enable ready check
|
|
426
|
-
maxRetriesPerRequest?: number // Max retries per request
|
|
427
|
-
// ... and many more ioredis options
|
|
428
|
-
}
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
## Error Handling
|
|
432
|
-
|
|
433
|
-
The package provides descriptive error messages for common issues:
|
|
434
|
-
|
|
435
|
-
- **Client replacement**: Thrown when attempting to replace existing Redis client
|
|
436
|
-
- **Context assertion**: Thrown when service context is invalid
|
|
437
|
-
- **Connection errors**: Propagated from ioredis client
|
|
438
|
-
|
|
439
|
-
```typescript
|
|
440
|
-
try {
|
|
441
|
-
await redisService.initialize('config-alias')
|
|
442
|
-
} catch (error) {
|
|
443
|
-
if (error.message.includes('Cannot replace existing redis client')) {
|
|
444
|
-
// Handle client replacement error
|
|
445
36
|
}
|
|
446
37
|
}
|
|
447
38
|
```
|
|
448
39
|
|
|
449
|
-
##
|
|
40
|
+
## API
|
|
450
41
|
|
|
451
|
-
|
|
452
|
-
- **Client Duplication**: Each db() call creates a duplicate client for isolation
|
|
453
|
-
- **Cluster Latency**: Cluster setup may add initialization time
|
|
454
|
-
- **Memory Usage**: Multiple Redis connections increase memory usage
|
|
455
|
-
- **Key Prefixing**: Adds minimal overhead for namespace isolation
|
|
42
|
+
### `makeRedisService(alias?): RedisDbService`
|
|
456
43
|
|
|
457
|
-
|
|
44
|
+
Creates the Redis service. `alias` defaults to `DEFAULT_ALIAS` (`'redis'`).
|
|
458
45
|
|
|
459
|
-
###
|
|
460
|
-
- Use authentication credentials for production Redis instances
|
|
461
|
-
- Configure TLS/SSL for Redis connections when needed
|
|
462
|
-
- Restrict Redis access to necessary IP addresses
|
|
46
|
+
### `appendRedis<C, T>(context, alias?): T`
|
|
463
47
|
|
|
464
|
-
|
|
465
|
-
- Be cautious with sensitive data in Redis (consider encryption)
|
|
466
|
-
- Use appropriate TTL values to limit data exposure time
|
|
467
|
-
- Implement proper access controls at the application level
|
|
48
|
+
Registers the Redis service in the context.
|
|
468
49
|
|
|
469
|
-
###
|
|
470
|
-
- Use layer-sensitive configurations for multi-tenant applications
|
|
471
|
-
- Leverage prefix management for data isolation between services
|
|
50
|
+
### `RedisMeta`
|
|
472
51
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
This package integrates with:
|
|
476
|
-
|
|
477
|
-
- **@owlmeans/redis-resource**: Base Redis resource types and interfaces
|
|
478
|
-
- **@owlmeans/server-context**: Server context and configuration management
|
|
479
|
-
- **@owlmeans/resource**: Base resource service patterns
|
|
480
|
-
- **@owlmeans/mongo**: For multi-database architectures
|
|
481
|
-
|
|
482
|
-
## Best Practices
|
|
483
|
-
|
|
484
|
-
1. **Use appropriate TTL values** for cached data to prevent memory bloat
|
|
485
|
-
2. **Configure clustering** for production high-availability
|
|
486
|
-
3. **Separate Redis configurations** by use case (cache vs sessions vs pub/sub)
|
|
487
|
-
4. **Monitor Redis memory usage** and implement eviction policies
|
|
488
|
-
5. **Use connection pooling** efficiently with proper client management
|
|
52
|
+
Extends `RedisOptions` (ioredis) — all ioredis connection options are supported in config.
|
|
489
53
|
|
|
490
54
|
## Related Packages
|
|
491
55
|
|
|
492
|
-
-
|
|
493
|
-
-
|
|
494
|
-
- **@owlmeans/server-context**: Server context management
|
|
495
|
-
- **@owlmeans/resource**: Base resource service patterns
|
|
496
|
-
|
|
497
|
-
## Redis Use Cases
|
|
498
|
-
|
|
499
|
-
### Caching
|
|
500
|
-
- API response caching
|
|
501
|
-
- Database query result caching
|
|
502
|
-
- Computed value caching
|
|
503
|
-
|
|
504
|
-
### Session Storage
|
|
505
|
-
- User session management
|
|
506
|
-
- Authentication token storage
|
|
507
|
-
- Shopping cart persistence
|
|
508
|
-
|
|
509
|
-
### Real-time Features
|
|
510
|
-
- Pub/Sub messaging
|
|
511
|
-
- Live notifications
|
|
512
|
-
- Real-time analytics
|
|
513
|
-
|
|
514
|
-
### Rate Limiting
|
|
515
|
-
- API rate limiting
|
|
516
|
-
- Request throttling
|
|
517
|
-
- Usage tracking
|
|
56
|
+
- [`@owlmeans/redis-resource`](../redis-resource) — pub/sub and streaming resources over this service
|
|
57
|
+
- [`@owlmeans/server-auth`](../server-auth) — `AUTH_CACHE` redis resource for auth token caching
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/redis",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"license": "MIT",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"scripts": {
|
|
6
7
|
"build": "tsc -b",
|
|
@@ -20,16 +21,17 @@
|
|
|
20
21
|
}
|
|
21
22
|
},
|
|
22
23
|
"devDependencies": {
|
|
24
|
+
"@owlmeans/dep-config": "workspace:*",
|
|
23
25
|
"@types/node": "^24.10.1",
|
|
24
26
|
"nodemon": "^3.1.11",
|
|
25
|
-
"typescript": "^
|
|
27
|
+
"typescript": "^6.0.2"
|
|
26
28
|
},
|
|
27
29
|
"dependencies": {
|
|
28
30
|
"@noble/hashes": "^1.5.0",
|
|
29
|
-
"@owlmeans/context": "^0.1.
|
|
30
|
-
"@owlmeans/redis-resource": "^0.1.
|
|
31
|
-
"@owlmeans/resource": "^0.1.
|
|
32
|
-
"@owlmeans/server-context": "^0.1.
|
|
31
|
+
"@owlmeans/context": "^0.1.3",
|
|
32
|
+
"@owlmeans/redis-resource": "^0.1.3",
|
|
33
|
+
"@owlmeans/resource": "^0.1.3",
|
|
34
|
+
"@owlmeans/server-context": "^0.1.3",
|
|
33
35
|
"@scure/base": "^1.1.9",
|
|
34
36
|
"ioredis": "^5.4.1"
|
|
35
37
|
},
|
package/tsconfig.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extends": [
|
|
3
|
-
"
|
|
3
|
+
"@owlmeans/dep-config/tsconfig.base.json",
|
|
4
|
+
"@owlmeans/dep-config/tsconfig.node.json"
|
|
4
5
|
],
|
|
5
6
|
"compilerOptions": {
|
|
6
|
-
"rootDir": "./src/",
|
|
7
|
-
"outDir": "./build/"
|
|
7
|
+
"rootDir": "./src/",
|
|
8
|
+
"outDir": "./build/"
|
|
8
9
|
},
|
|
9
10
|
"exclude": [
|
|
10
11
|
"./dist/**/*",
|
|
11
12
|
"./build/**/*",
|
|
12
13
|
"./*.ts"
|
|
13
14
|
]
|
|
14
|
-
}
|
|
15
|
+
}
|