@detiq/crawler 0.2.14 → 1.0.1

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/job-queue.js CHANGED
@@ -81,11 +81,11 @@ function makeJobName(type) {
81
81
  }
82
82
  const runningControllers = /* @__PURE__ */ new Map();
83
83
  const WORKER_ID = `${os.hostname()}:${process.pid}`;
84
- const STALE_JOB_TIMEOUT_MINUTES = Number(process.env.JOB_STALE_TIMEOUT_MINUTES ?? 30);
85
- const WORKER_POLL_INTERVAL_MS = Number(process.env.JOB_WORKER_POLL_INTERVAL_MS ?? 15e3);
86
- const WORKER_CONCURRENCY = Number(process.env.JOB_WORKER_CONCURRENCY ?? 3);
87
- const JOB_HEARTBEAT_INTERVAL_MS = Number(process.env.JOB_HEARTBEAT_INTERVAL_MS ?? 15e3);
88
- const TEST_EXEC_CONCURRENCY = Number(process.env.TEST_EXEC_CONCURRENCY ?? 3);
84
+ const STALE_JOB_TIMEOUT_MINUTES = Number(process.env.JOB_STALE_TIMEOUT_MINUTES) || 30;
85
+ const WORKER_POLL_INTERVAL_MS = Number(process.env.JOB_WORKER_POLL_INTERVAL_MS) || 15e3;
86
+ const WORKER_CONCURRENCY = Number(process.env.JOB_WORKER_CONCURRENCY) || 3;
87
+ const JOB_HEARTBEAT_INTERVAL_MS = Number(process.env.JOB_HEARTBEAT_INTERVAL_MS) || 15e3;
88
+ const TEST_EXEC_CONCURRENCY = Number(process.env.TEST_EXEC_CONCURRENCY) || 3;
89
89
  let jobDispatchTable = null;
90
90
  async function claimSpecificJob(jobId) {
91
91
  const rows = await prismaAdmin.$queryRaw`
@@ -1255,23 +1255,29 @@ async function processDiscoverJob(jobId, config, opts) {
1255
1255
  const { tenantId, projectId } = config;
1256
1256
  const controller = new AbortController();
1257
1257
  runningControllers.set(jobId, controller);
1258
+ const heartbeatTimer = setInterval(() => {
1259
+ void heartbeatJob(tenantId, jobId);
1260
+ }, JOB_HEARTBEAT_INTERVAL_MS);
1258
1261
  const allUrls = /* @__PURE__ */ new Set();
1259
1262
  let lastPartialFlush = 0;
1263
+ let lastFlushedPct = 0;
1260
1264
  const flushPartialUrls = async (pct, step) => {
1261
1265
  const now = Date.now();
1262
1266
  if (now - lastPartialFlush < 5e3 && allUrls.size < 5) return;
1267
+ const monotonic = Math.max(pct, lastFlushedPct);
1268
+ lastFlushedPct = monotonic;
1263
1269
  lastPartialFlush = now;
1264
1270
  try {
1265
1271
  await withTenant(
1266
1272
  tenantId,
1267
1273
  (tx) => tx.platformJob.update({
1268
1274
  where: { id: jobId },
1269
- data: { progress: pct, result: { step, partialUrls: Array.from(allUrls) }, heartbeatAt: /* @__PURE__ */ new Date() }
1275
+ data: { progress: monotonic, result: { step, partialUrls: Array.from(allUrls) }, heartbeatAt: /* @__PURE__ */ new Date() }
1270
1276
  })
1271
1277
  );
1272
1278
  } catch {
1273
1279
  }
1274
- await opts?.onProgress?.(pct);
1280
+ await opts?.onProgress?.(monotonic);
1275
1281
  };
1276
1282
  const onProgress = async (pct, step) => {
1277
1283
  await updateJobProgress(tenantId, jobId, pct, step);
@@ -1357,7 +1363,7 @@ async function processDiscoverJob(jobId, config, opts) {
1357
1363
  authToken: crawlCfg.authToken,
1358
1364
  authTokenHeader: crawlCfg.authTokenHeader,
1359
1365
  authTokenPrefix: crawlCfg.authTokenPrefix,
1360
- startUrls: sitemapUrls.length > 0 ? sitemapUrls : void 0,
1366
+ startUrls: crawlCfg.postLoginUrl ? [crawlCfg.postLoginUrl, ...sitemapUrls.length > 0 ? sitemapUrls : []] : sitemapUrls.length > 0 ? sitemapUrls : void 0,
1361
1367
  screenshotDir,
1362
1368
  maxScreens: maxDiscoverUrls,
1363
1369
  proxyUrl,
@@ -1432,6 +1438,7 @@ async function processDiscoverJob(jobId, config, opts) {
1432
1438
  })
1433
1439
  ).catch(console.error);
1434
1440
  } finally {
1441
+ clearInterval(heartbeatTimer);
1435
1442
  runningControllers.delete(jobId);
1436
1443
  }
1437
1444
  }