@zintrust/workers 0.1.29 → 0.1.30

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 (111) hide show
  1. package/README.md +16 -1
  2. package/dist/AnomalyDetection.d.ts +4 -0
  3. package/dist/AnomalyDetection.js +8 -0
  4. package/dist/BroadcastWorker.d.ts +2 -0
  5. package/dist/CanaryController.js +49 -5
  6. package/dist/ChaosEngineering.js +13 -0
  7. package/dist/ClusterLock.js +21 -10
  8. package/dist/DeadLetterQueue.js +12 -8
  9. package/dist/MultiQueueWorker.d.ts +1 -1
  10. package/dist/MultiQueueWorker.js +12 -7
  11. package/dist/NotificationWorker.d.ts +2 -0
  12. package/dist/PriorityQueue.d.ts +2 -2
  13. package/dist/PriorityQueue.js +20 -21
  14. package/dist/ResourceMonitor.js +65 -38
  15. package/dist/WorkerFactory.d.ts +23 -3
  16. package/dist/WorkerFactory.js +420 -40
  17. package/dist/WorkerInit.js +8 -3
  18. package/dist/WorkerMetrics.d.ts +2 -1
  19. package/dist/WorkerMetrics.js +152 -93
  20. package/dist/WorkerRegistry.d.ts +6 -0
  21. package/dist/WorkerRegistry.js +70 -1
  22. package/dist/WorkerShutdown.d.ts +21 -0
  23. package/dist/WorkerShutdown.js +82 -9
  24. package/dist/WorkerShutdownDurableObject.d.ts +12 -0
  25. package/dist/WorkerShutdownDurableObject.js +41 -0
  26. package/dist/build-manifest.json +171 -99
  27. package/dist/createQueueWorker.d.ts +2 -0
  28. package/dist/createQueueWorker.js +42 -27
  29. package/dist/dashboard/types.d.ts +5 -0
  30. package/dist/dashboard/workers-api.js +136 -43
  31. package/dist/http/WorkerApiController.js +1 -0
  32. package/dist/http/WorkerController.js +133 -85
  33. package/dist/http/WorkerMonitoringService.d.ts +11 -0
  34. package/dist/http/WorkerMonitoringService.js +62 -0
  35. package/dist/http/middleware/CustomValidation.js +1 -1
  36. package/dist/http/middleware/EditWorkerValidation.d.ts +1 -1
  37. package/dist/http/middleware/EditWorkerValidation.js +7 -6
  38. package/dist/http/middleware/ProcessorPathSanitizer.js +101 -35
  39. package/dist/http/middleware/WorkerValidationChain.js +1 -0
  40. package/dist/index.d.ts +2 -1
  41. package/dist/index.js +1 -0
  42. package/dist/routes/workers.js +48 -6
  43. package/dist/storage/WorkerStore.d.ts +4 -1
  44. package/dist/storage/WorkerStore.js +55 -7
  45. package/dist/telemetry/api/TelemetryAPI.d.ts +46 -0
  46. package/dist/telemetry/api/TelemetryAPI.js +219 -0
  47. package/dist/telemetry/api/TelemetryMonitoringService.d.ts +17 -0
  48. package/dist/telemetry/api/TelemetryMonitoringService.js +113 -0
  49. package/dist/telemetry/components/AlertPanel.d.ts +1 -0
  50. package/dist/telemetry/components/AlertPanel.js +13 -0
  51. package/dist/telemetry/components/CostTracking.d.ts +1 -0
  52. package/dist/telemetry/components/CostTracking.js +14 -0
  53. package/dist/telemetry/components/ResourceUsageChart.d.ts +1 -0
  54. package/dist/telemetry/components/ResourceUsageChart.js +11 -0
  55. package/dist/telemetry/components/WorkerHealthChart.d.ts +1 -0
  56. package/dist/telemetry/components/WorkerHealthChart.js +11 -0
  57. package/dist/telemetry/index.d.ts +15 -0
  58. package/dist/telemetry/index.js +60 -0
  59. package/dist/telemetry/routes/dashboard.d.ts +6 -0
  60. package/dist/telemetry/routes/dashboard.js +608 -0
  61. package/dist/ui/router/EmbeddedAssets.d.ts +4 -0
  62. package/dist/ui/router/EmbeddedAssets.js +13 -0
  63. package/dist/ui/router/ui.js +100 -4
  64. package/package.json +10 -6
  65. package/src/AnomalyDetection.ts +9 -0
  66. package/src/CanaryController.ts +41 -5
  67. package/src/ChaosEngineering.ts +14 -0
  68. package/src/ClusterLock.ts +22 -9
  69. package/src/DeadLetterQueue.ts +13 -8
  70. package/src/MultiQueueWorker.ts +15 -8
  71. package/src/PriorityQueue.ts +21 -22
  72. package/src/ResourceMonitor.ts +72 -40
  73. package/src/WorkerFactory.ts +545 -49
  74. package/src/WorkerInit.ts +8 -3
  75. package/src/WorkerMetrics.ts +183 -105
  76. package/src/WorkerRegistry.ts +80 -1
  77. package/src/WorkerShutdown.ts +115 -9
  78. package/src/WorkerShutdownDurableObject.ts +64 -0
  79. package/src/createQueueWorker.ts +73 -30
  80. package/src/dashboard/types.ts +5 -0
  81. package/src/dashboard/workers-api.ts +165 -52
  82. package/src/http/WorkerApiController.ts +1 -0
  83. package/src/http/WorkerController.ts +167 -90
  84. package/src/http/WorkerMonitoringService.ts +77 -0
  85. package/src/http/middleware/CustomValidation.ts +1 -1
  86. package/src/http/middleware/EditWorkerValidation.ts +7 -6
  87. package/src/http/middleware/ProcessorPathSanitizer.ts +123 -36
  88. package/src/http/middleware/WorkerValidationChain.ts +1 -0
  89. package/src/index.ts +6 -1
  90. package/src/routes/workers.ts +66 -9
  91. package/src/storage/WorkerStore.ts +59 -9
  92. package/src/telemetry/api/TelemetryAPI.ts +292 -0
  93. package/src/telemetry/api/TelemetryMonitoringService.ts +149 -0
  94. package/src/telemetry/components/AlertPanel.ts +13 -0
  95. package/src/telemetry/components/CostTracking.ts +14 -0
  96. package/src/telemetry/components/ResourceUsageChart.ts +11 -0
  97. package/src/telemetry/components/WorkerHealthChart.ts +11 -0
  98. package/src/telemetry/index.ts +121 -0
  99. package/src/telemetry/public/assets/zintrust-logo.svg +15 -0
  100. package/src/telemetry/routes/dashboard.ts +638 -0
  101. package/src/telemetry/styles/tailwind.css +1 -0
  102. package/src/telemetry/styles/zintrust-theme.css +8 -0
  103. package/src/ui/router/EmbeddedAssets.ts +13 -0
  104. package/src/ui/router/ui.ts +112 -5
  105. package/src/ui/workers/index.html +2 -2
  106. package/src/ui/workers/main.js +232 -61
  107. package/src/ui/workers/zintrust.svg +30 -0
  108. package/dist/dashboard/workers-dashboard-ui.d.ts +0 -3
  109. package/dist/dashboard/workers-dashboard-ui.js +0 -1026
  110. package/dist/dashboard/workers-dashboard.d.ts +0 -4
  111. package/dist/dashboard/workers-dashboard.js +0 -904
