conduithub 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/core/conduit-hub/index.cjs +1 -1
  2. package/dist/core/conduit-hub/index.d.cts +1 -1
  3. package/dist/core/conduit-hub/index.d.mts +1 -1
  4. package/dist/core/conduit-hub/index.d.ts +1 -1
  5. package/dist/core/conduit-hub/index.mjs +1 -1
  6. package/dist/core/config-manager/index.d.cts +1 -1
  7. package/dist/core/config-manager/index.d.mts +1 -1
  8. package/dist/core/config-manager/index.d.ts +1 -1
  9. package/dist/core/event-bus/index.cjs +4 -4
  10. package/dist/core/event-bus/index.mjs +1 -1
  11. package/dist/core/hook/index.cjs +6 -6
  12. package/dist/core/hook/index.mjs +1 -1
  13. package/dist/core/index.cjs +5 -3
  14. package/dist/core/index.d.cts +8 -184
  15. package/dist/core/index.d.mts +8 -184
  16. package/dist/core/index.d.ts +8 -184
  17. package/dist/core/index.mjs +4 -3
  18. package/dist/core/plugin/index.d.cts +1 -1
  19. package/dist/core/plugin/index.d.mts +1 -1
  20. package/dist/core/plugin/index.d.ts +1 -1
  21. package/dist/core/service-container/index.cjs +9 -9
  22. package/dist/core/service-container/index.mjs +1 -1
  23. package/dist/core/state-manager/index.cjs +3 -3
  24. package/dist/core/state-manager/index.mjs +1 -1
  25. package/dist/{shared/conduithub.BqUYv04j.cjs → error/index.cjs} +3 -0
  26. package/dist/error/index.d.cts +47 -0
  27. package/dist/error/index.d.mts +47 -0
  28. package/dist/error/index.d.ts +47 -0
  29. package/dist/{shared/conduithub.BDwZXllF.mjs → error/index.mjs} +3 -1
  30. package/dist/index.cjs +191 -16
  31. package/dist/index.d.cts +65 -47
  32. package/dist/index.d.mts +65 -47
  33. package/dist/index.d.ts +65 -47
  34. package/dist/index.mjs +161 -5
  35. package/dist/plugins/index.cjs +40 -0
  36. package/dist/plugins/index.d.cts +10 -0
  37. package/dist/plugins/index.d.mts +10 -0
  38. package/dist/plugins/index.d.ts +10 -0
  39. package/dist/plugins/index.mjs +24 -0
  40. package/dist/plugins/kafka/index.cjs +34 -0
  41. package/dist/plugins/kafka/index.d.cts +250 -0
  42. package/dist/plugins/kafka/index.d.mts +250 -0
  43. package/dist/plugins/kafka/index.d.ts +250 -0
  44. package/dist/plugins/kafka/index.mjs +23 -0
  45. package/dist/plugins/redis/index.cjs +33 -0
  46. package/dist/plugins/redis/index.d.cts +151 -0
  47. package/dist/plugins/redis/index.d.mts +151 -0
  48. package/dist/plugins/redis/index.d.ts +151 -0
  49. package/dist/plugins/redis/index.mjs +23 -0
  50. package/dist/shared/conduithub.0FKJet8c.cjs +1130 -0
  51. package/dist/shared/conduithub.B16qn6pY.mjs +174 -0
  52. package/dist/shared/conduithub.BW-S7Bp_.d.cts +181 -0
  53. package/dist/shared/conduithub.BdX_BLza.mjs +1124 -0
  54. package/dist/shared/conduithub.BzuAKyjY.mjs +971 -0
  55. package/dist/shared/conduithub.DSAmRivG.d.ts +181 -0
  56. package/dist/shared/conduithub.DhMIxMx2.cjs +981 -0
  57. package/dist/shared/{conduithub.gF2DFc43.cjs → conduithub.Dlvl2xGE.cjs} +3 -3
  58. package/dist/shared/conduithub.GrtzQn_7.d.mts +181 -0
  59. package/dist/shared/{conduithub.bsiNMTVD.mjs → conduithub.Up0QYVao.mjs} +1 -1
  60. package/dist/shared/conduithub.jH-df3Zd.cjs +181 -0
  61. package/dist/utils/index.cjs +3 -2
  62. package/dist/utils/index.mjs +3 -2
  63. package/package.json +22 -1
