@zintrust/core 0.4.65 → 0.4.67

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 (45) hide show
  1. package/package.json +1 -1
  2. package/src/boot/bootstrap.js +8 -2
  3. package/src/cli/commands/MigrateCommand.js +1 -1
  4. package/src/cli/commands/QueueRecoveryCommand.js +1 -1
  5. package/src/cli/scaffolding/env.d.ts.map +1 -1
  6. package/src/cli/scaffolding/env.js +3 -1
  7. package/src/cli/workers/QueueWorkRunner.d.ts.map +1 -1
  8. package/src/cli/workers/QueueWorkRunner.js +49 -23
  9. package/src/config/app.d.ts.map +1 -1
  10. package/src/config/app.js +13 -1
  11. package/src/config/broadcast.d.ts.map +1 -1
  12. package/src/config/broadcast.js +5 -0
  13. package/src/config/env.d.ts +1 -0
  14. package/src/config/env.d.ts.map +1 -1
  15. package/src/config/env.js +44 -6
  16. package/src/config/logger.d.ts.map +1 -1
  17. package/src/config/logger.js +5 -5
  18. package/src/config/type.d.ts +7 -2
  19. package/src/config/type.d.ts.map +1 -1
  20. package/src/helper/index.d.ts +11 -1
  21. package/src/helper/index.d.ts.map +1 -1
  22. package/src/helper/index.js +11 -1
  23. package/src/index.js +3 -3
  24. package/src/scheduler/ScheduleRunner.js +1 -1
  25. package/src/scheduler/cron/Cron.d.ts.map +1 -1
  26. package/src/scheduler/cron/Cron.js +6 -2
  27. package/src/tools/broadcast/Broadcast.d.ts.map +1 -1
  28. package/src/tools/broadcast/Broadcast.js +190 -36
  29. package/src/tools/queue/AdvancedQueue.d.ts.map +1 -1
  30. package/src/tools/queue/AdvancedQueue.js +41 -2
  31. package/src/tools/queue/JobRecoveryDaemon.js +1 -1
  32. package/src/tools/queue/Queue.d.ts +1 -0
  33. package/src/tools/queue/Queue.d.ts.map +1 -1
  34. package/src/tools/queue/Queue.js +19 -7
  35. package/src/types/Queue.d.ts +1 -0
  36. package/src/types/Queue.d.ts.map +1 -1
  37. package/src/zintrust.comon.d.ts +11 -0
  38. package/src/zintrust.comon.d.ts.map +1 -0
  39. package/src/zintrust.comon.js +17 -0
  40. package/src/zintrust.plugins.d.ts +7 -3
  41. package/src/zintrust.plugins.d.ts.map +1 -1
  42. package/src/zintrust.plugins.js +9 -3
  43. package/src/zintrust.plugins.wg.d.ts +1 -0
  44. package/src/zintrust.plugins.wg.d.ts.map +1 -1
  45. package/src/zintrust.plugins.wg.js +3 -0
@@ -50,7 +50,7 @@ const computeCronDelay = (schedule) => {
50
50
  }
51
51
  const tz = typeof schedule.timezone === 'string' && schedule.timezone.trim().length > 0
52
52
  ? schedule.timezone
53
- : 'UTC';
53
+ : undefined;
54
54
  const nextAt = Cron.nextRunAtMs(nowMs(), schedule.cron, tz);
55
55
  const baseDelay = Math.max(0, nextAt - nowMs());
56
56
  const jitter = resolveJitterMs(schedule.jitterMs);
