@detiq/crawler 0.2.13 → 1.0.0
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/crawler.js +9 -6
- package/dist/crawler.js.map +2 -2
- package/dist/job-queue.js +15 -8
- package/dist/job-queue.js.map +2 -2
- package/dist/session-capture.d.ts +1 -0
- package/dist/session-capture.js +2 -1
- package/dist/session-capture.js.map +2 -2
- package/dist/tls-fingerprint.js +1 -1
- package/dist/tls-fingerprint.js.map +2 -2
- package/package.json +2 -1
- package/src/crawler.ts +62 -22
- package/src/job-queue.ts +23 -20
- package/src/phash.ts +33 -0
- package/src/session-capture.ts +5 -2
- package/src/stealth/human-behavior.ts +13 -11
- package/src/vendor.d.ts +20 -0
- package/types/session-capture.d.ts +1 -0
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
|
|
85
|
-
const WORKER_POLL_INTERVAL_MS = Number(process.env.JOB_WORKER_POLL_INTERVAL_MS
|
|
86
|
-
const WORKER_CONCURRENCY = Number(process.env.JOB_WORKER_CONCURRENCY
|
|
87
|
-
const JOB_HEARTBEAT_INTERVAL_MS = Number(process.env.JOB_HEARTBEAT_INTERVAL_MS
|
|
88
|
-
const TEST_EXEC_CONCURRENCY = Number(process.env.TEST_EXEC_CONCURRENCY
|
|
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:
|
|
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?.(
|
|
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
|
}
|