@zintrust/core 0.1.24 → 0.1.26

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 (152) hide show
  1. package/package.json +4 -3
  2. package/src/auth/Auth.d.ts.map +1 -0
  3. package/src/boot/Application.d.ts.map +1 -1
  4. package/src/boot/Application.js +8 -0
  5. package/src/boot/bootstrap.js +34 -15
  6. package/src/cache/drivers/RedisDriver.d.ts.map +1 -1
  7. package/src/cache/drivers/RedisDriver.js +10 -5
  8. package/src/cli/CLI.d.ts.map +1 -1
  9. package/src/cli/CLI.js +6 -0
  10. package/src/cli/commands/QueueCommand.d.ts.map +1 -1
  11. package/src/cli/commands/QueueCommand.js +89 -39
  12. package/src/cli/commands/QueueLockCommand.d.ts +7 -0
  13. package/src/cli/commands/QueueLockCommand.d.ts.map +1 -0
  14. package/src/cli/commands/QueueLockCommand.js +138 -0
  15. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  16. package/src/cli/commands/StartCommand.js +15 -3
  17. package/src/cli/commands/TemplatesCommand.js +1 -1
  18. package/src/cli/commands/WorkerCommands.d.ts.map +1 -1
  19. package/src/cli/commands/WorkerCommands.js +46 -22
  20. package/src/cli/scaffolding/ProjectScaffolder.js +2 -2
  21. package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
  22. package/src/cli/scaffolding/RouteGenerator.js +27 -28
  23. package/src/cli/services/VersionChecker.d.ts +53 -0
  24. package/src/cli/services/VersionChecker.d.ts.map +1 -0
  25. package/src/cli/services/VersionChecker.js +180 -0
  26. package/src/cli/workers/QueueWorkRunner.d.ts.map +1 -1
  27. package/src/cli/workers/QueueWorkRunner.js +128 -7
  28. package/src/common/ExternalServiceUtils.d.ts +2 -2
  29. package/src/config/app.d.ts +4 -0
  30. package/src/config/app.d.ts.map +1 -1
  31. package/src/config/app.js +9 -0
  32. package/src/config/constants.d.ts +140 -10
  33. package/src/config/constants.d.ts.map +1 -1
  34. package/src/config/constants.js +86 -5
  35. package/src/config/index.d.ts +1 -0
  36. package/src/config/index.d.ts.map +1 -1
  37. package/src/config/middleware.d.ts +6 -6
  38. package/src/config/middleware.d.ts.map +1 -1
  39. package/src/config/middleware.js +6 -7
  40. package/src/config/queue.d.ts +4 -0
  41. package/src/config/queue.d.ts.map +1 -1
  42. package/src/config/queue.js +1 -1
  43. package/src/config/redis.d.ts +17 -0
  44. package/src/config/redis.d.ts.map +1 -0
  45. package/src/config/redis.js +54 -0
  46. package/src/config/type.d.ts +3 -0
  47. package/src/config/type.d.ts.map +1 -1
  48. package/src/http/Request.d.ts +10 -1
  49. package/src/http/Request.d.ts.map +1 -1
  50. package/src/http/Request.js +79 -7
  51. package/src/http/error-pages/ErrorPageRenderer.d.ts.map +1 -1
  52. package/src/http/error-pages/ErrorPageRenderer.js +4 -3
  53. package/src/index.d.ts +14 -11
  54. package/src/index.d.ts.map +1 -1
  55. package/src/index.js +18 -11
  56. package/src/lang/lang.d.ts +23 -0
  57. package/src/lang/lang.d.ts.map +1 -0
  58. package/src/lang/lang.js +22 -0
  59. package/src/middleware/ErrorHandlerMiddleware.d.ts.map +1 -1
  60. package/src/middleware/ErrorHandlerMiddleware.js +9 -1
  61. package/src/migrations/schema/SchemaCompiler.js +1 -1
  62. package/src/migrations/schema/types.d.ts +1 -1
  63. package/src/migrations/schema/types.d.ts.map +1 -1
  64. package/src/node.d.ts +1 -1
  65. package/src/node.d.ts.map +1 -1
  66. package/src/node.js +1 -1
  67. package/src/orm/Database.d.ts +1 -1
  68. package/src/orm/Database.d.ts.map +1 -1
  69. package/src/orm/Database.js +22 -3
  70. package/src/performance/Optimizer.js +1 -1
  71. package/src/routing/Router.d.ts +6 -2
  72. package/src/routing/Router.d.ts.map +1 -1
  73. package/src/routing/Router.js +19 -4
  74. package/src/runtime/PluginManager.js +1 -1
  75. package/src/runtime/PluginRegistry.js +2 -2
  76. package/src/start.d.ts.map +1 -1
  77. package/src/start.js +8 -7
  78. package/src/templates/TemplateRegistry.js +2 -2
  79. package/src/templates/TemplateRegistry.ts +2 -2
  80. package/src/templates/feature/Queue.ts.tpl +114 -0
  81. package/src/templates/project/basic/app/Controllers/UserController.ts.tpl +22 -0
  82. package/src/templates/project/basic/config/queue.ts.tpl +19 -0
  83. package/src/templates/project/basic/package.json.tpl +2 -1
  84. package/src/templates/project/basic/src/index.ts.tpl +0 -3
  85. package/src/tools/broadcast/drivers/Redis.d.ts.map +1 -1
  86. package/src/tools/broadcast/drivers/Redis.js +8 -56
  87. package/src/tools/mail/Mail.d.ts +1 -29
  88. package/src/tools/mail/Mail.d.ts.map +1 -1
  89. package/src/tools/mail/Mail.js +1 -111
  90. package/src/tools/mail/drivers/SendGrid.d.ts.map +1 -1
  91. package/src/tools/mail/drivers/SendGrid.js +4 -3
  92. package/src/tools/mail/drivers/Smtp.d.ts.map +1 -1
  93. package/src/tools/mail/drivers/Smtp.js +32 -10
  94. package/src/tools/mail/index.d.ts +40 -0
  95. package/src/tools/mail/index.d.ts.map +1 -0
  96. package/src/tools/mail/index.js +129 -0
  97. package/src/tools/mail/template-loader.d.ts +10 -0
  98. package/src/tools/mail/template-loader.d.ts.map +1 -0
  99. package/src/tools/mail/template-loader.js +101 -0
  100. package/src/tools/mail/template-utils.d.ts +10 -0
  101. package/src/tools/mail/template-utils.d.ts.map +1 -0
  102. package/src/tools/mail/template-utils.js +16 -0
  103. package/src/tools/mail/templates/index.d.ts +30 -0
  104. package/src/tools/mail/templates/index.d.ts.map +1 -1
  105. package/src/tools/mail/templates/index.js +69 -0
  106. package/src/tools/queue/AdvancedQueue.d.ts +19 -0
  107. package/src/tools/queue/AdvancedQueue.d.ts.map +1 -0
  108. package/src/tools/queue/AdvancedQueue.js +352 -0
  109. package/src/tools/queue/DeduplicationBuilder.d.ts +20 -0
  110. package/src/tools/queue/DeduplicationBuilder.d.ts.map +1 -0
  111. package/src/tools/queue/DeduplicationBuilder.js +77 -0
  112. package/src/tools/queue/LockProvider.d.ts +22 -0
  113. package/src/tools/queue/LockProvider.d.ts.map +1 -0
  114. package/src/tools/queue/LockProvider.js +282 -0
  115. package/src/tools/queue/Queue.d.ts.map +1 -1
  116. package/src/tools/queue/Queue.js +2 -1
  117. package/src/tools/queue/QueueExtensions.d.ts +46 -0
  118. package/src/tools/queue/QueueExtensions.d.ts.map +1 -0
  119. package/src/tools/queue/QueueExtensions.js +129 -0
  120. package/src/tools/queue/QueueRuntimeRegistration.d.ts.map +1 -1
  121. package/src/tools/queue/QueueRuntimeRegistration.js +2 -2
  122. package/src/tools/queue/drivers/Database.d.ts +23 -0
  123. package/src/tools/queue/drivers/Database.d.ts.map +1 -0
  124. package/src/tools/queue/drivers/Database.js +123 -0
  125. package/src/tools/queue/drivers/Redis.d.ts.map +1 -1
  126. package/src/tools/queue/drivers/Redis.js +11 -82
  127. package/src/tools/queue/index.d.ts +9 -0
  128. package/src/tools/queue/index.d.ts.map +1 -0
  129. package/src/tools/queue/index.js +7 -0
  130. package/src/tools/redis/RedisKeyManager.d.ts +64 -0
  131. package/src/tools/redis/RedisKeyManager.d.ts.map +1 -0
  132. package/src/tools/redis/RedisKeyManager.js +124 -0
  133. package/src/types/Queue.d.ts +62 -0
  134. package/src/types/Queue.d.ts.map +1 -0
  135. package/src/types/Queue.js +5 -0
  136. package/src/features/Auth.d.ts.map +0 -1
  137. package/src/features/Queue.d.ts +0 -21
  138. package/src/features/Queue.d.ts.map +0 -1
  139. package/src/features/Queue.js +0 -33
  140. package/src/templates/features/Queue.ts.tpl +0 -47
  141. package/src/tools/mail/templates/markdown/index.d.ts +0 -17
  142. package/src/tools/mail/templates/markdown/index.d.ts.map +0 -1
  143. package/src/tools/mail/templates/markdown/index.js +0 -49
  144. package/src/tools/mail/templates/markdown/registry.d.ts +0 -15
  145. package/src/tools/mail/templates/markdown/registry.d.ts.map +0 -1
  146. package/src/tools/mail/templates/markdown/registry.js +0 -34
  147. package/src/tools/mail/templates/markdown/validator.d.ts +0 -16
  148. package/src/tools/mail/templates/markdown/validator.d.ts.map +0 -1
  149. package/src/tools/mail/templates/markdown/validator.js +0 -24
  150. /package/src/{features → auth}/Auth.d.ts +0 -0
  151. /package/src/{features → auth}/Auth.js +0 -0
  152. /package/src/templates/{features → auth}/Auth.ts.tpl +0 -0