@@ -0,0 +1,971 @@
1
+ import 'node:fs';
2
+ import 'node:fs/promises';
3
+ import 'node:path';
4
+ import './conduithub.BNefRQsK.mjs';
5
+ import { r as redisConfigSchema } from './conduithub.B16qn6pY.mjs';
6
+ import { ConduitHub } from '../core/conduit-hub/index.mjs';
7
+ import 'process';
8
+ import 'readline';
9
+ import 'uuid';
10
+ import Redis from 'ioredis';
11
+ import { BasePlugin } from '../core/plugin/index.mjs';
12
+
13
+ function createNoopRedisClient() {
14
+ return {
15
+ set: async () => "OK",
16
+ get: async () => null,
17
+ del: async () => 0,
18
+ exists: async () => 0,
19
+ expire: async () => 1,
20
+ ttl: async () => -1,
21
+ hset: async () => 1,
22
+ hget: async () => null,
23
+ hgetall: async () => ({}),
24
+ hdel: async () => 0,
25
+ lpush: async () => 0,
26
+ rpush: async () => 0,
27
+ lpop: async () => null,
28
+ rpop: async () => null,
29
+ llen: async () => 0,
30
+ lrange: async () => [],
31
+ sadd: async () => 0,
32
+ srem: async () => 0,
33
+ smembers: async () => [],
34
+ sismember: async () => 0,
35
+ scard: async () => 0,
36
+ zadd: async () => 0,
37
+ zrange: async () => [],
38
+ ping: async () => "PONG",
39
+ flushdb: async () => "OK",
40
+ flushall: async () => "OK"
41
+ };
42
+ }
43
+ class RedisPlugin extends BasePlugin {
44
+ redis;
45
+ ioredisClient;
46
+ isConnected = false;
47
+ stats = {
48
+ totalCommands: 0,
49
+ successfulCommands: 0,
50
+ failedCommands: 0,
51
+ averageResponseTime: 0
52
+ };
53
+ async run(operation, payload, call) {
54
+ await this.executeHook("before-redis-operation", {
55
+ operation,
56
+ ...payload
57
+ });
58
+ const start = Date.now();
59
+ try {
60
+ const result = await call();
61
+ const duration = Date.now() - start;
62
+ this.stats.totalCommands++;
63
+ this.stats.successfulCommands++;
64
+ const n = this.stats.successfulCommands;
65
+ this.stats.averageResponseTime = this.stats.averageResponseTime + (duration - this.stats.averageResponseTime) / n;
66
+ this.stats.lastCommandTime = Date.now();
67
+ await this.executeHook("after-redis-operation", {
68
+ operation,
69
+ ...payload,
70
+ result
71
+ });
72
+ return result;
73
+ } catch (error) {
74
+ this.stats.totalCommands++;
75
+ this.stats.failedCommands++;
76
+ await this.executeHook("after-redis-operation", {
77
+ operation,
78
+ ...payload,
79
+ error
80
+ });
81
+ this.logger.log?.("error", `Redis ${operation} failed`, error);
82
+ throw error;
83
+ }
84
+ }
85
+ constructor(config) {
86
+ const normalized = redisConfigSchema.parse(config ?? {});
87
+ super({
88
+ name: "redis",
89
+ version: "1.0.0",
90
+ enabled: true,
91
+ dependencies: [],
92
+ config: normalized
93
+ });
94
+ }
95
+ createRedisWrapper(redisClient) {
96
+ return {
97
+ set: async (key, value, options) => {
98
+ if (!options || Object.keys(options).length === 0) {
99
+ return redisClient.set(key, String(value));
100
+ }
101
+ const args = [];
102
+ if (typeof options.EX === "number") {
103
+ args.push("EX", options.EX);
104
+ }
105
+ if (typeof options.PX === "number") {
106
+ args.push("PX", options.PX);
107
+ }
108
+ if (options.NX) {
109
+ args.push("NX");
110
+ }
111
+ if (options.XX) {
112
+ args.push("XX");
113
+ }
114
+ return redisClient.set(key, String(value), ...args);
115
+ },
116
+ get: (key) => redisClient.get(key),
117
+ del: (key) => Array.isArray(key) ? redisClient.del(...key) : redisClient.del(key),
118
+ exists: (key) => Array.isArray(key) ? redisClient.exists(...key) : redisClient.exists(key),
119
+ expire: (key, seconds) => redisClient.expire(key, seconds),
120
+ ttl: (key) => redisClient.ttl(key),
121
+ hset: (key, field, value) => redisClient.hset(key, field, value),
122
+ hget: (key, field) => redisClient.hget(key, field),
123
+ hgetall: (key) => redisClient.hgetall(key),
124
+ hdel: (key, field) => Array.isArray(field) ? redisClient.hdel(key, ...field) : redisClient.hdel(key, field),
125
+ lpush: (key, ...elements) => redisClient.lpush(key, ...elements),
126
+ rpush: (key, ...elements) => redisClient.rpush(key, ...elements),
127
+ lpop: (key) => redisClient.lpop(key),
128
+ rpop: (key) => redisClient.rpop(key),
129
+ llen: (key) => redisClient.llen(key),
130
+ lrange: (key, start, stop) => redisClient.lrange(key, start, stop),
131
+ sadd: (key, ...members) => redisClient.sadd(key, ...members),
132
+ srem: (key, ...members) => redisClient.srem(key, ...members),
133
+ smembers: (key) => redisClient.smembers(key),
134
+ sismember: (key, member) => redisClient.sismember(key, member),
135
+ scard: (key) => redisClient.scard(key),
136
+ zadd: (key, score, member) => redisClient.zadd(key, score, member),
137
+ zrange: (key, start, stop) => redisClient.zrange(key, start, stop),
138
+ ping: () => redisClient.ping(),
139
+ flushdb: () => redisClient.flushdb(),
140
+ flushall: () => redisClient.flushall()
141
+ };
142
+ }
143
+ getMetadata() {
144
+ return {
145
+ name: "redis",
146
+ version: "1.0.0",
147
+ description: "Redis plugin for ConduitHub - provides Redis client functionality",
148
+ author: "ConduitHub",
149
+ dependencies: [],
150
+ hooks: ["before-redis-operation", "after-redis-operation"],
151
+ events: ["redis-connected", "redis-disconnected", "redis-error"]
152
+ };
153
+ }
154
+ async onInitialize() {
155
+ this.logger.log?.("info", "Initializing Redis plugin...");
156
+ const config = this.getConfig().config;
157
+ try {
158
+ const redisOptions = {
159
+ host: config.host,
160
+ port: config.port,
161
+ db: config.db,
162
+ retryDelayOnFailover: config.retryDelayOnFailover,
163
+ maxRetriesPerRequest: config.maxRetriesPerRequest,
164
+ connectTimeout: config.connectionTimeout,
165
+ commandTimeout: config.commandTimeout,
166
+ lazyConnect: config.lazyConnect ?? (process.env.VITEST === "true" || process.env.NODE_ENV === "test")
167
+ };
168
+ if (config.password) redisOptions.password = config.password;
169
+ if (config.username) redisOptions.username = config.username;
170
+ if (config.keyPrefix) redisOptions.keyPrefix = config.keyPrefix;
171
+ if (config.tls) redisOptions.tls = config.tls;
172
+ const redisClient = new Redis(redisOptions);
173
+ this.ioredisClient = redisClient;
174
+ this.redis = this.createRedisWrapper(redisClient);
175
+ this.logger.log?.("info", "Redis client initialized");
176
+ } catch (error) {
177
+ this.logger.log?.(
178
+ "error",
179
+ "Failed to connect to Redis server, using no-op client",
180
+ error
181
+ );
182
+ this.ioredisClient = void 0;
183
+ this.redis = createNoopRedisClient();
184
+ }
185
+ }
186
+ async onStart() {
187
+ this.isConnected = true;
188
+ const cfg = this.getConfig().config;
189
+ await this.emit("redis-connected", {
190
+ host: cfg.host,
191
+ port: cfg.port,
192
+ db: cfg.db,
193
+ connected: true,
194
+ timestamp: Date.now()
195
+ });
196
+ this.logger.log?.("info", "Redis plugin started");
197
+ }
198
+ async onStop() {
199
+ this.isConnected = false;
200
+ const cfg = this.getConfig().config;
201
+ await this.emit("redis-disconnected", {
202
+ host: cfg.host,
203
+ port: cfg.port,
204
+ db: cfg.db,
205
+ connected: false,
206
+ timestamp: Date.now()
207
+ });
208
+ this.logger.log?.("info", "Redis plugin stopped");
209
+ }
210
+ async onDestroy() {
211
+ try {
212
+ if (this.ioredisClient) {
213
+ await Promise.race([
214
+ this.ioredisClient.quit(),
215
+ new Promise(
216
+ (_, reject) => setTimeout(() => reject(new Error("Quit timeout")), 1e3)
217
+ )
218
+ ]);
219
+ this.logger.log?.("info", "Redis connection closed gracefully");
220
+ }
221
+ } catch (error) {
222
+ this.logger.log?.("error", "Error closing Redis connection", error);
223
+ try {
224
+ if (this.ioredisClient) {
225
+ await Promise.race([
226
+ this.ioredisClient.disconnect(),
227
+ new Promise(
228
+ (_, reject) => setTimeout(
229
+ () => reject(new Error("Force disconnect timeout")),
230
+ 500
231
+ )
232
+ )
233
+ ]);
234
+ this.logger.log?.("info", "Redis connection force disconnected");
235
+ }
236
+ } catch (disconnectError) {
237
+ this.logger.log?.(
238
+ "error",
239
+ "Error during force disconnect",
240
+ disconnectError
241
+ );
242
+ }
243
+ } finally {
244
+ this.ioredisClient = void 0;
245
+ this.redis = createNoopRedisClient();
246
+ this.logger.log?.("info", "Redis plugin destroyed");
247
+ }
248
+ }
249
+ async set(key, value, options) {
250
+ return this.run(
251
+ "set",
252
+ { key, value, options },
253
+ () => this.redis.set(key, value, options)
254
+ );
255
+ }
256
+ async get(key) {
257
+ return this.run("get", { key }, () => this.redis.get(key));
258
+ }
259
+ async del(key) {
260
+ return this.run("del", { key }, () => this.redis.del(key));
261
+ }
262
+ async exists(key) {
263
+ await this.executeHook("before-redis-operation", {
264
+ operation: "exists",
265
+ key
266
+ });
267
+ try {
268
+ const result = await this.redis.exists(key);
269
+ await this.executeHook("after-redis-operation", {
270
+ operation: "exists",
271
+ key,
272
+ result
273
+ });
274
+ return result;
275
+ } catch (error) {
276
+ this.logger.log?.(
277
+ "error",
278
+ `Redis EXISTS operation failed for key: ${key}`,
279
+ error
280
+ );
281
+ throw error;
282
+ }
283
+ }
284
+ async expire(key, seconds) {
285
+ await this.executeHook("before-redis-operation", {
286
+ operation: "expire",
287
+ key,
288
+ seconds
289
+ });
290
+ try {
291
+ const result = await this.redis.expire(key, seconds);
292
+ await this.executeHook("after-redis-operation", {
293
+ operation: "expire",
294
+ key,
295
+ seconds,
296
+ result
297
+ });
298
+ return result;
299
+ } catch (error) {
300
+ this.logger.log?.(
301
+ "error",
302
+ `Redis EXPIRE operation failed for key: ${key}`,
303
+ error
304
+ );
305
+ throw error;
306
+ }
307
+ }
308
+ async ttl(key) {
309
+ await this.executeHook("before-redis-operation", { operation: "ttl", key });
310
+ try {
311
+ const result = await this.redis.ttl(key);
312
+ await this.executeHook("after-redis-operation", {
313
+ operation: "ttl",
314
+ key,
315
+ result
316
+ });
317
+ return result;
318
+ } catch (error) {
319
+ this.logger.log?.(
320
+ "error",
321
+ `Redis TTL operation failed for key: ${key}`,
322
+ error
323
+ );
324
+ throw error;
325
+ }
326
+ }
327
+ // Hash operations
328
+ async hset(key, field, value) {
329
+ await this.executeHook("before-redis-operation", {
330
+ operation: "hset",
331
+ key,
332
+ field,
333
+ value
334
+ });
335
+ try {
336
+ const result = await this.redis.hset(key, field, value);
337
+ await this.executeHook("after-redis-operation", {
338
+ operation: "hset",
339
+ key,
340
+ field,
341
+ value,
342
+ result
343
+ });
344
+ return result;
345
+ } catch (error) {
346
+ this.logger.log?.(
347
+ "error",
348
+ `Redis HSET operation failed for key: ${key}`,
349
+ error
350
+ );
351
+ throw error;
352
+ }
353
+ }
354
+ async hget(key, field) {
355
+ await this.executeHook("before-redis-operation", {
356
+ operation: "hget",
357
+ key,
358
+ field
359
+ });
360
+ try {
361
+ const result = await this.redis.hget(key, field);
362
+ await this.executeHook("after-redis-operation", {
363
+ operation: "hget",
364
+ key,
365
+ field,
366
+ result
367
+ });
368
+ return result;
369
+ } catch (error) {
370
+ this.logger.log?.(
371
+ "error",
372
+ `Redis HGET operation failed for key: ${key}`,
373
+ error
374
+ );
375
+ throw error;
376
+ }
377
+ }
378
+ async hgetall(key) {
379
+ await this.executeHook("before-redis-operation", {
380
+ operation: "hgetall",
381
+ key
382
+ });
383
+ try {
384
+ const result = await this.redis.hgetall(key);
385
+ await this.executeHook("after-redis-operation", {
386
+ operation: "hgetall",
387
+ key,
388
+ result
389
+ });
390
+ return result;
391
+ } catch (error) {
392
+ this.logger.log?.(
393
+ "error",
394
+ `Redis HGETALL operation failed for key: ${key}`,
395
+ error
396
+ );
397
+ throw error;
398
+ }
399
+ }
400
+ async hdel(key, field) {
401
+ await this.executeHook("before-redis-operation", {
402
+ operation: "hdel",
403
+ key,
404
+ field
405
+ });
406
+ try {
407
+ const result = await this.redis.hdel(key, field);
408
+ await this.executeHook("after-redis-operation", {
409
+ operation: "hdel",
410
+ key,
411
+ field,
412
+ result
413
+ });
414
+ return result;
415
+ } catch (error) {
416
+ this.logger.log?.(
417
+ "error",
418
+ `Redis HDEL operation failed for key: ${key}`,
419
+ error
420
+ );
421
+ throw error;
422
+ }
423
+ }
424
+ // List operations
425
+ async lpush(key, ...elements) {
426
+ await this.executeHook("before-redis-operation", {
427
+ operation: "lpush",
428
+ key,
429
+ elements
430
+ });
431
+ try {
432
+ const result = await this.redis.lpush(key, ...elements);
433
+ await this.executeHook("after-redis-operation", {
434
+ operation: "lpush",
435
+ key,
436
+ elements,
437
+ result
438
+ });
439
+ return result;
440
+ } catch (error) {
441
+ this.logger.log?.(
442
+ "error",
443
+ `Redis LPUSH operation failed for key: ${key}`,
444
+ error
445
+ );
446
+ throw error;
447
+ }
448
+ }
449
+ async rpush(key, ...elements) {
450
+ await this.executeHook("before-redis-operation", {
451
+ operation: "rpush",
452
+ key,
453
+ elements
454
+ });
455
+ try {
456
+ const result = await this.redis.rpush(key, ...elements);
457
+ await this.executeHook("after-redis-operation", {
458
+ operation: "rpush",
459
+ key,
460
+ elements,
461
+ result
462
+ });
463
+ return result;
464
+ } catch (error) {
465
+ this.logger.log?.(
466
+ "error",
467
+ `Redis RPUSH operation failed for key: ${key}`,
468
+ error
469
+ );
470
+ throw error;
471
+ }
472
+ }
473
+ async lpop(key) {
474
+ await this.executeHook("before-redis-operation", {
475
+ operation: "lpop",
476
+ key
477
+ });
478
+ try {
479
+ const result = await this.redis.lpop(key);
480
+ await this.executeHook("after-redis-operation", {
481
+ operation: "lpop",
482
+ key,
483
+ result
484
+ });
485
+ return result;
486
+ } catch (error) {
487
+ this.logger.log?.(
488
+ "error",
489
+ `Redis LPOP operation failed for key: ${key}`,
490
+ error
491
+ );
492
+ throw error;
493
+ }
494
+ }
495
+ async rpop(key) {
496
+ await this.executeHook("before-redis-operation", {
497
+ operation: "rpop",
498
+ key
499
+ });
500
+ try {
501
+ const result = await this.redis.rpop(key);
502
+ await this.executeHook("after-redis-operation", {
503
+ operation: "rpop",
504
+ key,
505
+ result
506
+ });
507
+ return result;
508
+ } catch (error) {
509
+ this.logger.log?.(
510
+ "error",
511
+ `Redis RPOP operation failed for key: ${key}`,
512
+ error
513
+ );
514
+ throw error;
515
+ }
516
+ }
517
+ async llen(key) {
518
+ await this.executeHook("before-redis-operation", {
519
+ operation: "llen",
520
+ key
521
+ });
522
+ try {
523
+ const result = await this.redis.llen(key);
524
+ await this.executeHook("after-redis-operation", {
525
+ operation: "llen",
526
+ key,
527
+ result
528
+ });
529
+ return result;
530
+ } catch (error) {
531
+ this.logger.log?.(
532
+ "error",
533
+ `Redis LLEN operation failed for key: ${key}`,
534
+ error
535
+ );
536
+ throw error;
537
+ }
538
+ }
539
+ async lrange(key, start, stop) {
540
+ await this.executeHook("before-redis-operation", {
541
+ operation: "lrange",
542
+ key,
543
+ start,
544
+ stop
545
+ });
546
+ try {
547
+ const result = await this.redis.lrange(key, start, stop);
548
+ await this.executeHook("after-redis-operation", {
549
+ operation: "lrange",
550
+ key,
551
+ start,
552
+ stop,
553
+ result
554
+ });
555
+ return result;
556
+ } catch (error) {
557
+ this.logger.log?.(
558
+ "error",
559
+ `Redis LRANGE operation failed for key: ${key}`,
560
+ error
561
+ );
562
+ throw error;
563
+ }
564
+ }
565
+ // Set operations
566
+ async sadd(key, ...members) {
567
+ await this.executeHook("before-redis-operation", {
568
+ operation: "sadd",
569
+ key,
570
+ members
571
+ });
572
+ try {
573
+ const result = await this.redis.sadd(key, ...members);
574
+ await this.executeHook("after-redis-operation", {
575
+ operation: "sadd",
576
+ key,
577
+ members,
578
+ result
579
+ });
580
+ return result;
581
+ } catch (error) {
582
+ this.logger.log?.(
583
+ "error",
584
+ `Redis SADD operation failed for key: ${key}`,
585
+ error
586
+ );
587
+ throw error;
588
+ }
589
+ }
590
+ async srem(key, ...members) {
591
+ await this.executeHook("before-redis-operation", {
592
+ operation: "srem",
593
+ key,
594
+ members
595
+ });
596
+ try {
597
+ const result = await this.redis.srem(key, ...members);
598
+ await this.executeHook("after-redis-operation", {
599
+ operation: "srem",
600
+ key,
601
+ members,
602
+ result
603
+ });
604
+ return result;
605
+ } catch (error) {
606
+ this.logger.log?.(
607
+ "error",
608
+ `Redis SREM operation failed for key: ${key}`,
609
+ error
610
+ );
611
+ throw error;
612
+ }
613
+ }
614
+ async smembers(key) {
615
+ await this.executeHook("before-redis-operation", {
616
+ operation: "smembers",
617
+ key
618
+ });
619
+ try {
620
+ const result = await this.redis.smembers(key);
621
+ await this.executeHook("after-redis-operation", {
622
+ operation: "smembers",
623
+ key,
624
+ result
625
+ });
626
+ return result;
627
+ } catch (error) {
628
+ this.logger.log?.(
629
+ "error",
630
+ `Redis SMEMBERS operation failed for key: ${key}`,
631
+ error
632
+ );
633
+ throw error;
634
+ }
635
+ }
636
+ async sismember(key, member) {
637
+ await this.executeHook("before-redis-operation", {
638
+ operation: "sismember",
639
+ key,
640
+ member
641
+ });
642
+ try {
643
+ const result = await this.redis.sismember(key, member);
644
+ await this.executeHook("after-redis-operation", {
645
+ operation: "sismember",
646
+ key,
647
+ member,
648
+ result
649
+ });
650
+ return result;
651
+ } catch (error) {
652
+ this.logger.log?.(
653
+ "error",
654
+ `Redis SISMEMBER operation failed for key: ${key}`,
655
+ error
656
+ );
657
+ throw error;
658
+ }
659
+ }
660
+ async scard(key) {
661
+ await this.executeHook("before-redis-operation", {
662
+ operation: "scard",
663
+ key
664
+ });
665
+ try {
666
+ const result = await this.redis.scard(key);
667
+ await this.executeHook("after-redis-operation", {
668
+ operation: "scard",
669
+ key,
670
+ result
671
+ });
672
+ return result;
673
+ } catch (error) {
674
+ this.logger.log?.(
675
+ "error",
676
+ `Redis SCARD operation failed for key: ${key}`,
677
+ error
678
+ );
679
+ throw error;
680
+ }
681
+ }
682
+ // Sorted set operations
683
+ async zadd(key, score, member) {
684
+ await this.executeHook("before-redis-operation", {
685
+ operation: "zadd",
686
+ key,
687
+ score,
688
+ member
689
+ });
690
+ try {
691
+ const result = await this.redis.zadd(key, score, member);
692
+ await this.executeHook("after-redis-operation", {
693
+ operation: "zadd",
694
+ key,
695
+ score,
696
+ member,
697
+ result
698
+ });
699
+ return result;
700
+ } catch (error) {
701
+ this.logger.log?.(
702
+ "error",
703
+ `Redis ZADD operation failed for key: ${key}`,
704
+ error
705
+ );
706
+ throw error;
707
+ }
708
+ }
709
+ async zrange(key, start, stop) {
710
+ await this.executeHook("before-redis-operation", {
711
+ operation: "zrange",
712
+ key,
713
+ start,
714
+ stop
715
+ });
716
+ try {
717
+ const result = await this.redis.zrange(key, start, stop);
718
+ await this.executeHook("after-redis-operation", {
719
+ operation: "zrange",
720
+ key,
721
+ start,
722
+ stop,
723
+ result
724
+ });
725
+ return result;
726
+ } catch (error) {
727
+ this.logger.log?.(
728
+ "error",
729
+ `Redis ZRANGE operation failed for key: ${key}`,
730
+ error
731
+ );
732
+ throw error;
733
+ }
734
+ }
735
+ // Utility methods
736
+ getConnectionInfo() {
737
+ const cfg = this.getConfig().config;
738
+ return {
739
+ host: cfg.host,
740
+ port: cfg.port,
741
+ db: cfg.db,
742
+ connected: this.isConnected,
743
+ timestamp: Date.now()
744
+ };
745
+ }
746
+ getStats() {
747
+ return { ...this.stats };
748
+ }
749
+ async ping() {
750
+ return this.run("ping", {}, () => this.redis.ping());
751
+ }
752
+ async flushdb() {
753
+ return this.run("flushdb", {}, () => this.redis.flushdb());
754
+ }
755
+ async flushall() {
756
+ return this.run("flushall", {}, () => this.redis.flushall());
757
+ }
758
+ }
759
+
760
+ let hub = null;
761
+ let redisPlugin = null;
762
+ function readRedisConfigFromEnv() {
763
+ const toNumber = (v) => v !== void 0 && v !== null && v !== "" && !Number.isNaN(Number(v)) ? Number(v) : void 0;
764
+ const toBoolean = (v) => v === "true" ? true : v === "false" ? false : void 0;
765
+ const host = process.env.REDIS_HOST;
766
+ const port = toNumber(process.env.REDIS_PORT);
767
+ const password = process.env.REDIS_PASSWORD;
768
+ const db = toNumber(process.env.REDIS_DB);
769
+ const username = process.env.REDIS_USERNAME;
770
+ const keyPrefix = process.env.REDIS_KEY_PREFIX;
771
+ const connectionTimeout = toNumber(process.env.REDIS_CONNECTION_TIMEOUT);
772
+ const commandTimeout = toNumber(process.env.REDIS_COMMAND_TIMEOUT);
773
+ const maxRetriesPerRequest = toNumber(
774
+ process.env.REDIS_MAX_RETRIES_PER_REQUEST
775
+ );
776
+ const retryDelayOnFailover = toNumber(
777
+ process.env.REDIS_RETRY_DELAY_ON_FAILOVER
778
+ );
779
+ const enableReadyCheck = toBoolean(process.env.REDIS_ENABLE_READY_CHECK);
780
+ const enableOfflineQueue = toBoolean(process.env.REDIS_ENABLE_OFFLINE_QUEUE);
781
+ const keepAlive = toBoolean(process.env.REDIS_KEEP_ALIVE);
782
+ const lazyConnect = toBoolean(process.env.REDIS_LAZY_CONNECT);
783
+ const familyEnv = process.env.REDIS_FAMILY;
784
+ const family = familyEnv === "IPv6" ? "IPv6" : familyEnv === "IPv4" ? "IPv4" : void 0;
785
+ const tlsCa = process.env.REDIS_TLS_CA;
786
+ const tlsCert = process.env.REDIS_TLS_CERT;
787
+ const tlsKey = process.env.REDIS_TLS_KEY;
788
+ const tlsRejectUnauthorized = toBoolean(
789
+ process.env.REDIS_TLS_REJECT_UNAUTHORIZED
790
+ );
791
+ const cfg = {};
792
+ if (host) cfg.host = host;
793
+ if (port !== void 0) cfg.port = port;
794
+ if (password) cfg.password = password;
795
+ if (db !== void 0) cfg.db = db;
796
+ if (username) cfg.username = username;
797
+ if (keyPrefix) cfg.keyPrefix = keyPrefix;
798
+ if (connectionTimeout !== void 0)
799
+ cfg.connectionTimeout = connectionTimeout;
800
+ if (commandTimeout !== void 0) cfg.commandTimeout = commandTimeout;
801
+ if (maxRetriesPerRequest !== void 0)
802
+ cfg.maxRetriesPerRequest = maxRetriesPerRequest;
803
+ if (retryDelayOnFailover !== void 0)
804
+ cfg.retryDelayOnFailover = retryDelayOnFailover;
805
+ if (enableReadyCheck !== void 0) cfg.enableReadyCheck = enableReadyCheck;
806
+ if (enableOfflineQueue !== void 0)
807
+ cfg.enableOfflineQueue = enableOfflineQueue;
808
+ if (keepAlive !== void 0) cfg.keepAlive = keepAlive;
809
+ if (lazyConnect !== void 0) cfg.lazyConnect = lazyConnect;
810
+ if (family !== void 0) cfg.family = family;
811
+ if (tlsCa || tlsCert || tlsKey || tlsRejectUnauthorized !== void 0) {
812
+ const tls = {
813
+ rejectUnauthorized: tlsRejectUnauthorized ?? true
814
+ };
815
+ if (tlsCa) tls.ca = tlsCa;
816
+ if (tlsCert) tls.cert = tlsCert;
817
+ if (tlsKey) tls.key = tlsKey;
818
+ cfg.tls = tls;
819
+ }
820
+ return cfg;
821
+ }
822
+ async function initRedis(override) {
823
+ if (redisPlugin) return redisPlugin;
824
+ const cfg = {
825
+ ...readRedisConfigFromEnv(),
826
+ ...override ?? {}
827
+ };
828
+ if (!hub) hub = ConduitHub.getInstance();
829
+ if (!hub.isInitialized) await hub.initialize({});
830
+ const plugin = new RedisPlugin(cfg);
831
+ await hub.registerPlugin(plugin);
832
+ await hub.startPlugin("RedisPlugin");
833
+ redisPlugin = plugin;
834
+ return plugin;
835
+ }
836
+ function getRedis() {
837
+ if (!redisPlugin)
838
+ throw new Error("RedisPlugin is not initialized. Call initRedis() first.");
839
+ return redisPlugin;
840
+ }
841
+ async function shutdownRedis() {
842
+ if (!hub) return;
843
+ try {
844
+ if (hub.isInitialized && hub.isPluginRegistered("RedisPlugin")) {
845
+ if (hub.isPluginRunning("RedisPlugin"))
846
+ await hub.stopPlugin("RedisPlugin");
847
+ await hub.unregisterPlugin("RedisPlugin");
848
+ }
849
+ } finally {
850
+ redisPlugin = null;
851
+ }
852
+ }
853
+ const redis = {
854
+ init: initRedis,
855
+ getPlugin: getRedis,
856
+ shutdown: shutdownRedis,
857
+ set: async (key, value, options) => {
858
+ const client = await initRedis();
859
+ return client.set(key, value, options);
860
+ },
861
+ get: async (key) => {
862
+ const client = await initRedis();
863
+ return client.get(key);
864
+ },
865
+ del: async (key) => {
866
+ const client = await initRedis();
867
+ return client.del(key);
868
+ },
869
+ exists: async (key) => {
870
+ const client = await initRedis();
871
+ return client.exists(key);
872
+ },
873
+ expire: async (key, seconds) => {
874
+ const client = await initRedis();
875
+ return client.expire(key, seconds);
876
+ },
877
+ ttl: async (key) => {
878
+ const client = await initRedis();
879
+ return client.ttl(key);
880
+ },
881
+ hset: async (key, field, value) => {
882
+ const client = await initRedis();
883
+ return client.hset(key, field, value);
884
+ },
885
+ hget: async (key, field) => {
886
+ const client = await initRedis();
887
+ return client.hget(key, field);
888
+ },
889
+ hgetall: async (key) => {
890
+ const client = await initRedis();
891
+ return client.hgetall(key);
892
+ },
893
+ hdel: async (key, field) => {
894
+ const client = await initRedis();
895
+ return client.hdel(key, field);
896
+ },
897
+ lpush: async (key, ...elements) => {
898
+ const client = await initRedis();
899
+ return client.lpush(key, ...elements);
900
+ },
901
+ rpush: async (key, ...elements) => {
902
+ const client = await initRedis();
903
+ return client.rpush(key, ...elements);
904
+ },
905
+ lpop: async (key) => {
906
+ const client = await initRedis();
907
+ return client.lpop(key);
908
+ },
909
+ rpop: async (key) => {
910
+ const client = await initRedis();
911
+ return client.rpop(key);
912
+ },
913
+ llen: async (key) => {
914
+ const client = await initRedis();
915
+ return client.llen(key);
916
+ },
917
+ lrange: async (key, start, stop) => {
918
+ const client = await initRedis();
919
+ return client.lrange(key, start, stop);
920
+ },
921
+ sadd: async (key, ...members) => {
922
+ const client = await initRedis();
923
+ return client.sadd(key, ...members);
924
+ },
925
+ srem: async (key, ...members) => {
926
+ const client = await initRedis();
927
+ return client.srem(key, ...members);
928
+ },
929
+ smembers: async (key) => {
930
+ const client = await initRedis();
931
+ return client.smembers(key);
932
+ },
933
+ sismember: async (key, member) => {
934
+ const client = await initRedis();
935
+ return client.sismember(key, member);
936
+ },
937
+ scard: async (key) => {
938
+ const client = await initRedis();
939
+ return client.scard(key);
940
+ },
941
+ zadd: async (key, score, member) => {
942
+ const client = await initRedis();
943
+ return client.zadd(key, score, member);
944
+ },
945
+ zrange: async (key, start, stop) => {
946
+ const client = await initRedis();
947
+ return client.zrange(key, start, stop);
948
+ },
949
+ ping: async () => {
950
+ const client = await initRedis();
951
+ return client.ping();
952
+ },
953
+ flushdb: async () => {
954
+ const client = await initRedis();
955
+ return client.flushdb();
956
+ },
957
+ flushall: async () => {
958
+ const client = await initRedis();
959
+ return client.flushall();
960
+ },
961
+ getConnectionInfo: async () => {
962
+ const client = await initRedis();
963
+ return client.getConnectionInfo();
964
+ },
965
+ getStats: async () => {
966
+ const client = await initRedis();
967
+ return client.getStats();
968
+ }
969
+ };
970
+
971
+ export { RedisPlugin as R, getRedis as g, initRedis as i, redis as r, shutdownRedis as s };