@trigger.dev/redis-worker 4.0.0-v4-beta.21 → 4.0.0-v4-beta.23
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/dist/index.cjs +230 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -4
- package/dist/index.d.ts +29 -4
- package/dist/index.js +230 -31
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
package/dist/index.cjs
CHANGED
|
@@ -8,6 +8,8 @@ var crypto = require('crypto');
|
|
|
8
8
|
require('@trigger.dev/core/v3/utils/flattenAttributes');
|
|
9
9
|
var v3 = require('@trigger.dev/core/v3');
|
|
10
10
|
var serverOnly = require('@trigger.dev/core/v3/serverOnly');
|
|
11
|
+
var zod = require('zod');
|
|
12
|
+
var cronParser = require('cron-parser');
|
|
11
13
|
|
|
12
14
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
15
|
|
|
@@ -8742,7 +8744,7 @@ var require_Redis = __commonJS({
|
|
|
8742
8744
|
var lodash_1 = require_lodash3();
|
|
8743
8745
|
var Deque = require_denque();
|
|
8744
8746
|
var debug = (0, utils_1.Debug)("redis");
|
|
8745
|
-
var
|
|
8747
|
+
var Redis4 = class _Redis extends Commander_1.default {
|
|
8746
8748
|
constructor(arg1, arg2, arg3) {
|
|
8747
8749
|
super();
|
|
8748
8750
|
this.status = "wait";
|
|
@@ -9305,12 +9307,12 @@ var require_Redis = __commonJS({
|
|
|
9305
9307
|
}).catch(lodash_1.noop);
|
|
9306
9308
|
}
|
|
9307
9309
|
};
|
|
9308
|
-
|
|
9309
|
-
|
|
9310
|
-
|
|
9311
|
-
(0, applyMixin_1.default)(
|
|
9312
|
-
(0, transaction_1.addTransactionSupport)(
|
|
9313
|
-
exports.default =
|
|
9310
|
+
Redis4.Cluster = cluster_1.default;
|
|
9311
|
+
Redis4.Command = Command_1.default;
|
|
9312
|
+
Redis4.defaultOptions = RedisOptions_1.DEFAULT_REDIS_OPTIONS;
|
|
9313
|
+
(0, applyMixin_1.default)(Redis4, events_1.EventEmitter);
|
|
9314
|
+
(0, transaction_1.addTransactionSupport)(Redis4.prototype);
|
|
9315
|
+
exports.default = Redis4;
|
|
9314
9316
|
}
|
|
9315
9317
|
});
|
|
9316
9318
|
|
|
@@ -9563,7 +9565,8 @@ var SimpleQueue = class {
|
|
|
9563
9565
|
id,
|
|
9564
9566
|
item: parsedItem,
|
|
9565
9567
|
job: parsedItem.job,
|
|
9566
|
-
timestamp
|
|
9568
|
+
timestamp,
|
|
9569
|
+
availableJobs: Object.keys(this.schema)
|
|
9567
9570
|
});
|
|
9568
9571
|
continue;
|
|
9569
9572
|
}
|
|
@@ -9644,8 +9647,30 @@ var SimpleQueue = class {
|
|
|
9644
9647
|
throw e;
|
|
9645
9648
|
}
|
|
9646
9649
|
}
|
|
9650
|
+
async getJob(id) {
|
|
9651
|
+
const result = await this.redis.getJob(`queue`, `items`, id);
|
|
9652
|
+
if (!result) {
|
|
9653
|
+
return null;
|
|
9654
|
+
}
|
|
9655
|
+
const [_, score, serializedItem] = result;
|
|
9656
|
+
const item = JSON.parse(serializedItem);
|
|
9657
|
+
return {
|
|
9658
|
+
id,
|
|
9659
|
+
job: item.job,
|
|
9660
|
+
item: item.item,
|
|
9661
|
+
visibilityTimeoutMs: item.visibilityTimeoutMs,
|
|
9662
|
+
attempt: item.attempt ?? 0,
|
|
9663
|
+
timestamp: new Date(Number(score)),
|
|
9664
|
+
deduplicationKey: item.deduplicationKey ?? void 0
|
|
9665
|
+
};
|
|
9666
|
+
}
|
|
9647
9667
|
async moveToDeadLetterQueue(id, errorMessage) {
|
|
9648
9668
|
try {
|
|
9669
|
+
this.logger.debug(`SimpleQueue ${this.name}.moveToDeadLetterQueue(): moving item to DLQ`, {
|
|
9670
|
+
queue: this.name,
|
|
9671
|
+
id,
|
|
9672
|
+
errorMessage
|
|
9673
|
+
});
|
|
9649
9674
|
const result = await this.redis.moveToDeadLetterQueue(
|
|
9650
9675
|
`queue`,
|
|
9651
9676
|
`items`,
|
|
@@ -9766,6 +9791,25 @@ var SimpleQueue = class {
|
|
|
9766
9791
|
return dequeued
|
|
9767
9792
|
`
|
|
9768
9793
|
});
|
|
9794
|
+
this.redis.defineCommand("getJob", {
|
|
9795
|
+
numberOfKeys: 2,
|
|
9796
|
+
lua: `
|
|
9797
|
+
local queue = KEYS[1]
|
|
9798
|
+
local items = KEYS[2]
|
|
9799
|
+
local jobId = ARGV[1]
|
|
9800
|
+
|
|
9801
|
+
local serializedItem = redis.call('HGET', items, jobId)
|
|
9802
|
+
|
|
9803
|
+
if serializedItem == false then
|
|
9804
|
+
return nil
|
|
9805
|
+
end
|
|
9806
|
+
|
|
9807
|
+
-- get the score from the queue sorted set
|
|
9808
|
+
local score = redis.call('ZSCORE', queue, jobId)
|
|
9809
|
+
|
|
9810
|
+
return { jobId, score, serializedItem }
|
|
9811
|
+
`
|
|
9812
|
+
});
|
|
9769
9813
|
this.redis.defineCommand("ackItem", {
|
|
9770
9814
|
numberOfKeys: 2,
|
|
9771
9815
|
lua: `
|
|
@@ -11007,6 +11051,11 @@ function validateConcurrency(concurrency) {
|
|
|
11007
11051
|
throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
11008
11052
|
}
|
|
11009
11053
|
}
|
|
11054
|
+
var CronSchema = zod.z.object({
|
|
11055
|
+
cron: zod.z.string(),
|
|
11056
|
+
lastTimestamp: zod.z.number().optional(),
|
|
11057
|
+
timestamp: zod.z.number()
|
|
11058
|
+
});
|
|
11010
11059
|
var defaultRetrySettings = {
|
|
11011
11060
|
maxAttempts: 12,
|
|
11012
11061
|
factor: 2,
|
|
@@ -11035,7 +11084,6 @@ var Worker = class _Worker {
|
|
|
11035
11084
|
this.jobs = options.jobs;
|
|
11036
11085
|
const { workers = 1, tasksPerWorker = 1, limit = 10 } = options.concurrency ?? {};
|
|
11037
11086
|
this.concurrency = { workers, tasksPerWorker, limit };
|
|
11038
|
-
this.limiter = pLimit(this.concurrency.limit);
|
|
11039
11087
|
const masterQueueObservableGauge = this.meter.createObservableGauge("redis_worker.queue.size", {
|
|
11040
11088
|
description: "The number of items in the queue",
|
|
11041
11089
|
unit: "items",
|
|
@@ -11086,7 +11134,7 @@ var Worker = class _Worker {
|
|
|
11086
11134
|
concurrency;
|
|
11087
11135
|
shutdownTimeoutMs;
|
|
11088
11136
|
// The p-limit limiter to control overall concurrency.
|
|
11089
|
-
|
|
11137
|
+
limiters = {};
|
|
11090
11138
|
async #updateQueueSizeMetric(observableResult) {
|
|
11091
11139
|
const queueSize = await this.queue.size();
|
|
11092
11140
|
observableResult.observe(queueSize, {
|
|
@@ -11100,19 +11148,30 @@ var Worker = class _Worker {
|
|
|
11100
11148
|
});
|
|
11101
11149
|
}
|
|
11102
11150
|
async #updateConcurrencyLimitActiveMetric(observableResult) {
|
|
11103
|
-
|
|
11104
|
-
|
|
11105
|
-
|
|
11151
|
+
for (const [workerId, limiter] of Object.entries(this.limiters)) {
|
|
11152
|
+
observableResult.observe(limiter.activeCount, {
|
|
11153
|
+
worker_name: this.options.name,
|
|
11154
|
+
worker_id: workerId
|
|
11155
|
+
});
|
|
11156
|
+
}
|
|
11106
11157
|
}
|
|
11107
11158
|
async #updateConcurrencyLimitPendingMetric(observableResult) {
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11159
|
+
for (const [workerId, limiter] of Object.entries(this.limiters)) {
|
|
11160
|
+
observableResult.observe(limiter.pendingCount, {
|
|
11161
|
+
worker_name: this.options.name,
|
|
11162
|
+
worker_id: workerId
|
|
11163
|
+
});
|
|
11164
|
+
}
|
|
11111
11165
|
}
|
|
11112
11166
|
start() {
|
|
11113
11167
|
const { workers, tasksPerWorker } = this.concurrency;
|
|
11168
|
+
this.logger.info("Starting worker", {
|
|
11169
|
+
workers,
|
|
11170
|
+
tasksPerWorker,
|
|
11171
|
+
concurrency: this.concurrency
|
|
11172
|
+
});
|
|
11114
11173
|
for (let i = 0; i < workers; i++) {
|
|
11115
|
-
this.workerLoops.push(this.runWorkerLoop(`worker-${nanoid(12)}`, tasksPerWorker));
|
|
11174
|
+
this.workerLoops.push(this.runWorkerLoop(`worker-${nanoid(12)}`, tasksPerWorker, i, workers));
|
|
11116
11175
|
}
|
|
11117
11176
|
this.setupShutdownHandlers();
|
|
11118
11177
|
this.subscriber = createRedisClient(this.options.redisOptions, {
|
|
@@ -11124,6 +11183,7 @@ var Worker = class _Worker {
|
|
|
11124
11183
|
}
|
|
11125
11184
|
});
|
|
11126
11185
|
this.setupSubscriber();
|
|
11186
|
+
this.setupCron();
|
|
11127
11187
|
return this;
|
|
11128
11188
|
}
|
|
11129
11189
|
/**
|
|
@@ -11262,37 +11322,78 @@ var Worker = class _Worker {
|
|
|
11262
11322
|
}
|
|
11263
11323
|
);
|
|
11264
11324
|
}
|
|
11325
|
+
async getJob(id) {
|
|
11326
|
+
return this.queue.getJob(id);
|
|
11327
|
+
}
|
|
11265
11328
|
/**
|
|
11266
11329
|
* The main loop that each worker runs. It repeatedly polls for items,
|
|
11267
11330
|
* processes them, and then waits before the next iteration.
|
|
11268
11331
|
*/
|
|
11269
|
-
async runWorkerLoop(workerId, taskCount) {
|
|
11332
|
+
async runWorkerLoop(workerId, taskCount, workerIndex, totalWorkers) {
|
|
11333
|
+
const limiter = pLimit(this.concurrency.limit);
|
|
11334
|
+
this.limiters[workerId] = limiter;
|
|
11270
11335
|
const pollIntervalMs = this.options.pollIntervalMs ?? 1e3;
|
|
11271
11336
|
const immediatePollIntervalMs = this.options.immediatePollIntervalMs ?? 100;
|
|
11337
|
+
const delayBetweenWorkers = this.options.pollIntervalMs ?? 1e3;
|
|
11338
|
+
const delay = delayBetweenWorkers * (totalWorkers - workerIndex);
|
|
11339
|
+
await _Worker.delay(delay);
|
|
11340
|
+
this.logger.info("Starting worker loop", {
|
|
11341
|
+
workerIndex,
|
|
11342
|
+
totalWorkers,
|
|
11343
|
+
delay,
|
|
11344
|
+
workerId,
|
|
11345
|
+
taskCount,
|
|
11346
|
+
pollIntervalMs,
|
|
11347
|
+
immediatePollIntervalMs,
|
|
11348
|
+
concurrencyOptions: this.concurrency
|
|
11349
|
+
});
|
|
11272
11350
|
while (!this.isShuttingDown) {
|
|
11273
|
-
if (
|
|
11351
|
+
if (limiter.activeCount + limiter.pendingCount >= this.concurrency.limit) {
|
|
11352
|
+
this.logger.debug("Worker at capacity, waiting", {
|
|
11353
|
+
workerId,
|
|
11354
|
+
concurrencyOptions: this.concurrency,
|
|
11355
|
+
activeCount: limiter.activeCount,
|
|
11356
|
+
pendingCount: limiter.pendingCount
|
|
11357
|
+
});
|
|
11274
11358
|
await _Worker.delay(pollIntervalMs);
|
|
11275
11359
|
continue;
|
|
11276
11360
|
}
|
|
11361
|
+
const $taskCount = Math.min(
|
|
11362
|
+
taskCount,
|
|
11363
|
+
this.concurrency.limit - limiter.activeCount - limiter.pendingCount
|
|
11364
|
+
);
|
|
11277
11365
|
try {
|
|
11278
11366
|
const items = await this.withHistogram(
|
|
11279
11367
|
this.metrics.dequeueDuration,
|
|
11280
|
-
this.queue.dequeue(taskCount),
|
|
11368
|
+
this.queue.dequeue($taskCount),
|
|
11281
11369
|
{
|
|
11282
11370
|
worker_id: workerId,
|
|
11283
|
-
task_count: taskCount
|
|
11371
|
+
task_count: $taskCount
|
|
11284
11372
|
}
|
|
11285
11373
|
);
|
|
11286
11374
|
if (items.length === 0) {
|
|
11375
|
+
this.logger.debug("No items to dequeue", {
|
|
11376
|
+
workerId,
|
|
11377
|
+
concurrencyOptions: this.concurrency,
|
|
11378
|
+
activeCount: limiter.activeCount,
|
|
11379
|
+
pendingCount: limiter.pendingCount
|
|
11380
|
+
});
|
|
11287
11381
|
await _Worker.delay(pollIntervalMs);
|
|
11288
11382
|
continue;
|
|
11289
11383
|
}
|
|
11384
|
+
this.logger.debug("Dequeued items", {
|
|
11385
|
+
workerId,
|
|
11386
|
+
itemCount: items.length,
|
|
11387
|
+
concurrencyOptions: this.concurrency,
|
|
11388
|
+
activeCount: limiter.activeCount,
|
|
11389
|
+
pendingCount: limiter.pendingCount
|
|
11390
|
+
});
|
|
11290
11391
|
for (const item of items) {
|
|
11291
|
-
|
|
11292
|
-
(
|
|
11293
|
-
|
|
11294
|
-
}
|
|
11295
|
-
);
|
|
11392
|
+
limiter(
|
|
11393
|
+
() => this.processItem(item, items.length, workerId, limiter)
|
|
11394
|
+
).catch((err) => {
|
|
11395
|
+
this.logger.error("Unhandled error in processItem:", { error: err, workerId, item });
|
|
11396
|
+
});
|
|
11296
11397
|
}
|
|
11297
11398
|
} catch (error) {
|
|
11298
11399
|
this.logger.error("Error dequeuing items:", { name: this.options.name, error });
|
|
@@ -11301,17 +11402,22 @@ var Worker = class _Worker {
|
|
|
11301
11402
|
}
|
|
11302
11403
|
await _Worker.delay(immediatePollIntervalMs);
|
|
11303
11404
|
}
|
|
11405
|
+
this.logger.info("Worker loop finished", { workerId });
|
|
11304
11406
|
}
|
|
11305
11407
|
/**
|
|
11306
11408
|
* Processes a single item.
|
|
11307
11409
|
*/
|
|
11308
|
-
async processItem({ id, job, item, visibilityTimeoutMs, attempt, timestamp, deduplicationKey }, batchSize, workerId) {
|
|
11410
|
+
async processItem({ id, job, item, visibilityTimeoutMs, attempt, timestamp, deduplicationKey }, batchSize, workerId, limiter) {
|
|
11309
11411
|
const catalogItem = this.options.catalog[job];
|
|
11310
11412
|
const handler = this.jobs[job];
|
|
11311
11413
|
if (!handler) {
|
|
11312
11414
|
this.logger.error(`No handler found for job type: ${job}`);
|
|
11313
11415
|
return;
|
|
11314
11416
|
}
|
|
11417
|
+
if (!catalogItem) {
|
|
11418
|
+
this.logger.error(`No catalog item found for job type: ${job}`);
|
|
11419
|
+
return;
|
|
11420
|
+
}
|
|
11315
11421
|
await startSpan(
|
|
11316
11422
|
this.tracer,
|
|
11317
11423
|
"processItem",
|
|
@@ -11327,6 +11433,9 @@ var Worker = class _Worker {
|
|
|
11327
11433
|
}
|
|
11328
11434
|
);
|
|
11329
11435
|
await this.queue.ack(id, deduplicationKey);
|
|
11436
|
+
if (catalogItem.cron) {
|
|
11437
|
+
await this.rescheduleCronJob(job, catalogItem, item);
|
|
11438
|
+
}
|
|
11330
11439
|
},
|
|
11331
11440
|
{
|
|
11332
11441
|
kind: SpanKind.CONSUMER,
|
|
@@ -11337,9 +11446,9 @@ var Worker = class _Worker {
|
|
|
11337
11446
|
job_timestamp: timestamp.getTime(),
|
|
11338
11447
|
job_age_in_ms: Date.now() - timestamp.getTime(),
|
|
11339
11448
|
worker_id: workerId,
|
|
11340
|
-
worker_limit_concurrency:
|
|
11341
|
-
worker_limit_active:
|
|
11342
|
-
worker_limit_pending:
|
|
11449
|
+
worker_limit_concurrency: limiter.concurrency,
|
|
11450
|
+
worker_limit_active: limiter.activeCount,
|
|
11451
|
+
worker_limit_pending: limiter.pendingCount,
|
|
11343
11452
|
worker_name: this.options.name,
|
|
11344
11453
|
batch_size: batchSize
|
|
11345
11454
|
}
|
|
@@ -11373,6 +11482,9 @@ var Worker = class _Worker {
|
|
|
11373
11482
|
errorMessage
|
|
11374
11483
|
});
|
|
11375
11484
|
await this.queue.moveToDeadLetterQueue(id, errorMessage);
|
|
11485
|
+
if (catalogItem.cron) {
|
|
11486
|
+
await this.rescheduleCronJob(job, catalogItem, item);
|
|
11487
|
+
}
|
|
11376
11488
|
return;
|
|
11377
11489
|
}
|
|
11378
11490
|
const retryDate = new Date(Date.now() + retryDelay);
|
|
@@ -11425,6 +11537,93 @@ var Worker = class _Worker {
|
|
|
11425
11537
|
static delay(ms) {
|
|
11426
11538
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
11427
11539
|
}
|
|
11540
|
+
setupCron() {
|
|
11541
|
+
const cronJobs = Object.entries(this.options.catalog).filter(([_, value]) => value.cron);
|
|
11542
|
+
if (cronJobs.length === 0) {
|
|
11543
|
+
return;
|
|
11544
|
+
}
|
|
11545
|
+
this.logger.info("Setting up cron jobs", {
|
|
11546
|
+
cronJobs: cronJobs.map(([job, value]) => ({
|
|
11547
|
+
job,
|
|
11548
|
+
cron: value.cron,
|
|
11549
|
+
jitterInMs: value.jitterInMs
|
|
11550
|
+
}))
|
|
11551
|
+
});
|
|
11552
|
+
const enqueuePromises = cronJobs.map(
|
|
11553
|
+
([job, value]) => this.enqueueCronJob(value.cron, job, value.jitterInMs)
|
|
11554
|
+
);
|
|
11555
|
+
Promise.allSettled(enqueuePromises).then((results) => {
|
|
11556
|
+
results.forEach((result) => {
|
|
11557
|
+
if (result.status === "fulfilled") {
|
|
11558
|
+
this.logger.info("Enqueued cron job", { result: result.value });
|
|
11559
|
+
} else {
|
|
11560
|
+
this.logger.error("Failed to enqueue cron job", { reason: result.reason });
|
|
11561
|
+
}
|
|
11562
|
+
});
|
|
11563
|
+
});
|
|
11564
|
+
}
|
|
11565
|
+
async enqueueCronJob(cron, job, jitter, lastTimestamp) {
|
|
11566
|
+
const scheduledAt = this.calculateNextScheduledAt(cron, lastTimestamp);
|
|
11567
|
+
const identifier = [job, this.timestampIdentifier(scheduledAt)].join(":");
|
|
11568
|
+
const appliedJitter = typeof jitter === "number" ? Math.random() * jitter - jitter / 2 : 0;
|
|
11569
|
+
const availableAt = new Date(scheduledAt.getTime() + appliedJitter);
|
|
11570
|
+
const enqueued = await this.enqueueOnce({
|
|
11571
|
+
id: identifier,
|
|
11572
|
+
job,
|
|
11573
|
+
payload: {
|
|
11574
|
+
timestamp: scheduledAt.getTime(),
|
|
11575
|
+
lastTimestamp: lastTimestamp?.getTime(),
|
|
11576
|
+
cron
|
|
11577
|
+
},
|
|
11578
|
+
availableAt
|
|
11579
|
+
});
|
|
11580
|
+
this.logger.info("Enqueued cron job", {
|
|
11581
|
+
identifier,
|
|
11582
|
+
cron,
|
|
11583
|
+
job,
|
|
11584
|
+
scheduledAt,
|
|
11585
|
+
enqueued,
|
|
11586
|
+
availableAt,
|
|
11587
|
+
appliedJitter,
|
|
11588
|
+
jitter
|
|
11589
|
+
});
|
|
11590
|
+
return {
|
|
11591
|
+
identifier,
|
|
11592
|
+
cron,
|
|
11593
|
+
job,
|
|
11594
|
+
scheduledAt,
|
|
11595
|
+
enqueued
|
|
11596
|
+
};
|
|
11597
|
+
}
|
|
11598
|
+
async rescheduleCronJob(job, catalogItem, item) {
|
|
11599
|
+
if (!catalogItem.cron) {
|
|
11600
|
+
return;
|
|
11601
|
+
}
|
|
11602
|
+
return this.enqueueCronJob(
|
|
11603
|
+
catalogItem.cron,
|
|
11604
|
+
job,
|
|
11605
|
+
catalogItem.jitterInMs,
|
|
11606
|
+
new Date(item.timestamp)
|
|
11607
|
+
);
|
|
11608
|
+
}
|
|
11609
|
+
calculateNextScheduledAt(cron, lastTimestamp) {
|
|
11610
|
+
const scheduledAt = cronParser.parseExpression(cron, {
|
|
11611
|
+
currentDate: lastTimestamp
|
|
11612
|
+
}).next().toDate();
|
|
11613
|
+
if (scheduledAt < /* @__PURE__ */ new Date()) {
|
|
11614
|
+
return this.calculateNextScheduledAt(cron);
|
|
11615
|
+
}
|
|
11616
|
+
return scheduledAt;
|
|
11617
|
+
}
|
|
11618
|
+
timestampIdentifier(timestamp) {
|
|
11619
|
+
const year = timestamp.getUTCFullYear();
|
|
11620
|
+
const month = timestamp.getUTCMonth();
|
|
11621
|
+
const day = timestamp.getUTCDate();
|
|
11622
|
+
const hour = timestamp.getUTCHours();
|
|
11623
|
+
const minute = timestamp.getUTCMinutes();
|
|
11624
|
+
const second = timestamp.getUTCSeconds();
|
|
11625
|
+
return `${year}-${month}-${day}-${hour}-${minute}-${second}`;
|
|
11626
|
+
}
|
|
11428
11627
|
setupSubscriber() {
|
|
11429
11628
|
const channel = `${this.options.name}:redrive`;
|
|
11430
11629
|
this.subscriber?.subscribe(channel, (err) => {
|
|
@@ -11481,6 +11680,7 @@ var Worker = class _Worker {
|
|
|
11481
11680
|
}
|
|
11482
11681
|
};
|
|
11483
11682
|
|
|
11683
|
+
exports.CronSchema = CronSchema;
|
|
11484
11684
|
exports.SimpleQueue = SimpleQueue;
|
|
11485
11685
|
exports.Worker = Worker;
|
|
11486
11686
|
//# sourceMappingURL=index.cjs.map
|