@@ -1 +1 @@
1
- {"version":3,"file":"Cron.d.ts","sourceRoot":"","sources":["../../../../src/scheduler/cron/Cron.ts"],"names":[],"mappings":"AAEA,KAAK,WAAW,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,IAAI,CAAA;CAAE,CAAC,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAEnG,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,WAAW,CAAC;IACxB,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,WAAW,CAAC;CACxB,CAAC,CAAC;AA0LH,eAAO,MAAM,IAAI;gBACH,MAAM,GAAG,QAAQ;uBA+BV,MAAM,QAAQ,MAAM,aAAY,MAAM,GAAW,MAAM;EAoB1E,CAAC;AAEH,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"Cron.d.ts","sourceRoot":"","sources":["../../../../src/scheduler/cron/Cron.ts"],"names":[],"mappings":"AAIA,KAAK,WAAW,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,IAAI,CAAA;CAAE,CAAC,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAEnG,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,WAAW,CAAC;IACxB,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,WAAW,CAAC;CACxB,CAAC,CAAC;AA0LH,eAAO,MAAM,IAAI;gBACH,MAAM,GAAG,QAAQ;uBA+BV,MAAM,QAAQ,MAAM,aAAa,MAAM,GAAG,MAAM;EAwBnE,CAAC;AAEH,eAAe,IAAI,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { resolveAppTimezone } from '../../config/env.js';
1
2
  const ANY = Object.freeze({ any: true });
2
3
  const toInt = (value) => {
3
4
  const n = Number.parseInt(value, 10);
@@ -179,16 +180,19 @@ export const Cron = Object.freeze({
179
180
  dayOfWeek: parseField(dow, { min: 0, max: 7 }, normalizeDow),
180
181
  });
181
182
  },
182
- nextRunAtMs(nowMs, expr, timeZone = 'UTC') {
183
+ nextRunAtMs(nowMs, expr, timeZone) {
183
184
  const spec = this.parse(expr);
184
185
  const base = new Date(nowMs);
186
+ const resolvedTimeZone = typeof timeZone === 'string' && timeZone.trim().length > 0
187
+ ? timeZone.trim()
188
+ : resolveAppTimezone();
185
189
  // Cron is minute-resolution; start from next minute boundary.
186
190
  base.setUTCSeconds(0, 0);
187
191
  base.setTime(base.getTime() + 60_000);
188
192
  // Bound search to 366 days (minute granularity). This is defensive; typical crons resolve quickly.
189
193
  const maxIterations = 366 * 24 * 60;
190
194
  for (let i = 0; i < maxIterations; i++) {
191
- const parts = getZonedParts(base, timeZone);
195
+ const parts = getZonedParts(base, resolvedTimeZone);
192
196
  if (matchesSpec(spec, parts))
193
197
  return base.getTime();
194
198
  base.setTime(base.getTime() + 60_000);
@@ -1 +1 @@
1
- {"version":3,"file":"Broadcast.d.ts","sourceRoot":"","sources":["../../../../src/tools/broadcast/Broadcast.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,KAAK,WAAW,GAAG,QAAQ,CAAC;IAC1B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,OAAO,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAC5E,CAAC,CAAC;AAEH,KAAK,qBAAqB,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,CAAC;AAC9E,KAAK,qBAAqB,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC1D,KAAK,kBAAkB,GAAG,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAShE,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC,CAAC;AAaH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,EAAE,EAAE,IAAI,CAAC;IACT,SAAS,EAAE,kBAAkB,CAAC;IAC9B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CAC9B,CAAC,CAAC;AA8jBH,eAAO,MAAM,SAAS;mBACC,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;kBAIxD,MAAM,SAAS,MAAM,QAAQ,OAAO;0BAU5B,MAAM,SAAS,MAAM,QAAQ,OAAO;wBAKvD,qBAAqB,YACnB;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;4BAO1C,MAAM,SACR,MAAM,QACP,OAAO,YACJ;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;qBAKpC,MAAM;8BAES,qBAAqB;kCAEjB,MAAM,SAAS,MAAM,QAAQ,OAAO;;uBAKrD,MAAM,GAAG,WAAW;EAmBvC,CAAC;AAEH,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"Broadcast.d.ts","sourceRoot":"","sources":["../../../../src/tools/broadcast/Broadcast.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,KAAK,WAAW,GAAG,QAAQ,CAAC;IAC1B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,OAAO,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAC5E,CAAC,CAAC;AAEH,KAAK,qBAAqB,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,CAAC;AAC9E,KAAK,qBAAqB,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC1D,KAAK,kBAAkB,GAAG,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAShE,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC,CAAC;AA0BH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,EAAE,EAAE,IAAI,CAAC;IACT,SAAS,EAAE,kBAAkB,CAAC;IAC9B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CAC9B,CAAC,CAAC;AA+xBH,eAAO,MAAM,SAAS;mBACC,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;kBAIxD,MAAM,SAAS,MAAM,QAAQ,OAAO;0BAU5B,MAAM,SAAS,MAAM,QAAQ,OAAO;wBAKvD,qBAAqB,YACnB;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;4BAO1C,MAAM,SACR,MAAM,QACP,OAAO,YACJ;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;qBAKpC,MAAM;8BAES,qBAAqB;kCAEjB,MAAM,SAAS,MAAM,QAAQ,OAAO;;uBAKrD,MAAM,GAAG,WAAW;EAmBvC,CAAC;AAEH,eAAe,SAAS,CAAC"}
@@ -14,6 +14,7 @@ const BROADCAST_CHANNEL_SCOPES = new Set([
14
14
  'persistent',
15
15
  ]);
16
16
  const INTERNAL_SOCKET_SECRET_HEADER = 'x-zintrust-socket-secret';
17
+ const DEFAULT_BROADCAST_EVENTS_PATH_TEMPLATE = '/apps/{appId}/events';
17
18
  const pickFirstNonEmpty = (...values) => {
18
19
  for (const value of values) {
19
20
  if (value.trim() !== '') {
@@ -108,24 +109,86 @@ const getLoopbackAlternativeBaseUrl = (value) => {
108
109
  }
109
110
  return '';
110
111
  };
112
+ const resolveBroadcastAppId = () => {
113
+ return (pickFirstNonEmpty(Env.get('PUSHER_APP_ID', ''), Env.get('BROADCAST_APP_ID', '')) || 'internal');
114
+ };
115
+ const resolveBroadcastSecret = () => {
116
+ return pickFirstNonEmpty(Env.get('BROADCAST_BRIDGE_SECRET', ''), Env.get('X_ZINTRUST_SOCKET_SEC', ''), Env.get('BROADCAST_SECRET', ''), Env.get('PUSHER_APP_SECRET', ''), Env.get('BROADCAST_APP_SECRET', ''));
117
+ };
118
+ const resolveBridgePath = (appId, value) => {
119
+ const raw = (value ?? DEFAULT_BROADCAST_EVENTS_PATH_TEMPLATE).trim();
120
+ const withLeadingSlash = raw === '' ? DEFAULT_BROADCAST_EVENTS_PATH_TEMPLATE : raw;
121
+ const normalized = withLeadingSlash.startsWith('/') ? withLeadingSlash : `/${withLeadingSlash}`;
122
+ return normalized
123
+ .replaceAll('{appId}', encodeURIComponent(appId))
124
+ .replaceAll(':appId', encodeURIComponent(appId));
125
+ };
126
+ const resolveExplicitEndpoint = (value, appId) => {
127
+ const absoluteUrl = toAbsoluteBaseUrl(value);
128
+ if (absoluteUrl === '') {
129
+ return '';
130
+ }
131
+ try {
132
+ const parsed = new URL(absoluteUrl);
133
+ if (parsed.pathname === '/' || parsed.pathname.trim() === '') {
134
+ parsed.pathname = resolveBridgePath(appId);
135
+ }
136
+ return parsed.toString();
137
+ }
138
+ catch {
139
+ return '';
140
+ }
141
+ };
142
+ const resolveLegacyBridgeEndpoint = (appId) => {
143
+ const host = Env.get('ZINTRUST_SOCKET_HOST', '').trim();
144
+ if (host === '') {
145
+ return '';
146
+ }
147
+ const port = Env.get('ZINTRUST_SOCKET_PORT', '').trim();
148
+ const protocol = pickFirstNonEmpty(Env.get('BROADCAST_BRIDGE_PROTOCOL', ''), 'http');
149
+ const portSuffix = port === '' ? '' : `:${port}`;
150
+ const baseUrl = `${protocol}://${host}${portSuffix}`;
151
+ try {
152
+ return new URL(resolveBridgePath(appId, Env.get('BROADCAST_BRIDGE_PATH', '')), baseUrl).toString();
153
+ }
154
+ catch {
155
+ return '';
156
+ }
157
+ };
158
+ const buildEndpointCandidates = (values) => {
159
+ const resolved = [];
160
+ for (const value of values) {
161
+ appendUnique(resolved, value);
162
+ appendUnique(resolved, getLoopbackAlternativeBaseUrl(value));
163
+ }
164
+ return resolved;
165
+ };
111
166
  const getInternalPublishConfig = () => {
112
167
  const baseUrls = [];
113
168
  appendUnique(baseUrls, toAbsoluteBaseUrl(Env.get('BROADCAST_INTERNAL_URL', '')));
114
169
  appendUnique(baseUrls, toAbsoluteBaseUrl(Env.get('APP_URL', '')));
115
170
  appendUnique(baseUrls, toAbsoluteBaseUrl(Env.get('BASE_URL', Env.BASE_URL ?? '')));
116
- const resolvedBaseUrls = [];
117
- for (const baseUrl of baseUrls) {
118
- appendUnique(resolvedBaseUrls, baseUrl);
119
- appendUnique(resolvedBaseUrls, getLoopbackAlternativeBaseUrl(baseUrl));
120
- }
121
- const appId = pickFirstNonEmpty(Env.get('PUSHER_APP_ID', ''), Env.get('BROADCAST_APP_ID', '')) || 'internal';
122
- const secret = pickFirstNonEmpty(Env.get('BROADCAST_SECRET', ''), Env.get('PUSHER_APP_SECRET', ''), Env.get('BROADCAST_APP_SECRET', ''));
171
+ const appId = resolveBroadcastAppId();
172
+ const secret = resolveBroadcastSecret();
123
173
  return Object.freeze({
124
- endpoints: resolvedBaseUrls.map((baseUrl) => new URL(`/apps/${encodeURIComponent(appId)}/events`, baseUrl).toString()),
174
+ endpoints: buildEndpointCandidates(baseUrls).map((baseUrl) => new URL(`/apps/${encodeURIComponent(appId)}/events`, baseUrl).toString()),
125
175
  appId,
126
176
  secret,
127
177
  });
128
178
  };
179
+ const getBridgePublishConfig = () => {
180
+ const appId = resolveBroadcastAppId();
181
+ return Object.freeze({
182
+ endpoints: buildEndpointCandidates([
183
+ resolveExplicitEndpoint(Env.get('BROADCAST_BRIDGE_URL', ''), appId),
184
+ resolveLegacyBridgeEndpoint(appId),
185
+ ]),
186
+ secret: resolveBroadcastSecret(),
187
+ });
188
+ };
189
+ const isIsolatedWorkerRuntime = () => {
190
+ return Env.getBool('WORKER_ISOLATED', false) || Env.getBool('DOCKER_WORKER', false);
191
+ };
129
192
  const parseJsonResponseSafe = async (response) => {
130
193
  const raw = await response.text();
131
194
  if (raw.trim() === '') {
@@ -264,6 +327,9 @@ const sendWithConfig = async (config, channel, event, data) => {
264
327
  if (driverName === 'redishttps') {
265
328
  return RedisHttpsDriver.send(config, channel, event, data);
266
329
  }
330
+ if (driverName === 'http-bridge') {
331
+ return publishViaHttpBridgeDriver(toHttpBridgeRuntimeConfig(config), normalizePublishInput({ channel, event, data }));
332
+ }
267
333
  throw ErrorFactory.createConfigError(`Broadcast driver not implemented: ${driverName}`);
268
334
  };
269
335
  const normalizeDelivery = (value) => {
@@ -363,7 +429,96 @@ const tryPublishViaInternalHttp = async (input) => {
363
429
  };
364
430
  return tryInternalPublishEndpoints(config.endpoints, config.secret, payload);
365
431
  };
432
+ const tryPublishViaConfiguredBridge = async (input, config) => {
433
+ if (config.endpoints.length === 0 || typeof globalThis.fetch !== 'function') {
434
+ return { result: null };
435
+ }
436
+ const payload = {
437
+ channels: input.channels,
438
+ event: input.event,
439
+ data: input.data,
440
+ ...(input.socketId === undefined ? {} : { socket_id: input.socketId }),
441
+ };
442
+ return tryInternalPublishEndpoints(config.endpoints, config.secret, payload);
443
+ };
444
+ const shouldUseAutomaticHttpBridge = (config, input) => {
445
+ if (input.delivery === 'driver') {
446
+ return false;
447
+ }
448
+ return config.driver === 'inmemory' && isIsolatedWorkerRuntime();
449
+ };
450
+ const toHttpBridgeRuntimeConfig = (config) => {
451
+ return Object.freeze({
452
+ url: config.url,
453
+ secret: config.secret,
454
+ });
455
+ };
456
+ const publishViaHttpBridgeDriver = async (config, input) => {
457
+ const bridgeConfig = Object.freeze({
458
+ endpoints: buildEndpointCandidates([
459
+ resolveExplicitEndpoint(config.url, resolveBroadcastAppId()),
460
+ ]),
461
+ secret: config.secret.trim(),
462
+ });
463
+ const bridgeResult = await tryPublishViaConfiguredBridge(input, bridgeConfig);
464
+ if (bridgeResult.result !== null) {
465
+ return {
466
+ ok: true,
467
+ transport: 'driver',
468
+ channels: bridgeResult.result.channels,
469
+ event: bridgeResult.result.event,
470
+ deliveries: bridgeResult.result.deliveries,
471
+ driver: 'http-bridge',
472
+ endpoint: bridgeResult.result.endpoint,
473
+ result: bridgeResult.result.result,
474
+ };
475
+ }
476
+ if (bridgeResult.error instanceof Error) {
477
+ throw bridgeResult.error;
478
+ }
479
+ throw ErrorFactory.createConfigError('HTTP bridge broadcast driver misconfigured: BROADCAST_BRIDGE_URL is required');
480
+ };
481
+ const tryPublishNonDriverTransports = async (normalized, selectedConfig) => {
482
+ const attemptedTransports = [];
483
+ let lastTransportError;
484
+ if (shouldUseAutomaticHttpBridge(selectedConfig, normalized)) {
485
+ attemptedTransports.push('internal-http');
486
+ const bridgeResult = await tryPublishViaConfiguredBridge(normalized, getBridgePublishConfig());
487
+ if (bridgeResult.result !== null) {
488
+ return { result: bridgeResult.result, attemptedTransports, lastTransportError };
489
+ }
490
+ if (bridgeResult.error !== undefined) {
491
+ lastTransportError = bridgeResult.error;
492
+ }
493
+ }
494
+ attemptedTransports.push('internal-http');
495
+ const internalHttpResult = await tryPublishViaInternalHttp(normalized);
496
+ if (internalHttpResult.result !== null) {
497
+ return { result: internalHttpResult.result, attemptedTransports, lastTransportError };
498
+ }
499
+ if (internalHttpResult.error !== undefined) {
500
+ lastTransportError = internalHttpResult.error;
501
+ }
502
+ attemptedTransports.push('socket');
503
+ const socketResult = await tryPublishViaSocket(normalized);
504
+ if (socketResult.result !== null) {
505
+ return { result: socketResult.result, attemptedTransports, lastTransportError };
506
+ }
507
+ if (socketResult.error !== undefined) {
508
+ lastTransportError = socketResult.error;
509
+ logTransportFallback('socket', {
510
+ error: describeError(socketResult.error),
511
+ });
512
+ }
513
+ return { result: null, attemptedTransports, lastTransportError };
514
+ };
366
515
  const publishWithConfig = async (config, broadcasterName, input) => {
516
+ if (config.driver === 'http-bridge') {
517
+ return {
518
+ ...(await publishViaHttpBridgeDriver(toHttpBridgeRuntimeConfig(config), input)),
519
+ ...(broadcasterName === undefined ? {} : { broadcaster: broadcasterName }),
520
+ };
521
+ }
367
522
  const results = await Promise.all(input.channels.map(async (channel) => sendWithConfig(config, channel, input.event, input.data)));
368
523
  return {
369
524
  ok: true,
@@ -377,39 +532,28 @@ const publishWithConfig = async (config, broadcasterName, input) => {
377
532
  };
378
533
  const publishInternal = async (input) => {
379
534
  const normalized = normalizePublishInput(input);
380
- const attemptedTransports = [];
381
- let lastTransportError;
382
- if (normalized.delivery !== 'driver') {
383
- attemptedTransports.push('internal-http');
384
- const internalHttpResult = await tryPublishViaInternalHttp(normalized);
385
- if (internalHttpResult.result !== null) {
386
- return { ...internalHttpResult.result, attemptedTransports };
387
- }
388
- if (internalHttpResult.error !== undefined) {
389
- lastTransportError = internalHttpResult.error;
390
- }
391
- attemptedTransports.push('socket');
392
- const socketResult = await tryPublishViaSocket(normalized);
393
- if (socketResult.result !== null) {
394
- return { ...socketResult.result, attemptedTransports };
395
- }
396
- if (socketResult.error !== undefined) {
397
- lastTransportError = socketResult.error;
398
- logTransportFallback('socket', {
399
- error: describeError(socketResult.error),
400
- });
401
- }
535
+ const selectedConfig = await resolveBroadcasterConfig(normalized.broadcaster);
536
+ const autoTransportResult = normalized.delivery === 'driver'
537
+ ? { result: null, attemptedTransports: [] }
538
+ : await tryPublishNonDriverTransports(normalized, selectedConfig);
539
+ if (autoTransportResult.result !== null) {
540
+ return {
541
+ ...autoTransportResult.result,
542
+ attemptedTransports: autoTransportResult.attemptedTransports,
543
+ };
402
544
  }
403
545
  if (normalized.delivery === 'socket') {
404
- if (lastTransportError instanceof Error) {
405
- throw lastTransportError;
546
+ if (autoTransportResult.lastTransportError instanceof Error) {
547
+ throw autoTransportResult.lastTransportError;
406
548
  }
407
549
  throw ErrorFactory.createConfigError('Socket publish delivery is not available.');
408
550
  }
409
- attemptedTransports.push('driver');
410
- const config = await resolveBroadcasterConfig(normalized.broadcaster);
551
+ const attemptedTransports = [
552
+ ...autoTransportResult.attemptedTransports,
553
+ 'driver',
554
+ ];
411
555
  return {
412
- ...(await publishWithConfig(config, normalized.broadcaster, normalized)),
556
+ ...(await publishWithConfig(selectedConfig, normalized.broadcaster, normalized)),
413
557
  attemptedTransports,
414
558
  };
415
559
  };
@@ -417,7 +561,7 @@ const publishLaterInternal = async (input, options = {}) => {
417
561
  const normalized = normalizePublishInput(input);
418
562
  const { queueName = 'broadcasts', timestamp = Date.now() } = options;
419
563
  const { Queue } = await import('../queue/Queue.js');
420
- return Queue.enqueue(queueName, {
564
+ const payload = {
421
565
  type: 'broadcast',
422
566
  channel: normalized.channels[0],
423
567
  channels: normalized.channels,
@@ -428,7 +572,17 @@ const publishLaterInternal = async (input, options = {}) => {
428
572
  delivery: normalized.delivery,
429
573
  timestamp,
430
574
  attempts: 0,
575
+ };
576
+ Logger.debug('Broadcast queued publish prepared', {
577
+ queueName,
578
+ channels: payload.channels,
579
+ compatibilityChannel: payload.channel,
580
+ event: payload.event,
581
+ delivery: payload.delivery,
582
+ broadcaster: payload.broadcaster,
583
+ timestamp: payload.timestamp,
431
584
  });
585
+ return Queue.enqueue(queueName, payload);
432
586
  };
433
587
  export const Broadcast = Object.freeze({
434
588
  async publish(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"AdvancedQueue.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/AdvancedQueue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAElB,SAAS,EAGT,WAAW,EACZ,MAAM,eAAe,CAAC;AAOvB,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5F,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3E,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,aAAa,CAiBtE"}
1
+ {"version":3,"file":"AdvancedQueue.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/AdvancedQueue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,kBAAkB,EAElB,SAAS,EAGT,WAAW,EACZ,MAAM,eAAe,CAAC;AAOvB,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5F,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3E,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,aAAa,CAiBtE"}
@@ -2,6 +2,7 @@
2
2
  * Advanced Queue Implementation
3
3
  * Extends ZinTrust queue functionality with deduplication and lock management
4
4
  */
5
+ import { isNonEmptyString } from '../../helper/index.js';
5
6
  import { Env } from '../../config/env.js';
6
7
  import { Logger } from '../../config/logger.js';
7
8
  import { queueConfig } from '../../config/queue.js';
@@ -93,6 +94,36 @@ function shouldAttachReleaseAfterMeta(options) {
93
94
  return false;
94
95
  return typeof options.deduplication.releaseAfter !== 'number';
95
96
  }
97
+ function normalizeOptionId(value) {
98
+ if (!isNonEmptyString(value))
99
+ return undefined;
100
+ const normalized = value.trim();
101
+ return normalized.length > 0 ? normalized : undefined;
102
+ }
103
+ function attachAdvancedIdentifiers(payload, options) {
104
+ const requestedJobId = normalizeOptionId(options.jobId);
105
+ const requestedUniqueId = normalizeOptionId(options.uniqueId);
106
+ if (requestedJobId === undefined && requestedUniqueId === undefined) {
107
+ return { payload, identifiersSkipped: false };
108
+ }
109
+ if (payload === null || payload === undefined || typeof payload !== 'object') {
110
+ return { payload, identifiersSkipped: true };
111
+ }
112
+ const payloadJobId = normalizeOptionId(payload.jobId);
113
+ const payloadUniqueId = normalizeOptionId(payload.uniqueId);
114
+ return {
115
+ payload: {
116
+ ...payload,
117
+ ...(payloadJobId === undefined && requestedJobId !== undefined
118
+ ? { jobId: requestedJobId }
119
+ : {}),
120
+ ...(payloadUniqueId === undefined && requestedUniqueId !== undefined
121
+ ? { uniqueId: requestedUniqueId }
122
+ : {}),
123
+ },
124
+ identifiersSkipped: false,
125
+ };
126
+ }
96
127
  function attachQueueMeta(payload, options) {
97
128
  if (!shouldAttachReleaseAfterMeta(options)) {
98
129
  return { payload, metaAttached: false };
@@ -198,8 +229,16 @@ async function enqueueWithDeduplication(name, payload, options, defaultLockProvi
198
229
  if (deduplicationResult !== null) {
199
230
  return deduplicationResult;
200
231
  }
201
- const { payload: payloadToSend, metaAttached } = attachQueueMeta(payload, options);
202
- if (!metaAttached && shouldAttachReleaseAfterMeta(options)) {
232
+ const { payload: payloadWithIdentifiers, identifiersSkipped } = attachAdvancedIdentifiers(payload, options);
233
+ if (identifiersSkipped) {
234
+ Logger.warn('Advanced queue identifiers could not be attached; payload is not an object', {
235
+ queueName: name,
236
+ jobId: normalizeOptionId(options.jobId),
237
+ uniqueId: normalizeOptionId(options.uniqueId),
238
+ });
239
+ }
240
+ const { payload: payloadToSend, metaAttached } = attachQueueMeta(payloadWithIdentifiers, options);
241
+ if (shouldAttachReleaseAfterMeta(options) && metaAttached === false) {
203
242
  Logger.warn('releaseAfter condition metadata could not be attached; payload is not an object', {
204
243
  queueName: name,
205
244
  releaseAfter: options.deduplication?.releaseAfter,
@@ -121,7 +121,7 @@ export const JobRecoveryDaemon = Object.freeze({
121
121
  try {
122
122
  await Queue.enqueue(record.queueName, {
123
123
  ...payload,
124
- uniqueId: record.jobId, // Preserves job ID (prevents duplication)
124
+ jobId: record.jobId,
125
125
  attempts: maxAttempts,
126
126
  _currentAttempts: record.attempts + 1,
127
127
  timestamp: Date.now() + backoffMs,
@@ -20,6 +20,7 @@ export interface BullMQPayload {
20
20
  templateData?: Record<string, unknown>;
21
21
  timestamp?: number;
22
22
  attempts?: number;
23
+ jobId?: string;
23
24
  uniqueId?: string;
24
25
  delay?: number;
25
26
  priority?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"Queue.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/Queue.ts"],"names":[],"mappings":"AAUA,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,MAAM,WAAW,YAAY;IAC3B,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;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAE5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,OAAO,GAAG,aAAa,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,IAAI,CAAC,EAAE,OAAO,CAAC;IAGf,aAAa,CAAC,EAAE;QACd,EAAE,EAAE,MAAM,CAAC;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACvE,CAAC;IAGF,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAID;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAO,MAOpC,CAAC;AA+EF,eAAO,MAAM,KAAK;mBACD,MAAM,UAAU,YAAY;aAIlC,IAAI;eAIF,MAAM,GAAG,YAAY;mBASX,MAAM,WAAW,aAAa,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAoE5E,CAAC,mBACN,MAAM,eACA,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;eActB,MAAM,MAAM,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;kBAcpD,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;iBAc9C,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EAa9D,CAAC;AAEH,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Queue.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/Queue.ts"],"names":[],"mappings":"AAUA,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,MAAM,WAAW,YAAY;IAC3B,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;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAE5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,OAAO,GAAG,aAAa,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,IAAI,CAAC,EAAE,OAAO,CAAC;IAGf,aAAa,CAAC,EAAE;QACd,EAAE,EAAE,MAAM,CAAC;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACvE,CAAC;IAGF,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAID;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAO,MAOpC,CAAC;AAwFF,eAAO,MAAM,KAAK;mBACD,MAAM,UAAU,YAAY;aAIlC,IAAI;eAIF,MAAM,GAAG,YAAY;mBASX,MAAM,WAAW,aAAa,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YA0E5E,CAAC,mBACN,MAAM,eACA,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;eActB,MAAM,MAAM,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;kBAcpD,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;iBAc9C,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EAa9D,CAAC;AAEH,eAAe,KAAK,CAAC"}
@@ -30,12 +30,18 @@ const shouldPreserveExistingStatus = (queueName, jobId) => {
30
30
  const existing = JobStateTracker.get(queueName, jobId);
31
31
  return existing?.status === 'pending_recovery';
32
32
  };
33
- const resolveRequestedUniqueId = (payload) => {
34
- if (typeof payload?.uniqueId !== 'string')
33
+ const normalizeRequestedId = (value) => {
34
+ if (typeof value !== 'string')
35
35
  return undefined;
36
- const normalized = payload.uniqueId.trim();
36
+ const normalized = value.trim();
37
37
  return normalized.length > 0 ? normalized : undefined;
38
38
  };
39
+ const resolveRequestedJobId = (payload) => {
40
+ return normalizeRequestedId(payload?.jobId);
41
+ };
42
+ const resolveRequestedUniqueId = (payload) => {
43
+ return normalizeRequestedId(payload?.uniqueId);
44
+ };
39
45
  const resolveMaxAttempts = (payload) => {
40
46
  if (typeof payload?.attempts !== 'number' || !Number.isFinite(payload.attempts))
41
47
  return undefined;
@@ -54,13 +60,13 @@ const markEnqueued = async (input) => {
54
60
  idempotencyKey: input.requestedUniqueId,
55
61
  });
56
62
  };
57
- const createFallbackJobId = (requestedUniqueId) => {
58
- if (requestedUniqueId !== undefined)
59
- return requestedUniqueId;
63
+ const createFallbackJobId = (requestedJobId) => {
64
+ if (requestedJobId !== undefined)
65
+ return requestedJobId;
60
66
  return `fallback-${generateUuid()}`;
61
67
  };
62
68
  const markFailedEnqueue = async (input) => {
63
- const fallbackJobId = createFallbackJobId(input.requestedUniqueId);
69
+ const fallbackJobId = createFallbackJobId(input.requestedJobId);
64
70
  await markEnqueued({
65
71
  queueName: input.queueName,
66
72
  jobId: fallbackJobId,
@@ -92,6 +98,7 @@ export const Queue = Object.freeze({
92
98
  },
93
99
  async enqueue(queue, payload, driverName) {
94
100
  const resolvedDriver = resolveDriverName(driverName);
101
+ const requestedJobId = resolveRequestedJobId(payload);
95
102
  const requestedUniqueId = resolveRequestedUniqueId(payload);
96
103
  try {
97
104
  const jobId = await QueueTracing.traceOperation({
@@ -99,6 +106,7 @@ export const Queue = Object.freeze({
99
106
  operation: 'enqueue',
100
107
  attributes: {
101
108
  driverName: resolvedDriver,
109
+ hasJobId: requestedJobId !== undefined,
102
110
  hasUniqueId: requestedUniqueId !== undefined,
103
111
  },
104
112
  execute: async () => {
@@ -110,6 +118,7 @@ export const Queue = Object.freeze({
110
118
  queue,
111
119
  driver: resolvedDriver,
112
120
  jobId,
121
+ requestedJobId,
113
122
  requestedUniqueId,
114
123
  });
115
124
  if (shouldPreserveExistingStatus(queue, jobId)) {
@@ -117,6 +126,7 @@ export const Queue = Object.freeze({
117
126
  queue,
118
127
  driver: resolvedDriver,
119
128
  jobId,
129
+ requestedJobId,
120
130
  requestedUniqueId,
121
131
  });
122
132
  return jobId;
@@ -134,6 +144,7 @@ export const Queue = Object.freeze({
134
144
  const fallbackJobId = await markFailedEnqueue({
135
145
  queueName: queue,
136
146
  payload,
147
+ requestedJobId,
137
148
  requestedUniqueId,
138
149
  error,
139
150
  });
@@ -141,6 +152,7 @@ export const Queue = Object.freeze({
141
152
  queue,
142
153
  driver: resolvedDriver,
143
154
  fallbackJobId,
155
+ requestedJobId,
144
156
  requestedUniqueId,
145
157
  error: error instanceof Error ? error.message : String(error),
146
158
  });
@@ -42,6 +42,7 @@ export interface QueueConfig {
42
42
  lockProvider?: string;
43
43
  }
44
44
  export interface AdvancedJobOptions {
45
+ jobId?: string;
45
46
  uniqueId?: string;
46
47
  uniqueVia?: string;
47
48
  deduplication?: DeduplicationOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"Queue.d.ts","sourceRoot":"","sources":["../../../src/types/Queue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,gBAAgB,CAAC;CACnD;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,IAAI;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,IAAI,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;IACtC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,QAAQ,GAAG,cAAc,GAAG,QAAQ,CAAC;CAC9C;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC3C"}
1
+ {"version":3,"file":"Queue.d.ts","sourceRoot":"","sources":["../../../src/types/Queue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,gBAAgB,CAAC;CACnD;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,IAAI;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,IAAI,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;IACtC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,QAAQ,GAAG,cAAc,GAAG,QAAQ,CAAC;CAC9C;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC3C"}
@@ -0,0 +1,11 @@
1
+ import '../packages/db-d1/src/register.js';
2
+ import '../packages/db-mysql/src/register.js';
3
+ import '../packages/db-postgres/src/register.js';
4
+ import '../packages/db-sqlite/src/register.js';
5
+ import '../packages/db-sqlserver/src/register.js';
6
+ import '../packages/mail-sendgrid/src/register.js';
7
+ import '../packages/mail-smtp/src/register.js';
8
+ import '@zintrust/queue-monitor';
9
+ import '../packages/queue-redis/src/register.js';
10
+ import '../packages/workers/src/register.js';
11
+ //# sourceMappingURL=zintrust.comon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zintrust.comon.d.ts","sourceRoot":"","sources":["../../src/zintrust.comon.ts"],"names":[],"mappings":"AAQA,OAAO,mCAAmC,CAAC;AAC3C,OAAO,sCAAsC,CAAC;AAC9C,OAAO,yCAAyC,CAAC;AACjD,OAAO,uCAAuC,CAAC;AAC/C,OAAO,0CAA0C,CAAC;AAClD,OAAO,2CAA2C,CAAC;AACnD,OAAO,uCAAuC,CAAC;AAC/C,OAAO,wCAAwC,CAAC;AAChD,OAAO,yCAAyC,CAAC;AACjD,OAAO,qCAAqC,CAAC"}
@@ -0,0 +1,17 @@
1
+ /* eslint-disable no-restricted-imports */
2
+ // /**
3
+ // * ZinTrust comon plugin auto-imports
4
+ // *
5
+ // * This file is managed by `zin plugin install` and contains side-effect
6
+ // * imports that register optional adapters/drivers into core registries.
7
+ // */
8
+ import '../packages/db-d1/src/register.js';
9
+ import '../packages/db-mysql/src/register.js';
10
+ import '../packages/db-postgres/src/register.js';
11
+ import '../packages/db-sqlite/src/register.js';
12
+ import '../packages/db-sqlserver/src/register.js';
13
+ import '../packages/mail-sendgrid/src/register.js';
14
+ import '../packages/mail-smtp/src/register.js';
15
+ import '@zintrust/queue-monitor';
16
+ import '../packages/queue-redis/src/register.js';
17
+ import '../packages/workers/src/register.js';
@@ -1,8 +1,12 @@
1
1
  /**
2
- * Auto-generated fallback module.
3
- * This file is created by scripts/ensure-worker-plugins.mjs when missing.
4
- * It allows optional runtime plugin imports to resolve in CI/scaffolded setups.
2
+ * ZinTrust plugin auto-imports
3
+ *
4
+ * In real projects, this file is managed by `zin plugin install` and contains
5
+ * side-effect imports (e.g. `@zintrust/db-sqlite/register`) that register
6
+ * optional adapters/drivers into core registries.
7
+ *
5
8
  */
9
+ export type {};
6
10
  export declare const __zintrustGeneratedPluginStub = "zintrust.plugins.ts";
7
11
  declare const _default: {};
8
12
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"zintrust.plugins.d.ts","sourceRoot":"","sources":["../../src/zintrust.plugins.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,6BAA6B,wBAAwB,CAAC;;AACnE,wBAAkB"}
1
+ {"version":3,"file":"zintrust.plugins.d.ts","sourceRoot":"","sources":["../../src/zintrust.plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,YAAY,EAAE,CAAC;AAgBf,eAAO,MAAM,6BAA6B,wBAAwB,CAAC;;AACnE,wBAAkB"}
@@ -1,7 +1,13 @@
1
1
  /**
2
- * Auto-generated fallback module.
3
- * This file is created by scripts/ensure-worker-plugins.mjs when missing.
4
- * It allows optional runtime plugin imports to resolve in CI/scaffolded setups.
2
+ * ZinTrust plugin auto-imports
3
+ *
4
+ * In real projects, this file is managed by `zin plugin install` and contains
5
+ * side-effect imports (e.g. `@zintrust/db-sqlite/register`) that register
6
+ * optional adapters/drivers into core registries.
7
+ *
5
8
  */
9
+ import * as SystemDebuggerRuntime from './runtime/plugins/system-debugger-runtime.js';
10
+ globalThis.__zintrust_system_debugger_plugin_requested__ = true;
11
+ globalThis.__zintrust_system_debugger_runtime__ = SystemDebuggerRuntime;
6
12
  export const __zintrustGeneratedPluginStub = 'zintrust.plugins.ts';
7
13
  export default {};
@@ -3,6 +3,7 @@
3
3
  * This file is created by scripts/ensure-worker-plugins.mjs when missing.
4
4
  * It allows optional runtime plugin imports to resolve in CI/scaffolded setups.
5
5
  */
6
+ export type {};
6
7
  export declare const __zintrustGeneratedPluginStub = "zintrust.plugins.wg.ts";
7
8
  declare const _default: {};
8
9
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"zintrust.plugins.wg.d.ts","sourceRoot":"","sources":["../../src/zintrust.plugins.wg.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,6BAA6B,2BAA2B,CAAC;;AACtE,wBAAkB"}
1
+ {"version":3,"file":"zintrust.plugins.wg.d.ts","sourceRoot":"","sources":["../../src/zintrust.plugins.wg.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,YAAY,EAAE,CAAC;AAgBf,eAAO,MAAM,6BAA6B,2BAA2B,CAAC;;AACtE,wBAAkB"}