@detiq/crawler 0.2.11 → 0.2.13
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/Dockerfile +27 -11
- package/package.json +1 -1
- package/src/crawler.ts +1 -1
- package/src/job-queue.ts +12 -2
- package/src/tls-fingerprint.ts +1 -1
package/Dockerfile
CHANGED
|
@@ -16,13 +16,25 @@ RUN apt-get update && apt-get install -y curl && \
|
|
|
16
16
|
apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
17
17
|
|
|
18
18
|
# Workspace manifests (layer cache)
|
|
19
|
+
# Copy all workspace package.json files so npm ci can resolve the full lockfile.
|
|
20
|
+
# Packages not used by the crawler (api, web, etc.) are stubs; their source is not copied later.
|
|
19
21
|
COPY package.json package-lock.json ./
|
|
20
|
-
COPY packages/
|
|
21
|
-
COPY packages/database/package.json packages/database/
|
|
22
|
-
COPY packages/app-brain/package.json packages/app-brain/
|
|
22
|
+
COPY packages/agent-cli/package.json packages/agent-cli/
|
|
23
23
|
COPY packages/agents/package.json packages/agents/
|
|
24
|
+
COPY packages/api/package.json packages/api/
|
|
25
|
+
COPY packages/app-brain/package.json packages/app-brain/
|
|
26
|
+
COPY packages/chrome-extension/package.json packages/chrome-extension/
|
|
27
|
+
COPY packages/connectors/package.json packages/connectors/
|
|
28
|
+
COPY packages/core/package.json packages/core/
|
|
24
29
|
COPY packages/crawler/package.json packages/crawler/
|
|
25
|
-
|
|
30
|
+
COPY packages/database/package.json packages/database/
|
|
31
|
+
COPY packages/github-action/package.json packages/github-action/
|
|
32
|
+
COPY packages/reranker/package.json packages/reranker/
|
|
33
|
+
COPY packages/sdk/package.json packages/sdk/
|
|
34
|
+
COPY packages/session-receiver/package.json packages/session-receiver/
|
|
35
|
+
COPY packages/vscode-extension/package.json packages/vscode-extension/
|
|
36
|
+
COPY packages/web/package.json packages/web/
|
|
37
|
+
RUN npm ci --include=dev
|
|
26
38
|
|
|
27
39
|
# Re-install chromium after npm ci so the browser revision matches the
|
|
28
40
|
# exact playwright version resolved by the lockfile (not the base image's
|
|
@@ -31,16 +43,20 @@ RUN npx playwright install chromium
|
|
|
31
43
|
|
|
32
44
|
# Source
|
|
33
45
|
COPY tsconfig.base.json ./
|
|
34
|
-
COPY packages/
|
|
35
|
-
COPY packages/
|
|
36
|
-
COPY packages/
|
|
37
|
-
COPY packages/
|
|
38
|
-
COPY packages/
|
|
46
|
+
COPY packages/database packages/database
|
|
47
|
+
COPY packages/reranker packages/reranker
|
|
48
|
+
COPY packages/core packages/core
|
|
49
|
+
COPY packages/connectors packages/connectors
|
|
50
|
+
COPY packages/app-brain packages/app-brain
|
|
51
|
+
COPY packages/agents packages/agents
|
|
52
|
+
COPY packages/crawler packages/crawler
|
|
39
53
|
|
|
40
|
-
# Build
|
|
54
|
+
# Build order: database → reranker → core → connectors → app-brain → agents → crawler
|
|
41
55
|
RUN npx prisma generate --schema packages/database/prisma/schema.prisma && \
|
|
42
|
-
npm run -w @detiq/core build && \
|
|
43
56
|
npm run -w @detiq/database build && \
|
|
57
|
+
npm run -w @detiq/reranker build && \
|
|
58
|
+
npm run -w @detiq/core build && \
|
|
59
|
+
npm run -w @detiq/connectors build && \
|
|
44
60
|
npm run -w @detiq/app-brain build && \
|
|
45
61
|
npm run -w @detiq/agents build && \
|
|
46
62
|
npm run -w @detiq/crawler build
|
package/package.json
CHANGED
package/src/crawler.ts
CHANGED
|
@@ -1340,7 +1340,7 @@ export async function crawlProject(opts: {
|
|
|
1340
1340
|
}
|
|
1341
1341
|
let checkpointSuccessCount = 0;
|
|
1342
1342
|
let maxSeenTotal = 0; // track high-water mark so progress % never goes backwards
|
|
1343
|
-
let lastEmittedPct =
|
|
1343
|
+
let lastEmittedPct = 20; // floor above auth-discovery + login phases (max ~19%)
|
|
1344
1344
|
const crawlLoopStart = Date.now();
|
|
1345
1345
|
const startUrl = page.url();
|
|
1346
1346
|
// Resume from previous segment's pending queue if provided
|
package/src/job-queue.ts
CHANGED
|
@@ -1551,25 +1551,34 @@ async function processDiscoverJob(jobId: string, config: any, opts?: ProcessJobO
|
|
|
1551
1551
|
const controller = new AbortController();
|
|
1552
1552
|
runningControllers.set(jobId, controller);
|
|
1553
1553
|
|
|
1554
|
+
// Independent heartbeat timer — keeps heartbeatAt fresh even when no URLs are
|
|
1555
|
+
// arriving (e.g. during auth login, page-load waits, 2FA handling).
|
|
1556
|
+
const heartbeatTimer = setInterval(() => {
|
|
1557
|
+
void heartbeatJob(tenantId, jobId);
|
|
1558
|
+
}, JOB_HEARTBEAT_INTERVAL_MS);
|
|
1559
|
+
|
|
1554
1560
|
// Shared accumulator — updated by onUrlsDiscovered callback as each page is visited.
|
|
1555
1561
|
// This lets the frontend poll and see a growing list before the job finishes.
|
|
1556
1562
|
const allUrls = new Set<string>();
|
|
1557
1563
|
let lastPartialFlush = 0;
|
|
1564
|
+
let lastFlushedPct = 0; // high-water mark — progress never decreases
|
|
1558
1565
|
|
|
1559
1566
|
const flushPartialUrls = async (pct: number, step: string) => {
|
|
1560
1567
|
const now = Date.now();
|
|
1561
1568
|
// Flush to DB at most every 5 seconds to avoid excessive writes
|
|
1562
1569
|
if (now - lastPartialFlush < 5_000 && allUrls.size < 5) return;
|
|
1570
|
+
const monotonic = Math.max(pct, lastFlushedPct);
|
|
1571
|
+
lastFlushedPct = monotonic;
|
|
1563
1572
|
lastPartialFlush = now;
|
|
1564
1573
|
try {
|
|
1565
1574
|
await withTenant(tenantId, (tx) =>
|
|
1566
1575
|
tx.platformJob.update({
|
|
1567
1576
|
where: { id: jobId },
|
|
1568
|
-
data: { progress:
|
|
1577
|
+
data: { progress: monotonic, result: { step, partialUrls: Array.from(allUrls) } as any, heartbeatAt: new Date() },
|
|
1569
1578
|
})
|
|
1570
1579
|
);
|
|
1571
1580
|
} catch { /* non-fatal */ }
|
|
1572
|
-
await opts?.onProgress?.(
|
|
1581
|
+
await opts?.onProgress?.(monotonic);
|
|
1573
1582
|
};
|
|
1574
1583
|
|
|
1575
1584
|
const onProgress = async (pct: number, step: string) => {
|
|
@@ -1773,6 +1782,7 @@ async function processDiscoverJob(jobId: string, config: any, opts?: ProcessJobO
|
|
|
1773
1782
|
})
|
|
1774
1783
|
).catch(console.error);
|
|
1775
1784
|
} finally {
|
|
1785
|
+
clearInterval(heartbeatTimer);
|
|
1776
1786
|
runningControllers.delete(jobId);
|
|
1777
1787
|
}
|
|
1778
1788
|
}
|
package/src/tls-fingerprint.ts
CHANGED
|
@@ -82,7 +82,7 @@ export async function probeTlsFingerprint(host: string, port = 443): Promise<{
|
|
|
82
82
|
protocol: socket.getProtocol() ?? 'unknown',
|
|
83
83
|
cipher: socket.getCipher()?.name ?? 'unknown',
|
|
84
84
|
authorized: socket.authorized,
|
|
85
|
-
subjectCN: cert?.subject?.CN ?? null,
|
|
85
|
+
subjectCN: cert?.subject?.CN?.toString() ?? null,
|
|
86
86
|
});
|
|
87
87
|
socket.destroy();
|
|
88
88
|
});
|