@zintrust/workers 0.4.4 → 0.4.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/dist/BroadcastWorker.d.ts +5 -0
- package/dist/NotificationWorker.d.ts +5 -0
- package/dist/WorkerFactory.d.ts +8 -0
- package/dist/WorkerFactory.js +334 -32
- package/dist/WorkerInit.d.ts +17 -0
- package/dist/WorkerInit.js +54 -2
- package/dist/WorkerShutdownDurableObject.d.ts +12 -0
- package/dist/WorkerShutdownDurableObject.js +41 -0
- package/dist/build-manifest.json +557 -0
- package/dist/createQueueWorker.d.ts +5 -0
- package/dist/createQueueWorker.js +26 -10
- package/dist/dashboard/workers-api.js +46 -8
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/register.d.ts +3 -3
- package/dist/register.js +10 -4
- package/dist/ui/workers/index.html +202 -0
- package/dist/ui/workers/main.js +1952 -0
- package/dist/ui/workers/styles.css +1350 -0
- package/dist/ui/workers/zintrust.svg +30 -0
- package/package.json +11 -4
- package/src/WorkerFactory.ts +483 -36
- package/src/WorkerInit.ts +81 -3
- package/src/createQueueWorker.ts +44 -14
- package/src/dashboard/workers-api.ts +60 -13
- package/src/index.ts +9 -3
- package/src/register.ts +13 -8
package/src/WorkerInit.ts
CHANGED
|
@@ -148,7 +148,7 @@ type PersistenceOverride = WorkerPersistenceConfig;
|
|
|
148
148
|
|
|
149
149
|
type AutoStartTask = AutoStartCandidate & {
|
|
150
150
|
persistenceOverride: PersistenceOverride;
|
|
151
|
-
source: 'database' | 'redis' | 'memory';
|
|
151
|
+
source: 'database' | 'redis' | 'memory' | 'file';
|
|
152
152
|
};
|
|
153
153
|
|
|
154
154
|
const resolveAutoStartCandidates = (records: AutoStartCandidate[]): AutoStartCandidate[] => {
|
|
@@ -229,6 +229,79 @@ const collectAutoStartTasks = async (): Promise<AutoStartTask[]> => {
|
|
|
229
229
|
return tasks;
|
|
230
230
|
};
|
|
231
231
|
|
|
232
|
+
export const buildFileBackedAutoStartTasks = (
|
|
233
|
+
records: AutoStartCandidate[],
|
|
234
|
+
warn: (message: string) => void = Logger.warn
|
|
235
|
+
): AutoStartTask[] => {
|
|
236
|
+
const tasks: AutoStartTask[] = [];
|
|
237
|
+
const seenWorkerNames = new Set<string>();
|
|
238
|
+
const candidates = resolveAutoStartCandidates(records);
|
|
239
|
+
|
|
240
|
+
for (const record of candidates) {
|
|
241
|
+
if (seenWorkerNames.has(record.name)) {
|
|
242
|
+
warn(
|
|
243
|
+
`Worker ${record.name} appears multiple times in file-backed discovery; keeping the first definition and skipping duplicates.`
|
|
244
|
+
);
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
seenWorkerNames.add(record.name);
|
|
249
|
+
tasks.push({
|
|
250
|
+
...record,
|
|
251
|
+
persistenceOverride: { driver: 'memory' },
|
|
252
|
+
source: 'file',
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return tasks;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export const selectAutoStartTasks = (
|
|
260
|
+
persistedTasks: AutoStartTask[],
|
|
261
|
+
fileRecords: AutoStartCandidate[],
|
|
262
|
+
warn: (message: string) => void = Logger.warn
|
|
263
|
+
): AutoStartTask[] => {
|
|
264
|
+
if (persistedTasks.length > 0) {
|
|
265
|
+
return persistedTasks;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return buildFileBackedAutoStartTasks(fileRecords, warn);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
export const selectAutoStartNames = (
|
|
272
|
+
persistedRecords: AutoStartCandidate[],
|
|
273
|
+
fileRecords: AutoStartCandidate[],
|
|
274
|
+
warn: (message: string) => void = Logger.warn
|
|
275
|
+
): { names: string[]; source: 'persisted' | 'file' | 'none' } => {
|
|
276
|
+
const persistedNames = resolveAutoStartCandidates(persistedRecords).map((record) => record.name);
|
|
277
|
+
|
|
278
|
+
if (persistedNames.length > 0) {
|
|
279
|
+
return { names: persistedNames, source: 'persisted' };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const fileNames = buildFileBackedAutoStartTasks(fileRecords, warn).map((record) => record.name);
|
|
283
|
+
return { names: fileNames, source: fileNames.length > 0 ? 'file' : 'none' };
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const collectFileBackedAutoStartTasks = async (): Promise<AutoStartTask[]> => {
|
|
287
|
+
try {
|
|
288
|
+
const records = await WorkerFactory.listFileBackedRecords();
|
|
289
|
+
const tasks = buildFileBackedAutoStartTasks(records);
|
|
290
|
+
|
|
291
|
+
Logger.debug('File-backed auto-start discovery', {
|
|
292
|
+
totalRecords: records.length,
|
|
293
|
+
candidateCount: tasks.length,
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
return tasks;
|
|
297
|
+
} catch (error) {
|
|
298
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
299
|
+
Logger.warn(`File-backed auto-start discovery failed: ${message}`);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return [];
|
|
303
|
+
};
|
|
304
|
+
|
|
232
305
|
const isWorkerTrulyRunning = async (name: string): Promise<boolean> => {
|
|
233
306
|
const existing = WorkerFactory.get(name);
|
|
234
307
|
if (!existing) return false;
|
|
@@ -357,16 +430,21 @@ async function autoStartPersistedWorkers(): Promise<void> {
|
|
|
357
430
|
}
|
|
358
431
|
|
|
359
432
|
try {
|
|
360
|
-
|
|
433
|
+
let candidates = await collectAutoStartTasks();
|
|
434
|
+
|
|
435
|
+
if (candidates.length === 0) {
|
|
436
|
+
candidates = await collectFileBackedAutoStartTasks();
|
|
437
|
+
}
|
|
361
438
|
|
|
362
439
|
const results = await Promise.all(candidates.map(async (record) => autoStartOneWorker(record)));
|
|
363
440
|
|
|
364
441
|
const startedCount = results.filter((item) => item.started).length;
|
|
365
442
|
const skippedCount = results.filter((item) => item.skipped).length;
|
|
366
|
-
Logger.info('Auto-started
|
|
443
|
+
Logger.info('Auto-started workers', {
|
|
367
444
|
total: candidates.length,
|
|
368
445
|
started: startedCount,
|
|
369
446
|
skipped: skippedCount,
|
|
447
|
+
source: candidates[0]?.source ?? 'none',
|
|
370
448
|
});
|
|
371
449
|
} catch (error) {
|
|
372
450
|
const message = error instanceof Error ? error.message : String(error);
|
package/src/createQueueWorker.ts
CHANGED
|
@@ -2,6 +2,17 @@ import type { BullMQPayload, QueueMessage } from '@zintrust/core';
|
|
|
2
2
|
import * as Core from '@zintrust/core';
|
|
3
3
|
import { Env, Logger, Queue } from '@zintrust/core';
|
|
4
4
|
|
|
5
|
+
type QueueApi = Readonly<{
|
|
6
|
+
enqueue: (queue: string, payload: BullMQPayload, driverName?: string) => Promise<string>;
|
|
7
|
+
dequeue: <TPayload>(
|
|
8
|
+
queue: string,
|
|
9
|
+
driverName?: string
|
|
10
|
+
) => Promise<QueueMessage<TPayload> | undefined>;
|
|
11
|
+
ack: (queue: string, id: string, driverName?: string) => Promise<void>;
|
|
12
|
+
}>;
|
|
13
|
+
|
|
14
|
+
const TypedQueue = Queue as QueueApi;
|
|
15
|
+
|
|
5
16
|
const RETRY_BASE_DELAY_MS = 1000;
|
|
6
17
|
const RETRY_MAX_DELAY_MS = 30000;
|
|
7
18
|
|
|
@@ -97,9 +108,7 @@ const getAttemptsFromMessage = <TPayload>(message: QueueMessage<TPayload>): numb
|
|
|
97
108
|
typeof message.payload === 'object' && message.payload !== null
|
|
98
109
|
? normalizeAttempts((message.payload as Record<string, unknown>)['attempts'])
|
|
99
110
|
: 0;
|
|
100
|
-
const messageAttempts = normalizeAttempts(
|
|
101
|
-
(message as QueueMessage<TPayload> & { attempts?: number }).attempts
|
|
102
|
-
);
|
|
111
|
+
const messageAttempts = normalizeAttempts(message.attempts);
|
|
103
112
|
return Math.max(payloadAttempts, messageAttempts);
|
|
104
113
|
};
|
|
105
114
|
|
|
@@ -127,6 +136,11 @@ type QueueWorker = {
|
|
|
127
136
|
signal?: AbortSignal;
|
|
128
137
|
maxDurationMs?: number;
|
|
129
138
|
}) => Promise<number>;
|
|
139
|
+
__zintrustQueueWorkerMeta?: Readonly<{
|
|
140
|
+
kindLabel: string;
|
|
141
|
+
defaultQueueName: string;
|
|
142
|
+
maxAttempts: number;
|
|
143
|
+
}>;
|
|
130
144
|
};
|
|
131
145
|
|
|
132
146
|
export type CreateQueueWorkerOptions<TPayload> = {
|
|
@@ -147,6 +161,14 @@ const buildBaseLogFields = <TPayload>(
|
|
|
147
161
|
};
|
|
148
162
|
};
|
|
149
163
|
|
|
164
|
+
const toBullMQPayload = <TPayload>(payload: TPayload): BullMQPayload => {
|
|
165
|
+
if (typeof payload === 'object' && payload !== null) {
|
|
166
|
+
return { ...(payload as Record<string, unknown>) };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return { payload };
|
|
170
|
+
};
|
|
171
|
+
|
|
150
172
|
type TrackerApi = {
|
|
151
173
|
started?: (input: {
|
|
152
174
|
queueName: string;
|
|
@@ -258,8 +280,8 @@ const checkAndRequeueIfNotDue = async <TPayload>(
|
|
|
258
280
|
...baseLogFields,
|
|
259
281
|
dueAt: new Date(timestamp).toISOString(),
|
|
260
282
|
});
|
|
261
|
-
await
|
|
262
|
-
await
|
|
283
|
+
await TypedQueue.enqueue(queueName, toBullMQPayload(message.payload), driverName);
|
|
284
|
+
await TypedQueue.ack(queueName, message.id, driverName);
|
|
263
285
|
return true;
|
|
264
286
|
};
|
|
265
287
|
|
|
@@ -272,7 +294,7 @@ const onProcessSuccess = async <TPayload>(input: {
|
|
|
272
294
|
startedAtMs: number;
|
|
273
295
|
baseLogFields: Record<string, unknown>;
|
|
274
296
|
}): Promise<boolean> => {
|
|
275
|
-
await
|
|
297
|
+
await TypedQueue.ack(input.queueName, input.message.id, input.driverName);
|
|
276
298
|
|
|
277
299
|
if (typeof input.trackerApi.completed === 'function') {
|
|
278
300
|
await input.trackerApi.completed({
|
|
@@ -319,10 +341,7 @@ const onProcessFailure = async <TPayload>(input: {
|
|
|
319
341
|
if (nextAttempts < input.options.maxAttempts) {
|
|
320
342
|
const retryDelayMs = getRetryDelayMs(nextAttempts);
|
|
321
343
|
retryAt = new Date(Date.now() + retryDelayMs).toISOString();
|
|
322
|
-
const currentPayload =
|
|
323
|
-
typeof input.message.payload === 'object' && input.message.payload !== null
|
|
324
|
-
? (input.message.payload as Record<string, unknown>)
|
|
325
|
-
: ({ payload: input.message.payload } as Record<string, unknown>);
|
|
344
|
+
const currentPayload = toBullMQPayload(input.message.payload);
|
|
326
345
|
|
|
327
346
|
const payloadForRetry: BullMQPayload = {
|
|
328
347
|
...currentPayload,
|
|
@@ -330,7 +349,7 @@ const onProcessFailure = async <TPayload>(input: {
|
|
|
330
349
|
timestamp: Date.now() + retryDelayMs,
|
|
331
350
|
};
|
|
332
351
|
|
|
333
|
-
await
|
|
352
|
+
await TypedQueue.enqueue(input.queueName, payloadForRetry, input.driverName);
|
|
334
353
|
Logger.info(`${input.options.kindLabel} re-queued for retry`, {
|
|
335
354
|
...input.baseLogFields,
|
|
336
355
|
attempts: nextAttempts,
|
|
@@ -338,7 +357,7 @@ const onProcessFailure = async <TPayload>(input: {
|
|
|
338
357
|
});
|
|
339
358
|
}
|
|
340
359
|
|
|
341
|
-
await
|
|
360
|
+
await TypedQueue.ack(input.queueName, input.message.id, input.driverName);
|
|
342
361
|
await removeHeartbeatIfSupported(input.queueName, input.message.id);
|
|
343
362
|
|
|
344
363
|
if (typeof input.trackerApi.failed === 'function') {
|
|
@@ -404,7 +423,7 @@ const processQueueMessage = async <TPayload>(
|
|
|
404
423
|
queueName: string,
|
|
405
424
|
driverName?: string
|
|
406
425
|
): Promise<boolean> => {
|
|
407
|
-
const message = await
|
|
426
|
+
const message = await TypedQueue.dequeue<TPayload>(queueName, driverName);
|
|
408
427
|
if (!message) return false;
|
|
409
428
|
|
|
410
429
|
const baseLogFields = buildBaseLogFields(message, options.getLogFields);
|
|
@@ -597,6 +616,17 @@ export function createQueueWorker<TPayload>(
|
|
|
597
616
|
const processAll = createProcessAll(options.defaultQueueName, processOne);
|
|
598
617
|
const runOnce = createRunOnce(options.defaultQueueName, processOne);
|
|
599
618
|
const startWorker = createStartWorker(options.kindLabel, options.defaultQueueName, processOne);
|
|
619
|
+
const queueWorkerMeta = Object.freeze({
|
|
620
|
+
kindLabel: options.kindLabel,
|
|
621
|
+
defaultQueueName: options.defaultQueueName,
|
|
622
|
+
maxAttempts: options.maxAttempts,
|
|
623
|
+
});
|
|
600
624
|
|
|
601
|
-
return Object.freeze({
|
|
625
|
+
return Object.freeze({
|
|
626
|
+
processOne,
|
|
627
|
+
processAll,
|
|
628
|
+
runOnce,
|
|
629
|
+
startWorker,
|
|
630
|
+
__zintrustQueueWorkerMeta: queueWorkerMeta,
|
|
631
|
+
});
|
|
602
632
|
}
|
|
@@ -278,6 +278,10 @@ async function getWorkersFromMixedPersistence(
|
|
|
278
278
|
...transformToWorkerData(redisRecords, 'redis'),
|
|
279
279
|
];
|
|
280
280
|
|
|
281
|
+
if (workers.length === 0) {
|
|
282
|
+
return getWorkersFromFileFallback(limit, query.includeInactive === true);
|
|
283
|
+
}
|
|
284
|
+
|
|
281
285
|
return {
|
|
282
286
|
workers,
|
|
283
287
|
total:
|
|
@@ -312,6 +316,11 @@ async function getWorkersFromSinglePersistence(
|
|
|
312
316
|
{ driver: normalizedDriver },
|
|
313
317
|
{ offset, limit, includeInactive: query.includeInactive }
|
|
314
318
|
);
|
|
319
|
+
|
|
320
|
+
if (driverRecords.length === 0) {
|
|
321
|
+
return getWorkersFromFileFallback(limit, query.includeInactive === true);
|
|
322
|
+
}
|
|
323
|
+
|
|
315
324
|
const workers = transformToWorkerData(driverRecords, normalizedDriver);
|
|
316
325
|
|
|
317
326
|
return {
|
|
@@ -333,6 +342,35 @@ async function getWorkersFromSinglePersistence(
|
|
|
333
342
|
}
|
|
334
343
|
}
|
|
335
344
|
|
|
345
|
+
async function getWorkersFromFileFallback(
|
|
346
|
+
limit: number,
|
|
347
|
+
includeInactive: boolean
|
|
348
|
+
): Promise<PersistenceResult> {
|
|
349
|
+
try {
|
|
350
|
+
const discovered = await WorkerFactory.listFileBackedRecords();
|
|
351
|
+
const filtered = includeInactive
|
|
352
|
+
? discovered
|
|
353
|
+
: discovered.filter((record) => record.activeStatus !== false);
|
|
354
|
+
|
|
355
|
+
return {
|
|
356
|
+
workers: transformToWorkerData(filtered, 'memory'),
|
|
357
|
+
total: filtered.length,
|
|
358
|
+
drivers: getAvailableDriversFromDrivers(['memory']),
|
|
359
|
+
effectiveLimit: limit,
|
|
360
|
+
prePaginated: false,
|
|
361
|
+
};
|
|
362
|
+
} catch (error) {
|
|
363
|
+
Logger.debug('File-backed worker fallback failed', error);
|
|
364
|
+
return {
|
|
365
|
+
workers: [],
|
|
366
|
+
total: 0,
|
|
367
|
+
drivers: getAvailableDriversFromDrivers(['memory']),
|
|
368
|
+
effectiveLimit: limit,
|
|
369
|
+
prePaginated: false,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
336
374
|
const normalizeDriver = (driver: string): WorkerDriver => {
|
|
337
375
|
if (driver === 'db' || driver === 'database') return 'database';
|
|
338
376
|
if (driver === 'redis') return 'redis';
|
|
@@ -527,17 +565,17 @@ async function getQueueData(): Promise<QueueData> {
|
|
|
527
565
|
// Get queue statistics based on QUEUE_DRIVER
|
|
528
566
|
switch (queueDriver) {
|
|
529
567
|
case 'redis':
|
|
530
|
-
return getRedisQueueData();
|
|
568
|
+
return await getRedisQueueData();
|
|
531
569
|
case 'database':
|
|
532
|
-
return getDatabaseQueueData();
|
|
570
|
+
return await getDatabaseQueueData();
|
|
533
571
|
case 'db':
|
|
534
|
-
return getDatabaseQueueData();
|
|
572
|
+
return await getDatabaseQueueData();
|
|
535
573
|
default:
|
|
536
|
-
return getMemoryQueueData();
|
|
574
|
+
return await getMemoryQueueData();
|
|
537
575
|
}
|
|
538
576
|
} catch (error) {
|
|
539
577
|
Logger.error('Error fetching queue data:', error);
|
|
540
|
-
return getMemoryQueueData();
|
|
578
|
+
return await getMemoryQueueData();
|
|
541
579
|
}
|
|
542
580
|
}
|
|
543
581
|
|
|
@@ -603,7 +641,12 @@ async function getDatabaseQueueData(): Promise<QueueData> {
|
|
|
603
641
|
const db = await useEnsureDbConnected();
|
|
604
642
|
|
|
605
643
|
// Get queue statistics from actual database tables using proper query builder
|
|
606
|
-
const queueStats
|
|
644
|
+
const queueStats: {
|
|
645
|
+
totalQueues: number;
|
|
646
|
+
totalJobs: number;
|
|
647
|
+
processingJobs: number;
|
|
648
|
+
failedJobs: number;
|
|
649
|
+
} | null = await db
|
|
607
650
|
.table('queue_jobs')
|
|
608
651
|
.select('COUNT(DISTINCT queue) as totalQueues')
|
|
609
652
|
.selectAs('COUNT(*)', 'totalJobs')
|
|
@@ -612,12 +655,7 @@ async function getDatabaseQueueData(): Promise<QueueData> {
|
|
|
612
655
|
'processingJobs'
|
|
613
656
|
)
|
|
614
657
|
.selectAs('SUM(CASE WHEN failed_at IS NOT NULL THEN 1 ELSE 0 END)', 'failedJobs')
|
|
615
|
-
.first()
|
|
616
|
-
totalQueues: number;
|
|
617
|
-
totalJobs: number;
|
|
618
|
-
processingJobs: number;
|
|
619
|
-
failedJobs: number;
|
|
620
|
-
} | null;
|
|
658
|
+
.first();
|
|
621
659
|
|
|
622
660
|
const stats = queueStats || {
|
|
623
661
|
totalQueues: 0,
|
|
@@ -733,7 +771,9 @@ async function enrichWithDetails(workers: WorkerData[]): Promise<WorkerData[]> {
|
|
|
733
771
|
async function buildWorkerDetails(worker: WorkerData): Promise<WorkerData> {
|
|
734
772
|
try {
|
|
735
773
|
const persistenceOverride = resolvePersistenceOverride(worker.driver);
|
|
736
|
-
const persisted =
|
|
774
|
+
const persisted =
|
|
775
|
+
(await WorkerFactory.getPersisted(worker.name, persistenceOverride)) ??
|
|
776
|
+
(await WorkerFactory.getFileBackedRecord(worker.name));
|
|
737
777
|
const health = await getWorkerHealthSnapshot(worker.name, worker.health);
|
|
738
778
|
const metrics = await getWorkerMetricsSnapshot(worker.name, worker);
|
|
739
779
|
const configuration = buildWorkerConfiguration(worker, persisted);
|
|
@@ -896,6 +936,13 @@ export async function getWorkerDetails(name: string, driver?: string): Promise<W
|
|
|
896
936
|
}
|
|
897
937
|
}
|
|
898
938
|
|
|
939
|
+
if (!worker) {
|
|
940
|
+
const fileBacked = await WorkerFactory.getFileBackedRecord(name);
|
|
941
|
+
if (fileBacked) {
|
|
942
|
+
worker = buildWorkerFromRecord(fileBacked, 'memory');
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
899
946
|
if (!worker) {
|
|
900
947
|
throw ErrorFactory.createWorkerError(`Worker ${name} not found`);
|
|
901
948
|
}
|
package/src/index.ts
CHANGED
|
@@ -44,7 +44,12 @@ export type {
|
|
|
44
44
|
WorkerFactoryConfig,
|
|
45
45
|
WorkerPersistenceConfig,
|
|
46
46
|
} from './WorkerFactory';
|
|
47
|
-
export {
|
|
47
|
+
export {
|
|
48
|
+
buildFileBackedAutoStartTasks,
|
|
49
|
+
selectAutoStartNames,
|
|
50
|
+
selectAutoStartTasks,
|
|
51
|
+
WorkerInit,
|
|
52
|
+
} from './WorkerInit';
|
|
48
53
|
export { WorkerShutdown } from './WorkerShutdown';
|
|
49
54
|
|
|
50
55
|
// HTTP Controllers & Routes
|
|
@@ -66,10 +71,10 @@ export type {
|
|
|
66
71
|
WorkerConfig,
|
|
67
72
|
WorkerCostConfig,
|
|
68
73
|
WorkerObservabilityConfig,
|
|
69
|
-
WorkerStatus,
|
|
70
|
-
WorkerVersioningConfig,
|
|
71
74
|
WorkersConfigOverrides,
|
|
72
75
|
WorkersGlobalConfig,
|
|
76
|
+
WorkerStatus,
|
|
77
|
+
WorkerVersioningConfig,
|
|
73
78
|
} from '@zintrust/core';
|
|
74
79
|
|
|
75
80
|
// Re-export bullmq types for type compatibility
|
|
@@ -92,6 +97,7 @@ export type {
|
|
|
92
97
|
} from './ChaosEngineering';
|
|
93
98
|
export type { ISLAConfig, ISLAReport, ISLAStatus, ISLAViolation, ITimeRange } from './SLAMonitor';
|
|
94
99
|
|
|
100
|
+
export type * from './config/workerConfig';
|
|
95
101
|
export type * from './type';
|
|
96
102
|
|
|
97
103
|
/**
|
package/src/register.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
type Registry = {
|
|
2
|
+
register: (id: string, provider: CliCommandProvider) => void;
|
|
3
|
+
};
|
|
4
|
+
|
|
1
5
|
type CliCommandProvider = {
|
|
2
6
|
getCommand: () => unknown;
|
|
3
7
|
name?: string;
|
|
4
8
|
};
|
|
5
9
|
|
|
6
|
-
type Registry = {
|
|
7
|
-
register: (id: string, provider: CliCommandProvider) => void;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
10
|
type WorkerCommandsModule = {
|
|
11
11
|
WorkerCommands: {
|
|
12
12
|
createWorkerListCommand: () => CliCommandProvider;
|
|
@@ -20,7 +20,12 @@ type WorkerCommandsModule = {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
const commandModule = (await (async (): Promise<WorkerCommandsModule> => {
|
|
23
|
-
|
|
23
|
+
const workerCommandsSpecifier = '@zintrust/core/worker-commands';
|
|
24
|
+
try {
|
|
25
|
+
return (await import(workerCommandsSpecifier)) as unknown as WorkerCommandsModule;
|
|
26
|
+
} catch {
|
|
27
|
+
return (await import('@zintrust/core/cli')) as unknown as WorkerCommandsModule;
|
|
28
|
+
}
|
|
24
29
|
})()) satisfies WorkerCommandsModule;
|
|
25
30
|
|
|
26
31
|
const getWorkerProviders = (): Array<[string, CliCommandProvider]> => {
|
|
@@ -59,12 +64,12 @@ registerWorkerCliCommands({
|
|
|
59
64
|
});
|
|
60
65
|
|
|
61
66
|
try {
|
|
62
|
-
const
|
|
67
|
+
const coreCli = (await import('@zintrust/core/cli')) as unknown as {
|
|
63
68
|
OptionalCliCommandRegistry?: Registry;
|
|
64
69
|
};
|
|
65
70
|
|
|
66
|
-
if (
|
|
67
|
-
registerWorkerCliCommands(
|
|
71
|
+
if (coreCli.OptionalCliCommandRegistry !== undefined) {
|
|
72
|
+
registerWorkerCliCommands(coreCli.OptionalCliCommandRegistry);
|
|
68
73
|
}
|
|
69
74
|
} catch {
|
|
70
75
|
// no-op
|