@microfox/ai-worker 1.0.1 → 1.0.2
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/CHANGELOG.md +6 -0
- package/README.md +18 -0
- package/dist/chunk-4WU5ZCHS.mjs +1053 -0
- package/dist/chunk-4WU5ZCHS.mjs.map +1 -0
- package/dist/chunk-BJPQY2NJ.mjs +186 -0
- package/dist/chunk-BJPQY2NJ.mjs.map +1 -0
- package/dist/client-D25XR0V8.d.mts +167 -0
- package/dist/client-D25XR0V8.d.ts +167 -0
- package/dist/client.d.mts +2 -64
- package/dist/client.d.ts +2 -64
- package/dist/client.js +107 -2
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +7 -3
- package/dist/handler.d.mts +83 -14
- package/dist/handler.d.ts +83 -14
- package/dist/handler.js +773 -5
- package/dist/handler.js.map +1 -1
- package/dist/handler.mjs +7 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1027 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +159 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
- package/dist/chunk-FQCZSXDI.mjs +0 -83
- package/dist/chunk-FQCZSXDI.mjs.map +0 -1
- package/dist/chunk-WVR4JVWK.mjs +0 -285
- package/dist/chunk-WVR4JVWK.mjs.map +0 -1
package/dist/handler.js
CHANGED
|
@@ -20,9 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/handler.ts
|
|
21
21
|
var handler_exports = {};
|
|
22
22
|
__export(handler_exports, {
|
|
23
|
-
|
|
23
|
+
SQS_MAX_DELAY_SECONDS: () => SQS_MAX_DELAY_SECONDS,
|
|
24
|
+
createLambdaHandler: () => createLambdaHandler,
|
|
25
|
+
wrapHandlerForQueue: () => wrapHandlerForQueue
|
|
24
26
|
});
|
|
25
27
|
module.exports = __toCommonJS(handler_exports);
|
|
28
|
+
var import_client_sqs = require("@aws-sdk/client-sqs");
|
|
26
29
|
|
|
27
30
|
// src/mongoJobStore.ts
|
|
28
31
|
var import_mongodb = require("mongodb");
|
|
@@ -49,6 +52,21 @@ async function getCollection() {
|
|
|
49
52
|
const client = await getClient();
|
|
50
53
|
return client.db(dbName).collection(collectionName);
|
|
51
54
|
}
|
|
55
|
+
async function getJobById(jobId) {
|
|
56
|
+
try {
|
|
57
|
+
const coll = await getCollection();
|
|
58
|
+
const doc = await coll.findOne({ _id: jobId });
|
|
59
|
+
if (!doc) return null;
|
|
60
|
+
const { _id, ...r } = doc;
|
|
61
|
+
return r;
|
|
62
|
+
} catch (e) {
|
|
63
|
+
console.error("[Worker] MongoDB getJobById failed:", {
|
|
64
|
+
jobId,
|
|
65
|
+
error: e?.message ?? String(e)
|
|
66
|
+
});
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
52
70
|
function createMongoJobStore(workerId, jobId, input, metadata) {
|
|
53
71
|
return {
|
|
54
72
|
update: async (update) => {
|
|
@@ -120,6 +138,36 @@ function createMongoJobStore(workerId, jobId, input, metadata) {
|
|
|
120
138
|
});
|
|
121
139
|
return null;
|
|
122
140
|
}
|
|
141
|
+
},
|
|
142
|
+
appendInternalJob: async (entry) => {
|
|
143
|
+
try {
|
|
144
|
+
const coll = await getCollection();
|
|
145
|
+
await coll.updateOne(
|
|
146
|
+
{ _id: jobId },
|
|
147
|
+
{ $push: { internalJobs: entry } }
|
|
148
|
+
);
|
|
149
|
+
} catch (e) {
|
|
150
|
+
console.error("[Worker] MongoDB job store appendInternalJob failed:", {
|
|
151
|
+
jobId,
|
|
152
|
+
workerId,
|
|
153
|
+
error: e?.message ?? String(e)
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
getJob: async (otherJobId) => {
|
|
158
|
+
try {
|
|
159
|
+
const coll = await getCollection();
|
|
160
|
+
const doc = await coll.findOne({ _id: otherJobId });
|
|
161
|
+
if (!doc) return null;
|
|
162
|
+
const { _id, ...r } = doc;
|
|
163
|
+
return r;
|
|
164
|
+
} catch (e) {
|
|
165
|
+
console.error("[Worker] MongoDB job store getJob failed:", {
|
|
166
|
+
otherJobId,
|
|
167
|
+
error: e?.message ?? String(e)
|
|
168
|
+
});
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
123
171
|
}
|
|
124
172
|
};
|
|
125
173
|
}
|
|
@@ -147,7 +195,646 @@ function isMongoJobStoreConfigured() {
|
|
|
147
195
|
return Boolean(uri?.trim());
|
|
148
196
|
}
|
|
149
197
|
|
|
198
|
+
// src/redisJobStore.ts
|
|
199
|
+
var import_redis = require("@upstash/redis");
|
|
200
|
+
var redisUrl = process.env.WORKER_UPSTASH_REDIS_REST_URL || process.env.UPSTASH_REDIS_REST_URL || process.env.UPSTASH_REDIS_URL;
|
|
201
|
+
var redisToken = process.env.WORKER_UPSTASH_REDIS_REST_TOKEN || process.env.UPSTASH_REDIS_REST_TOKEN || process.env.UPSTASH_REDIS_TOKEN;
|
|
202
|
+
var jobKeyPrefix = process.env.WORKER_UPSTASH_REDIS_JOBS_PREFIX || process.env.UPSTASH_REDIS_KEY_PREFIX || process.env.REDIS_WORKER_JOB_PREFIX || "worker:jobs:";
|
|
203
|
+
var defaultTtlSeconds = 60 * 60 * 24 * 7;
|
|
204
|
+
var jobTtlSeconds = typeof process.env.WORKER_JOBS_TTL_SECONDS === "string" ? parseInt(process.env.WORKER_JOBS_TTL_SECONDS, 10) || defaultTtlSeconds : typeof process.env.REDIS_WORKER_JOB_TTL_SECONDS === "string" ? parseInt(process.env.REDIS_WORKER_JOB_TTL_SECONDS, 10) || defaultTtlSeconds : typeof process.env.WORKFLOW_JOBS_TTL_SECONDS === "string" ? parseInt(process.env.WORKFLOW_JOBS_TTL_SECONDS, 10) || defaultTtlSeconds : defaultTtlSeconds;
|
|
205
|
+
var redisClient = null;
|
|
206
|
+
function getRedis() {
|
|
207
|
+
if (!redisUrl || !redisToken) {
|
|
208
|
+
throw new Error(
|
|
209
|
+
"Upstash Redis configuration missing. Set WORKER_UPSTASH_REDIS_REST_URL and WORKER_UPSTASH_REDIS_REST_TOKEN (or UPSTASH_REDIS_REST_URL/UPSTASH_REDIS_REST_TOKEN)."
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
if (!redisClient) {
|
|
213
|
+
redisClient = new import_redis.Redis({
|
|
214
|
+
url: redisUrl,
|
|
215
|
+
token: redisToken
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return redisClient;
|
|
219
|
+
}
|
|
220
|
+
function jobKey(jobId) {
|
|
221
|
+
return `${jobKeyPrefix}${jobId}`;
|
|
222
|
+
}
|
|
223
|
+
function internalListKey(jobId) {
|
|
224
|
+
return `${jobKeyPrefix}${jobId}:internal`;
|
|
225
|
+
}
|
|
226
|
+
function isRedisJobStoreConfigured() {
|
|
227
|
+
return Boolean((redisUrl || "").trim() && (redisToken || "").trim());
|
|
228
|
+
}
|
|
229
|
+
async function loadJob(jobId) {
|
|
230
|
+
const redis = getRedis();
|
|
231
|
+
const key = jobKey(jobId);
|
|
232
|
+
const data = await redis.hgetall(key);
|
|
233
|
+
if (!data || Object.keys(data).length === 0) return null;
|
|
234
|
+
const parseJson = (val) => {
|
|
235
|
+
if (!val) return void 0;
|
|
236
|
+
try {
|
|
237
|
+
return JSON.parse(val);
|
|
238
|
+
} catch {
|
|
239
|
+
return void 0;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
const listKey = internalListKey(jobId);
|
|
243
|
+
const listItems = await redis.lrange(listKey, 0, -1);
|
|
244
|
+
let internalJobs;
|
|
245
|
+
if (listItems && listItems.length > 0) {
|
|
246
|
+
internalJobs = listItems.map((s) => {
|
|
247
|
+
try {
|
|
248
|
+
return JSON.parse(s);
|
|
249
|
+
} catch {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
}).filter(Boolean);
|
|
253
|
+
} else {
|
|
254
|
+
internalJobs = parseJson(data.internalJobs);
|
|
255
|
+
}
|
|
256
|
+
const record = {
|
|
257
|
+
jobId: data.jobId,
|
|
258
|
+
workerId: data.workerId,
|
|
259
|
+
status: data.status || "queued",
|
|
260
|
+
input: parseJson(data.input) ?? {},
|
|
261
|
+
output: parseJson(data.output),
|
|
262
|
+
error: parseJson(data.error),
|
|
263
|
+
metadata: parseJson(data.metadata) ?? {},
|
|
264
|
+
internalJobs,
|
|
265
|
+
createdAt: data.createdAt,
|
|
266
|
+
updatedAt: data.updatedAt,
|
|
267
|
+
completedAt: data.completedAt
|
|
268
|
+
};
|
|
269
|
+
return record;
|
|
270
|
+
}
|
|
271
|
+
function createRedisJobStore(workerId, jobId, input, metadata) {
|
|
272
|
+
return {
|
|
273
|
+
update: async (update) => {
|
|
274
|
+
const redis = getRedis();
|
|
275
|
+
const key = jobKey(jobId);
|
|
276
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
277
|
+
const existing = await loadJob(jobId);
|
|
278
|
+
const next = {};
|
|
279
|
+
const mergedMeta = { ...existing?.metadata ?? {} };
|
|
280
|
+
if (update.metadata) {
|
|
281
|
+
Object.assign(mergedMeta, update.metadata);
|
|
282
|
+
}
|
|
283
|
+
if (update.progress !== void 0 || update.progressMessage !== void 0) {
|
|
284
|
+
mergedMeta.progress = update.progress;
|
|
285
|
+
mergedMeta.progressMessage = update.progressMessage;
|
|
286
|
+
}
|
|
287
|
+
next.metadata = mergedMeta;
|
|
288
|
+
if (update.status !== void 0) {
|
|
289
|
+
next.status = update.error ? "failed" : update.status;
|
|
290
|
+
if ((update.status === "completed" || update.status === "failed") && !existing?.completedAt) {
|
|
291
|
+
next.completedAt = now;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (update.output !== void 0) next.output = update.output;
|
|
295
|
+
if (update.error !== void 0) next.error = update.error;
|
|
296
|
+
const toSet = {};
|
|
297
|
+
if (next.status) toSet["status"] = String(next.status);
|
|
298
|
+
if (next.output !== void 0) toSet["output"] = JSON.stringify(next.output);
|
|
299
|
+
if (next.error !== void 0) toSet["error"] = JSON.stringify(next.error);
|
|
300
|
+
if (next.metadata !== void 0) toSet["metadata"] = JSON.stringify(next.metadata);
|
|
301
|
+
if (next.completedAt) {
|
|
302
|
+
toSet["completedAt"] = next.completedAt;
|
|
303
|
+
}
|
|
304
|
+
toSet["updatedAt"] = now;
|
|
305
|
+
await redis.hset(key, toSet);
|
|
306
|
+
if (jobTtlSeconds > 0) {
|
|
307
|
+
await redis.expire(key, jobTtlSeconds);
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
get: async () => {
|
|
311
|
+
return loadJob(jobId);
|
|
312
|
+
},
|
|
313
|
+
appendInternalJob: async (entry) => {
|
|
314
|
+
const redis = getRedis();
|
|
315
|
+
const listKey = internalListKey(jobId);
|
|
316
|
+
await redis.rpush(listKey, JSON.stringify(entry));
|
|
317
|
+
const mainKey = jobKey(jobId);
|
|
318
|
+
await redis.hset(mainKey, { updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
319
|
+
if (jobTtlSeconds > 0) {
|
|
320
|
+
await redis.expire(listKey, jobTtlSeconds);
|
|
321
|
+
await redis.expire(mainKey, jobTtlSeconds);
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
getJob: async (otherJobId) => {
|
|
325
|
+
return loadJob(otherJobId);
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
async function upsertRedisJob(jobId, workerId, input, metadata) {
|
|
330
|
+
const redis = getRedis();
|
|
331
|
+
const key = jobKey(jobId);
|
|
332
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
333
|
+
const doc = {
|
|
334
|
+
jobId,
|
|
335
|
+
workerId,
|
|
336
|
+
status: "queued",
|
|
337
|
+
input,
|
|
338
|
+
metadata,
|
|
339
|
+
createdAt: now,
|
|
340
|
+
updatedAt: now
|
|
341
|
+
};
|
|
342
|
+
const toSet = {
|
|
343
|
+
jobId,
|
|
344
|
+
workerId,
|
|
345
|
+
status: doc.status,
|
|
346
|
+
input: JSON.stringify(doc.input ?? {}),
|
|
347
|
+
metadata: JSON.stringify(doc.metadata ?? {}),
|
|
348
|
+
createdAt: now,
|
|
349
|
+
updatedAt: now
|
|
350
|
+
};
|
|
351
|
+
await redis.hset(key, toSet);
|
|
352
|
+
if (jobTtlSeconds > 0) {
|
|
353
|
+
await redis.expire(key, jobTtlSeconds);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/queueJobStore.ts
|
|
358
|
+
var import_redis2 = require("@upstash/redis");
|
|
359
|
+
var import_mongodb2 = require("mongodb");
|
|
360
|
+
var mongoUri = process.env.DATABASE_MONGODB_URI || process.env.MONGODB_URI;
|
|
361
|
+
var mongoDbName = process.env.DATABASE_MONGODB_DB || process.env.MONGODB_DB || "mediamake";
|
|
362
|
+
var mongoQueueCollectionName = process.env.MONGODB_QUEUE_JOBS_COLLECTION || "queue_jobs";
|
|
363
|
+
var mongoClientPromise = null;
|
|
364
|
+
async function getMongoClient() {
|
|
365
|
+
if (!mongoUri) {
|
|
366
|
+
throw new Error(
|
|
367
|
+
"MongoDB URI required for queue job store. Set DATABASE_MONGODB_URI or MONGODB_URI."
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
if (!mongoClientPromise) {
|
|
371
|
+
mongoClientPromise = new import_mongodb2.MongoClient(mongoUri, {
|
|
372
|
+
maxPoolSize: 10,
|
|
373
|
+
minPoolSize: 0,
|
|
374
|
+
serverSelectionTimeoutMS: 1e4
|
|
375
|
+
}).connect();
|
|
376
|
+
}
|
|
377
|
+
return mongoClientPromise;
|
|
378
|
+
}
|
|
379
|
+
async function getMongoQueueCollection() {
|
|
380
|
+
const client = await getMongoClient();
|
|
381
|
+
return client.db(mongoDbName).collection(mongoQueueCollectionName);
|
|
382
|
+
}
|
|
383
|
+
var redisUrl2 = process.env.WORKER_UPSTASH_REDIS_REST_URL || process.env.UPSTASH_REDIS_REST_URL || process.env.UPSTASH_REDIS_URL;
|
|
384
|
+
var redisToken2 = process.env.WORKER_UPSTASH_REDIS_REST_TOKEN || process.env.UPSTASH_REDIS_REST_TOKEN || process.env.UPSTASH_REDIS_TOKEN;
|
|
385
|
+
var queueKeyPrefix = process.env.WORKER_UPSTASH_REDIS_QUEUE_PREFIX || process.env.UPSTASH_REDIS_QUEUE_PREFIX || "worker:queue-jobs:";
|
|
386
|
+
var defaultTtlSeconds2 = 60 * 60 * 24 * 7;
|
|
387
|
+
var queueJobTtlSeconds = typeof process.env.WORKER_QUEUE_JOBS_TTL_SECONDS === "string" ? parseInt(process.env.WORKER_QUEUE_JOBS_TTL_SECONDS, 10) || defaultTtlSeconds2 : typeof process.env.WORKER_JOBS_TTL_SECONDS === "string" ? parseInt(process.env.WORKER_JOBS_TTL_SECONDS, 10) || defaultTtlSeconds2 : defaultTtlSeconds2;
|
|
388
|
+
var redisClient2 = null;
|
|
389
|
+
function getRedis2() {
|
|
390
|
+
if (!redisUrl2 || !redisToken2) {
|
|
391
|
+
throw new Error(
|
|
392
|
+
"Upstash Redis configuration missing for queue job store. Set WORKER_UPSTASH_REDIS_REST_URL and WORKER_UPSTASH_REDIS_REST_TOKEN (or UPSTASH_REDIS_REST_URL/UPSTASH_REDIS_REST_TOKEN)."
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
if (!redisClient2) {
|
|
396
|
+
redisClient2 = new import_redis2.Redis({
|
|
397
|
+
url: redisUrl2,
|
|
398
|
+
token: redisToken2
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
return redisClient2;
|
|
402
|
+
}
|
|
403
|
+
function queueKey(id) {
|
|
404
|
+
return `${queueKeyPrefix}${id}`;
|
|
405
|
+
}
|
|
406
|
+
function stepsFromHash(val) {
|
|
407
|
+
if (Array.isArray(val)) return val;
|
|
408
|
+
if (typeof val === "string") {
|
|
409
|
+
try {
|
|
410
|
+
const parsed = JSON.parse(val);
|
|
411
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
412
|
+
} catch {
|
|
413
|
+
return [];
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return [];
|
|
417
|
+
}
|
|
418
|
+
function metadataFromHash(val) {
|
|
419
|
+
if (val && typeof val === "object" && !Array.isArray(val)) return val;
|
|
420
|
+
if (typeof val === "string") {
|
|
421
|
+
try {
|
|
422
|
+
const parsed = JSON.parse(val);
|
|
423
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
424
|
+
} catch {
|
|
425
|
+
return {};
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return {};
|
|
429
|
+
}
|
|
430
|
+
async function loadQueueJobRedis(queueJobId) {
|
|
431
|
+
const redis = getRedis2();
|
|
432
|
+
const key = queueKey(queueJobId);
|
|
433
|
+
const data = await redis.hgetall(key);
|
|
434
|
+
if (!data || typeof data !== "object" || Object.keys(data).length === 0) return null;
|
|
435
|
+
const d = data;
|
|
436
|
+
const record = {
|
|
437
|
+
id: d.id === void 0 ? queueJobId : String(d.id),
|
|
438
|
+
queueId: String(d.queueId ?? ""),
|
|
439
|
+
status: String(d.status ?? "running"),
|
|
440
|
+
steps: stepsFromHash(d.steps),
|
|
441
|
+
metadata: metadataFromHash(d.metadata),
|
|
442
|
+
createdAt: String(d.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()),
|
|
443
|
+
updatedAt: String(d.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()),
|
|
444
|
+
completedAt: d.completedAt != null ? String(d.completedAt) : void 0
|
|
445
|
+
};
|
|
446
|
+
return record;
|
|
447
|
+
}
|
|
448
|
+
async function saveQueueJobRedis(record) {
|
|
449
|
+
const redis = getRedis2();
|
|
450
|
+
const key = queueKey(record.id);
|
|
451
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
452
|
+
const toSet = {
|
|
453
|
+
id: record.id,
|
|
454
|
+
queueId: record.queueId,
|
|
455
|
+
status: record.status,
|
|
456
|
+
steps: JSON.stringify(record.steps || []),
|
|
457
|
+
metadata: JSON.stringify(record.metadata || {}),
|
|
458
|
+
createdAt: record.createdAt || now,
|
|
459
|
+
updatedAt: record.updatedAt || now
|
|
460
|
+
};
|
|
461
|
+
if (record.completedAt) {
|
|
462
|
+
toSet.completedAt = record.completedAt;
|
|
463
|
+
}
|
|
464
|
+
await redis.hset(key, toSet);
|
|
465
|
+
if (queueJobTtlSeconds > 0) {
|
|
466
|
+
await redis.expire(key, queueJobTtlSeconds);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
function getStoreType() {
|
|
470
|
+
const t = (process.env.WORKER_DATABASE_TYPE || "upstash-redis").toLowerCase();
|
|
471
|
+
return t === "mongodb" ? "mongodb" : "upstash-redis";
|
|
472
|
+
}
|
|
473
|
+
function preferMongo() {
|
|
474
|
+
return getStoreType() === "mongodb" && Boolean(mongoUri?.trim());
|
|
475
|
+
}
|
|
476
|
+
function preferRedis() {
|
|
477
|
+
return getStoreType() !== "mongodb" && Boolean((redisUrl2 || "").trim() && (redisToken2 || "").trim());
|
|
478
|
+
}
|
|
479
|
+
async function upsertInitialQueueJob(options) {
|
|
480
|
+
const { queueJobId, queueId, firstWorkerId, firstWorkerJobId, metadata } = options;
|
|
481
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
482
|
+
if (preferMongo()) {
|
|
483
|
+
const coll = await getMongoQueueCollection();
|
|
484
|
+
const existing = await coll.findOne({ _id: queueJobId });
|
|
485
|
+
if (existing) {
|
|
486
|
+
const steps = existing.steps ?? [];
|
|
487
|
+
if (steps.length === 0) {
|
|
488
|
+
steps.push({
|
|
489
|
+
workerId: firstWorkerId,
|
|
490
|
+
workerJobId: firstWorkerJobId,
|
|
491
|
+
status: "queued"
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
await coll.updateOne(
|
|
495
|
+
{ _id: queueJobId },
|
|
496
|
+
{
|
|
497
|
+
$set: {
|
|
498
|
+
steps,
|
|
499
|
+
updatedAt: now
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
);
|
|
503
|
+
} else {
|
|
504
|
+
const doc = {
|
|
505
|
+
_id: queueJobId,
|
|
506
|
+
id: queueJobId,
|
|
507
|
+
queueId,
|
|
508
|
+
status: "running",
|
|
509
|
+
steps: [
|
|
510
|
+
{
|
|
511
|
+
workerId: firstWorkerId,
|
|
512
|
+
workerJobId: firstWorkerJobId,
|
|
513
|
+
status: "queued"
|
|
514
|
+
}
|
|
515
|
+
],
|
|
516
|
+
metadata: metadata ?? {},
|
|
517
|
+
createdAt: now,
|
|
518
|
+
updatedAt: now
|
|
519
|
+
};
|
|
520
|
+
await coll.updateOne(
|
|
521
|
+
{ _id: queueJobId },
|
|
522
|
+
{ $set: doc },
|
|
523
|
+
{ upsert: true }
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
if (preferRedis()) {
|
|
529
|
+
const existing = await loadQueueJobRedis(queueJobId);
|
|
530
|
+
if (existing) {
|
|
531
|
+
if (!existing.steps || existing.steps.length === 0) {
|
|
532
|
+
existing.steps = [
|
|
533
|
+
{
|
|
534
|
+
workerId: firstWorkerId,
|
|
535
|
+
workerJobId: firstWorkerJobId,
|
|
536
|
+
status: "queued"
|
|
537
|
+
}
|
|
538
|
+
];
|
|
539
|
+
}
|
|
540
|
+
existing.updatedAt = now;
|
|
541
|
+
await saveQueueJobRedis(existing);
|
|
542
|
+
} else {
|
|
543
|
+
const record = {
|
|
544
|
+
id: queueJobId,
|
|
545
|
+
queueId,
|
|
546
|
+
status: "running",
|
|
547
|
+
steps: [
|
|
548
|
+
{
|
|
549
|
+
workerId: firstWorkerId,
|
|
550
|
+
workerJobId: firstWorkerJobId,
|
|
551
|
+
status: "queued"
|
|
552
|
+
}
|
|
553
|
+
],
|
|
554
|
+
metadata: metadata ?? {},
|
|
555
|
+
createdAt: now,
|
|
556
|
+
updatedAt: now
|
|
557
|
+
};
|
|
558
|
+
await saveQueueJobRedis(record);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
async function updateQueueJobStepInStore(options) {
|
|
563
|
+
const { queueJobId, stepIndex, status, input, output, error } = options;
|
|
564
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
565
|
+
if (preferMongo()) {
|
|
566
|
+
const coll = await getMongoQueueCollection();
|
|
567
|
+
const existing = await coll.findOne({ _id: queueJobId });
|
|
568
|
+
if (!existing) return;
|
|
569
|
+
const step = existing.steps[stepIndex];
|
|
570
|
+
if (!step) return;
|
|
571
|
+
const mergedStep = {
|
|
572
|
+
...step,
|
|
573
|
+
status,
|
|
574
|
+
...input !== void 0 && { input },
|
|
575
|
+
...output !== void 0 && { output },
|
|
576
|
+
...error !== void 0 && { error },
|
|
577
|
+
startedAt: step.startedAt ?? (status === "running" ? now : step.startedAt),
|
|
578
|
+
completedAt: step.completedAt ?? (status === "completed" || status === "failed" ? now : step.completedAt)
|
|
579
|
+
};
|
|
580
|
+
const setDoc = {
|
|
581
|
+
steps: existing.steps,
|
|
582
|
+
updatedAt: now
|
|
583
|
+
};
|
|
584
|
+
setDoc.steps[stepIndex] = mergedStep;
|
|
585
|
+
if (status === "failed") {
|
|
586
|
+
setDoc.status = "failed";
|
|
587
|
+
if (!existing.completedAt) setDoc.completedAt = now;
|
|
588
|
+
} else if (status === "completed" && stepIndex === existing.steps.length - 1) {
|
|
589
|
+
setDoc.status = "completed";
|
|
590
|
+
if (!existing.completedAt) setDoc.completedAt = now;
|
|
591
|
+
}
|
|
592
|
+
await coll.updateOne(
|
|
593
|
+
{ _id: queueJobId },
|
|
594
|
+
{
|
|
595
|
+
$set: setDoc
|
|
596
|
+
}
|
|
597
|
+
);
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
if (preferRedis()) {
|
|
601
|
+
const existing = await loadQueueJobRedis(queueJobId);
|
|
602
|
+
if (!existing) {
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
const steps = existing.steps || [];
|
|
606
|
+
const step = steps[stepIndex];
|
|
607
|
+
if (!step) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
step.status = status;
|
|
611
|
+
if (input !== void 0) step.input = input;
|
|
612
|
+
if (output !== void 0) step.output = output;
|
|
613
|
+
if (error !== void 0) step.error = error;
|
|
614
|
+
if (status === "running") {
|
|
615
|
+
step.startedAt = step.startedAt ?? now;
|
|
616
|
+
}
|
|
617
|
+
if (status === "completed" || status === "failed") {
|
|
618
|
+
step.completedAt = step.completedAt ?? now;
|
|
619
|
+
}
|
|
620
|
+
existing.steps = steps;
|
|
621
|
+
existing.updatedAt = now;
|
|
622
|
+
if (status === "failed") {
|
|
623
|
+
existing.status = "failed";
|
|
624
|
+
existing.completedAt = existing.completedAt ?? now;
|
|
625
|
+
} else if (status === "completed" && stepIndex === steps.length - 1) {
|
|
626
|
+
existing.status = "completed";
|
|
627
|
+
existing.completedAt = existing.completedAt ?? now;
|
|
628
|
+
}
|
|
629
|
+
await saveQueueJobRedis(existing);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
async function appendQueueJobStepInStore(options) {
|
|
633
|
+
const { queueJobId, workerId, workerJobId } = options;
|
|
634
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
635
|
+
if (preferMongo()) {
|
|
636
|
+
const coll = await getMongoQueueCollection();
|
|
637
|
+
await coll.updateOne(
|
|
638
|
+
{ _id: queueJobId },
|
|
639
|
+
{
|
|
640
|
+
$push: {
|
|
641
|
+
steps: {
|
|
642
|
+
workerId,
|
|
643
|
+
workerJobId,
|
|
644
|
+
status: "queued"
|
|
645
|
+
}
|
|
646
|
+
},
|
|
647
|
+
$set: { updatedAt: now }
|
|
648
|
+
}
|
|
649
|
+
);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
if (preferRedis()) {
|
|
653
|
+
const existing = await loadQueueJobRedis(queueJobId);
|
|
654
|
+
if (!existing) return;
|
|
655
|
+
const steps = existing.steps || [];
|
|
656
|
+
steps.push({
|
|
657
|
+
workerId,
|
|
658
|
+
workerJobId,
|
|
659
|
+
status: "queued"
|
|
660
|
+
});
|
|
661
|
+
existing.steps = steps;
|
|
662
|
+
existing.updatedAt = now;
|
|
663
|
+
await saveQueueJobRedis(existing);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
150
667
|
// src/handler.ts
|
|
668
|
+
var SQS_MAX_DELAY_SECONDS = 900;
|
|
669
|
+
var WORKER_QUEUE_KEY = "__workerQueue";
|
|
670
|
+
async function notifyQueueJobStep(queueJobId, action, params) {
|
|
671
|
+
try {
|
|
672
|
+
if (action === "append") {
|
|
673
|
+
if (!params.workerId || !params.workerJobId) return;
|
|
674
|
+
await appendQueueJobStepInStore({
|
|
675
|
+
queueJobId,
|
|
676
|
+
workerId: params.workerId,
|
|
677
|
+
workerJobId: params.workerJobId
|
|
678
|
+
});
|
|
679
|
+
if (process.env.DEBUG_WORKER_QUEUES === "1") {
|
|
680
|
+
console.log("[Worker] Queue job step appended", {
|
|
681
|
+
queueJobId,
|
|
682
|
+
workerId: params.workerId,
|
|
683
|
+
workerJobId: params.workerJobId
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
if (params.stepIndex === void 0) return;
|
|
689
|
+
const status = action === "start" ? "running" : action === "complete" ? "completed" : action === "fail" ? "failed" : void 0;
|
|
690
|
+
if (!status) return;
|
|
691
|
+
await updateQueueJobStepInStore({
|
|
692
|
+
queueJobId,
|
|
693
|
+
stepIndex: params.stepIndex,
|
|
694
|
+
workerId: params.workerId || "",
|
|
695
|
+
workerJobId: params.workerJobId,
|
|
696
|
+
status,
|
|
697
|
+
input: params.input,
|
|
698
|
+
output: params.output,
|
|
699
|
+
error: params.error
|
|
700
|
+
});
|
|
701
|
+
if (process.env.DEBUG_WORKER_QUEUES === "1") {
|
|
702
|
+
console.log("[Worker] Queue job step updated", {
|
|
703
|
+
queueJobId,
|
|
704
|
+
action,
|
|
705
|
+
stepIndex: params.stepIndex,
|
|
706
|
+
status
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
} catch (err) {
|
|
710
|
+
console.warn("[Worker] Queue job update error:", {
|
|
711
|
+
queueJobId,
|
|
712
|
+
action,
|
|
713
|
+
error: err?.message ?? String(err)
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
function wrapHandlerForQueue(handler, queueRuntime) {
|
|
718
|
+
return async (params) => {
|
|
719
|
+
const queueContext = params.input?.[WORKER_QUEUE_KEY];
|
|
720
|
+
const output = await handler(params);
|
|
721
|
+
if (!queueContext || typeof queueContext !== "object" || !queueContext.id) {
|
|
722
|
+
return output;
|
|
723
|
+
}
|
|
724
|
+
const { id: queueId, stepIndex, initialInput, queueJobId } = queueContext;
|
|
725
|
+
const next = queueRuntime.getNextStep(queueId, stepIndex);
|
|
726
|
+
if (!next) {
|
|
727
|
+
return output;
|
|
728
|
+
}
|
|
729
|
+
const childJobId = `job-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
730
|
+
if (queueJobId) {
|
|
731
|
+
await notifyQueueJobStep(queueJobId, "append", {
|
|
732
|
+
workerJobId: childJobId,
|
|
733
|
+
workerId: next.workerId
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
let nextInput = output;
|
|
737
|
+
if (next.mapInputFromPrev && typeof queueRuntime.invokeMapInput === "function") {
|
|
738
|
+
nextInput = await queueRuntime.invokeMapInput(queueId, stepIndex + 1, output, initialInput);
|
|
739
|
+
}
|
|
740
|
+
const nextInputWithQueue = {
|
|
741
|
+
...nextInput !== null && typeof nextInput === "object" ? nextInput : { value: nextInput },
|
|
742
|
+
[WORKER_QUEUE_KEY]: {
|
|
743
|
+
id: queueId,
|
|
744
|
+
stepIndex: stepIndex + 1,
|
|
745
|
+
initialInput,
|
|
746
|
+
queueJobId
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
const debug = process.env.AI_WORKER_QUEUES_DEBUG === "1";
|
|
750
|
+
if (debug) {
|
|
751
|
+
console.log("[Worker] Queue chain dispatching next:", {
|
|
752
|
+
queueId,
|
|
753
|
+
fromStep: stepIndex,
|
|
754
|
+
nextWorkerId: next.workerId,
|
|
755
|
+
delaySeconds: next.delaySeconds
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
await params.ctx.dispatchWorker(next.workerId, nextInputWithQueue, {
|
|
759
|
+
await: false,
|
|
760
|
+
delaySeconds: next.delaySeconds,
|
|
761
|
+
jobId: childJobId
|
|
762
|
+
});
|
|
763
|
+
return output;
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
var DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
767
|
+
var DEFAULT_POLL_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
768
|
+
function sanitizeWorkerIdForEnv(workerId) {
|
|
769
|
+
return workerId.replace(/-/g, "_").toUpperCase();
|
|
770
|
+
}
|
|
771
|
+
function getQueueUrlForWorker(calleeWorkerId) {
|
|
772
|
+
const key = `WORKER_QUEUE_URL_${sanitizeWorkerIdForEnv(calleeWorkerId)}`;
|
|
773
|
+
return process.env[key]?.trim() || void 0;
|
|
774
|
+
}
|
|
775
|
+
function createDispatchWorker(parentJobId, parentWorkerId, parentContext, jobStore) {
|
|
776
|
+
return async (calleeWorkerId, input, options) => {
|
|
777
|
+
const childJobId = options?.jobId || `job-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
778
|
+
const metadata = options?.metadata ?? {};
|
|
779
|
+
const serializedContext = {};
|
|
780
|
+
if (parentContext.requestId) serializedContext.requestId = parentContext.requestId;
|
|
781
|
+
const messageBody = {
|
|
782
|
+
workerId: calleeWorkerId,
|
|
783
|
+
jobId: childJobId,
|
|
784
|
+
input: input ?? {},
|
|
785
|
+
context: serializedContext,
|
|
786
|
+
webhookUrl: options?.webhookUrl,
|
|
787
|
+
metadata,
|
|
788
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
789
|
+
};
|
|
790
|
+
const queueUrl = getQueueUrlForWorker(calleeWorkerId);
|
|
791
|
+
if (queueUrl) {
|
|
792
|
+
const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || "us-east-1";
|
|
793
|
+
const sqs = new import_client_sqs.SQSClient({ region });
|
|
794
|
+
const delaySeconds = options?.await !== true && options?.delaySeconds != null ? Math.min(SQS_MAX_DELAY_SECONDS, Math.max(0, Math.floor(options.delaySeconds))) : void 0;
|
|
795
|
+
const sendResult = await sqs.send(
|
|
796
|
+
new import_client_sqs.SendMessageCommand({
|
|
797
|
+
QueueUrl: queueUrl,
|
|
798
|
+
MessageBody: JSON.stringify(messageBody),
|
|
799
|
+
...delaySeconds !== void 0 && delaySeconds > 0 ? { DelaySeconds: delaySeconds } : {}
|
|
800
|
+
})
|
|
801
|
+
);
|
|
802
|
+
const messageId = sendResult.MessageId ?? void 0;
|
|
803
|
+
if (jobStore?.appendInternalJob) {
|
|
804
|
+
await jobStore.appendInternalJob({ jobId: childJobId, workerId: calleeWorkerId });
|
|
805
|
+
}
|
|
806
|
+
if (options?.await && jobStore?.getJob) {
|
|
807
|
+
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
808
|
+
const pollTimeoutMs = options.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;
|
|
809
|
+
const deadline = Date.now() + pollTimeoutMs;
|
|
810
|
+
while (Date.now() < deadline) {
|
|
811
|
+
const child = await jobStore.getJob(childJobId);
|
|
812
|
+
if (!child) {
|
|
813
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
814
|
+
continue;
|
|
815
|
+
}
|
|
816
|
+
if (child.status === "completed") {
|
|
817
|
+
return { jobId: childJobId, messageId, output: child.output };
|
|
818
|
+
}
|
|
819
|
+
if (child.status === "failed") {
|
|
820
|
+
const err = child.error;
|
|
821
|
+
throw new Error(
|
|
822
|
+
err?.message ?? `Child worker ${calleeWorkerId} failed`
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
826
|
+
}
|
|
827
|
+
throw new Error(
|
|
828
|
+
`Child worker ${calleeWorkerId} (${childJobId}) did not complete within ${pollTimeoutMs}ms`
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
return { jobId: childJobId, messageId };
|
|
832
|
+
}
|
|
833
|
+
throw new Error(
|
|
834
|
+
`WORKER_QUEUE_URL_${sanitizeWorkerIdForEnv(calleeWorkerId)} is not set. Configure queue URL for worker-to-worker dispatch, or run in local mode.`
|
|
835
|
+
);
|
|
836
|
+
};
|
|
837
|
+
}
|
|
151
838
|
async function sendWebhook(webhookUrl, payload) {
|
|
152
839
|
try {
|
|
153
840
|
const response = await fetch(webhookUrl, {
|
|
@@ -187,18 +874,53 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
187
874
|
try {
|
|
188
875
|
messageBody = JSON.parse(record.body);
|
|
189
876
|
const { workerId, jobId, input, context, webhookUrl, metadata = {} } = messageBody;
|
|
877
|
+
const raw = (process.env.WORKER_DATABASE_TYPE || "upstash-redis").toLowerCase();
|
|
878
|
+
const jobStoreType = raw === "mongodb" ? "mongodb" : "upstash-redis";
|
|
879
|
+
if (jobStoreType === "upstash-redis" && isRedisJobStoreConfigured()) {
|
|
880
|
+
const existing = await loadJob(jobId);
|
|
881
|
+
if (existing && (existing.status === "completed" || existing.status === "failed")) {
|
|
882
|
+
console.log("[Worker] Skipping already terminal job (idempotent):", {
|
|
883
|
+
jobId,
|
|
884
|
+
workerId,
|
|
885
|
+
status: existing.status
|
|
886
|
+
});
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
} else if (jobStoreType === "mongodb" || isMongoJobStoreConfigured()) {
|
|
890
|
+
const existing = await getJobById(jobId);
|
|
891
|
+
if (existing && (existing.status === "completed" || existing.status === "failed")) {
|
|
892
|
+
console.log("[Worker] Skipping already terminal job (idempotent):", {
|
|
893
|
+
jobId,
|
|
894
|
+
workerId,
|
|
895
|
+
status: existing.status
|
|
896
|
+
});
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
190
900
|
let jobStore;
|
|
191
|
-
if (
|
|
901
|
+
if (jobStoreType === "upstash-redis" && isRedisJobStoreConfigured()) {
|
|
902
|
+
await upsertRedisJob(jobId, workerId, input, metadata);
|
|
903
|
+
jobStore = createRedisJobStore(workerId, jobId, input, metadata);
|
|
904
|
+
} else if (jobStoreType === "mongodb" || isMongoJobStoreConfigured()) {
|
|
192
905
|
await upsertJob(jobId, workerId, input, metadata);
|
|
193
906
|
jobStore = createMongoJobStore(workerId, jobId, input, metadata);
|
|
194
907
|
}
|
|
195
|
-
const
|
|
908
|
+
const baseContext = {
|
|
196
909
|
jobId,
|
|
197
910
|
workerId,
|
|
198
911
|
requestId: context.requestId || lambdaContext.awsRequestId,
|
|
199
|
-
...jobStore ? { jobStore } : {},
|
|
200
912
|
...context
|
|
201
913
|
};
|
|
914
|
+
const handlerContext = {
|
|
915
|
+
...baseContext,
|
|
916
|
+
...jobStore ? { jobStore } : {},
|
|
917
|
+
dispatchWorker: createDispatchWorker(
|
|
918
|
+
jobId,
|
|
919
|
+
workerId,
|
|
920
|
+
baseContext,
|
|
921
|
+
jobStore
|
|
922
|
+
)
|
|
923
|
+
};
|
|
202
924
|
if (jobStore) {
|
|
203
925
|
try {
|
|
204
926
|
await jobStore.update({ status: "running" });
|
|
@@ -214,6 +936,32 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
214
936
|
});
|
|
215
937
|
}
|
|
216
938
|
}
|
|
939
|
+
const queueCtx = input?.__workerQueue ?? metadata?.__workerQueue;
|
|
940
|
+
if (queueCtx?.queueJobId && typeof queueCtx.stepIndex === "number") {
|
|
941
|
+
if (queueCtx.stepIndex === 0) {
|
|
942
|
+
try {
|
|
943
|
+
await upsertInitialQueueJob({
|
|
944
|
+
queueJobId: queueCtx.queueJobId,
|
|
945
|
+
queueId: queueCtx.id,
|
|
946
|
+
firstWorkerId: workerId,
|
|
947
|
+
firstWorkerJobId: jobId,
|
|
948
|
+
metadata
|
|
949
|
+
});
|
|
950
|
+
} catch (e) {
|
|
951
|
+
console.warn("[Worker] Failed to upsert initial queue job:", {
|
|
952
|
+
queueJobId: queueCtx.queueJobId,
|
|
953
|
+
queueId: queueCtx.id,
|
|
954
|
+
error: e?.message ?? String(e)
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
await notifyQueueJobStep(queueCtx.queueJobId, "start", {
|
|
959
|
+
stepIndex: queueCtx.stepIndex,
|
|
960
|
+
workerJobId: jobId,
|
|
961
|
+
workerId,
|
|
962
|
+
input
|
|
963
|
+
});
|
|
964
|
+
}
|
|
217
965
|
let output;
|
|
218
966
|
try {
|
|
219
967
|
output = await handler({
|
|
@@ -253,6 +1001,15 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
253
1001
|
});
|
|
254
1002
|
}
|
|
255
1003
|
}
|
|
1004
|
+
const queueCtxFail = input?.__workerQueue ?? metadata?.__workerQueue;
|
|
1005
|
+
if (queueCtxFail?.queueJobId && typeof queueCtxFail.stepIndex === "number") {
|
|
1006
|
+
await notifyQueueJobStep(queueCtxFail.queueJobId, "fail", {
|
|
1007
|
+
stepIndex: queueCtxFail.stepIndex,
|
|
1008
|
+
workerJobId: jobId,
|
|
1009
|
+
workerId,
|
|
1010
|
+
error: errorPayload.error
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
256
1013
|
if (webhookUrl) {
|
|
257
1014
|
await sendWebhook(webhookUrl, errorPayload);
|
|
258
1015
|
}
|
|
@@ -276,6 +1033,15 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
276
1033
|
});
|
|
277
1034
|
}
|
|
278
1035
|
}
|
|
1036
|
+
const queueCtxSuccess = input?.__workerQueue ?? metadata?.__workerQueue;
|
|
1037
|
+
if (queueCtxSuccess?.queueJobId && typeof queueCtxSuccess.stepIndex === "number") {
|
|
1038
|
+
await notifyQueueJobStep(queueCtxSuccess.queueJobId, "complete", {
|
|
1039
|
+
stepIndex: queueCtxSuccess.stepIndex,
|
|
1040
|
+
workerJobId: jobId,
|
|
1041
|
+
workerId,
|
|
1042
|
+
output
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
279
1045
|
console.log("[Worker] Job completed:", {
|
|
280
1046
|
jobId,
|
|
281
1047
|
workerId,
|
|
@@ -306,6 +1072,8 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
306
1072
|
}
|
|
307
1073
|
// Annotate the CommonJS export names for ESM import in node:
|
|
308
1074
|
0 && (module.exports = {
|
|
309
|
-
|
|
1075
|
+
SQS_MAX_DELAY_SECONDS,
|
|
1076
|
+
createLambdaHandler,
|
|
1077
|
+
wrapHandlerForQueue
|
|
310
1078
|
});
|
|
311
1079
|
//# sourceMappingURL=handler.js.map
|