@@ -5,7 +5,7 @@
5
5
  * Coordinates orderly shutdown of all worker modules and the WorkerFactory.
6
6
  */
7
7
 
8
- import { Logger } from '@zintrust/core';
8
+ import { Cloudflare, Logger } from '@zintrust/core';
9
9
  import { WorkerFactory } from './WorkerFactory';
10
10
 
11
11
  // ============================================================================
@@ -36,6 +36,12 @@ interface IShutdownState {
36
36
  reason: string | null;
37
37
  }
38
38
 
39
+ type DurableShutdownState = {
40
+ shuttingDown: boolean;
41
+ startedAt?: string;
42
+ reason?: string;
43
+ };
44
+
39
45
  // ============================================================================
40
46
  // Implementation
41
47
  // ============================================================================
@@ -47,8 +53,67 @@ const state: IShutdownState = {
47
53
  reason: null,
48
54
  };
49
55
 
56
+ const getDurableShutdownStub = (): {
57
+ fetch: (input: string | URL, init?: RequestInit) => Promise<Response>;
58
+ } | null => {
59
+ const env = Cloudflare.getWorkersEnv();
60
+ if (env === null) return null;
61
+
62
+ const namespace = env['WORKER_SHUTDOWN'] as
63
+ | {
64
+ idFromName?: (name: string) => unknown;
65
+ get?: (id: unknown) => {
66
+ fetch: (input: string | URL, init?: RequestInit) => Promise<Response>;
67
+ };
68
+ }
69
+ | undefined;
70
+
71
+ if (
72
+ !namespace ||
73
+ typeof namespace.idFromName !== 'function' ||
74
+ typeof namespace.get !== 'function'
75
+ ) {
76
+ return null;
77
+ }
78
+
79
+ const id = namespace.idFromName('zintrust-shutdown');
80
+ return namespace.get(id) ?? null;
81
+ };
82
+
83
+ const requestDurableShutdown = async (reason = 'manual'): Promise<boolean> => {
84
+ const stub = getDurableShutdownStub();
85
+ if (!stub) {
86
+ Logger.warn('Worker shutdown Durable Object binding not configured');
87
+ return false;
88
+ }
89
+
90
+ const res = await stub.fetch('https://worker-shutdown/shutdown', {
91
+ method: 'POST',
92
+ headers: { 'content-type': 'application/json' },
93
+ body: JSON.stringify({ reason }),
94
+ });
95
+
96
+ return res.ok;
97
+ };
98
+
99
+ const getDurableShutdownState = async (): Promise<DurableShutdownState | null> => {
100
+ const stub = getDurableShutdownStub();
101
+ if (!stub) return null;
102
+
103
+ const res = await stub.fetch('https://worker-shutdown/status');
104
+ if (!res.ok) return null;
105
+ return (await res.json()) as DurableShutdownState;
106
+ };
107
+
50
108
  let shutdownHandlersRegistered = false;
