@common-stack/store-redis 8.2.5-alpha.33 → 8.2.5-alpha.35
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/lib/containers/container.d.ts +2 -0
- package/lib/containers/container.js +9 -0
- package/lib/containers/index.d.ts +1 -0
- package/lib/core/index.d.ts +3 -0
- package/lib/core/ioredis.d.ts +15 -0
- package/lib/core/ioredis.js +31 -0
- package/lib/core/keyBuilder/generate-query-cache-key.d.ts +57 -0
- package/lib/core/keyBuilder/generate-query-cache-key.js +88 -0
- package/lib/core/keyBuilder/index.d.ts +18 -0
- package/lib/core/keyBuilder/index.js +27 -0
- package/lib/core/keyBuilder/redis-key-builder.d.ts +152 -0
- package/lib/core/keyBuilder/redis-key-builder.js +185 -0
- package/lib/core/keyBuilder/sanitize-redis-key.d.ts +118 -0
- package/lib/core/keyBuilder/sanitize-redis-key.js +120 -0
- package/lib/core/upstash-redis.d.ts +14 -0
- package/lib/core/upstash-redis.js +27 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +7 -3
- package/lib/interfaces/index.d.ts +1 -6
- package/lib/interfaces/redis.d.ts +11 -0
- package/lib/module.d.ts +2 -0
- package/lib/module.js +9 -0
- package/lib/services/RedisCacheManager.d.ts +77 -0
- package/lib/services/RedisCacheManager.js +185 -0
- package/lib/services/index.d.ts +1 -5
- package/lib/templates/constants/SERVER_TYPES.ts.template +0 -1
- package/lib/templates/repositories/IRedisKeyBuilder.ts.template +4 -4
- package/lib/templates/repositories/redisCommonTypes.ts.template +2 -163
- package/lib/templates/{repositories/IRedisCacheManager.ts.template → services/RedisCacheManager.ts.template} +7 -7
- package/package.json +8 -7
- package/lib/interfaces/cache-manager.d.ts +0 -28
- package/lib/interfaces/redis-key-options.d.ts +0 -35
- package/lib/interfaces/redis-key-options.js +0 -17
- package/lib/interfaces/storage-backend.d.ts +0 -17
- package/lib/templates/repositories/IRedisService.ts.template +0 -236
- package/lib/templates/repositories/IRedisStorageBackend.ts.template +0 -229
- package/lib/utils/index.d.ts +0 -5
- package/lib/utils/redis-key-builder.d.ts +0 -32
- package/lib/utils/redis-key-builder.js +0 -68
- package/lib/utils/redis-key-sanitizer.d.ts +0 -30
- package/lib/utils/redis-key-sanitizer.js +0 -54
|
@@ -5,109 +5,15 @@
|
|
|
5
5
|
* These types provide a standardized approach to working with Redis operations, including
|
|
6
6
|
* key management, caching, and storage patterns.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* - RedisNamespace: Enum for organizing keys into logical namespaces
|
|
11
|
-
* - CacheContext: Context information for cache operations (tenant, user, org)
|
|
12
|
-
* - CachePolicy: Configuration for cache TTL and scope
|
|
13
|
-
* - RedisValue: Union type for values that can be stored in Redis
|
|
14
|
-
* - RedisHashValue: Type for Redis hash field values
|
|
15
|
-
* - RedisScanOptions: Options for scanning Redis keys
|
|
16
|
-
*
|
|
17
|
-
* These types ensure consistency across Redis operations, providing type safety and
|
|
18
|
-
* clear contracts for data caching and storage throughout the application.
|
|
8
|
+
* Most types are generated from GraphQL schema via codegen.
|
|
9
|
+
* Additional runtime types (RedisValue, RedisHashValue) are defined here.
|
|
19
10
|
*
|
|
20
11
|
* @see IRedisCacheManager - Cache manager interface using these types
|
|
21
12
|
* @see IRedisStorageBackend - Storage backend interface using these types
|
|
22
13
|
* @see IRedisKeyBuilder - Key builder interface using these types
|
|
23
14
|
*/
|
|
24
15
|
|
|
25
|
-
/**
|
|
26
|
-
* Options for building Redis keys with standardized format
|
|
27
|
-
*
|
|
28
|
-
* @property tenantId - Tenant ID for multi-tenant isolation (defaults to 'default')
|
|
29
|
-
* @property namespace - Namespace to categorize keys (e.g., 'cache', 'session', 'storage')
|
|
30
|
-
* @property segments - Additional key segments to append
|
|
31
|
-
* @property userId - Optional user ID for user-specific keys
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* const keyOptions: RedisKeyOptions = {
|
|
35
|
-
* tenantId: 'tenant-123',
|
|
36
|
-
* namespace: RedisNamespace.CACHE,
|
|
37
|
-
* segments: ['user', 'profile']
|
|
38
|
-
* };
|
|
39
|
-
* // Produces key: APP_NAME:tenant-123:cache:user:profile
|
|
40
|
-
*/
|
|
41
|
-
export interface RedisKeyOptions {
|
|
42
|
-
tenantId?: string;
|
|
43
|
-
namespace: string;
|
|
44
|
-
segments: string[];
|
|
45
|
-
userId?: string;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Standard Redis namespaces for organizing keys
|
|
50
|
-
* Using namespaces helps prevent key collisions and makes bulk operations easier
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* // Use namespaces to organize cache keys
|
|
54
|
-
* const cacheKey = buildRedisKey({
|
|
55
|
-
* tenantId: 'tenant-123',
|
|
56
|
-
* namespace: RedisNamespace.CACHE,
|
|
57
|
-
* segments: ['query', 'users']
|
|
58
|
-
* });
|
|
59
|
-
*/
|
|
60
|
-
export enum RedisNamespace {
|
|
61
|
-
CACHE = 'cache',
|
|
62
|
-
SESSION = 'session',
|
|
63
|
-
TENANT = 'tenant',
|
|
64
|
-
CONFIG = 'config',
|
|
65
|
-
EXTENSION = 'extension',
|
|
66
|
-
CONTRIBUTION = 'contribution',
|
|
67
|
-
STORAGE = 'storage',
|
|
68
|
-
PERMISSION = 'permission',
|
|
69
|
-
TEMP = 'temp',
|
|
70
|
-
QUEUE = 'queue',
|
|
71
|
-
LOCK = 'lock',
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Context for cache operations
|
|
76
|
-
* Provides tenant, user, and organization isolation for cached data
|
|
77
|
-
*
|
|
78
|
-
* @property tenantId - Tenant identifier for multi-tenant applications
|
|
79
|
-
* @property userId - User identifier for user-specific caching
|
|
80
|
-
* @property orgId - Organization identifier for org-level caching
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* const ctx: CacheContext = {
|
|
84
|
-
* tenantId: 'tenant-123',
|
|
85
|
-
* userId: 'user-456',
|
|
86
|
-
* orgId: 'org-789'
|
|
87
|
-
* };
|
|
88
|
-
*/
|
|
89
|
-
export interface CacheContext {
|
|
90
|
-
tenantId?: string;
|
|
91
|
-
userId?: string;
|
|
92
|
-
orgId?: string;
|
|
93
|
-
}
|
|
94
16
|
|
|
95
|
-
/**
|
|
96
|
-
* Cache policy for controlling cache behavior
|
|
97
|
-
*
|
|
98
|
-
* @property maxAge - Maximum age in seconds (TTL)
|
|
99
|
-
* @property scope - Cache scope (PUBLIC, PRIVATE, etc.)
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* const policy: CachePolicy = {
|
|
103
|
-
* maxAge: 3600, // 1 hour
|
|
104
|
-
* scope: 'PRIVATE'
|
|
105
|
-
* };
|
|
106
|
-
*/
|
|
107
|
-
export interface CachePolicy {
|
|
108
|
-
maxAge: number;
|
|
109
|
-
scope?: string;
|
|
110
|
-
}
|
|
111
17
|
|
|
112
18
|
/**
|
|
113
19
|
* Union type for values that can be stored in Redis
|
|
@@ -120,70 +26,3 @@ export type RedisValue = string | number | Buffer | null;
|
|
|
120
26
|
* Hashes in Redis store field-value pairs
|
|
121
27
|
*/
|
|
122
28
|
export type RedisHashValue = Record<string, string>;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Options for scanning Redis keys
|
|
126
|
-
* Used for iterating through keys matching a pattern
|
|
127
|
-
*
|
|
128
|
-
* @property match - Pattern to match keys (supports wildcards)
|
|
129
|
-
* @property count - Number of keys to return per iteration
|
|
130
|
-
* @property type - Optional Redis data type to filter by
|
|
131
|
-
*
|
|
132
|
-
* @example
|
|
133
|
-
* const scanOptions: RedisScanOptions = {
|
|
134
|
-
* match: 'APP:tenant-*:cache:*',
|
|
135
|
-
* count: 100,
|
|
136
|
-
* type: 'string'
|
|
137
|
-
* };
|
|
138
|
-
*/
|
|
139
|
-
export interface RedisScanOptions {
|
|
140
|
-
match?: string;
|
|
141
|
-
count?: number;
|
|
142
|
-
type?: 'string' | 'list' | 'set' | 'zset' | 'hash' | 'stream';
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Result from a Redis SCAN operation
|
|
147
|
-
*
|
|
148
|
-
* @property cursor - Next cursor position (0 means scan is complete)
|
|
149
|
-
* @property keys - Array of keys matching the scan criteria
|
|
150
|
-
*/
|
|
151
|
-
export interface RedisScanResult {
|
|
152
|
-
cursor: string;
|
|
153
|
-
keys: string[];
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Options for Redis bulk operations
|
|
158
|
-
* Used when performing operations on multiple keys
|
|
159
|
-
*
|
|
160
|
-
* @property pipeline - Whether to use Redis pipeline for batch operations
|
|
161
|
-
* @property transaction - Whether to wrap operations in a MULTI/EXEC transaction
|
|
162
|
-
*/
|
|
163
|
-
export interface RedisBulkOptions {
|
|
164
|
-
pipeline?: boolean;
|
|
165
|
-
transaction?: boolean;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Redis connection configuration
|
|
170
|
-
*
|
|
171
|
-
* @property host - Redis server host
|
|
172
|
-
* @property port - Redis server port
|
|
173
|
-
* @property password - Optional password for authentication
|
|
174
|
-
* @property db - Database number to use
|
|
175
|
-
* @property keyPrefix - Prefix to add to all keys
|
|
176
|
-
* @property maxRetriesPerRequest - Maximum retry attempts
|
|
177
|
-
* @property enableReadyCheck - Whether to check connection is ready
|
|
178
|
-
* @property lazyConnect - Whether to delay connection until first command
|
|
179
|
-
*/
|
|
180
|
-
export interface RedisConnectionConfig {
|
|
181
|
-
host?: string;
|
|
182
|
-
port?: number;
|
|
183
|
-
password?: string;
|
|
184
|
-
db?: number;
|
|
185
|
-
keyPrefix?: string;
|
|
186
|
-
maxRetriesPerRequest?: number;
|
|
187
|
-
enableReadyCheck?: boolean;
|
|
188
|
-
lazyConnect?: boolean;
|
|
189
|
-
}
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
* while maintaining cache correctness through intelligent invalidation strategies.
|
|
25
25
|
*
|
|
26
26
|
* @see IRedisStorageBackend - For simpler key-value storage
|
|
27
|
-
* @see
|
|
28
|
-
* @see
|
|
27
|
+
* @see ICachePolicy - For cache TTL and scope configuration
|
|
28
|
+
* @see ICacheContext - For tenant/user isolation
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
import type { DocumentNode } from 'graphql';
|
|
32
|
-
import {
|
|
32
|
+
import { ICacheContext, ICachePolicy } from 'common/server';
|
|
33
33
|
|
|
34
34
|
export interface IRedisCacheManager {
|
|
35
35
|
/**
|
|
@@ -60,7 +60,7 @@ export interface IRedisCacheManager {
|
|
|
60
60
|
get<T>(
|
|
61
61
|
query: string | DocumentNode,
|
|
62
62
|
variables: Record<string, any>,
|
|
63
|
-
ctx:
|
|
63
|
+
ctx: ICacheContext
|
|
64
64
|
): Promise<T | null>;
|
|
65
65
|
|
|
66
66
|
/**
|
|
@@ -97,8 +97,8 @@ export interface IRedisCacheManager {
|
|
|
97
97
|
query: string | DocumentNode,
|
|
98
98
|
variables: Record<string, any>,
|
|
99
99
|
data: T,
|
|
100
|
-
ctx:
|
|
101
|
-
cachePolicy?:
|
|
100
|
+
ctx: ICacheContext,
|
|
101
|
+
cachePolicy?: ICachePolicy
|
|
102
102
|
): Promise<void>;
|
|
103
103
|
|
|
104
104
|
/**
|
|
@@ -143,7 +143,7 @@ export interface IRedisCacheManager {
|
|
|
143
143
|
del(
|
|
144
144
|
query: string | DocumentNode,
|
|
145
145
|
variables?: Record<string, unknown>,
|
|
146
|
-
ctx?:
|
|
146
|
+
ctx?: ICacheContext,
|
|
147
147
|
shouldRemoveAll?: boolean
|
|
148
148
|
): Promise<void>;
|
|
149
149
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@common-stack/store-redis",
|
|
3
|
-
"version": "8.2.5-alpha.
|
|
3
|
+
"version": "8.2.5-alpha.35",
|
|
4
4
|
"description": "Redis store utilities and services for common-stack",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": "CDMBase LLC",
|
|
@@ -24,13 +24,14 @@
|
|
|
24
24
|
"watch": "npm run build:lib:watch"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@common-stack/core": "8.2.5-alpha.
|
|
27
|
+
"@common-stack/core": "8.2.5-alpha.35"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"common": "8.2.5-alpha.
|
|
30
|
+
"common": "8.2.5-alpha.35",
|
|
31
31
|
"ioredis": "^5.3.2"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
+
"graphql": ">=16.0.0",
|
|
34
35
|
"inversify": "*",
|
|
35
36
|
"ioredis": ">=5.0.0"
|
|
36
37
|
},
|
|
@@ -44,15 +45,15 @@
|
|
|
44
45
|
],
|
|
45
46
|
"repositories": [
|
|
46
47
|
"./${libDir}/templates/repositories/IRedisKeyBuilder.ts.template",
|
|
47
|
-
"./${libDir}/templates/repositories/IRedisStorageBackend.ts.template",
|
|
48
|
-
"./${libDir}/templates/repositories/IRedisCacheManager.ts.template",
|
|
49
|
-
"./${libDir}/templates/repositories/IRedisService.ts.template",
|
|
50
48
|
"./${libDir}/templates/repositories/redisCommonTypes.ts.template"
|
|
49
|
+
],
|
|
50
|
+
"services": [
|
|
51
|
+
"./${libDir}/templates/services/RedisCacheManager.ts.template"
|
|
51
52
|
]
|
|
52
53
|
}
|
|
53
54
|
},
|
|
54
55
|
"typescript": {
|
|
55
56
|
"definition": "lib/index.d.ts"
|
|
56
57
|
},
|
|
57
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "33d6be7fdf924ca76bc1b98cee3031d55a8115d7"
|
|
58
59
|
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { DocumentNode } from 'graphql';
|
|
2
|
-
import type { CacheContext } from './redis-key-options';
|
|
3
|
-
/**
|
|
4
|
-
* Cache policy for controlling cache behavior
|
|
5
|
-
*/
|
|
6
|
-
export interface CachePolicy {
|
|
7
|
-
/** Maximum age in seconds */
|
|
8
|
-
maxAge: number;
|
|
9
|
-
/** Cache scope (PUBLIC, PRIVATE, etc.) */
|
|
10
|
-
scope?: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Redis cache manager interface for GraphQL query caching
|
|
14
|
-
*/
|
|
15
|
-
export interface IRedisCacheManager {
|
|
16
|
-
/**
|
|
17
|
-
* Get cached data for a query
|
|
18
|
-
*/
|
|
19
|
-
get<T>(query: string | DocumentNode, variables: Record<string, any>, ctx: CacheContext): Promise<T | null>;
|
|
20
|
-
/**
|
|
21
|
-
* Set cached data for a query
|
|
22
|
-
*/
|
|
23
|
-
set<T>(query: string | DocumentNode, variables: Record<string, any>, data: T, ctx: CacheContext, cachePolicy?: CachePolicy): Promise<void>;
|
|
24
|
-
/**
|
|
25
|
-
* Delete cached data for a query
|
|
26
|
-
*/
|
|
27
|
-
del(query: string | DocumentNode, variables?: Record<string, unknown>, ctx?: CacheContext, shouldRemoveAll?: boolean): Promise<void>;
|
|
28
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Options for building Redis keys with standardized format
|
|
3
|
-
*/
|
|
4
|
-
export interface RedisKeyOptions {
|
|
5
|
-
/** Tenant ID for multi-tenant isolation */
|
|
6
|
-
tenantId?: string;
|
|
7
|
-
/** Namespace to categorize keys (e.g., 'cache', 'session', 'storage') */
|
|
8
|
-
namespace: string;
|
|
9
|
-
/** Additional key segments to append */
|
|
10
|
-
segments: string[];
|
|
11
|
-
/** Optional user ID for user-specific keys */
|
|
12
|
-
userId?: string;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Standard Redis namespaces for organizing keys
|
|
16
|
-
*/
|
|
17
|
-
export declare enum RedisNamespace {
|
|
18
|
-
CACHE = "cache",
|
|
19
|
-
SESSION = "session",
|
|
20
|
-
TENANT = "tenant",
|
|
21
|
-
CONFIG = "config",
|
|
22
|
-
EXTENSION = "extension",
|
|
23
|
-
CONTRIBUTION = "contribution",
|
|
24
|
-
STORAGE = "storage",
|
|
25
|
-
PERMISSION = "permission",
|
|
26
|
-
TEMP = "temp"
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Context for cache operations
|
|
30
|
-
*/
|
|
31
|
-
export interface CacheContext {
|
|
32
|
-
tenantId?: string;
|
|
33
|
-
userId?: string;
|
|
34
|
-
orgId?: string;
|
|
35
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Standard Redis namespaces for organizing keys
|
|
3
|
-
*/
|
|
4
|
-
var RedisNamespace;
|
|
5
|
-
(function (RedisNamespace) {
|
|
6
|
-
RedisNamespace["CACHE"] = "cache";
|
|
7
|
-
RedisNamespace["SESSION"] = "session";
|
|
8
|
-
RedisNamespace["TENANT"] = "tenant";
|
|
9
|
-
RedisNamespace["CONFIG"] = "config";
|
|
10
|
-
RedisNamespace["EXTENSION"] = "extension";
|
|
11
|
-
RedisNamespace["CONTRIBUTION"] = "contribution";
|
|
12
|
-
RedisNamespace["STORAGE"] = "storage";
|
|
13
|
-
RedisNamespace["PERMISSION"] = "permission";
|
|
14
|
-
RedisNamespace["TEMP"] = "temp";
|
|
15
|
-
})(RedisNamespace || (RedisNamespace = {}));
|
|
16
|
-
|
|
17
|
-
export { RedisNamespace };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic storage backend interface for simple key-value operations
|
|
3
|
-
*/
|
|
4
|
-
export interface IStorageBackend {
|
|
5
|
-
/**
|
|
6
|
-
* Get a value by key
|
|
7
|
-
*/
|
|
8
|
-
get(key: string): Promise<string | null>;
|
|
9
|
-
/**
|
|
10
|
-
* Set a value for a key
|
|
11
|
-
*/
|
|
12
|
-
set(key: string, value: string): Promise<void>;
|
|
13
|
-
/**
|
|
14
|
-
* Clear all keys in this storage
|
|
15
|
-
*/
|
|
16
|
-
clear(): Promise<void>;
|
|
17
|
-
}
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
/**
|
|
3
|
-
* @file IRedisService.ts
|
|
4
|
-
* @description Defines the IRedisService interface for advanced Redis operations and patterns.
|
|
5
|
-
* This interface provides high-level Redis operations beyond simple key-value storage,
|
|
6
|
-
* including pub/sub, streams, sorted sets, and distributed locking.
|
|
7
|
-
*
|
|
8
|
-
* The Redis service is designed for:
|
|
9
|
-
* - Pub/Sub messaging patterns
|
|
10
|
-
* - Distributed locking (mutex)
|
|
11
|
-
* - Rate limiting
|
|
12
|
-
* - Leaderboards and rankings (sorted sets)
|
|
13
|
-
* - Event streams
|
|
14
|
-
* - Queue management
|
|
15
|
-
*
|
|
16
|
-
* Key features:
|
|
17
|
-
* - Pub/Sub for real-time messaging
|
|
18
|
-
* - Distributed locks for resource coordination
|
|
19
|
-
* - Rate limiting for API throttling
|
|
20
|
-
* - Sorted sets for rankings and leaderboards
|
|
21
|
-
* - Redis Streams for event sourcing
|
|
22
|
-
* - Pipeline operations for performance
|
|
23
|
-
*
|
|
24
|
-
* This service layer provides advanced Redis patterns that go beyond simple caching
|
|
25
|
-
* and storage, enabling sophisticated distributed system architectures.
|
|
26
|
-
*
|
|
27
|
-
* @see IRedisCacheManager - For query caching
|
|
28
|
-
* @see IRedisStorageBackend - For simple key-value storage
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
export interface IRedisService {
|
|
32
|
-
/**
|
|
33
|
-
* Publish a message to a Redis channel
|
|
34
|
-
* Part of the Pub/Sub pattern for real-time messaging
|
|
35
|
-
*
|
|
36
|
-
* @param channel - Channel name to publish to
|
|
37
|
-
* @param message - Message to publish (will be stringified if object)
|
|
38
|
-
* @returns Promise resolving to number of subscribers that received the message
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* // Publish user update event
|
|
42
|
-
* await redisService.publish('user:updates', JSON.stringify({
|
|
43
|
-
* userId: '123',
|
|
44
|
-
* action: 'updated'
|
|
45
|
-
* }));
|
|
46
|
-
*/
|
|
47
|
-
publish(channel: string, message: string): Promise<number>;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Subscribe to a Redis channel
|
|
51
|
-
* Receives messages published to the channel
|
|
52
|
-
*
|
|
53
|
-
* @param channel - Channel name to subscribe to
|
|
54
|
-
* @param callback - Function called when message received
|
|
55
|
-
* @returns Promise that resolves when subscribed
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* // Subscribe to user updates
|
|
59
|
-
* await redisService.subscribe('user:updates', (message) => {
|
|
60
|
-
* const event = JSON.parse(message);
|
|
61
|
-
* console.log(`User ${event.userId} was ${event.action}`);
|
|
62
|
-
* });
|
|
63
|
-
*/
|
|
64
|
-
subscribe(channel: string, callback: (message: string) => void): Promise<void>;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Unsubscribe from a Redis channel
|
|
68
|
-
*
|
|
69
|
-
* @param channel - Channel name to unsubscribe from
|
|
70
|
-
* @returns Promise that resolves when unsubscribed
|
|
71
|
-
*
|
|
72
|
-
* @example
|
|
73
|
-
* // Unsubscribe from updates
|
|
74
|
-
* await redisService.unsubscribe('user:updates');
|
|
75
|
-
*/
|
|
76
|
-
unsubscribe(channel: string): Promise<void>;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Acquire a distributed lock
|
|
80
|
-
* Ensures only one process can execute critical section
|
|
81
|
-
*
|
|
82
|
-
* @param key - Lock key (unique identifier for the resource)
|
|
83
|
-
* @param ttl - Lock TTL in milliseconds (auto-release if process dies)
|
|
84
|
-
* @param retries - Number of retry attempts
|
|
85
|
-
* @returns Promise resolving to lock token (needed for release) or null if failed
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* // Acquire lock for order processing
|
|
89
|
-
* const lock = await redisService.acquireLock('order:123:processing', 5000);
|
|
90
|
-
* if (lock) {
|
|
91
|
-
* try {
|
|
92
|
-
* await processOrder('123');
|
|
93
|
-
* } finally {
|
|
94
|
-
* await redisService.releaseLock('order:123:processing', lock);
|
|
95
|
-
* }
|
|
96
|
-
* }
|
|
97
|
-
*/
|
|
98
|
-
acquireLock(key: string, ttl: number, retries?: number): Promise<string | null>;
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Release a distributed lock
|
|
102
|
-
* Only the process that acquired the lock can release it
|
|
103
|
-
*
|
|
104
|
-
* @param key - Lock key
|
|
105
|
-
* @param token - Lock token returned from acquireLock
|
|
106
|
-
* @returns Promise resolving to true if lock was released
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* // Release lock after critical section
|
|
110
|
-
* await redisService.releaseLock('resource:123', lockToken);
|
|
111
|
-
*/
|
|
112
|
-
releaseLock(key: string, token: string): Promise<boolean>;
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Check rate limit for a key
|
|
116
|
-
* Implements sliding window rate limiting
|
|
117
|
-
*
|
|
118
|
-
* @param key - Rate limit key (e.g., userId or IP address)
|
|
119
|
-
* @param limit - Maximum requests allowed
|
|
120
|
-
* @param window - Time window in seconds
|
|
121
|
-
* @returns Promise resolving to object with allowed status and remaining count
|
|
122
|
-
*
|
|
123
|
-
* @example
|
|
124
|
-
* // Check API rate limit
|
|
125
|
-
* const rateLimitStatus = await redisService.checkRateLimit(
|
|
126
|
-
* `api:user:${userId}`,
|
|
127
|
-
* 100, // 100 requests
|
|
128
|
-
* 3600 // per hour
|
|
129
|
-
* );
|
|
130
|
-
*
|
|
131
|
-
* if (!rateLimitStatus.allowed) {
|
|
132
|
-
* throw new Error('Rate limit exceeded');
|
|
133
|
-
* }
|
|
134
|
-
*/
|
|
135
|
-
checkRateLimit(
|
|
136
|
-
key: string,
|
|
137
|
-
limit: number,
|
|
138
|
-
window: number
|
|
139
|
-
): Promise<{
|
|
140
|
-
allowed: boolean;
|
|
141
|
-
remaining: number;
|
|
142
|
-
resetAt: number;
|
|
143
|
-
}>;
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Add member to sorted set with score
|
|
147
|
-
* Useful for leaderboards, rankings, and time-ordered data
|
|
148
|
-
*
|
|
149
|
-
* @param key - Sorted set key
|
|
150
|
-
* @param score - Score for ordering (lower scores first)
|
|
151
|
-
* @param member - Member to add
|
|
152
|
-
* @returns Promise resolving to number of elements added
|
|
153
|
-
*
|
|
154
|
-
* @example
|
|
155
|
-
* // Add user score to leaderboard
|
|
156
|
-
* await redisService.sortedSetAdd('leaderboard:game1', 1000, 'user-123');
|
|
157
|
-
*/
|
|
158
|
-
sortedSetAdd(key: string, score: number, member: string): Promise<number>;
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Get top members from sorted set
|
|
162
|
-
*
|
|
163
|
-
* @param key - Sorted set key
|
|
164
|
-
* @param start - Start index (0-based)
|
|
165
|
-
* @param stop - Stop index (-1 for all)
|
|
166
|
-
* @param withScores - Whether to include scores in result
|
|
167
|
-
* @returns Promise resolving to array of members (and scores if requested)
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* // Get top 10 players
|
|
171
|
-
* const topPlayers = await redisService.sortedSetRange(
|
|
172
|
-
* 'leaderboard:game1',
|
|
173
|
-
* 0,
|
|
174
|
-
* 9,
|
|
175
|
-
* true
|
|
176
|
-
* );
|
|
177
|
-
* // Result: [{member: 'user-1', score: 1500}, {member: 'user-2', score: 1400}, ...]
|
|
178
|
-
*/
|
|
179
|
-
sortedSetRange(
|
|
180
|
-
key: string,
|
|
181
|
-
start: number,
|
|
182
|
-
stop: number,
|
|
183
|
-
withScores?: boolean
|
|
184
|
-
): Promise<Array<{ member: string; score?: number }>>;
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Get member rank in sorted set
|
|
188
|
-
*
|
|
189
|
-
* @param key - Sorted set key
|
|
190
|
-
* @param member - Member to get rank for
|
|
191
|
-
* @returns Promise resolving to rank (0-based) or null if not found
|
|
192
|
-
*
|
|
193
|
-
* @example
|
|
194
|
-
* // Get user's leaderboard position
|
|
195
|
-
* const rank = await redisService.sortedSetRank('leaderboard:game1', 'user-123');
|
|
196
|
-
* console.log(`You are ranked #${rank + 1}`);
|
|
197
|
-
*/
|
|
198
|
-
sortedSetRank(key: string, member: string): Promise<number | null>;
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Add entry to Redis Stream
|
|
202
|
-
* Useful for event sourcing and message queues
|
|
203
|
-
*
|
|
204
|
-
* @param key - Stream key
|
|
205
|
-
* @param fields - Fields to add to stream entry
|
|
206
|
-
* @returns Promise resolving to entry ID
|
|
207
|
-
*
|
|
208
|
-
* @example
|
|
209
|
-
* // Add event to stream
|
|
210
|
-
* const entryId = await redisService.streamAdd('events:user-actions', {
|
|
211
|
-
* userId: '123',
|
|
212
|
-
* action: 'login',
|
|
213
|
-
* timestamp: Date.now().toString()
|
|
214
|
-
* });
|
|
215
|
-
*/
|
|
216
|
-
streamAdd(key: string, fields: Record<string, string>): Promise<string>;
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Read entries from Redis Stream
|
|
220
|
-
*
|
|
221
|
-
* @param key - Stream key
|
|
222
|
-
* @param options - Read options (count, id to start from)
|
|
223
|
-
* @returns Promise resolving to array of stream entries
|
|
224
|
-
*
|
|
225
|
-
* @example
|
|
226
|
-
* // Read last 100 events
|
|
227
|
-
* const events = await redisService.streamRead('events:user-actions', {
|
|
228
|
-
* count: 100,
|
|
229
|
-
* id: '0' // Start from beginning
|
|
230
|
-
* });
|
|
231
|
-
*/
|
|
232
|
-
streamRead(
|
|
233
|
-
key: string,
|
|
234
|
-
options?: { count?: number; id?: string }
|
|
235
|
-
): Promise<Array<{ id: string; fields: Record<string, string> }>>;
|
|
236
|
-
}
|