@@ -0,0 +1,282 @@
1
+ /* eslint-disable @typescript-eslint/require-await */
2
+ /**
3
+ * Lock Provider Implementation
4
+ * Provides distributed lock management for job deduplication
5
+ */
6
+ import { ErrorFactory } from '../../exceptions/ZintrustError.js';
7
+ import { Logger } from '../../config/logger.js';
8
+ import { createBaseDrivers } from '../../config/queue.js';
9
+ import { createRedisConnection } from '../../config/workers.js';
10
+ import { ZintrustLang } from '../../lang/lang.js';
11
+ // Singleton Redis client for locks to avoid connection spam
12
+ let redisClient = null;
13
+ function getRedisClient() {
14
+ if (!redisClient) {
15
+ const redisConfig = createBaseDrivers().redis;
16
+ // Adapt queue config to worker config format if needed
17
+ redisClient = createRedisConnection({
18
+ host: redisConfig.host,
19
+ port: redisConfig.port,
20
+ password: redisConfig.password,
21
+ db: redisConfig.database,
22
+ });
23
+ }
24
+ return redisClient;
25
+ }
26
+ const METRICS_SUFFIX = {
27
+ attempts: 'metrics:attempts',
28
+ acquired: 'metrics:acquired',
29
+ collisions: 'metrics:collisions',
30
+ };
31
+ const recordLockAttempt = async (prefix, acquired) => {
32
+ const client = getRedisClient();
33
+ try {
34
+ const attemptsKey = `${prefix}${METRICS_SUFFIX.attempts}`;
35
+ const acquiredKey = `${prefix}${METRICS_SUFFIX.acquired}`;
36
+ const collisionsKey = `${prefix}${METRICS_SUFFIX.collisions}`;
37
+ const operations = [client.incr(attemptsKey)];
38
+ operations.push(acquired ? client.incr(acquiredKey) : client.incr(collisionsKey));
39
+ await Promise.allSettled(operations);
40
+ }
41
+ catch (error) {
42
+ Logger.debug('Lock metrics update failed', { error });
43
+ }
44
+ };
45
+ function createAcquireMethod(prefix, defaultTtl) {
46
+ return async function acquire(key, options = {}) {
47
+ const lockKey = `${prefix}${key}`;
48
+ const ttl = options.ttl ?? defaultTtl;
49
+ const client = getRedisClient();
50
+ try {
51
+ // Use SET NX PX to acquire lock
52
+ const result = await client.set(lockKey, 'locked', 'PX', ttl, 'NX');
53
+ const acquired = result === 'OK';
54
+ const expires = new Date(Date.now() + ttl);
55
+ Logger.debug(`Lock acquisition attempt`, { key: lockKey, ttl, acquired });
56
+ void recordLockAttempt(prefix, acquired);
57
+ return {
58
+ key: lockKey,
59
+ ttl,
60
+ acquired,
61
+ expires,
62
+ };
63
+ }
64
+ catch (error) {
65
+ Logger.error(`Failed to acquire lock`, { key: lockKey, error });
66
+ throw error;
67
+ }
68
+ };
69
+ }
70
+ function normalizeLockKey(prefix, key) {
71
+ return key.startsWith(prefix) ? key : `${prefix}${key}`;
72
+ }
73
+ function createReleaseMethod(prefix) {
74
+ return async function release(lock) {
75
+ try {
76
+ const client = getRedisClient();
77
+ const lockKey = normalizeLockKey(prefix, lock.key);
78
+ await client.del(lockKey);
79
+ Logger.debug(`Lock release`, { key: lockKey });
80
+ }
81
+ catch (error) {
82
+ Logger.error(`Failed to release lock`, { key: lock.key, error });
83
+ throw error;
84
+ }
85
+ };
86
+ }
87
+ function createExtendMethod(prefix) {
88
+ return async function extend(lock, ttl) {
89
+ try {
90
+ const client = getRedisClient();
91
+ const lockKey = normalizeLockKey(prefix, lock.key);
92
+ // Use PEXPIRE to extend
93
+ const result = await client.pexpire(lockKey, ttl);
94
+ const success = result === 1;
95
+ if (success) {
96
+ const newExpires = new Date(Date.now() + ttl);
97
+ Logger.debug(`Lock extension`, { key: lockKey, ttl, newExpires });
98
+ lock.ttl = ttl;
99
+ lock.expires = newExpires;
100
+ }
101
+ return success;
102
+ }
103
+ catch (error) {
104
+ Logger.error(`Failed to extend lock`, { key: lock.key, error });
105
+ return false;
106
+ }
107
+ };
108
+ }
109
+ function createStatusMethod(prefix) {
110
+ return async function status(key) {
111
+ const lockKey = `${prefix}${key}`;
112
+ try {
113
+ const client = getRedisClient();
114
+ const ttl = await client.pttl(lockKey);
115
+ const exists = ttl > 0;
116
+ Logger.debug(`Lock status check`, { key: lockKey, exists, ttl });
117
+ return {
118
+ exists,
119
+ ttl: exists ? ttl : undefined,
120
+ expires: exists ? new Date(Date.now() + ttl) : undefined,
121
+ };
122
+ }
123
+ catch (error) {
124
+ Logger.error(`Failed to check lock status`, { key: lockKey, error });
125
+ return { exists: false };
126
+ }
127
+ };
128
+ }
129
+ function createListMethod(prefix) {
130
+ return async function list(pattern = '*') {
131
+ try {
132
+ const client = getRedisClient();
133
+ const searchPattern = `${prefix}${pattern}`;
134
+ const keys = [];
135
+ let cursor = '0';
136
+ do {
137
+ // SCAN to avoid blocking Redis in production environments
138
+ // eslint-disable-next-line no-await-in-loop
139
+ const [nextCursor, batch] = await client.scan(cursor, 'MATCH', searchPattern, 'COUNT', '200');
140
+ cursor = nextCursor;
141
+ keys.push(...batch);
142
+ } while (cursor !== '0');
143
+ return keys.map((k) => k.replace(prefix, ''));
144
+ }
145
+ catch (error) {
146
+ Logger.error(`Failed to list locks`, { pattern, error });
147
+ return [];
148
+ }
149
+ };
150
+ }
151
+ /**
152
+ * Redis-based Lock Provider Implementation
153
+ */
154
+ export function createRedisLockProvider(config) {
155
+ const prefix = config.prefix ?? ZintrustLang.ZINTRUST_LOCKS_PREFIX;
156
+ const defaultTtl = config.defaultTtl ?? ZintrustLang.ZINTRUST_LOCKS_TTL;
157
+ return {
158
+ acquire: createAcquireMethod(prefix, defaultTtl),
159
+ release: createReleaseMethod(prefix),
160
+ extend: createExtendMethod(prefix),
161
+ status: createStatusMethod(prefix),
162
+ list: createListMethod(prefix),
163
+ };
164
+ }
165
+ /**
166
+ * Memory-based Lock Provider (for testing/sync driver)
167
+ */
168
+ function globToRegExp(pattern) {
169
+ // Escape all regex metacharacters, then turn '*' into '.*' as a wildcard
170
+ const escaped = pattern.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw `\$&`);
171
+ const regexSource = escaped.replaceAll(String.raw `\*`, '.*');
172
+ return new RegExp(`^${regexSource}$`);
173
+ }
174
+ export function createMemoryLockProvider(config) {
175
+ const locks = new Map();
176
+ const prefix = config.prefix ?? ZintrustLang.MEMORY_LOCKS;
177
+ const defaultTtl = config.defaultTtl ?? ZintrustLang.ZINTRUST_LOCKS_TTL;
178
+ return {
179
+ async acquire(key, options = {}) {
180
+ const lockKey = `${prefix}${key}`;
181
+ const ttl = options.ttl ?? defaultTtl;
182
+ const expires = new Date(Date.now() + ttl);
183
+ if (locks.has(lockKey)) {
184
+ const existingLock = locks.get(lockKey);
185
+ if (existingLock !== undefined && existingLock.expires > new Date()) {
186
+ return {
187
+ key: lockKey,
188
+ ttl,
189
+ acquired: false,
190
+ expires,
191
+ };
192
+ }
193
+ // Lock expired, remove it
194
+ locks.delete(lockKey);
195
+ }
196
+ const lock = {
197
+ key: lockKey,
198
+ ttl,
199
+ acquired: true,
200
+ expires,
201
+ };
202
+ locks.set(lockKey, lock);
203
+ Logger.debug(`Memory lock acquired`, { key: lockKey, ttl });
204
+ return lock;
205
+ },
206
+ async release(lock) {
207
+ const lockKey = normalizeLockKey(prefix, lock.key);
208
+ locks.delete(lockKey);
209
+ Logger.debug(`Memory lock released`, { key: lockKey });
210
+ },
211
+ async extend(lock, ttl) {
212
+ const lockKey = normalizeLockKey(prefix, lock.key);
213
+ const existingLock = locks.get(lockKey);
214
+ if (!existingLock) {
215
+ return false;
216
+ }
217
+ existingLock.ttl = ttl;
218
+ existingLock.expires = new Date(Date.now() + ttl);
219
+ Logger.debug(`Memory lock extended`, { key: lockKey, ttl });
220
+ return true;
221
+ },
222
+ async status(key) {
223
+ const lockKey = `${prefix}${key}`;
224
+ const lock = locks.get(lockKey);
225
+ if (!lock) {
226
+ return { exists: false };
227
+ }
228
+ if (lock.expires <= new Date()) {
229
+ locks.delete(lockKey);
230
+ return { exists: false };
231
+ }
232
+ return {
233
+ exists: true,
234
+ ttl: lock.ttl,
235
+ expires: lock.expires,
236
+ };
237
+ },
238
+ async list(pattern = '*') {
239
+ // Simple glob-style match for memory provider ('*' as wildcard)
240
+ const regex = globToRegExp(pattern);
241
+ const keys = [];
242
+ for (const key of locks.keys()) {
243
+ const strippedKey = key.replace(prefix, '');
244
+ if (regex.test(strippedKey)) {
245
+ keys.push(strippedKey);
246
+ }
247
+ }
248
+ return keys;
249
+ },
250
+ };
251
+ }
252
+ /**
253
+ * Lock Provider Registry
254
+ */
255
+ const lockProviders = new Map();
256
+ export function registerLockProvider(name, provider) {
257
+ lockProviders.set(name, provider);
258
+ Logger.info(`Lock provider registered`, { name });
259
+ }
260
+ export function getLockProvider(name) {
261
+ return lockProviders.get(name);
262
+ }
263
+ /**
264
+ * Clear all registered lock providers (for testing purposes)
265
+ * @internal
266
+ */
267
+ export function clearLockProviders() {
268
+ lockProviders.clear();
269
+ }
270
+ /**
271
+ * Create lock provider based on configuration
272
+ */
273
+ export function createLockProvider(config) {
274
+ switch (config.type) {
275
+ case ZintrustLang.REDIS:
276
+ return createRedisLockProvider(config);
277
+ case ZintrustLang.MEMORY:
278
+ return createMemoryLockProvider(config);
279
+ default:
280
+ throw ErrorFactory.createConfigError(`Unsupported lock provider type: ${config.type}`);
281
+ }
282
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"Queue.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/Queue.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF,UAAU,YAAY;IACpB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC1E,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAID,eAAO,MAAM,KAAK;mBACD,MAAM,UAAU,YAAY;aAIlC,IAAI;eAIF,MAAM,GAAG,YAAY;YAUlB,CAAC,mBAAmB,MAAM,WAAW,CAAC,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAK7E,CAAC,mBACN,MAAM,eACA,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;eAKtB,MAAM,MAAM,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;kBAKpD,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;iBAK9C,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EAI9D,CAAC;AAEH,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Queue.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/Queue.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF,UAAU,YAAY;IACpB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC1E,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAID,eAAO,MAAM,KAAK;mBACD,MAAM,UAAU,YAAY;aAIlC,IAAI;eAIF,MAAM,GAAG,YAAY;YAUlB,CAAC,mBAAmB,MAAM,WAAW,CAAC,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAM7E,CAAC,mBACN,MAAM,eACA,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;eAKtB,MAAM,MAAM,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;kBAKpD,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;iBAK9C,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EAI9D,CAAC;AAEH,eAAe,KAAK,CAAC"}
@@ -20,7 +20,8 @@ export const Queue = Object.freeze({
20
20
  },
21
21
  async enqueue(queue, payload, driverName) {
22
22
  const driver = Queue.get(driverName);
23
- return driver.enqueue(queue, payload);
23
+ const jobId = await driver.enqueue(queue, payload);
24
+ return jobId;
24
25
  },
25
26
  async dequeue(queue, driverName) {
26
27
  const driver = Queue.get(driverName);
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Queue Extensions - Backward Compatible Extensions
3
+ * Extends existing Queue functionality without breaking changes
4
+ */
5
+ import type { AdvancedJobOptions, QueueConfig } from '../../types/Queue';
6
+ import { createDeduplicationBuilder } from './DeduplicationBuilder';
7
+ /**
8
+ * Extend existing Queue with advanced capabilities
9
+ * This provides a migration path for existing code
10
+ */
11
+ export declare function extendQueue(config: QueueConfig): void;
12
+ /**
13
+ * Enhanced enqueue method that supports advanced options
14
+ * This can be used as a drop-in replacement for Queue.enqueue
15
+ */
16
+ export declare function enqueueAdvanced(name: string, payload: unknown, options?: AdvancedJobOptions): Promise<string>;
17
+ /**
18
+ * Initialize default lock providers
19
+ */
20
+ export declare function initializeDefaultLockProviders(): void;
21
+ /**
22
+ * Get deduplication builder instance
23
+ */
24
+ export declare function getDeduplicationBuilder(): ReturnType<typeof createDeduplicationBuilder>;
25
+ /**
26
+ * Queue utilities for lock management
27
+ */
28
+ export declare const QueueLocks: {
29
+ release: (key: string) => Promise<void>;
30
+ extend: (key: string, ttl: number) => Promise<boolean>;
31
+ status: (key: string) => Promise<boolean>;
32
+ };
33
+ /**
34
+ * Migration helpers for existing queue code
35
+ */
36
+ export declare const MigrationHelpers: {
37
+ /**
38
+ * Convert existing job options to advanced options
39
+ */
40
+ toAdvancedOptions(existingOptions: Record<string, unknown>, uniqueId?: string): AdvancedJobOptions;
41
+ /**
42
+ * Add deduplication to existing job patterns
43
+ */
44
+ withDeduplication(existingOptions: Record<string, unknown>, deduplicationId: string, ttl?: number): AdvancedJobOptions;
45
+ };
46
+ //# sourceMappingURL=QueueExtensions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueueExtensions.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/QueueExtensions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAsB,WAAW,EAAE,MAAM,eAAe,CAAC;AAKzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAMzE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAWrD;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAuBrD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAEvF;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE;IACvB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAkC3C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;OAEG;uCAEgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,aAC7B,MAAM,GAChB,kBAAkB;IAOrB;;OAEG;uCAEgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mBACvB,MAAM,QACjB,MAAM,GACX,kBAAkB;CAStB,CAAC"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Queue Extensions - Backward Compatible Extensions
3
+ * Extends existing Queue functionality without breaking changes
4
+ */
5
+ import { Logger } from '../../config/logger.js';
6
+ import { createValidationError } from '../../exceptions/ZintrustError.js';
7
+ import { ZintrustLang } from '../../lang/lang.js';
8
+ import { createAdvancedQueue } from './AdvancedQueue.js';
9
+ import { createDeduplicationBuilder } from './DeduplicationBuilder.js';
10
+ import { createLockProvider, registerLockProvider } from './LockProvider.js';
11
+ import { Queue } from './Queue.js';
12
+ let advancedQueueRef = null;
13
+ /**
14
+ * Extend existing Queue with advanced capabilities
15
+ * This provides a migration path for existing code
16
+ */
17
+ export function extendQueue(config) {
18
+ try {
19
+ const advancedQueue = createAdvancedQueue(config);
20
+ advancedQueueRef = advancedQueue;
21
+ Logger.info(`Queue extended with advanced capabilities`, { queueName: config.name });
22
+ }
23
+ catch (error) {
24
+ Logger.error(`Failed to extend queue with advanced capabilities`, { error });
25
+ throw error;
26
+ }
27
+ }
28
+ /**
29
+ * Enhanced enqueue method that supports advanced options
30
+ * This can be used as a drop-in replacement for Queue.enqueue
31
+ */
32
+ export async function enqueueAdvanced(name, payload, options = {}) {
33
+ if (advancedQueueRef === null) {
34
+ Logger.warn(`Advanced queue not initialized, falling back to standard enqueue`);
35
+ return Queue.enqueue(name, payload);
36
+ }
37
+ return advancedQueueRef.enqueue(name, payload, options);
38
+ }
39
+ /**
40
+ * Initialize default lock providers
41
+ */
42
+ export function initializeDefaultLockProviders() {
43
+ // Register memory lock provider for sync driver
44
+ registerLockProvider(ZintrustLang.MEMORY, createLockProvider({
45
+ type: ZintrustLang.MEMORY,
46
+ prefix: ZintrustLang.ZINTRUST_LOCKS_PREFIX,
47
+ defaultTtl: ZintrustLang.ZINTRUST_LOCKS_TTL,
48
+ }));
49
+ // Register Redis lock provider if Redis is available
50
+ try {
51
+ const redisConfig = {
52
+ type: ZintrustLang.REDIS,
53
+ prefix: ZintrustLang.ZINTRUST_LOCKS_PREFIX,
54
+ defaultTtl: ZintrustLang.ZINTRUST_LOCKS_TTL,
55
+ };
56
+ registerLockProvider('redis', createLockProvider(redisConfig));
57
+ Logger.info(`Redis lock provider registered`);
58
+ }
59
+ catch (error) {
60
+ Logger.warn(`Redis lock provider registration failed, using memory provider`, { error });
61
+ }
62
+ }
63
+ /**
64
+ * Get deduplication builder instance
65
+ */
66
+ export function getDeduplicationBuilder() {
67
+ return createDeduplicationBuilder();
68
+ }
69
+ /**
70
+ * Queue utilities for lock management
71
+ */
72
+ export const QueueLocks = {
73
+ /**
74
+ * Release a lock by key
75
+ */
76
+ async release(key) {
77
+ if (advancedQueueRef !== null) {
78
+ return advancedQueueRef.releaseLock(key);
79
+ }
80
+ throw createValidationError('Advanced queue not initialized. Call extendQueue() first.');
81
+ },
82
+ /**
83
+ * Extend a lock's TTL
84
+ */
85
+ async extend(key, ttl) {
86
+ if (advancedQueueRef !== null) {
87
+ return advancedQueueRef.extendLock(key, ttl);
88
+ }
89
+ throw createValidationError('Advanced queue not initialized. Call extendQueue() first.');
90
+ },
91
+ /**
92
+ * Check lock status
93
+ */
94
+ async status(key) {
95
+ const { getLockProvider } = await import('../../tools/queue/LockProvider.js');
96
+ const lockProvider = getLockProvider(ZintrustLang.MEMORY);
97
+ if (lockProvider !== undefined) {
98
+ const status = await lockProvider.status(key);
99
+ return status.exists;
100
+ }
101
+ return false;
102
+ },
103
+ };
104
+ /**
105
+ * Migration helpers for existing queue code
106
+ */
107
+ export const MigrationHelpers = {
108
+ /**
109
+ * Convert existing job options to advanced options
110
+ */
111
+ toAdvancedOptions(existingOptions, uniqueId) {
112
+ return {
113
+ ...existingOptions,
114
+ ...(uniqueId !== null && uniqueId !== undefined && uniqueId !== '' && { uniqueId }),
115
+ };
116
+ },
117
+ /**
118
+ * Add deduplication to existing job patterns
119
+ */
120
+ withDeduplication(existingOptions, deduplicationId, ttl) {
121
+ return {
122
+ ...existingOptions,
123
+ deduplication: createDeduplicationBuilder()
124
+ .id(deduplicationId)
125
+ .expireAfter(ttl ?? ZintrustLang.ZINTRUST_LOCKS_TTL)
126
+ .build(),
127
+ };
128
+ },
129
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"QueueRuntimeRegistration.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/QueueRuntimeRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAOjD;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAczE"}
1
+ {"version":3,"file":"QueueRuntimeRegistration.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/QueueRuntimeRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAOjD;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAazE"}
@@ -1,6 +1,6 @@
1
1
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
2
+ import { DatabaseQueue } from '../queue/drivers/Database.js';
2
3
  import { InMemoryQueue } from '../queue/drivers/InMemory.js';
3
- import { RedisQueue } from '../queue/drivers/Redis.js';
4
4
  import { Queue } from '../queue/Queue.js';
5
5
  /**
6
6
  * Register queue drivers from runtime config.
@@ -13,9 +13,9 @@ import { Queue } from '../queue/Queue.js';
13
13
  export function registerQueuesFromRuntimeConfig(config) {
14
14
  // Built-in drivers (core)
15
15
  Queue.register('inmemory', InMemoryQueue);
16
+ Queue.register('db', DatabaseQueue);
16
17
  // Project templates use QUEUE_DRIVER=sync; treat this as an alias of in-memory.
17
18
  Queue.register('sync', InMemoryQueue);
18
- Queue.register('redis', RedisQueue);
19
19
  const defaultName = (config.default ?? '').toString().trim().toLowerCase();
20
20
  if (defaultName.length === 0) {
21
21
  throw ErrorFactory.createConfigError('Queue default driver is not configured');
@@ -0,0 +1,23 @@
1
+ import type { QueueMessage } from '../../queue/Queue';
2
+ export interface DatabaseQueueConfig {
3
+ connection?: string;
4
+ table?: string;
5
+ retryAttempts?: number;
6
+ visibilityTimeout?: number;
7
+ }
8
+ export interface IDatabaseQueueDriver {
9
+ enqueue<T = unknown>(queue: string, payload: T, connectionName?: string): Promise<string>;
10
+ dequeue<T = unknown>(queue: string, connectionName?: string): Promise<QueueMessage<T> | undefined>;
11
+ ack(queue: string, id: string, connectionName?: string): Promise<void>;
12
+ length(queue: string, connectionName?: string): Promise<number>;
13
+ drain(queue: string, connectionName?: string): Promise<void>;
14
+ }
15
+ export declare const DatabaseQueue: {
16
+ readonly enqueue: <T = unknown>(queue: string, payload: T, connectionName?: string) => Promise<string>;
17
+ readonly dequeue: <T = unknown>(queue: string, connectionName?: string) => Promise<QueueMessage<T> | undefined>;
18
+ readonly ack: (queue: string, id: string, connectionName?: string) => Promise<void>;
19
+ readonly length: (queue: string, connectionName?: string) => Promise<number>;
20
+ readonly drain: (queue: string, connectionName?: string) => Promise<void>;
21
+ };
22
+ export default DatabaseQueue;
23
+ //# sourceMappingURL=Database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Database.d.ts","sourceRoot":"","sources":["../../../../../src/tools/queue/drivers/Database.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1F,OAAO,CAAC,CAAC,GAAG,OAAO,EACjB,KAAK,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IACxC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED,eAAO,MAAM,aAAa;uBAkBR,CAAC,mBACN,MAAM,WACJ,CAAC,mBACO,MAAM,KACtB,OAAO,CAAC,MAAM,CAAC;uBAkBJ,CAAC,mBACN,MAAM,mBACI,MAAM,KACtB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;0BAsEtB,MAAM,MAAM,MAAM,mBAAmB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;6BAYxD,MAAM,mBAAmB,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;4BAoBlD,MAAM,mBAAmB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;CASlE,CAAC;AAEL,eAAe,aAAa,CAAC"}
@@ -0,0 +1,123 @@
1
+ import { Env } from '../../../config/env.js';
2
+ import { Logger } from '../../../config/logger.js';
3
+ import { ErrorFactory } from '../../../exceptions/ZintrustError.js';
4
+ import { useDatabase } from '../../../orm/Database.js';
5
+ import { QueryBuilder } from '../../../orm/QueryBuilder.js';
6
+ export const DatabaseQueue = (() => {
7
+ const connections = new Map();
8
+ const getConnection = (connectionName) => {
9
+ const name = connectionName ?? Env.get('DB_CONNECTION', 'default');
10
+ if (!connections.has(name)) {
11
+ connections.set(name, useDatabase(undefined, name));
12
+ }
13
+ const connection = connections.get(name);
14
+ if (!connection) {
15
+ throw ErrorFactory.createConfigError(`Database connection '${name}' not found`);
16
+ }
17
+ return connection;
18
+ };
19
+ const getTableName = () => Env.get('QUEUE_DB_TABLE', 'queue_jobs');
20
+ return {
21
+ async enqueue(queue, payload, connectionName) {
22
+ const db = getConnection(connectionName);
23
+ const tableName = getTableName();
24
+ const result = await QueryBuilder.create(tableName, db).insert({
25
+ queue,
26
+ payload: JSON.stringify(payload),
27
+ attempts: 0,
28
+ max_attempts: Env.getInt('QUEUE_DB_RETRY_ATTEMPTS', 3),
29
+ created_at: new Date(),
30
+ available_at: new Date(),
31
+ });
32
+ const jobId = result.id;
33
+ Logger.info(`[DatabaseQueue] Job enqueued: ${jobId} to queue: ${queue}`);
34
+ return jobId;
35
+ },
36
+ async dequeue(queue, connectionName) {
37
+ const db = getConnection(connectionName);
38
+ const tableName = getTableName();
39
+ const visibilityTimeout = Env.getInt('QUEUE_DB_VISIBILITY_TIMEOUT', 30);
40
+ const timeoutDate = new Date(Date.now() - visibilityTimeout * 1000);
41
+ // Try to reserve a job using atomic update
42
+ const result = await db.transaction(async (trx) => {
43
+ const job = await QueryBuilder.create(tableName, trx)
44
+ .select('id', 'payload', 'attempts', 'max_attempts')
45
+ .where('queue', '=', queue)
46
+ .where('available_at', '<=', new Date())
47
+ .where('reserved_at', '=', null)
48
+ .orWhere('reserved_at', '<=', timeoutDate)
49
+ .where('failed_at', '=', null)
50
+ .orderBy('available_at', 'ASC')
51
+ .limit(1)
52
+ .first();
53
+ if (!job)
54
+ return null;
55
+ // Check if job has exceeded max attempts
56
+ if (job.attempts >= job.max_attempts) {
57
+ // Move to dead letter queue
58
+ await QueryBuilder.create('queue_jobs_failed', trx).insert({
59
+ original_id: job.id,
60
+ queue,
61
+ payload: job.payload,
62
+ attempts: job.attempts,
63
+ failed_at: new Date(),
64
+ error_message: 'Max attempts exceeded',
65
+ });
66
+ // Remove from active queue
67
+ await QueryBuilder.create(tableName, trx).where('id', '=', job.id).delete();
68
+ Logger.warn(`[DatabaseQueue] Job ${job.id} exceeded max attempts (${job.max_attempts}), moved to dead letter queue`);
69
+ return null;
70
+ }
71
+ // Calculate exponential backoff delay
72
+ const backoffDelay = Math.min(Math.pow(2, job.attempts) * 1000, 30000); // Max 30 seconds
73
+ const nextAvailableAt = new Date(Date.now() + backoffDelay);
74
+ // Reserve the job and set next available time
75
+ await QueryBuilder.create(tableName, trx)
76
+ .where('id', '=', job.id)
77
+ .update({
78
+ reserved_at: new Date(),
79
+ attempts: job.attempts + 1,
80
+ available_at: nextAvailableAt,
81
+ });
82
+ Logger.debug(`[DatabaseQueue] Job ${job.id} reserved, attempt ${job.attempts + 1}/${job.max_attempts}, next available at ${nextAvailableAt.toISOString()}`);
83
+ return job;
84
+ });
85
+ if (!result)
86
+ return undefined;
87
+ return {
88
+ id: result.id,
89
+ payload: JSON.parse(result.payload),
90
+ attempts: result.attempts,
91
+ };
92
+ },
93
+ async ack(queue, id, connectionName) {
94
+ const db = getConnection(connectionName);
95
+ const tableName = getTableName();
96
+ await QueryBuilder.create(tableName, db)
97
+ .where('id', '=', id)
98
+ .where('queue', '=', queue)
99
+ .delete();
100
+ Logger.debug(`[DatabaseQueue] Job acknowledged: ${id} from queue: ${queue}`);
101
+ },
102
+ async length(queue, connectionName) {
103
+ const db = getConnection(connectionName);
104
+ const tableName = getTableName();
105
+ const result = await QueryBuilder.create(tableName, db)
106
+ .select('id')
107
+ .where('queue', '=', queue)
108
+ .where('available_at', '<=', new Date())
109
+ .where('reserved_at', '=', null)
110
+ .orWhere('reserved_at', '<=', new Date(Date.now() - Env.getInt('QUEUE_DB_VISIBILITY_TIMEOUT', 30) * 1000))
111
+ .where('failed_at', '=', null)
112
+ .get();
113
+ return result?.length ?? 0;
114
+ },
115
+ async drain(queue, connectionName) {
116
+ const db = getConnection(connectionName);
117
+ const tableName = getTableName();
118
+ await QueryBuilder.create(tableName, db).where('queue', '=', queue).delete();
119
+ Logger.info(`[DatabaseQueue] Queue drained: ${queue}`);
120
+ },
121
+ };
122
+ })();
123
+ export default DatabaseQueue;
@@ -1 +1 @@
1
- {"version":3,"file":"Redis.d.ts","sourceRoot":"","sources":["../../../../../src/tools/queue/drivers/Redis.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAoBvD,eAAO,MAAM,UAAU;uBAuDL,CAAC,mBAAmB,MAAM,WAAW,CAAC,KAAG,OAAO,CAAC,MAAM,CAAC;uBAQxD,CAAC,mBAAmB,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;2BAY7D,MAAM,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;6BAMjC,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;4BAKzB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;CAKzC,CAAC;AAEL,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"Redis.d.ts","sourceRoot":"","sources":["../../../../../src/tools/queue/drivers/Redis.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,eAAO,MAAM,UAAU;uBAEL,CAAC,mBAAmB,MAAM,WAAW,CAAC,KAAG,OAAO,CAAC,MAAM,CAAC;uBAKxD,CAAC,mBAAmB,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;2BAK7D,MAAM,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;6BAKjC,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;4BAKzB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;CAKzC,CAAC;AAEL,eAAe,UAAU,CAAC"}