@nitpicker/crawler 0.11.0 → 0.13.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/README.md +6 -4
- package/lib/archive/archive-accessor.d.ts +2 -2
- package/lib/archive/archive-accessor.js +2 -2
- package/lib/archive/archive-lock.d.ts +7 -0
- package/lib/archive/archive-lock.js +7 -0
- package/lib/archive/archive.d.ts +175 -13
- package/lib/archive/archive.js +198 -14
- 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/create-adjunct-tables.d.ts +43 -0
- package/lib/archive/create-adjunct-tables.js +213 -0
- package/lib/archive/create-entity-tables.d.ts +173 -0
- package/lib/archive/create-entity-tables.js +318 -0
- package/lib/archive/create-progress-reporter.d.ts +30 -0
- package/lib/archive/create-progress-reporter.js +38 -0
- package/lib/archive/create-ref-tables.d.ts +35 -0
- package/lib/archive/create-ref-tables.js +188 -0
- package/lib/archive/database.d.ts +130 -182
- package/lib/archive/database.js +524 -1777
- package/lib/archive/db-ops/_shared/clear-write-ref-caches.d.ts +27 -0
- package/lib/archive/db-ops/_shared/clear-write-ref-caches.js +34 -0
- package/lib/archive/db-ops/_shared/create-write-ref-caches.d.ts +17 -0
- package/lib/archive/db-ops/_shared/create-write-ref-caches.js +26 -0
- package/lib/archive/db-ops/_shared/decode-json-ref.d.ts +17 -0
- package/lib/archive/db-ops/_shared/decode-json-ref.js +31 -0
- package/lib/archive/db-ops/_shared/load-response-headers-by-set-ids.d.ts +20 -0
- package/lib/archive/db-ops/_shared/load-response-headers-by-set-ids.js +53 -0
- package/lib/archive/db-ops/_shared/resolve-content-item-id.d.ts +61 -0
- package/lib/archive/db-ops/_shared/resolve-content-item-id.js +111 -0
- package/lib/archive/db-ops/_shared/resolve-url-or-blob.d.ts +23 -0
- package/lib/archive/db-ops/_shared/resolve-url-or-blob.js +29 -0
- package/lib/archive/db-ops/_shared/retry-setting.d.ts +16 -0
- package/lib/archive/db-ops/_shared/retry-setting.js +18 -0
- package/lib/archive/db-ops/_shared/safe-parse-json.d.ts +11 -0
- package/lib/archive/db-ops/_shared/safe-parse-json.js +18 -0
- package/lib/archive/db-ops/_shared/types.d.ts +53 -0
- package/lib/archive/db-ops/_shared/types.js +1 -0
- package/lib/archive/db-ops/_shared/upsert-blob-ref.d.ts +25 -0
- package/lib/archive/db-ops/_shared/upsert-blob-ref.js +48 -0
- package/lib/archive/db-ops/_shared/upsert-content-type-ref.d.ts +30 -0
- package/lib/archive/db-ops/_shared/upsert-content-type-ref.js +45 -0
- package/lib/archive/db-ops/_shared/upsert-json-ref.d.ts +22 -0
- package/lib/archive/db-ops/_shared/upsert-json-ref.js +41 -0
- package/lib/archive/db-ops/_shared/upsert-response-headers.d.ts +35 -0
- package/lib/archive/db-ops/_shared/upsert-response-headers.js +49 -0
- package/lib/archive/db-ops/_shared/upsert-url-ref.d.ts +39 -0
- package/lib/archive/db-ops/_shared/upsert-url-ref.js +62 -0
- package/lib/archive/db-ops/analysis/replace-analysis-violations.d.ts +28 -0
- package/lib/archive/db-ops/analysis/replace-analysis-violations.js +152 -0
- package/lib/archive/db-ops/anchors/get-anchors-on-page.d.ts +10 -0
- package/lib/archive/db-ops/anchors/get-anchors-on-page.js +21 -0
- package/lib/archive/db-ops/config/get-base-url.d.ts +8 -0
- package/lib/archive/db-ops/config/get-base-url.js +14 -0
- package/lib/archive/db-ops/config/get-config.d.ts +10 -0
- package/lib/archive/db-ops/config/get-config.js +27 -0
- package/lib/archive/db-ops/config/get-name.d.ts +8 -0
- package/lib/archive/db-ops/config/get-name.js +14 -0
- package/lib/archive/db-ops/config/info-column-allowlist.d.ts +7 -0
- package/lib/archive/db-ops/config/info-column-allowlist.js +26 -0
- package/lib/archive/db-ops/config/info-json-columns.d.ts +5 -0
- package/lib/archive/db-ops/config/info-json-columns.js +10 -0
- package/lib/archive/db-ops/config/set-config.d.ts +12 -0
- package/lib/archive/db-ops/config/set-config.js +21 -0
- package/lib/archive/db-ops/config/update-config.d.ts +17 -0
- package/lib/archive/db-ops/config/update-config.js +36 -0
- package/lib/archive/db-ops/errors/insert-crawl-error.d.ts +15 -0
- package/lib/archive/db-ops/errors/insert-crawl-error.js +21 -0
- package/lib/archive/db-ops/errors/insert-page-error.d.ts +21 -0
- package/lib/archive/db-ops/errors/insert-page-error.js +28 -0
- package/lib/archive/db-ops/errors/list-dns-burned-host-candidates.d.ts +22 -0
- package/lib/archive/db-ops/errors/list-dns-burned-host-candidates.js +141 -0
- package/lib/archive/db-ops/html/get-html-of-page-by-id.d.ts +18 -0
- package/lib/archive/db-ops/html/get-html-of-page-by-id.js +29 -0
- package/lib/archive/db-ops/inventory/record-inventory-run.d.ts +21 -0
- package/lib/archive/db-ops/inventory/record-inventory-run.js +38 -0
- package/lib/archive/db-ops/lifecycle/checkpoint.d.ts +8 -0
- package/lib/archive/db-ops/lifecycle/checkpoint.js +9 -0
- package/lib/archive/db-ops/lifecycle/destroy.d.ts +6 -0
- package/lib/archive/db-ops/lifecycle/destroy.js +7 -0
- package/lib/archive/db-ops/lifecycle/init.d.ts +22 -0
- package/lib/archive/db-ops/lifecycle/init.js +42 -0
- package/lib/archive/db-ops/meta/get-jsonld-of-page.d.ts +13 -0
- package/lib/archive/db-ops/meta/get-jsonld-of-page.js +27 -0
- package/lib/archive/db-ops/meta/get-tags-of-page.d.ts +12 -0
- package/lib/archive/db-ops/meta/get-tags-of-page.js +28 -0
- package/lib/archive/db-ops/pages/order/set-url-order.d.ts +8 -0
- package/lib/archive/db-ops/pages/order/set-url-order.js +32 -0
- package/lib/archive/db-ops/pages/read/build-page-query.d.ts +18 -0
- package/lib/archive/db-ops/pages/read/build-page-query.js +40 -0
- package/lib/archive/db-ops/pages/read/get-crawling-state.d.ts +70 -0
- package/lib/archive/db-ops/pages/read/get-crawling-state.js +98 -0
- package/lib/archive/db-ops/pages/read/get-existing-page-urls.d.ts +15 -0
- package/lib/archive/db-ops/pages/read/get-existing-page-urls.js +30 -0
- package/lib/archive/db-ops/pages/read/get-page-count.d.ts +12 -0
- package/lib/archive/db-ops/pages/read/get-page-count.js +21 -0
- package/lib/archive/db-ops/pages/read/get-page-source-by-url.d.ts +24 -0
- package/lib/archive/db-ops/pages/read/get-page-source-by-url.js +28 -0
- package/lib/archive/db-ops/pages/read/get-pages-with-rels.d.ts +38 -0
- package/lib/archive/db-ops/pages/read/get-pages-with-rels.js +107 -0
- package/lib/archive/db-ops/pages/read/get-pages.d.ts +11 -0
- package/lib/archive/db-ops/pages/read/get-pages.js +51 -0
- package/lib/archive/db-ops/pages/read/get-scraped-html-page-count.d.ts +18 -0
- package/lib/archive/db-ops/pages/read/get-scraped-html-page-count.js +25 -0
- package/lib/archive/db-ops/pages/read/reconstruct-page-rows.d.ts +31 -0
- package/lib/archive/db-ops/pages/read/reconstruct-page-rows.js +32 -0
- package/lib/archive/db-ops/pages/reset/repromote-external-pages.d.ts +24 -0
- package/lib/archive/db-ops/pages/reset/repromote-external-pages.js +93 -0
- package/lib/archive/db-ops/pages/reset/reset-failed-pages.d.ts +47 -0
- package/lib/archive/db-ops/pages/reset/reset-failed-pages.js +124 -0
- package/lib/archive/db-ops/pages/write/insert-inventory-seeds.d.ts +37 -0
- package/lib/archive/db-ops/pages/write/insert-inventory-seeds.js +72 -0
- package/lib/archive/db-ops/pages/write/insert-jsonld.d.ts +17 -0
- package/lib/archive/db-ops/pages/write/insert-jsonld.js +49 -0
- package/lib/archive/db-ops/pages/write/insert-page.d.ts +36 -0
- package/lib/archive/db-ops/pages/write/insert-page.js +208 -0
- package/lib/archive/db-ops/pages/write/insert-tags.d.ts +16 -0
- package/lib/archive/db-ops/pages/write/insert-tags.js +34 -0
- package/lib/archive/db-ops/pages/write/link-redirect-sources.d.ts +36 -0
- package/lib/archive/db-ops/pages/write/link-redirect-sources.js +93 -0
- package/lib/archive/db-ops/pages/write/record-redirect.d.ts +35 -0
- package/lib/archive/db-ops/pages/write/record-redirect.js +100 -0
- package/lib/archive/db-ops/pages/write/set-skipped-page.d.ts +13 -0
- package/lib/archive/db-ops/pages/write/set-skipped-page.js +22 -0
- package/lib/archive/db-ops/pages/write/update-page.d.ts +29 -0
- package/lib/archive/db-ops/pages/write/update-page.js +334 -0
- package/lib/archive/db-ops/pages/write/write-page-html-blob.d.ts +19 -0
- package/lib/archive/db-ops/pages/write/write-page-html-blob.js +41 -0
- package/lib/archive/db-ops/referrers/get-redirects-for-pages.d.ts +9 -0
- package/lib/archive/db-ops/referrers/get-redirects-for-pages.js +15 -0
- package/lib/archive/db-ops/referrers/get-referrers-of-page.d.ts +17 -0
- package/lib/archive/db-ops/referrers/get-referrers-of-page.js +32 -0
- package/lib/archive/db-ops/referrers/get-referrers-of-resource.d.ts +8 -0
- package/lib/archive/db-ops/referrers/get-referrers-of-resource.js +15 -0
- package/lib/archive/db-ops/resources/build-resource-query.d.ts +25 -0
- package/lib/archive/db-ops/resources/build-resource-query.js +29 -0
- package/lib/archive/db-ops/resources/get-existing-resource-urls.d.ts +9 -0
- package/lib/archive/db-ops/resources/get-existing-resource-urls.js +24 -0
- package/lib/archive/db-ops/resources/get-resource-by-url.d.ts +13 -0
- package/lib/archive/db-ops/resources/get-resource-by-url.js +22 -0
- package/lib/archive/db-ops/resources/get-resource-url-list.d.ts +9 -0
- package/lib/archive/db-ops/resources/get-resource-url-list.js +13 -0
- package/lib/archive/db-ops/resources/get-resources.d.ts +8 -0
- package/lib/archive/db-ops/resources/get-resources.js +11 -0
- package/lib/archive/db-ops/resources/insert-inventory-resources.d.ts +24 -0
- package/lib/archive/db-ops/resources/insert-inventory-resources.js +64 -0
- package/lib/archive/db-ops/resources/insert-resource-referrers.d.ts +15 -0
- package/lib/archive/db-ops/resources/insert-resource-referrers.js +54 -0
- package/lib/archive/db-ops/resources/insert-resource.d.ts +34 -0
- package/lib/archive/db-ops/resources/insert-resource.js +73 -0
- package/lib/archive/db-ops/resources/reconstruct-resource-rows.d.ts +26 -0
- package/lib/archive/db-ops/resources/reconstruct-resource-rows.js +30 -0
- package/lib/archive/decode-html-blob.d.ts +18 -0
- package/lib/archive/decode-html-blob.js +31 -0
- package/lib/archive/derive-lineage-from-parent.d.ts +37 -0
- package/lib/archive/derive-lineage-from-parent.js +42 -0
- package/lib/archive/drop-legacy-tables.d.ts +45 -0
- package/lib/archive/drop-legacy-tables.js +56 -0
- package/lib/archive/filesystem/rename.js +1 -1
- package/lib/archive/get-failed-page-messages.d.ts +44 -0
- package/lib/archive/get-failed-page-messages.js +132 -0
- package/lib/archive/init-schema.d.ts +35 -39
- package/lib/archive/init-schema.js +111 -320
- package/lib/archive/is-inventory-source.d.ts +21 -0
- package/lib/archive/is-inventory-source.js +22 -0
- package/lib/archive/limited-page-ids.d.ts +2 -1
- package/lib/archive/limited-page-ids.js +5 -4
- package/lib/archive/meta/assert-compatible-version.d.ts +24 -3
- package/lib/archive/meta/assert-compatible-version.js +24 -3
- package/lib/archive/meta/types.d.ts +87 -1
- package/lib/archive/meta/types.js +34 -2
- package/lib/archive/migrate-entity-tables.d.ts +45 -0
- package/lib/archive/migrate-entity-tables.js +56 -0
- package/lib/archive/migrate-ref-tables.d.ts +25 -0
- package/lib/archive/migrate-ref-tables.js +38 -0
- package/lib/archive/page-meta-column-maps.d.ts +32 -0
- package/lib/archive/page-meta-column-maps.js +43 -0
- package/lib/archive/page.d.ts +6 -6
- package/lib/archive/page.js +5 -5
- package/lib/archive/peek-archive-lock.d.ts +2 -2
- package/lib/archive/peek-archive-lock.js +2 -2
- package/lib/archive/populate-entity-tables/collapse-anchor-rows.d.ts +41 -0
- package/lib/archive/populate-entity-tables/collapse-anchor-rows.js +87 -0
- package/lib/archive/populate-entity-tables/derive-dom-path.d.ts +35 -0
- package/lib/archive/populate-entity-tables/derive-dom-path.js +72 -0
- package/lib/archive/populate-entity-tables/is-blob-ref-value.d.ts +16 -0
- package/lib/archive/populate-entity-tables/is-blob-ref-value.js +19 -0
- package/lib/archive/populate-entity-tables/match-images-to-dom-paths.d.ts +66 -0
- package/lib/archive/populate-entity-tables/match-images-to-dom-paths.js +96 -0
- package/lib/archive/populate-entity-tables/populate-anchor-edges.d.ts +33 -0
- package/lib/archive/populate-entity-tables/populate-anchor-edges.js +153 -0
- package/lib/archive/populate-entity-tables/populate-content-items.d.ts +40 -0
- package/lib/archive/populate-entity-tables/populate-content-items.js +141 -0
- package/lib/archive/populate-entity-tables/populate-entities.d.ts +81 -0
- package/lib/archive/populate-entity-tables/populate-entities.js +111 -0
- package/lib/archive/populate-entity-tables/populate-image-items.d.ts +91 -0
- package/lib/archive/populate-entity-tables/populate-image-items.js +223 -0
- package/lib/archive/populate-entity-tables/populate-page-meta.d.ts +33 -0
- package/lib/archive/populate-entity-tables/populate-page-meta.js +267 -0
- package/lib/archive/populate-entity-tables/populate-resource-items.d.ts +22 -0
- package/lib/archive/populate-entity-tables/populate-resource-items.js +114 -0
- package/lib/archive/populate-entity-tables/populate-resource-ref-edges.d.ts +31 -0
- package/lib/archive/populate-entity-tables/populate-resource-ref-edges.js +33 -0
- package/lib/archive/populate-entity-tables/resolve-blob-refs.d.ts +31 -0
- package/lib/archive/populate-entity-tables/resolve-blob-refs.js +100 -0
- package/lib/archive/populate-entity-tables/resolve-content-type-refs.d.ts +22 -0
- package/lib/archive/populate-entity-tables/resolve-content-type-refs.js +27 -0
- package/lib/archive/populate-entity-tables/resolve-header-sets.d.ts +49 -0
- package/lib/archive/populate-entity-tables/resolve-header-sets.js +122 -0
- package/lib/archive/populate-entity-tables/resolve-json-refs.d.ts +25 -0
- package/lib/archive/populate-entity-tables/resolve-json-refs.js +67 -0
- package/lib/archive/populate-entity-tables/resolve-text-refs.d.ts +30 -0
- package/lib/archive/populate-entity-tables/resolve-text-refs.js +61 -0
- package/lib/archive/populate-entity-tables/resolve-url-or-blob-from-maps.d.ts +21 -0
- package/lib/archive/populate-entity-tables/resolve-url-or-blob-from-maps.js +27 -0
- package/lib/archive/populate-entity-tables/resolve-url-refs.d.ts +33 -0
- package/lib/archive/populate-entity-tables/resolve-url-refs.js +60 -0
- package/lib/archive/populate-entity-tables/test-utils/count-rows.d.ts +17 -0
- package/lib/archive/populate-entity-tables/test-utils/count-rows.js +20 -0
- package/lib/archive/populate-entity-tables/test-utils/seed-content-items.d.ts +25 -0
- package/lib/archive/populate-entity-tables/test-utils/seed-content-items.js +42 -0
- package/lib/archive/populate-entity-tables/test-utils/setup-entities-db.d.ts +23 -0
- package/lib/archive/populate-entity-tables/test-utils/setup-entities-db.js +178 -0
- package/lib/archive/populate-entity-tables/types.d.ts +157 -0
- package/lib/archive/populate-entity-tables/types.js +12 -0
- package/lib/archive/populate-entity-tables/upsert-text-refs.d.ts +38 -0
- package/lib/archive/populate-entity-tables/upsert-text-refs.js +78 -0
- package/lib/archive/populate-ref-tables/classify-content-type.d.ts +16 -0
- package/lib/archive/populate-ref-tables/classify-content-type.js +52 -0
- package/lib/archive/populate-ref-tables/compute-content-hash.d.ts +22 -0
- package/lib/archive/populate-ref-tables/compute-content-hash.js +26 -0
- package/lib/archive/populate-ref-tables/compute-header-flags.d.ts +16 -0
- package/lib/archive/populate-ref-tables/compute-header-flags.js +70 -0
- package/lib/archive/populate-ref-tables/content-type-rules.d.ts +38 -0
- package/lib/archive/populate-ref-tables/content-type-rules.js +133 -0
- package/lib/archive/populate-ref-tables/create-header-table-caches.d.ts +25 -0
- package/lib/archive/populate-ref-tables/create-header-table-caches.js +49 -0
- package/lib/archive/populate-ref-tables/data-uri-url-refs-limit.d.ts +15 -0
- package/lib/archive/populate-ref-tables/data-uri-url-refs-limit.js +15 -0
- package/lib/archive/populate-ref-tables/decode-data-uri.d.ts +21 -0
- package/lib/archive/populate-ref-tables/decode-data-uri.js +126 -0
- package/lib/archive/populate-ref-tables/decompose-header-set.d.ts +29 -0
- package/lib/archive/populate-ref-tables/decompose-header-set.js +157 -0
- package/lib/archive/populate-ref-tables/decompose-url.d.ts +25 -0
- package/lib/archive/populate-ref-tables/decompose-url.js +70 -0
- package/lib/archive/populate-ref-tables/header-stability.d.ts +19 -0
- package/lib/archive/populate-ref-tables/header-stability.js +22 -0
- package/lib/archive/populate-ref-tables/header-value-cache-key.d.ts +17 -0
- package/lib/archive/populate-ref-tables/header-value-cache-key.js +19 -0
- package/lib/archive/populate-ref-tables/normalize-mime.d.ts +24 -0
- package/lib/archive/populate-ref-tables/normalize-mime.js +36 -0
- package/lib/archive/populate-ref-tables/populate-blob-refs.d.ts +38 -0
- package/lib/archive/populate-ref-tables/populate-blob-refs.js +134 -0
- package/lib/archive/populate-ref-tables/populate-content-type-refs.d.ts +27 -0
- package/lib/archive/populate-ref-tables/populate-content-type-refs.js +70 -0
- package/lib/archive/populate-ref-tables/populate-header-tables.d.ts +35 -0
- package/lib/archive/populate-ref-tables/populate-header-tables.js +80 -0
- package/lib/archive/populate-ref-tables/populate-json-refs.d.ts +29 -0
- package/lib/archive/populate-ref-tables/populate-json-refs.js +101 -0
- package/lib/archive/populate-ref-tables/populate-refs.d.ts +51 -0
- package/lib/archive/populate-ref-tables/populate-refs.js +62 -0
- package/lib/archive/populate-ref-tables/populate-text-refs.d.ts +32 -0
- package/lib/archive/populate-ref-tables/populate-text-refs.js +133 -0
- package/lib/archive/populate-ref-tables/populate-url-refs.d.ts +28 -0
- package/lib/archive/populate-ref-tables/populate-url-refs.js +148 -0
- package/lib/archive/populate-ref-tables/test-utils/count-rows.d.ts +15 -0
- package/lib/archive/populate-ref-tables/test-utils/count-rows.js +17 -0
- package/lib/archive/populate-ref-tables/types.d.ts +197 -0
- package/lib/archive/populate-ref-tables/types.js +7 -0
- package/lib/archive/populate-ref-tables/upsert-one-header-set.d.ts +34 -0
- package/lib/archive/populate-ref-tables/upsert-one-header-set.js +208 -0
- package/lib/archive/populate-ref-tables/volatile-header-names.d.ts +20 -0
- package/lib/archive/populate-ref-tables/volatile-header-names.js +33 -0
- package/lib/archive/redirect-table.d.ts +4 -2
- package/lib/archive/redirect-table.js +15 -10
- package/lib/archive/resolve-redirect-chain.d.ts +3 -3
- package/lib/archive/resolve-redirect-chain.js +2 -2
- package/lib/archive/resource.d.ts +1 -1
- package/lib/archive/retarget-legacy-fk-tables.d.ts +47 -0
- package/lib/archive/retarget-legacy-fk-tables.js +107 -0
- package/lib/archive/test-utils/fk-parent-tables.d.ts +15 -0
- package/lib/archive/test-utils/fk-parent-tables.js +19 -0
- package/lib/archive/test-utils/seed-content-item.d.ts +35 -0
- package/lib/archive/test-utils/seed-content-item.js +42 -0
- package/lib/archive/test-utils/setup-legacy-fk-db.d.ts +33 -0
- package/lib/archive/test-utils/setup-legacy-fk-db.js +270 -0
- package/lib/archive/types.d.ts +151 -15
- package/lib/archive/verify-migration/capture-rejection.d.ts +24 -0
- package/lib/archive/verify-migration/capture-rejection.js +31 -0
- package/lib/archive/verify-migration/check-anchor-edges-count.d.ts +34 -0
- package/lib/archive/verify-migration/check-anchor-edges-count.js +72 -0
- package/lib/archive/verify-migration/check-anchor-edges-sum.d.ts +13 -0
- package/lib/archive/verify-migration/check-anchor-edges-sum.js +27 -0
- package/lib/archive/verify-migration/check-content-items-count.d.ts +16 -0
- package/lib/archive/verify-migration/check-content-items-count.js +30 -0
- package/lib/archive/verify-migration/check-content-type-preservation.d.ts +22 -0
- package/lib/archive/verify-migration/check-content-type-preservation.js +40 -0
- package/lib/archive/verify-migration/check-foreign-key-integrity.d.ts +31 -0
- package/lib/archive/verify-migration/check-foreign-key-integrity.js +47 -0
- package/lib/archive/verify-migration/check-image-items-count.d.ts +12 -0
- package/lib/archive/verify-migration/check-image-items-count.js +26 -0
- package/lib/archive/verify-migration/check-page-meta-count.d.ts +15 -0
- package/lib/archive/verify-migration/check-page-meta-count.js +31 -0
- package/lib/archive/verify-migration/check-reader-parity.d.ts +23 -0
- package/lib/archive/verify-migration/check-reader-parity.js +211 -0
- package/lib/archive/verify-migration/check-resource-items-count.d.ts +17 -0
- package/lib/archive/verify-migration/check-resource-items-count.js +33 -0
- package/lib/archive/verify-migration/check-url-round-trip.d.ts +43 -0
- package/lib/archive/verify-migration/check-url-round-trip.js +112 -0
- package/lib/archive/verify-migration/types.d.ts +70 -0
- package/lib/archive/verify-migration/types.js +63 -0
- package/lib/archive/verify-migration/verify-migration.d.ts +41 -0
- package/lib/archive/verify-migration/verify-migration.js +120 -0
- 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/capture-image-dom-paths.d.ts +33 -0
- package/lib/crawler/capture-image-dom-paths.js +39 -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/collect-image-dom-paths.d.ts +23 -0
- package/lib/crawler/collect-image-dom-paths.js +64 -0
- package/lib/crawler/crawler.d.ts +22 -1
- package/lib/crawler/crawler.js +679 -117
- 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-resource-source.d.ts +25 -15
- package/lib/crawler/derive-resource-source.js +28 -17
- 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/fetch-destination.d.ts +12 -4
- package/lib/crawler/fetch-destination.js +94 -16
- package/lib/crawler/inject-scope-auth.d.ts +1 -1
- package/lib/crawler/inject-scope-auth.js +1 -1
- 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-puppeteer-fallback-candidate.d.ts +16 -0
- package/lib/crawler/is-puppeteer-fallback-candidate.js +63 -0
- package/lib/crawler/link-list.d.ts +21 -1
- package/lib/crawler/link-list.js +23 -3
- package/lib/crawler/normalize-content-type.d.ts +1 -1
- package/lib/crawler/normalize-content-type.js +1 -1
- 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/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 +108 -1
- package/lib/crawler-orchestrator.d.ts +22 -3
- package/lib/crawler-orchestrator.js +312 -73
- package/lib/crawler.d.ts +15 -2
- package/lib/crawler.js +24 -1
- package/lib/permanent-error-kinds.d.ts +43 -0
- package/lib/permanent-error-kinds.js +48 -0
- package/lib/types.d.ts +84 -0
- package/lib/utils/compute-file-sha256.d.ts +24 -0
- package/lib/utils/compute-file-sha256.js +56 -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/package.json +12 -12
- package/lib/archive/migrate-crawl-errors.d.ts +0 -20
- package/lib/archive/migrate-crawl-errors.js +0 -38
- package/lib/archive/migrate-html-blob-tables.d.ts +0 -24
- package/lib/archive/migrate-html-blob-tables.js +0 -53
- package/lib/archive/migrate-page-errors.d.ts +0 -16
- package/lib/archive/migrate-page-errors.js +0 -35
- package/lib/archive/migrate-pages-resources-source.d.ts +0 -16
- package/lib/archive/migrate-pages-resources-source.js +0 -46
- package/lib/utils/error/error-emitter.d.ts +0 -18
- package/lib/utils/error/error-emitter.js +0 -29
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { RedirectEdgeResult } from './types.js';
|
|
2
|
+
import type { PageData } from '@d-zero/beholder';
|
|
3
|
+
import type { ExURL } from '@d-zero/shared/parse-url';
|
|
4
|
+
/**
|
|
5
|
+
* Parameters for {@link buildJsRedirectEdge}.
|
|
6
|
+
*/
|
|
7
|
+
export interface BuildJsRedirectEdgeParams {
|
|
8
|
+
/** Source URL puppeteer was asked to navigate to. */
|
|
9
|
+
url: ExURL;
|
|
10
|
+
/**
|
|
11
|
+
* Whether `url` is external to the crawl scope. Propagated onto the
|
|
12
|
+
* synthesised `PageData` so downstream `linkList.done` classifies the
|
|
13
|
+
* source the same way the original scrape would have.
|
|
14
|
+
*/
|
|
15
|
+
isExternal: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Raw error message from `BrowserScrapeResult.error`. The rescue only
|
|
18
|
+
* fires when this matches the narrow `Page.goto returned null` sentinel
|
|
19
|
+
* (see {@link isJsRedirectErrorShape}) — anything else falls through
|
|
20
|
+
* so genuine browser failures surface unchanged.
|
|
21
|
+
*/
|
|
22
|
+
errorMessage: string | null | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Value of `BrowserScrapeResult.postNavigationUrl` — the URL puppeteer's
|
|
25
|
+
* `page.url()` reported after the throw. Passed to
|
|
26
|
+
* {@link deriveJsRedirectTarget} for canonicalisation, credential strip,
|
|
27
|
+
* and scheme filtering.
|
|
28
|
+
*/
|
|
29
|
+
postNavigationUrl: string | null | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* When present, the rescue builds the redirect-edge `PageData` by
|
|
32
|
+
* spreading this HEAD-pre-flight result and overriding `redirectPaths`.
|
|
33
|
+
* Use this on the HEAD-success-then-puppeteer-fail path so the source row
|
|
34
|
+
* carries the real HTTP-level status / content-type from HEAD. When
|
|
35
|
+
* omitted, the rescue builds a synthetic placeholder via
|
|
36
|
+
* {@link linkToPageData} with `status = -1` / `statusText = errorMessage`
|
|
37
|
+
* — used on the HEAD-fail-then-puppeteer-fallback path where there is
|
|
38
|
+
* no HEAD response to draw from.
|
|
39
|
+
*/
|
|
40
|
+
headCheckResult?: PageData;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build a JS-redirect `RedirectEdgeResult` when the browser-scrape error
|
|
44
|
+
* looks like puppeteer's `page.goto() === null` shape AND `page.url()`
|
|
45
|
+
* resolved to a meaningfully-different URL.
|
|
46
|
+
*
|
|
47
|
+
* **Why this helper exists** — both rescue call sites in
|
|
48
|
+
* `Crawler.#scrapePage` (the HEAD-success-then-puppeteer-fail tail and the
|
|
49
|
+
* HEAD-fail-then-puppeteer-fallback branch inside `#sendHeadRequest`) run
|
|
50
|
+
* the same three-step recipe: classify the error shape → derive a JS target
|
|
51
|
+
* from `page.url()` → synthesise a redirect-edge result. Inlining the recipe
|
|
52
|
+
* twice means a future change to `deriveJsRedirectTarget`'s contract or the
|
|
53
|
+
* sentinel string has to be applied to both copies in sync; collapsing into
|
|
54
|
+
* a single helper keeps the rescue's invariants in one place. The
|
|
55
|
+
* intentional difference between the two call sites (whether to fold a
|
|
56
|
+
* HEAD result into the synthesised PageData or to start from a
|
|
57
|
+
* `linkToPageData` placeholder) is reduced to a single optional parameter
|
|
58
|
+
* (`headCheckResult`), preserving both shapes without behavioural drift.
|
|
59
|
+
*
|
|
60
|
+
* The helper logs at `crawlerLog` whenever it fires so operators tailing
|
|
61
|
+
* `DEBUG=Nitpicker:Crawler` see exactly which URL got rescued and to which
|
|
62
|
+
* destination — without this trail the rescue is invisible to anyone
|
|
63
|
+
* debugging "why did this 200-OK source row land in the archive as a 301?".
|
|
64
|
+
* @param params - Inputs gathered at the call site.
|
|
65
|
+
* @returns A `RedirectEdgeResult` when the rescue applies, otherwise
|
|
66
|
+
* `null` (the caller should fall through to the existing error path).
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildJsRedirectEdge(params: BuildJsRedirectEdgeParams): RedirectEdgeResult | null;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { crawlerLog } from '../debug.js';
|
|
2
|
+
import { deriveJsRedirectTarget } from './derive-js-redirect-target.js';
|
|
3
|
+
import { isJsRedirectErrorShape } from './is-js-redirect-error-shape.js';
|
|
4
|
+
import { linkToPageData } from './link-to-page-data.js';
|
|
5
|
+
/**
|
|
6
|
+
* Build a JS-redirect `RedirectEdgeResult` when the browser-scrape error
|
|
7
|
+
* looks like puppeteer's `page.goto() === null` shape AND `page.url()`
|
|
8
|
+
* resolved to a meaningfully-different URL.
|
|
9
|
+
*
|
|
10
|
+
* **Why this helper exists** — both rescue call sites in
|
|
11
|
+
* `Crawler.#scrapePage` (the HEAD-success-then-puppeteer-fail tail and the
|
|
12
|
+
* HEAD-fail-then-puppeteer-fallback branch inside `#sendHeadRequest`) run
|
|
13
|
+
* the same three-step recipe: classify the error shape → derive a JS target
|
|
14
|
+
* from `page.url()` → synthesise a redirect-edge result. Inlining the recipe
|
|
15
|
+
* twice means a future change to `deriveJsRedirectTarget`'s contract or the
|
|
16
|
+
* sentinel string has to be applied to both copies in sync; collapsing into
|
|
17
|
+
* a single helper keeps the rescue's invariants in one place. The
|
|
18
|
+
* intentional difference between the two call sites (whether to fold a
|
|
19
|
+
* HEAD result into the synthesised PageData or to start from a
|
|
20
|
+
* `linkToPageData` placeholder) is reduced to a single optional parameter
|
|
21
|
+
* (`headCheckResult`), preserving both shapes without behavioural drift.
|
|
22
|
+
*
|
|
23
|
+
* The helper logs at `crawlerLog` whenever it fires so operators tailing
|
|
24
|
+
* `DEBUG=Nitpicker:Crawler` see exactly which URL got rescued and to which
|
|
25
|
+
* destination — without this trail the rescue is invisible to anyone
|
|
26
|
+
* debugging "why did this 200-OK source row land in the archive as a 301?".
|
|
27
|
+
* @param params - Inputs gathered at the call site.
|
|
28
|
+
* @returns A `RedirectEdgeResult` when the rescue applies, otherwise
|
|
29
|
+
* `null` (the caller should fall through to the existing error path).
|
|
30
|
+
*/
|
|
31
|
+
export function buildJsRedirectEdge(params) {
|
|
32
|
+
if (!isJsRedirectErrorShape(params.errorMessage)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const jsRedirectTarget = deriveJsRedirectTarget(params.url.withoutHashAndAuth, params.postNavigationUrl);
|
|
36
|
+
if (jsRedirectTarget === null) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const pageData = params.headCheckResult
|
|
40
|
+
? { ...params.headCheckResult, redirectPaths: [jsRedirectTarget] }
|
|
41
|
+
: linkToPageData({
|
|
42
|
+
url: params.url,
|
|
43
|
+
isExternal: params.isExternal,
|
|
44
|
+
isLowerLayer: false,
|
|
45
|
+
dest: {
|
|
46
|
+
redirectPaths: [jsRedirectTarget],
|
|
47
|
+
status: -1,
|
|
48
|
+
statusText: typeof params.errorMessage === 'string' ? params.errorMessage : '',
|
|
49
|
+
contentType: null,
|
|
50
|
+
contentLength: null,
|
|
51
|
+
responseHeaders: null,
|
|
52
|
+
title: '',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
crawlerLog('JS-redirect rescue fired for %s → %s (HEAD %s)', params.url.href, jsRedirectTarget, params.headCheckResult ? 'available' : 'absent');
|
|
56
|
+
return { type: 'redirect-edge', source: 'js-redirect', pageData };
|
|
57
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CrawlerEventTypes, InventoryMode } from './types.js';
|
|
2
|
+
import type { PageData } from '../utils/types/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build the payload for the {@link CrawlerEventTypes.redirect} event so the
|
|
5
|
+
* `{ result, source }` shape is constructed in one place. Pure function —
|
|
6
|
+
* no I/O, no side effects, just the wiring that connects
|
|
7
|
+
* {@link derivePageSource} to the emit call.
|
|
8
|
+
*
|
|
9
|
+
* Exists so a unit test can pin the wiring directly. Before extraction
|
|
10
|
+
* the assembly lived inline in `Crawler.#scrape`, which meant the only
|
|
11
|
+
* way to catch "someone deletes the `source` field" or "someone passes
|
|
12
|
+
* `inventoryMode` where it should pass `derivePageSource(...)`" was the
|
|
13
|
+
* inventory E2E. Now a single-purpose spec exercises the construction.
|
|
14
|
+
*
|
|
15
|
+
* The originating URL passed in `pageUrlWithoutHashAndAuth` must be the
|
|
16
|
+
* URL the redirect chain STARTS from (the page being scraped), not the
|
|
17
|
+
* destination — see `Database.recordRedirect` JSDoc for why
|
|
18
|
+
* lineage propagates from origin, not from the destination.
|
|
19
|
+
* @param pageData - HEAD-resolved page data carrying the redirect chain.
|
|
20
|
+
* @param inventoryMode - Inventory-mode config from `CrawlerOptions.inventoryMode`, or `null` outside `--inventory`.
|
|
21
|
+
* @param pageUrlWithoutHashAndAuth - The originating page URL keyed by `withoutHashAndAuth`.
|
|
22
|
+
* @returns The exact event payload to feed `emit('redirect', ...)`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildRedirectEvent(pageData: PageData, inventoryMode: InventoryMode | null, pageUrlWithoutHashAndAuth: string): CrawlerEventTypes['redirect'];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { derivePageSource } from './derive-page-source.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build the payload for the {@link CrawlerEventTypes.redirect} event so the
|
|
4
|
+
* `{ result, source }` shape is constructed in one place. Pure function —
|
|
5
|
+
* no I/O, no side effects, just the wiring that connects
|
|
6
|
+
* {@link derivePageSource} to the emit call.
|
|
7
|
+
*
|
|
8
|
+
* Exists so a unit test can pin the wiring directly. Before extraction
|
|
9
|
+
* the assembly lived inline in `Crawler.#scrape`, which meant the only
|
|
10
|
+
* way to catch "someone deletes the `source` field" or "someone passes
|
|
11
|
+
* `inventoryMode` where it should pass `derivePageSource(...)`" was the
|
|
12
|
+
* inventory E2E. Now a single-purpose spec exercises the construction.
|
|
13
|
+
*
|
|
14
|
+
* The originating URL passed in `pageUrlWithoutHashAndAuth` must be the
|
|
15
|
+
* URL the redirect chain STARTS from (the page being scraped), not the
|
|
16
|
+
* destination — see `Database.recordRedirect` JSDoc for why
|
|
17
|
+
* lineage propagates from origin, not from the destination.
|
|
18
|
+
* @param pageData - HEAD-resolved page data carrying the redirect chain.
|
|
19
|
+
* @param inventoryMode - Inventory-mode config from `CrawlerOptions.inventoryMode`, or `null` outside `--inventory`.
|
|
20
|
+
* @param pageUrlWithoutHashAndAuth - The originating page URL keyed by `withoutHashAndAuth`.
|
|
21
|
+
* @returns The exact event payload to feed `emit('redirect', ...)`.
|
|
22
|
+
*/
|
|
23
|
+
export function buildRedirectEvent(pageData, inventoryMode, pageUrlWithoutHashAndAuth) {
|
|
24
|
+
return {
|
|
25
|
+
result: pageData,
|
|
26
|
+
source: derivePageSource(inventoryMode, pageUrlWithoutHashAndAuth),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { DomPathCandidate } from '../archive/populate-entity-tables/types.js';
|
|
2
|
+
import type { Page as PuppeteerPage } from 'puppeteer';
|
|
3
|
+
/**
|
|
4
|
+
* Captures every `<img>` in the rendered document — its `outerHTML` and
|
|
5
|
+
* its `dom_path` string — in document order, for `image_items.dom_path_text_id`
|
|
6
|
+
* resolution at write time.
|
|
7
|
+
*
|
|
8
|
+
* `@d-zero/beholder`'s image metadata carries the element's `outerHTML`
|
|
9
|
+
* (`sourceCode`) but no positional information, so the crawler runs this
|
|
10
|
+
* one extra `page.evaluate` after `scrapeStart` returns, while the page
|
|
11
|
+
* is still alive. The in-browser walk is
|
|
12
|
+
* {@link ./collect-image-dom-paths.ts} — a self-contained function whose
|
|
13
|
+
* source puppeteer serialises into the page, and whose spec pins its
|
|
14
|
+
* output against the Node-side
|
|
15
|
+
* {@link ../archive/populate-entity-tables/derive-dom-path.ts} so a
|
|
16
|
+
* live-crawled archive and one whose dom paths were reconstructed from
|
|
17
|
+
* HTML snapshots by the migration script produce identical strings for
|
|
18
|
+
* identical DOM shapes.
|
|
19
|
+
*
|
|
20
|
+
* Returns `undefined` on any evaluation failure (page context died,
|
|
21
|
+
* navigation raced the call) — dom paths are best-effort enrichment and
|
|
22
|
+
* a capture failure must not fail the scrape. Callers fall back to the
|
|
23
|
+
* `unknown/<id>` synthetic marker per image via
|
|
24
|
+
* {@link ../archive/populate-entity-tables/match-images-to-dom-paths.ts}.
|
|
25
|
+
* @param page - The live puppeteer page, after the scrape completed and
|
|
26
|
+
* before the browser closes.
|
|
27
|
+
* @returns Candidates in document order, or `undefined` when the page
|
|
28
|
+
* could not be evaluated.
|
|
29
|
+
* @example
|
|
30
|
+
* const result = await scraper.scrapeStart(page, url, options);
|
|
31
|
+
* const imageDomPaths = await captureImageDomPaths(page);
|
|
32
|
+
*/
|
|
33
|
+
export declare function captureImageDomPaths(page: PuppeteerPage): Promise<DomPathCandidate[] | undefined>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { collectImageDomPaths } from './collect-image-dom-paths.js';
|
|
2
|
+
/**
|
|
3
|
+
* Captures every `<img>` in the rendered document — its `outerHTML` and
|
|
4
|
+
* its `dom_path` string — in document order, for `image_items.dom_path_text_id`
|
|
5
|
+
* resolution at write time.
|
|
6
|
+
*
|
|
7
|
+
* `@d-zero/beholder`'s image metadata carries the element's `outerHTML`
|
|
8
|
+
* (`sourceCode`) but no positional information, so the crawler runs this
|
|
9
|
+
* one extra `page.evaluate` after `scrapeStart` returns, while the page
|
|
10
|
+
* is still alive. The in-browser walk is
|
|
11
|
+
* {@link ./collect-image-dom-paths.ts} — a self-contained function whose
|
|
12
|
+
* source puppeteer serialises into the page, and whose spec pins its
|
|
13
|
+
* output against the Node-side
|
|
14
|
+
* {@link ../archive/populate-entity-tables/derive-dom-path.ts} so a
|
|
15
|
+
* live-crawled archive and one whose dom paths were reconstructed from
|
|
16
|
+
* HTML snapshots by the migration script produce identical strings for
|
|
17
|
+
* identical DOM shapes.
|
|
18
|
+
*
|
|
19
|
+
* Returns `undefined` on any evaluation failure (page context died,
|
|
20
|
+
* navigation raced the call) — dom paths are best-effort enrichment and
|
|
21
|
+
* a capture failure must not fail the scrape. Callers fall back to the
|
|
22
|
+
* `unknown/<id>` synthetic marker per image via
|
|
23
|
+
* {@link ../archive/populate-entity-tables/match-images-to-dom-paths.ts}.
|
|
24
|
+
* @param page - The live puppeteer page, after the scrape completed and
|
|
25
|
+
* before the browser closes.
|
|
26
|
+
* @returns Candidates in document order, or `undefined` when the page
|
|
27
|
+
* could not be evaluated.
|
|
28
|
+
* @example
|
|
29
|
+
* const result = await scraper.scrapeStart(page, url, options);
|
|
30
|
+
* const imageDomPaths = await captureImageDomPaths(page);
|
|
31
|
+
*/
|
|
32
|
+
export async function captureImageDomPaths(page) {
|
|
33
|
+
try {
|
|
34
|
+
return await page.evaluate(collectImageDomPaths);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clears the DNS-burned host cache and resets the short-circuit counter.
|
|
3
|
+
* Called between crawl sessions, alongside `clearDestinationCache`, to
|
|
4
|
+
* avoid leaking state from a previous session into a fresh one.
|
|
5
|
+
*/
|
|
6
|
+
export declare function clearDnsBurnedHostCache(): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { dnsBurnedHostCache } from './dns-burned-host-cache.js';
|
|
2
|
+
import { dnsBurnedHostShortCircuitCounter } from './dns-burned-host-short-circuit-counter.js';
|
|
3
|
+
/**
|
|
4
|
+
* Clears the DNS-burned host cache and resets the short-circuit counter.
|
|
5
|
+
* Called between crawl sessions, alongside `clearDestinationCache`, to
|
|
6
|
+
* avoid leaking state from a previous session into a fresh one.
|
|
7
|
+
*/
|
|
8
|
+
export function clearDnsBurnedHostCache() {
|
|
9
|
+
dnsBurnedHostCache.clear();
|
|
10
|
+
dnsBurnedHostShortCircuitCounter.count = 0;
|
|
11
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { DomPathCandidate } from '../archive/populate-entity-tables/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Collects every `<img>` in a document — its `outerHTML` and its
|
|
4
|
+
* `dom_path` string — in document order.
|
|
5
|
+
*
|
|
6
|
+
* **Self-contained by contract.** This function is passed verbatim to
|
|
7
|
+
* puppeteer's `page.evaluate`, which serialises the function source and
|
|
8
|
+
* executes it inside the browser: it must not reference imports,
|
|
9
|
+
* module-scope bindings, or any closure state. That constraint is also
|
|
10
|
+
* what makes single-sourcing possible — the exact same function body
|
|
11
|
+
* runs in the browser during a live crawl AND in Node (against a jsdom
|
|
12
|
+
* document) in its spec, so the dom-path derivation cannot drift between
|
|
13
|
+
* the two runtimes. The spec additionally pins its output against
|
|
14
|
+
* {@link ../archive/populate-entity-tables/derive-dom-path.ts} (the
|
|
15
|
+
* Node-side derivation the migration script uses) element-for-element.
|
|
16
|
+
* @param doc - The document to walk. Defaults to the global `document`,
|
|
17
|
+
* which is how the in-browser `page.evaluate(collectImageDomPaths)`
|
|
18
|
+
* call resolves it; Node callers (specs) pass a jsdom document.
|
|
19
|
+
* @returns Candidates in document order.
|
|
20
|
+
* @example
|
|
21
|
+
* const candidates = await page.evaluate(collectImageDomPaths);
|
|
22
|
+
*/
|
|
23
|
+
export declare function collectImageDomPaths(doc?: Document): DomPathCandidate[];
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collects every `<img>` in a document — its `outerHTML` and its
|
|
3
|
+
* `dom_path` string — in document order.
|
|
4
|
+
*
|
|
5
|
+
* **Self-contained by contract.** This function is passed verbatim to
|
|
6
|
+
* puppeteer's `page.evaluate`, which serialises the function source and
|
|
7
|
+
* executes it inside the browser: it must not reference imports,
|
|
8
|
+
* module-scope bindings, or any closure state. That constraint is also
|
|
9
|
+
* what makes single-sourcing possible — the exact same function body
|
|
10
|
+
* runs in the browser during a live crawl AND in Node (against a jsdom
|
|
11
|
+
* document) in its spec, so the dom-path derivation cannot drift between
|
|
12
|
+
* the two runtimes. The spec additionally pins its output against
|
|
13
|
+
* {@link ../archive/populate-entity-tables/derive-dom-path.ts} (the
|
|
14
|
+
* Node-side derivation the migration script uses) element-for-element.
|
|
15
|
+
* @param doc - The document to walk. Defaults to the global `document`,
|
|
16
|
+
* which is how the in-browser `page.evaluate(collectImageDomPaths)`
|
|
17
|
+
* call resolves it; Node callers (specs) pass a jsdom document.
|
|
18
|
+
* @returns Candidates in document order.
|
|
19
|
+
* @example
|
|
20
|
+
* const candidates = await page.evaluate(collectImageDomPaths);
|
|
21
|
+
*/
|
|
22
|
+
export function collectImageDomPaths(doc) {
|
|
23
|
+
const target = doc ?? document;
|
|
24
|
+
/**
|
|
25
|
+
* Counts earlier same-tag siblings, returning the 1-based ordinal.
|
|
26
|
+
* @param element - The element whose ordinal is being computed.
|
|
27
|
+
* @param tag - The element's lower-cased tag name.
|
|
28
|
+
* @returns 1-based ordinal among same-tag siblings.
|
|
29
|
+
*/
|
|
30
|
+
function computeSiblingOrdinal(element, tag) {
|
|
31
|
+
let count = 1;
|
|
32
|
+
let sibling = element.previousElementSibling;
|
|
33
|
+
while (sibling !== null) {
|
|
34
|
+
if (sibling.tagName.toLowerCase() === tag) {
|
|
35
|
+
count += 1;
|
|
36
|
+
}
|
|
37
|
+
sibling = sibling.previousElementSibling;
|
|
38
|
+
}
|
|
39
|
+
return count;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Derives the slash-joined dom_path for one element.
|
|
43
|
+
* @param element - The element to derive the path for.
|
|
44
|
+
* @returns The dom_path string.
|
|
45
|
+
*/
|
|
46
|
+
function deriveDomPath(element) {
|
|
47
|
+
const segments = [];
|
|
48
|
+
let current = element;
|
|
49
|
+
while (current !== null) {
|
|
50
|
+
const tag = current.tagName.toLowerCase();
|
|
51
|
+
if (tag === 'html') {
|
|
52
|
+
segments.unshift('html');
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
segments.unshift(`${tag}[${computeSiblingOrdinal(current, tag)}]`);
|
|
56
|
+
current = current.parentElement;
|
|
57
|
+
}
|
|
58
|
+
return segments.join('/');
|
|
59
|
+
}
|
|
60
|
+
return Array.from(target.querySelectorAll('img'), (img) => ({
|
|
61
|
+
outerHTML: img.outerHTML,
|
|
62
|
+
path: deriveDomPath(img),
|
|
63
|
+
}));
|
|
64
|
+
}
|
package/lib/crawler/crawler.d.ts
CHANGED
|
@@ -71,7 +71,8 @@ export default class Crawler extends EventEmitter<CrawlerEventTypes> {
|
|
|
71
71
|
* before reaching the dealer so a URL that exists in both sources — which
|
|
72
72
|
* is common in append-mode when a new root coincides with a repromoted
|
|
73
73
|
* previously-external page — does not race on two parallel slots.
|
|
74
|
-
* @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`).
|
|
75
76
|
* @param opts - Optional overrides; currently only `recursive` is honoured.
|
|
76
77
|
* @param opts.recursive - When `false`, disables recursive discovery and forces list-mode.
|
|
77
78
|
* Defaults to the constructor option's `recursive` value.
|
|
@@ -80,6 +81,26 @@ export default class Crawler extends EventEmitter<CrawlerEventTypes> {
|
|
|
80
81
|
start(urls: ExURL[], opts?: {
|
|
81
82
|
recursive?: boolean;
|
|
82
83
|
}): void;
|
|
84
|
+
/**
|
|
85
|
+
* Launches a fresh Puppeteer browser, runs the beholder scraper, and cleans up.
|
|
86
|
+
*
|
|
87
|
+
* WHY per-URL browser: Each URL gets its own browser instance to ensure
|
|
88
|
+
* complete isolation (cookies, cache, service workers). The browser is always
|
|
89
|
+
* closed in the `finally` block, even on error.
|
|
90
|
+
*
|
|
91
|
+
* The cascade-guard contract for the puppeteer-fallback success / skipped
|
|
92
|
+
* branches can be exercised via `vi.spyOn(Crawler.prototype,
|
|
93
|
+
* '_launchBrowserAndScrape')` in unit tests. There is no production
|
|
94
|
+
* consumer outside this class.
|
|
95
|
+
* @internal
|
|
96
|
+
* @param url - Target URL to scrape
|
|
97
|
+
* @param update - Callback for progress messages
|
|
98
|
+
* @param isExternal - Whether the URL is external to the crawl scope
|
|
99
|
+
* @param metadataOnly - When true, only extract title metadata
|
|
100
|
+
* @param headCheckResult - Optional HEAD result to pass to the scraper, avoiding a redundant request
|
|
101
|
+
* @returns The scrape result from beholder
|
|
102
|
+
*/
|
|
103
|
+
private _launchBrowserAndScrape;
|
|
83
104
|
/**
|
|
84
105
|
* The default maximum number of concurrent scraping processes.
|
|
85
106
|
*
|