51
109
 
110
+ const signalHandlers: {
111
+ sigterm?: () => Promise<void>;
112
+ sighup?: () => Promise<void>;
113
+ uncaughtException?: (error: Error) => Promise<void>;
114
+ unhandledRejection?: (reason: unknown) => void;
115
+ } = {};
116
+
52
117
  /**
53
118
  * Perform graceful shutdown of all worker modules
54
119
  */
@@ -115,14 +180,15 @@ function registerShutdownHandlers(): void {
115
180
  Logger.debug('Registering worker management system shutdown handlers');
116
181
 
117
182
  // SIGTERM - graceful shutdown (Docker, systemd, etc.)
118
- process.on('SIGTERM', async () => {
183
+ signalHandlers.sigterm = async (): Promise<void> => {
119
184
  Logger.info('📨 Received SIGTERM signal');
120
185
  try {
121
186
  await shutdown({ signal: 'SIGTERM', timeout: 30000, forceExit: true });
122
187
  } catch (error) {
123
188
  Logger.error('Error during SIGTERM shutdown', error);
124
189
  }
125
- });
190
+ };
191
+ process.on('SIGTERM', signalHandlers.sigterm);
126
192
 
127
193
  // SIGINT - user interrupt (Ctrl+C) - REMOVED: handled by bootstrap.ts to prevent race condition
128
194
  // process.on('SIGINT', async () => {
@@ -135,17 +201,18 @@ function registerShutdownHandlers(): void {
135
201
  // });
136
202
 
137
203
  // SIGHUP - terminal closed
138
- process.on('SIGHUP', async () => {
204
+ signalHandlers.sighup = async (): Promise<void> => {
139
205
  Logger.info('📨 Received SIGHUP signal');
140
206
  try {
141
207
  await shutdown({ signal: 'SIGHUP', timeout: 30000, forceExit: true });
142
208
  } catch (error) {
143
209
  Logger.error('Error during SIGHUP shutdown', error);
144
210
  }
145
- });
211
+ };
212
+ process.on('SIGHUP', signalHandlers.sighup);
146
213
 
147
214
  // Handle uncaught errors during shutdown
148
- process.on('uncaughtException', async (error: Error) => {
215
+ signalHandlers.uncaughtException = async (error: Error): Promise<void> => {
149
216
  Logger.error('💥 Uncaught exception during worker operations', error);
150
217
  try {
151
218
  await shutdown({ signal: 'uncaughtException', timeout: 10000, forceExit: true });
@@ -153,19 +220,43 @@ function registerShutdownHandlers(): void {
153
220
  // Ignore errors during emergency shutdown
154
221
  }
155
222
  process.exit(1);
156
- });
223
+ };
224
+ process.on('uncaughtException', signalHandlers.uncaughtException);
157
225
 
158
- process.on('unhandledRejection', (reason: unknown) => {
226
+ signalHandlers.unhandledRejection = (reason: unknown): void => {
159
227
  // Only log the error - don't shut down the entire application
160
228
  Logger.error('💥 Unhandled promise rejection detected', reason);
161
229
  Logger.warn('⚠️ This error has been logged but will not shut down the server');
162
230
  Logger.warn('⚠️ Check the error context and fix the underlying issue');
163
- });
231
+ };
232
+ process.on('unhandledRejection', signalHandlers.unhandledRejection);
164
233
 
165
234
  shutdownHandlersRegistered = true;
166
235
  Logger.debug('Worker management system shutdown handlers registered');
167
236
  }
168
237
 
238
+ /**
239
+ * Unregister process signal handlers (for hot reload/testing)
240
+ */
241
+ function unregisterShutdownHandlers(): void {
242
+ if (!shutdownHandlersRegistered) return;
243
+
244
+ if (signalHandlers.sigterm) process.off('SIGTERM', signalHandlers.sigterm);
245
+ if (signalHandlers.sighup) process.off('SIGHUP', signalHandlers.sighup);
246
+ if (signalHandlers.uncaughtException)
247
+ process.off('uncaughtException', signalHandlers.uncaughtException);
248
+ if (signalHandlers.unhandledRejection)
249
+ process.off('unhandledRejection', signalHandlers.unhandledRejection);
250
+
251
+ signalHandlers.sigterm = undefined;
252
+ signalHandlers.sighup = undefined;
253
+ signalHandlers.uncaughtException = undefined;
254
+ signalHandlers.unhandledRejection = undefined;
255
+
256
+ shutdownHandlersRegistered = false;
257
+ Logger.debug('Worker management system shutdown handlers unregistered');
258
+ }
259
+
169
260
  /**
170
261
  * Check if system is currently shutting down
171
262
  */
@@ -195,6 +286,11 @@ export const WorkerShutdown = Object.freeze({
195
286
  */
196
287
  registerShutdownHandlers,
197
288
 
289
+ /**
290
+ * Unregister process signal handlers (for hot reload/testing)
291
+ */
292
+ unregisterShutdownHandlers,
293
+
198
294
  /**
199
295
  * Check if system is currently shutting down
200
296
  */
@@ -204,4 +300,14 @@ export const WorkerShutdown = Object.freeze({
204
300
  * Get current shutdown state
205
301
  */
206
302
  getShutdownState,
303
+
304
+ /**
305
+ * Request shutdown via Durable Object (Workers)
306
+ */
307
+ requestDurableShutdown,
308
+
309
+ /**
310
+ * Read shutdown state from Durable Object (Workers)
311
+ */
312
+ getDurableShutdownState,
207
313
  });
@@ -0,0 +1,64 @@
1
+ import { Logger } from '@zintrust/core';
2
+
3
+ type DurableObjectState = {
4
+ storage: {
5
+ get: (key: string) => Promise<unknown>;
6
+ put: (key: string, value: unknown) => Promise<void>;
7
+ };
8
+ };
9
+
10
+ type ShutdownState = {
11
+ shuttingDown: boolean;
12
+ startedAt?: string;
13
+ reason?: string;
14
+ };
15
+
16
+ const loadState = async (state: DurableObjectState): Promise<ShutdownState> => {
17
+ const stored = (await state.storage.get('shutdown')) as ShutdownState | undefined;
18
+ return stored ?? { shuttingDown: false };
19
+ };
20
+
21
+ const saveState = async (state: DurableObjectState, value: ShutdownState): Promise<void> => {
22
+ await state.storage.put('shutdown', value);
23
+ };
24
+
25
+ // eslint-disable-next-line no-restricted-syntax
26
+ export class ZinTrustWorkerShutdownDurableObject {
27
+ private readonly state: DurableObjectState;
28
+
29
+ constructor(state: DurableObjectState) {
30
+ this.state = state;
31
+ }
32
+
33
+ async fetch(request: Request): Promise<Response> {
34
+ const url = new URL(request.url);
35
+ const path = url.pathname;
36
+
37
+ if (request.method === 'GET' && path === '/status') {
38
+ const current = await loadState(this.state);
39
+ return new Response(JSON.stringify(current), {
40
+ status: 200,
41
+ headers: { 'content-type': 'application/json' },
42
+ });
43
+ }
44
+
45
+ if (request.method === 'POST' && path === '/shutdown') {
46
+ const payload = (await request.json().catch(() => ({}))) as { reason?: string };
47
+ const next: ShutdownState = {
48
+ shuttingDown: true,
49
+ startedAt: new Date().toISOString(),
50
+ reason: payload.reason ?? 'manual',
51
+ };
52
+
53
+ await saveState(this.state, next);
54
+ Logger.info('Worker shutdown requested via Durable Object', next);
55
+
56
+ return new Response(JSON.stringify({ ok: true }), {
57
+ status: 202,
58
+ headers: { 'content-type': 'application/json' },
59
+ });
60
+ }
61
+
62
+ return new Response('Not Found', { status: 404 });
63
+ }
64
+ }
@@ -1,4 +1,4 @@
1
- import type { QueueMessage } from '@zintrust/core';
1
+ import type { BullMQPayload, QueueMessage } from '@zintrust/core';
2
2
  import { Logger, Queue } from '@zintrust/core';
3
3
 
4
4
  type QueueWorker = {
@@ -8,11 +8,13 @@ type QueueWorker = {
8
8
  queueName?: string;
9
9
  driverName?: string;
10
10
  maxItems?: number;
11
+ maxDurationMs?: number;
11
12
  }) => Promise<number>;
12
13
  startWorker: (opts?: {
13
14
  queueName?: string;
14
15
  driverName?: string;
15
16
  signal?: AbortSignal;
17
+ maxDurationMs?: number;
16
18
  }) => Promise<number>;
17
19
  };
18
20
 
@@ -54,7 +56,7 @@ const createProcessOne = <TPayload>(
54
56
  dueAt: new Date(timestamp).toISOString(),
55
57
  });
56
58
  // Re-queue original payload
57
- await Queue.enqueue(queueName, message.payload, driverName);
59
+ await Queue.enqueue(queueName, message.payload as BullMQPayload, driverName);
58
60
  await Queue.ack(queueName, message.id, driverName);
59
61
  return false;
60
62
  }
@@ -75,7 +77,7 @@ const createProcessOne = <TPayload>(
75
77
  });
