@nitpicker/crawler 0.9.0 → 0.12.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/lib/archive/archive-accessor.d.ts +87 -14
- package/lib/archive/archive-accessor.js +162 -36
- package/lib/archive/archive.d.ts +262 -24
- package/lib/archive/archive.js +397 -86
- package/lib/archive/cache/compute-archive-cache-key.d.ts +39 -0
- package/lib/archive/cache/compute-archive-cache-key.js +95 -0
- package/lib/archive/cache/extract-archive-to-cache.d.ts +43 -0
- package/lib/archive/cache/extract-archive-to-cache.js +309 -0
- package/lib/archive/cache/get-archive-cache-root.d.ts +20 -0
- package/lib/archive/cache/get-archive-cache-root.js +53 -0
- package/lib/archive/cache/is-archive-cache-disabled.d.ts +24 -0
- package/lib/archive/cache/is-archive-cache-disabled.js +34 -0
- package/lib/archive/cache/resolve-archive-cache-dir.d.ts +26 -0
- package/lib/archive/cache/resolve-archive-cache-dir.js +32 -0
- package/lib/archive/database.d.ts +411 -26
- package/lib/archive/database.js +1881 -540
- package/lib/archive/derive-lineage-from-parent.d.ts +37 -0
- package/lib/archive/derive-lineage-from-parent.js +42 -0
- package/lib/archive/filesystem/peek-tar-top-dir.d.ts +28 -0
- package/lib/archive/filesystem/peek-tar-top-dir.js +65 -0
- package/lib/archive/get-failed-page-messages.d.ts +43 -0
- package/lib/archive/get-failed-page-messages.js +131 -0
- package/lib/archive/init-schema.d.ts +53 -2
- package/lib/archive/init-schema.js +399 -15
- package/lib/archive/is-inventory-source.d.ts +21 -0
- package/lib/archive/is-inventory-source.js +22 -0
- package/lib/archive/meta/assert-compatible-version.d.ts +39 -0
- package/lib/archive/meta/assert-compatible-version.js +72 -0
- package/lib/archive/meta/classify-jsonld-type.d.ts +23 -0
- package/lib/archive/meta/classify-jsonld-type.js +43 -0
- package/lib/archive/meta/compare-semver.d.ts +23 -0
- package/lib/archive/meta/compare-semver.js +51 -0
- package/lib/archive/meta/compute-page-denormalized.d.ts +21 -0
- package/lib/archive/meta/compute-page-denormalized.js +35 -0
- package/lib/archive/meta/derive-flat-from-meta.d.ts +35 -0
- package/lib/archive/meta/derive-flat-from-meta.js +158 -0
- package/lib/archive/meta/derive-meta-extras.d.ts +20 -0
- package/lib/archive/meta/derive-meta-extras.js +23 -0
- package/lib/archive/meta/extract-tags-for-archive.d.ts +18 -0
- package/lib/archive/meta/extract-tags-for-archive.js +36 -0
- package/lib/archive/meta/summarize-jsonld.d.ts +17 -0
- package/lib/archive/meta/summarize-jsonld.js +29 -0
- package/lib/archive/meta/summarize-tags.d.ts +16 -0
- package/lib/archive/meta/summarize-tags.js +33 -0
- package/lib/archive/meta/types.d.ts +207 -0
- package/lib/archive/meta/types.js +33 -0
- package/lib/archive/migrate-crawl-errors.d.ts +20 -0
- package/lib/archive/migrate-crawl-errors.js +38 -0
- package/lib/archive/migrate-html-blob-tables.d.ts +24 -0
- package/lib/archive/migrate-html-blob-tables.js +53 -0
- package/lib/archive/migrate-inventory-runs.d.ts +29 -0
- package/lib/archive/migrate-inventory-runs.js +52 -0
- package/lib/archive/migrate-page-errors.d.ts +16 -0
- package/lib/archive/migrate-page-errors.js +35 -0
- package/lib/archive/migrate-pages-resources-source.d.ts +16 -0
- package/lib/archive/migrate-pages-resources-source.js +46 -0
- package/lib/archive/page.d.ts +187 -49
- package/lib/archive/page.js +258 -63
- package/lib/archive/peek-archive-lock.d.ts +40 -0
- package/lib/archive/peek-archive-lock.js +62 -0
- package/lib/archive/resolve-redirect-chain.d.ts +33 -0
- package/lib/archive/resolve-redirect-chain.js +27 -0
- package/lib/archive/types.d.ts +168 -26
- package/lib/classify-error-kind.d.ts +19 -0
- package/lib/classify-error-kind.js +122 -0
- package/lib/crawler/build-js-redirect-edge.d.ts +68 -0
- package/lib/crawler/build-js-redirect-edge.js +57 -0
- package/lib/crawler/build-redirect-event.d.ts +24 -0
- package/lib/crawler/build-redirect-event.js +28 -0
- package/lib/crawler/clear-dns-burned-host-cache.d.ts +6 -0
- package/lib/crawler/clear-dns-burned-host-cache.js +11 -0
- package/lib/crawler/close-browser-safely.d.ts +64 -0
- package/lib/crawler/close-browser-safely.js +73 -0
- package/lib/crawler/crawler.d.ts +7 -2
- package/lib/crawler/crawler.js +919 -113
- package/lib/crawler/create-change-phase-handler.d.ts +54 -0
- package/lib/crawler/create-change-phase-handler.js +44 -0
- package/lib/crawler/derive-js-redirect-target.d.ts +68 -0
- package/lib/crawler/derive-js-redirect-target.js +129 -0
- package/lib/crawler/derive-page-source.d.ts +23 -0
- package/lib/crawler/derive-page-source.js +28 -0
- package/lib/crawler/derive-resource-source.d.ts +33 -0
- package/lib/crawler/derive-resource-source.js +37 -0
- package/lib/crawler/dns-burned-host-cache.d.ts +26 -0
- package/lib/crawler/dns-burned-host-cache.js +25 -0
- package/lib/crawler/dns-burned-host-short-circuit-counter.d.ts +13 -0
- package/lib/crawler/dns-burned-host-short-circuit-counter.js +11 -0
- package/lib/crawler/drain-phase-errors.d.ts +48 -0
- package/lib/crawler/drain-phase-errors.js +35 -0
- package/lib/crawler/fetch-destination.d.ts +12 -4
- package/lib/crawler/fetch-destination.js +132 -18
- package/lib/crawler/format-crawl-progress.d.ts +12 -3
- package/lib/crawler/format-crawl-progress.js +14 -6
- package/lib/crawler/handle-browser-close.d.ts +29 -0
- package/lib/crawler/handle-browser-close.js +28 -0
- package/lib/crawler/is-html-content-type.d.ts +17 -0
- package/lib/crawler/is-html-content-type.js +19 -0
- package/lib/crawler/is-js-redirect-error-shape.d.ts +40 -0
- package/lib/crawler/is-js-redirect-error-shape.js +53 -0
- package/lib/crawler/is-likely-html-url.d.ts +22 -0
- package/lib/crawler/is-likely-html-url.js +65 -0
- package/lib/crawler/is-puppeteer-fallback-candidate.d.ts +16 -0
- package/lib/crawler/is-puppeteer-fallback-candidate.js +63 -0
- package/lib/crawler/kill-process-tree.d.ts +94 -0
- package/lib/crawler/kill-process-tree.js +178 -0
- package/lib/crawler/link-list.d.ts +21 -1
- package/lib/crawler/link-list.js +25 -4
- package/lib/crawler/link-to-page-data.d.ts +13 -5
- package/lib/crawler/link-to-page-data.js +26 -5
- package/lib/crawler/log-undrained-phase-errors.d.ts +37 -0
- package/lib/crawler/log-undrained-phase-errors.js +34 -0
- package/lib/crawler/normalize-content-type.d.ts +14 -0
- package/lib/crawler/normalize-content-type.js +20 -0
- package/lib/crawler/partition-urls-by-html.d.ts +16 -0
- package/lib/crawler/partition-urls-by-html.js +23 -0
- package/lib/crawler/plan-sub-resource-emits.d.ts +63 -0
- package/lib/crawler/plan-sub-resource-emits.js +44 -0
- package/lib/crawler/preload-short-circuit-error.d.ts +22 -0
- package/lib/crawler/preload-short-circuit-error.js +25 -0
- package/lib/crawler/redirect-dest-key.d.ts +19 -0
- package/lib/crawler/redirect-dest-key.js +27 -0
- package/lib/crawler/resource-to-page-data.d.ts +28 -0
- package/lib/crawler/resource-to-page-data.js +59 -0
- package/lib/crawler/should-burn-host.d.ts +78 -0
- package/lib/crawler/should-burn-host.js +61 -0
- package/lib/crawler/should-get-fallback-on-head-failure.d.ts +38 -0
- package/lib/crawler/should-get-fallback-on-head-failure.js +46 -0
- package/lib/crawler/types.d.ts +229 -1
- package/lib/crawler-orchestrator.d.ts +105 -3
- package/lib/crawler-orchestrator.js +620 -20
- package/lib/crawler.d.ts +8 -2
- package/lib/crawler.js +6 -1
- package/lib/permanent-error-kinds.d.ts +43 -0
- package/lib/permanent-error-kinds.js +48 -0
- package/lib/resource-row-to-lookup-result.d.ts +13 -0
- package/lib/resource-row-to-lookup-result.js +20 -0
- package/lib/types.d.ts +95 -1
- package/lib/utils/compute-file-sha256.d.ts +23 -0
- package/lib/utils/compute-file-sha256.js +55 -0
- package/lib/utils/error/emit-error-with-retry.d.ts +40 -0
- package/lib/utils/error/emit-error-with-retry.js +44 -0
- package/lib/utils/error/emit-error.d.ts +39 -0
- package/lib/utils/error/emit-error.js +41 -0
- package/lib/utils/object/parse-response-headers.d.ts +12 -0
- package/lib/utils/object/parse-response-headers.js +26 -0
- package/package.json +11 -11
- package/lib/utils/error/error-emitter.d.ts +0 -18
- package/lib/utils/error/error-emitter.js +0 -29
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { crawlerLog } from '../debug.js';
|
|
2
|
+
import { killProcessTree } from './kill-process-tree.js';
|
|
3
|
+
/**
|
|
4
|
+
* Default time to wait for a graceful `browser.close()` before force-killing
|
|
5
|
+
* the underlying Chromium process, in milliseconds.
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_CLOSE_TIMEOUT_MS = 30 * 1000;
|
|
8
|
+
/**
|
|
9
|
+
* Closes a Puppeteer browser, falling back to a hard tree-kill if the graceful
|
|
10
|
+
* close hangs.
|
|
11
|
+
*
|
|
12
|
+
* WHY: When a page's Chromium session dies mid-scrape (e.g. a viewport change
|
|
13
|
+
* detaches the frame, surfacing `Attempted to use detached Frame` or
|
|
14
|
+
* `Session closed`), the CDP connection can be left wedged. A bare
|
|
15
|
+
* `await browser.close()` then never settles, stalling the `deal()` worker and
|
|
16
|
+
* hanging the whole crawl. Racing the close against a timeout and SIGKILLing
|
|
17
|
+
* the Chromium process tree (parent + renderer/network/zygote children) on
|
|
18
|
+
* expiry guarantees the worker always completes and no orphan subprocesses are
|
|
19
|
+
* left behind.
|
|
20
|
+
*
|
|
21
|
+
* The losing timer is cleared explicitly in `.finally()` so it never keeps the
|
|
22
|
+
* event loop alive after the race settles (a plain `delay()` in `Promise.race`
|
|
23
|
+
* would leak the timer until it fires).
|
|
24
|
+
*
|
|
25
|
+
* The tree-kill happens via {@link killProcessTree}, which enumerates
|
|
26
|
+
* descendants through `ps` (POSIX) or delegates to `taskkill /T /F` (Windows).
|
|
27
|
+
* `childProcess.kill('SIGKILL')` is still invoked on the parent up-front
|
|
28
|
+
* because Node's `ChildProcess.killed` flag governs how Node treats the
|
|
29
|
+
* spawn handle (reaping etc.); without it the parent would linger in Node's
|
|
30
|
+
* process table even after the OS-level kill.
|
|
31
|
+
* @param browser - The browser to close.
|
|
32
|
+
* @param timeoutMs - Milliseconds to wait for a graceful close before force-killing.
|
|
33
|
+
* Defaults to {@link DEFAULT_CLOSE_TIMEOUT_MS}.
|
|
34
|
+
* @param deps - Test-time overrides (default-free for production callers).
|
|
35
|
+
* @returns `true` if the graceful close timed out (and a tree-kill was
|
|
36
|
+
* attempted), `false` if `close()` settled in time.
|
|
37
|
+
*/
|
|
38
|
+
export async function closeBrowserSafely(browser, timeoutMs = DEFAULT_CLOSE_TIMEOUT_MS, deps = {}) {
|
|
39
|
+
// Capture the process up-front: after a successful close() puppeteer
|
|
40
|
+
// releases its internal reference and process() returns null, so we would
|
|
41
|
+
// have no handle to tree-kill on timeout.
|
|
42
|
+
const childProcess = browser.process();
|
|
43
|
+
let timeoutHandle;
|
|
44
|
+
const timedOut = await Promise.race([
|
|
45
|
+
browser
|
|
46
|
+
.close()
|
|
47
|
+
.then(() => false)
|
|
48
|
+
.catch(() => false),
|
|
49
|
+
new Promise((resolve) => {
|
|
50
|
+
timeoutHandle = setTimeout(() => resolve(true), timeoutMs);
|
|
51
|
+
}),
|
|
52
|
+
]).finally(() => {
|
|
53
|
+
if (timeoutHandle) {
|
|
54
|
+
clearTimeout(timeoutHandle);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
if (timedOut && childProcess && !childProcess.killed) {
|
|
58
|
+
// Mark the Node ChildProcess as killed so Node's reaping logic treats
|
|
59
|
+
// it correctly; then walk the OS process tree.
|
|
60
|
+
childProcess.kill('SIGKILL');
|
|
61
|
+
// Capture pid once: ChildProcess.pid is technically `number | undefined`
|
|
62
|
+
// (undefined before spawn settles), and reading it twice across the
|
|
63
|
+
// `await` below would force the second read to re-widen back to
|
|
64
|
+
// `number | undefined` regardless of the typeof guard. Snapshotting
|
|
65
|
+
// makes the type and the runtime value match.
|
|
66
|
+
const pid = childProcess.pid;
|
|
67
|
+
if (typeof pid === 'number') {
|
|
68
|
+
const killTree = deps.killTree ?? ((p, sig) => killProcessTree(p, sig, { log: crawlerLog }));
|
|
69
|
+
await killTree(pid, 'SIGKILL');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return timedOut;
|
|
73
|
+
}
|
package/lib/crawler/crawler.d.ts
CHANGED
|
@@ -53,8 +53,11 @@ export default class Crawler extends EventEmitter<CrawlerEventTypes> {
|
|
|
53
53
|
* @param pending - URLs that were pending (not yet scraped) in the previous session.
|
|
54
54
|
* @param scraped - URLs that were already scraped in the previous session.
|
|
55
55
|
* @param resources - Resource URLs that were already captured in the previous session.
|
|
56
|
+
* @param pagesScrapedOffset - Number of HTML pages already rendered in previous
|
|
57
|
+
* sessions, used to seed the session-spanning progress counter. Defaults to 0
|
|
58
|
+
* for callers that don't need cross-session accuracy in the progress display.
|
|
56
59
|
*/
|
|
57
|
-
resume(pending: string[], scraped: string[], resources: string[]): void;
|
|
60
|
+
resume(pending: string[], scraped: string[], resources: string[], pagesScrapedOffset?: number): void;
|
|
58
61
|
/**
|
|
59
62
|
* Start crawling from one or more root URLs.
|
|
60
63
|
*
|
|
@@ -68,7 +71,8 @@ export default class Crawler extends EventEmitter<CrawlerEventTypes> {
|
|
|
68
71
|
* before reaching the dealer so a URL that exists in both sources — which
|
|
69
72
|
* is common in append-mode when a new root coincides with a repromoted
|
|
70
73
|
* previously-external page — does not race on two parallel slots.
|
|
71
|
-
* @param urls - The list of root URLs to begin crawling from.
|
|
74
|
+
* @param urls - The list of root URLs to begin crawling from. May be empty
|
|
75
|
+
* when resumed pending URLs already exist (for example `--retry-failed`).
|
|
72
76
|
* @param opts - Optional overrides; currently only `recursive` is honoured.
|
|
73
77
|
* @param opts.recursive - When `false`, disables recursive discovery and forces list-mode.
|
|
74
78
|
* Defaults to the constructor option's `recursive` value.
|
|
@@ -77,6 +81,7 @@ export default class Crawler extends EventEmitter<CrawlerEventTypes> {
|
|
|
77
81
|
start(urls: ExURL[], opts?: {
|
|
78
82
|
recursive?: boolean;
|
|
79
83
|
}): void;
|
|
84
|
+
private _launchBrowserAndScrape;
|
|
80
85
|
/**
|
|
81
86
|
* The default maximum number of concurrent scraping processes.
|
|
82
87
|
*
|