76
78
 
77
79
  if (attempts < options.maxAttempts) {
78
- await Queue.enqueue(queueName, message.payload, driverName);
80
+ await Queue.enqueue(queueName, message.payload as BullMQPayload, driverName);
79
81
  Logger.info(`${options.kindLabel} re-queued for retry`, {
80
82
  ...baseLogFields,
81
83
  attempts: attempts + 1,
@@ -83,7 +85,8 @@ const createProcessOne = <TPayload>(
83
85
  }
84
86
 
85
87
  await Queue.ack(queueName, message.id, driverName);
86
- return false;
88
+ // We processed the message (even if it failed), so return true to continue processing
89
+ return true;
87
90
  }
88
91
  };
89
92
  };
@@ -109,29 +112,49 @@ const createProcessAll = (
109
112
  const createRunOnce = (
110
113
  defaultQueueName: string,
111
114
  processOne: (queueName?: string, driverName?: string) => Promise<boolean>
112
- ): ((opts?: { queueName?: string; driverName?: string; maxItems?: number }) => Promise<number>) => {
115
+ ): ((opts?: {
116
+ queueName?: string;
117
+ driverName?: string;
118
+ maxItems?: number;
119
+ maxDurationMs?: number;
120
+ concurrency?: number;
121
+ }) => Promise<number>) => {
113
122
  return async (opts = {}): Promise<number> => {
114
- const { queueName = defaultQueueName, driverName, maxItems } = opts;
115
- let processed = 0;
116
-
117
- if (maxItems === undefined) {
123
+ const {
124
+ queueName = defaultQueueName,
125
+ driverName,
126
+ maxItems,
127
+ maxDurationMs = 30000,
128
+ concurrency = 1,
129
+ } = opts;
130
+ const startTime = Date.now();
131
+ let totalProcessed = 0;
132
+
133
+ // Helper for single worker loop
134
+ const runWorker = async (): Promise<number> => {
135
+ let workerProcessed = 0;
118
136
  while (true) {
137
+ if (maxDurationMs > 0 && Date.now() - startTime > maxDurationMs) {
138
+ break;
139
+ }
140
+ if (maxItems !== undefined && totalProcessed >= maxItems) {
141
+ break;
142
+ }
143
+
119
144
  // eslint-disable-next-line no-await-in-loop
120
145
  const didProcess = await processOne(queueName, driverName);
121
146
  if (!didProcess) break;
122
- processed++;
147
+
148
+ workerProcessed++;
149
+ totalProcessed++; // Shared counter (approximation in parallel)
123
150
  }
124
- return processed;
125
- }
151
+ return workerProcessed;
152
+ };
126
153
 
127
- for (let i = 0; i < maxItems; i++) {
128
- // eslint-disable-next-line no-await-in-loop
129
- const didProcess = await processOne(queueName, driverName);
130
- if (!didProcess) break;
131
- processed++;
132
- }
154
+ // Run workers in parallel
155
+ await Promise.all(Array.from({ length: Math.max(1, concurrency) }).map(() => runWorker()));
133
156
 
134
- return processed;
157
+ return totalProcessed;
135
158
  };
136
159
  };
137
160
 
@@ -143,22 +166,42 @@ const createStartWorker = (
143
166
  queueName?: string;
144
167
  driverName?: string;
145
168
  signal?: AbortSignal;
169
+ maxDurationMs?: number;
170
+ concurrency?: number;
146
171
  }) => Promise<number>) => {
147
172
  return async (opts = {}): Promise<number> => {
148
- const { queueName = defaultQueueName, driverName, signal } = opts;
173
+ const {
174
+ queueName = defaultQueueName,
175
+ driverName,
176
+ signal,
177
+ maxDurationMs = 300000,
178
+ concurrency = 1,
179
+ } = opts;
180
+
181
+ Logger.info(`Starting ${kindLabel} worker (drain-until-empty)`, { queueName, concurrency });
182
+
183
+ const startTime = Date.now();
184
+ let totalProcessed = 0;
185
+
186
+ const runWorker = async (): Promise<void> => {
187
+ while (signal?.aborted !== true) {
188
+ if (maxDurationMs > 0 && Date.now() - startTime > maxDurationMs) {
189
+ Logger.warn(`${kindLabel} worker timeout reached`, { queueName, totalProcessed });
190
+ break;
191
+ }
149
192
 
150
- Logger.info(`Starting ${kindLabel} worker (drain-until-empty)`, { queueName });
193
+ // eslint-disable-next-line no-await-in-loop
194
+ const didProcess = await processOne(queueName, driverName);
195
+ if (!didProcess) break;
196
+ totalProcessed++;
197
+ }
198
+ };
151
199
 
152
- let processedCount = 0;
153
- while (signal?.aborted !== true) {
154
- // eslint-disable-next-line no-await-in-loop
155
- const didProcess = await processOne(queueName, driverName);
156
- if (!didProcess) break;
157
- processedCount++;
158
- }
200
+ // Run workers in parallel
201
+ await Promise.all(Array.from({ length: Math.max(1, concurrency) }).map(() => runWorker()));
159
202
 
160
- Logger.info(`${kindLabel} worker finished (queue drained)`, { queueName, processedCount });
161
- return processedCount;
203
+ Logger.info(`${kindLabel} worker finished (queue drained)`, { queueName, totalProcessed });
204
+ return totalProcessed;
162
205
  };
163
206
  };
164
207
 
@@ -1,5 +1,7 @@
1
1
  // Worker Configuration Types
2
2
  export interface WorkerConfiguration {
3
+ processorSpec?: string | null;
4
+ activeStatus?: boolean | null;
3
5
  [key: string]: string | number | boolean | null | undefined | object;
4
6
  }
5
7
 
@@ -49,6 +51,7 @@ export interface WorkerData {
49
51
  avgTime: number;
50
52
  memory: number;
51
53
  autoStart: boolean;
54
+ activeStatus?: boolean;
52
55
  details?: {
53
56
  configuration: WorkerConfiguration;
54
57
  health: WorkerHealth;
@@ -95,6 +98,7 @@ export type GetWorkersQuery = {
95
98
  driver?: WorkerDriver;
96
99
  search?: string;
97
100
  includeDetails?: boolean;
101
+ includeInactive?: boolean;
98
102
  };
99
103
 
100
104
  // UI Options Types
@@ -116,6 +120,7 @@ export type RawWorkerData = {
116
120
  processed?: number;
117
121
  version?: string;
118
122
  autoStart?: boolean;
123
+ activeStatus?: boolean;
119
124
  queueName?: string;
120
125
  details?: {
121
126
  configuration: WorkerConfiguration;