@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.
Files changed (387) hide show
  1. package/README.md +6 -4
  2. package/lib/archive/archive-accessor.d.ts +2 -2
  3. package/lib/archive/archive-accessor.js +2 -2
  4. package/lib/archive/archive-lock.d.ts +7 -0
  5. package/lib/archive/archive-lock.js +7 -0
  6. package/lib/archive/archive.d.ts +175 -13
  7. package/lib/archive/archive.js +198 -14
  8. package/lib/archive/cache/compute-archive-cache-key.d.ts +39 -0
  9. package/lib/archive/cache/compute-archive-cache-key.js +95 -0
  10. package/lib/archive/cache/extract-archive-to-cache.d.ts +43 -0
  11. package/lib/archive/cache/extract-archive-to-cache.js +309 -0
  12. package/lib/archive/cache/get-archive-cache-root.d.ts +20 -0
  13. package/lib/archive/cache/get-archive-cache-root.js +53 -0
  14. package/lib/archive/cache/is-archive-cache-disabled.d.ts +24 -0
  15. package/lib/archive/cache/is-archive-cache-disabled.js +34 -0
  16. package/lib/archive/cache/resolve-archive-cache-dir.d.ts +26 -0
  17. package/lib/archive/cache/resolve-archive-cache-dir.js +32 -0
  18. package/lib/archive/create-adjunct-tables.d.ts +43 -0
  19. package/lib/archive/create-adjunct-tables.js +213 -0
  20. package/lib/archive/create-entity-tables.d.ts +173 -0
  21. package/lib/archive/create-entity-tables.js +318 -0
  22. package/lib/archive/create-progress-reporter.d.ts +30 -0
  23. package/lib/archive/create-progress-reporter.js +38 -0
  24. package/lib/archive/create-ref-tables.d.ts +35 -0
  25. package/lib/archive/create-ref-tables.js +188 -0
  26. package/lib/archive/database.d.ts +130 -182
  27. package/lib/archive/database.js +524 -1777
  28. package/lib/archive/db-ops/_shared/clear-write-ref-caches.d.ts +27 -0
  29. package/lib/archive/db-ops/_shared/clear-write-ref-caches.js +34 -0
  30. package/lib/archive/db-ops/_shared/create-write-ref-caches.d.ts +17 -0
  31. package/lib/archive/db-ops/_shared/create-write-ref-caches.js +26 -0
  32. package/lib/archive/db-ops/_shared/decode-json-ref.d.ts +17 -0
  33. package/lib/archive/db-ops/_shared/decode-json-ref.js +31 -0
  34. package/lib/archive/db-ops/_shared/load-response-headers-by-set-ids.d.ts +20 -0
  35. package/lib/archive/db-ops/_shared/load-response-headers-by-set-ids.js +53 -0
  36. package/lib/archive/db-ops/_shared/resolve-content-item-id.d.ts +61 -0
  37. package/lib/archive/db-ops/_shared/resolve-content-item-id.js +111 -0
  38. package/lib/archive/db-ops/_shared/resolve-url-or-blob.d.ts +23 -0
  39. package/lib/archive/db-ops/_shared/resolve-url-or-blob.js +29 -0
  40. package/lib/archive/db-ops/_shared/retry-setting.d.ts +16 -0
  41. package/lib/archive/db-ops/_shared/retry-setting.js +18 -0
  42. package/lib/archive/db-ops/_shared/safe-parse-json.d.ts +11 -0
  43. package/lib/archive/db-ops/_shared/safe-parse-json.js +18 -0
  44. package/lib/archive/db-ops/_shared/types.d.ts +53 -0
  45. package/lib/archive/db-ops/_shared/types.js +1 -0
  46. package/lib/archive/db-ops/_shared/upsert-blob-ref.d.ts +25 -0
  47. package/lib/archive/db-ops/_shared/upsert-blob-ref.js +48 -0
  48. package/lib/archive/db-ops/_shared/upsert-content-type-ref.d.ts +30 -0
  49. package/lib/archive/db-ops/_shared/upsert-content-type-ref.js +45 -0
  50. package/lib/archive/db-ops/_shared/upsert-json-ref.d.ts +22 -0
  51. package/lib/archive/db-ops/_shared/upsert-json-ref.js +41 -0
  52. package/lib/archive/db-ops/_shared/upsert-response-headers.d.ts +35 -0
  53. package/lib/archive/db-ops/_shared/upsert-response-headers.js +49 -0
  54. package/lib/archive/db-ops/_shared/upsert-url-ref.d.ts +39 -0
  55. package/lib/archive/db-ops/_shared/upsert-url-ref.js +62 -0
  56. package/lib/archive/db-ops/analysis/replace-analysis-violations.d.ts +28 -0
  57. package/lib/archive/db-ops/analysis/replace-analysis-violations.js +152 -0
  58. package/lib/archive/db-ops/anchors/get-anchors-on-page.d.ts +10 -0
  59. package/lib/archive/db-ops/anchors/get-anchors-on-page.js +21 -0
  60. package/lib/archive/db-ops/config/get-base-url.d.ts +8 -0
  61. package/lib/archive/db-ops/config/get-base-url.js +14 -0
  62. package/lib/archive/db-ops/config/get-config.d.ts +10 -0
  63. package/lib/archive/db-ops/config/get-config.js +27 -0
  64. package/lib/archive/db-ops/config/get-name.d.ts +8 -0
  65. package/lib/archive/db-ops/config/get-name.js +14 -0
  66. package/lib/archive/db-ops/config/info-column-allowlist.d.ts +7 -0
  67. package/lib/archive/db-ops/config/info-column-allowlist.js +26 -0
  68. package/lib/archive/db-ops/config/info-json-columns.d.ts +5 -0
  69. package/lib/archive/db-ops/config/info-json-columns.js +10 -0
  70. package/lib/archive/db-ops/config/set-config.d.ts +12 -0
  71. package/lib/archive/db-ops/config/set-config.js +21 -0
  72. package/lib/archive/db-ops/config/update-config.d.ts +17 -0
  73. package/lib/archive/db-ops/config/update-config.js +36 -0
  74. package/lib/archive/db-ops/errors/insert-crawl-error.d.ts +15 -0
  75. package/lib/archive/db-ops/errors/insert-crawl-error.js +21 -0
  76. package/lib/archive/db-ops/errors/insert-page-error.d.ts +21 -0
  77. package/lib/archive/db-ops/errors/insert-page-error.js +28 -0
  78. package/lib/archive/db-ops/errors/list-dns-burned-host-candidates.d.ts +22 -0
  79. package/lib/archive/db-ops/errors/list-dns-burned-host-candidates.js +141 -0
  80. package/lib/archive/db-ops/html/get-html-of-page-by-id.d.ts +18 -0
  81. package/lib/archive/db-ops/html/get-html-of-page-by-id.js +29 -0
  82. package/lib/archive/db-ops/inventory/record-inventory-run.d.ts +21 -0
  83. package/lib/archive/db-ops/inventory/record-inventory-run.js +38 -0
  84. package/lib/archive/db-ops/lifecycle/checkpoint.d.ts +8 -0
  85. package/lib/archive/db-ops/lifecycle/checkpoint.js +9 -0
  86. package/lib/archive/db-ops/lifecycle/destroy.d.ts +6 -0
  87. package/lib/archive/db-ops/lifecycle/destroy.js +7 -0
  88. package/lib/archive/db-ops/lifecycle/init.d.ts +22 -0
  89. package/lib/archive/db-ops/lifecycle/init.js +42 -0
  90. package/lib/archive/db-ops/meta/get-jsonld-of-page.d.ts +13 -0
  91. package/lib/archive/db-ops/meta/get-jsonld-of-page.js +27 -0
  92. package/lib/archive/db-ops/meta/get-tags-of-page.d.ts +12 -0
  93. package/lib/archive/db-ops/meta/get-tags-of-page.js +28 -0
  94. package/lib/archive/db-ops/pages/order/set-url-order.d.ts +8 -0
  95. package/lib/archive/db-ops/pages/order/set-url-order.js +32 -0
  96. package/lib/archive/db-ops/pages/read/build-page-query.d.ts +18 -0
  97. package/lib/archive/db-ops/pages/read/build-page-query.js +40 -0
  98. package/lib/archive/db-ops/pages/read/get-crawling-state.d.ts +70 -0
  99. package/lib/archive/db-ops/pages/read/get-crawling-state.js +98 -0
  100. package/lib/archive/db-ops/pages/read/get-existing-page-urls.d.ts +15 -0
  101. package/lib/archive/db-ops/pages/read/get-existing-page-urls.js +30 -0
  102. package/lib/archive/db-ops/pages/read/get-page-count.d.ts +12 -0
  103. package/lib/archive/db-ops/pages/read/get-page-count.js +21 -0
  104. package/lib/archive/db-ops/pages/read/get-page-source-by-url.d.ts +24 -0
  105. package/lib/archive/db-ops/pages/read/get-page-source-by-url.js +28 -0
  106. package/lib/archive/db-ops/pages/read/get-pages-with-rels.d.ts +38 -0
  107. package/lib/archive/db-ops/pages/read/get-pages-with-rels.js +107 -0
  108. package/lib/archive/db-ops/pages/read/get-pages.d.ts +11 -0
  109. package/lib/archive/db-ops/pages/read/get-pages.js +51 -0
  110. package/lib/archive/db-ops/pages/read/get-scraped-html-page-count.d.ts +18 -0
  111. package/lib/archive/db-ops/pages/read/get-scraped-html-page-count.js +25 -0
  112. package/lib/archive/db-ops/pages/read/reconstruct-page-rows.d.ts +31 -0
  113. package/lib/archive/db-ops/pages/read/reconstruct-page-rows.js +32 -0
  114. package/lib/archive/db-ops/pages/reset/repromote-external-pages.d.ts +24 -0
  115. package/lib/archive/db-ops/pages/reset/repromote-external-pages.js +93 -0
  116. package/lib/archive/db-ops/pages/reset/reset-failed-pages.d.ts +47 -0
  117. package/lib/archive/db-ops/pages/reset/reset-failed-pages.js +124 -0
  118. package/lib/archive/db-ops/pages/write/insert-inventory-seeds.d.ts +37 -0
  119. package/lib/archive/db-ops/pages/write/insert-inventory-seeds.js +72 -0
  120. package/lib/archive/db-ops/pages/write/insert-jsonld.d.ts +17 -0
  121. package/lib/archive/db-ops/pages/write/insert-jsonld.js +49 -0
  122. package/lib/archive/db-ops/pages/write/insert-page.d.ts +36 -0
  123. package/lib/archive/db-ops/pages/write/insert-page.js +208 -0
  124. package/lib/archive/db-ops/pages/write/insert-tags.d.ts +16 -0
  125. package/lib/archive/db-ops/pages/write/insert-tags.js +34 -0
  126. package/lib/archive/db-ops/pages/write/link-redirect-sources.d.ts +36 -0
  127. package/lib/archive/db-ops/pages/write/link-redirect-sources.js +93 -0
  128. package/lib/archive/db-ops/pages/write/record-redirect.d.ts +35 -0
  129. package/lib/archive/db-ops/pages/write/record-redirect.js +100 -0
  130. package/lib/archive/db-ops/pages/write/set-skipped-page.d.ts +13 -0
  131. package/lib/archive/db-ops/pages/write/set-skipped-page.js +22 -0
  132. package/lib/archive/db-ops/pages/write/update-page.d.ts +29 -0
  133. package/lib/archive/db-ops/pages/write/update-page.js +334 -0
  134. package/lib/archive/db-ops/pages/write/write-page-html-blob.d.ts +19 -0
  135. package/lib/archive/db-ops/pages/write/write-page-html-blob.js +41 -0
  136. package/lib/archive/db-ops/referrers/get-redirects-for-pages.d.ts +9 -0
  137. package/lib/archive/db-ops/referrers/get-redirects-for-pages.js +15 -0
  138. package/lib/archive/db-ops/referrers/get-referrers-of-page.d.ts +17 -0
  139. package/lib/archive/db-ops/referrers/get-referrers-of-page.js +32 -0
  140. package/lib/archive/db-ops/referrers/get-referrers-of-resource.d.ts +8 -0
  141. package/lib/archive/db-ops/referrers/get-referrers-of-resource.js +15 -0
  142. package/lib/archive/db-ops/resources/build-resource-query.d.ts +25 -0
  143. package/lib/archive/db-ops/resources/build-resource-query.js +29 -0
  144. package/lib/archive/db-ops/resources/get-existing-resource-urls.d.ts +9 -0
  145. package/lib/archive/db-ops/resources/get-existing-resource-urls.js +24 -0
  146. package/lib/archive/db-ops/resources/get-resource-by-url.d.ts +13 -0
  147. package/lib/archive/db-ops/resources/get-resource-by-url.js +22 -0
  148. package/lib/archive/db-ops/resources/get-resource-url-list.d.ts +9 -0
  149. package/lib/archive/db-ops/resources/get-resource-url-list.js +13 -0
  150. package/lib/archive/db-ops/resources/get-resources.d.ts +8 -0
  151. package/lib/archive/db-ops/resources/get-resources.js +11 -0
  152. package/lib/archive/db-ops/resources/insert-inventory-resources.d.ts +24 -0
  153. package/lib/archive/db-ops/resources/insert-inventory-resources.js +64 -0
  154. package/lib/archive/db-ops/resources/insert-resource-referrers.d.ts +15 -0
  155. package/lib/archive/db-ops/resources/insert-resource-referrers.js +54 -0
  156. package/lib/archive/db-ops/resources/insert-resource.d.ts +34 -0
  157. package/lib/archive/db-ops/resources/insert-resource.js +73 -0
  158. package/lib/archive/db-ops/resources/reconstruct-resource-rows.d.ts +26 -0
  159. package/lib/archive/db-ops/resources/reconstruct-resource-rows.js +30 -0
  160. package/lib/archive/decode-html-blob.d.ts +18 -0
  161. package/lib/archive/decode-html-blob.js +31 -0
  162. package/lib/archive/derive-lineage-from-parent.d.ts +37 -0
  163. package/lib/archive/derive-lineage-from-parent.js +42 -0
  164. package/lib/archive/drop-legacy-tables.d.ts +45 -0
  165. package/lib/archive/drop-legacy-tables.js +56 -0
  166. package/lib/archive/filesystem/rename.js +1 -1
  167. package/lib/archive/get-failed-page-messages.d.ts +44 -0
  168. package/lib/archive/get-failed-page-messages.js +132 -0
  169. package/lib/archive/init-schema.d.ts +35 -39
  170. package/lib/archive/init-schema.js +111 -320
  171. package/lib/archive/is-inventory-source.d.ts +21 -0
  172. package/lib/archive/is-inventory-source.js +22 -0
  173. package/lib/archive/limited-page-ids.d.ts +2 -1
  174. package/lib/archive/limited-page-ids.js +5 -4
  175. package/lib/archive/meta/assert-compatible-version.d.ts +24 -3
  176. package/lib/archive/meta/assert-compatible-version.js +24 -3
  177. package/lib/archive/meta/types.d.ts +87 -1
  178. package/lib/archive/meta/types.js +34 -2
  179. package/lib/archive/migrate-entity-tables.d.ts +45 -0
  180. package/lib/archive/migrate-entity-tables.js +56 -0
  181. package/lib/archive/migrate-ref-tables.d.ts +25 -0
  182. package/lib/archive/migrate-ref-tables.js +38 -0
  183. package/lib/archive/page-meta-column-maps.d.ts +32 -0
  184. package/lib/archive/page-meta-column-maps.js +43 -0
  185. package/lib/archive/page.d.ts +6 -6
  186. package/lib/archive/page.js +5 -5
  187. package/lib/archive/peek-archive-lock.d.ts +2 -2
  188. package/lib/archive/peek-archive-lock.js +2 -2
  189. package/lib/archive/populate-entity-tables/collapse-anchor-rows.d.ts +41 -0
  190. package/lib/archive/populate-entity-tables/collapse-anchor-rows.js +87 -0
  191. package/lib/archive/populate-entity-tables/derive-dom-path.d.ts +35 -0
  192. package/lib/archive/populate-entity-tables/derive-dom-path.js +72 -0
  193. package/lib/archive/populate-entity-tables/is-blob-ref-value.d.ts +16 -0
  194. package/lib/archive/populate-entity-tables/is-blob-ref-value.js +19 -0
  195. package/lib/archive/populate-entity-tables/match-images-to-dom-paths.d.ts +66 -0
  196. package/lib/archive/populate-entity-tables/match-images-to-dom-paths.js +96 -0
  197. package/lib/archive/populate-entity-tables/populate-anchor-edges.d.ts +33 -0
  198. package/lib/archive/populate-entity-tables/populate-anchor-edges.js +153 -0
  199. package/lib/archive/populate-entity-tables/populate-content-items.d.ts +40 -0
  200. package/lib/archive/populate-entity-tables/populate-content-items.js +141 -0
  201. package/lib/archive/populate-entity-tables/populate-entities.d.ts +81 -0
  202. package/lib/archive/populate-entity-tables/populate-entities.js +111 -0
  203. package/lib/archive/populate-entity-tables/populate-image-items.d.ts +91 -0
  204. package/lib/archive/populate-entity-tables/populate-image-items.js +223 -0
  205. package/lib/archive/populate-entity-tables/populate-page-meta.d.ts +33 -0
  206. package/lib/archive/populate-entity-tables/populate-page-meta.js +267 -0
  207. package/lib/archive/populate-entity-tables/populate-resource-items.d.ts +22 -0
  208. package/lib/archive/populate-entity-tables/populate-resource-items.js +114 -0
  209. package/lib/archive/populate-entity-tables/populate-resource-ref-edges.d.ts +31 -0
  210. package/lib/archive/populate-entity-tables/populate-resource-ref-edges.js +33 -0
  211. package/lib/archive/populate-entity-tables/resolve-blob-refs.d.ts +31 -0
  212. package/lib/archive/populate-entity-tables/resolve-blob-refs.js +100 -0
  213. package/lib/archive/populate-entity-tables/resolve-content-type-refs.d.ts +22 -0
  214. package/lib/archive/populate-entity-tables/resolve-content-type-refs.js +27 -0
  215. package/lib/archive/populate-entity-tables/resolve-header-sets.d.ts +49 -0
  216. package/lib/archive/populate-entity-tables/resolve-header-sets.js +122 -0
  217. package/lib/archive/populate-entity-tables/resolve-json-refs.d.ts +25 -0
  218. package/lib/archive/populate-entity-tables/resolve-json-refs.js +67 -0
  219. package/lib/archive/populate-entity-tables/resolve-text-refs.d.ts +30 -0
  220. package/lib/archive/populate-entity-tables/resolve-text-refs.js +61 -0
  221. package/lib/archive/populate-entity-tables/resolve-url-or-blob-from-maps.d.ts +21 -0
  222. package/lib/archive/populate-entity-tables/resolve-url-or-blob-from-maps.js +27 -0
  223. package/lib/archive/populate-entity-tables/resolve-url-refs.d.ts +33 -0
  224. package/lib/archive/populate-entity-tables/resolve-url-refs.js +60 -0
  225. package/lib/archive/populate-entity-tables/test-utils/count-rows.d.ts +17 -0
  226. package/lib/archive/populate-entity-tables/test-utils/count-rows.js +20 -0
  227. package/lib/archive/populate-entity-tables/test-utils/seed-content-items.d.ts +25 -0
  228. package/lib/archive/populate-entity-tables/test-utils/seed-content-items.js +42 -0
  229. package/lib/archive/populate-entity-tables/test-utils/setup-entities-db.d.ts +23 -0
  230. package/lib/archive/populate-entity-tables/test-utils/setup-entities-db.js +178 -0
  231. package/lib/archive/populate-entity-tables/types.d.ts +157 -0
  232. package/lib/archive/populate-entity-tables/types.js +12 -0
  233. package/lib/archive/populate-entity-tables/upsert-text-refs.d.ts +38 -0
  234. package/lib/archive/populate-entity-tables/upsert-text-refs.js +78 -0
  235. package/lib/archive/populate-ref-tables/classify-content-type.d.ts +16 -0
  236. package/lib/archive/populate-ref-tables/classify-content-type.js +52 -0
  237. package/lib/archive/populate-ref-tables/compute-content-hash.d.ts +22 -0
  238. package/lib/archive/populate-ref-tables/compute-content-hash.js +26 -0
  239. package/lib/archive/populate-ref-tables/compute-header-flags.d.ts +16 -0
  240. package/lib/archive/populate-ref-tables/compute-header-flags.js +70 -0
  241. package/lib/archive/populate-ref-tables/content-type-rules.d.ts +38 -0
  242. package/lib/archive/populate-ref-tables/content-type-rules.js +133 -0
  243. package/lib/archive/populate-ref-tables/create-header-table-caches.d.ts +25 -0
  244. package/lib/archive/populate-ref-tables/create-header-table-caches.js +49 -0
  245. package/lib/archive/populate-ref-tables/data-uri-url-refs-limit.d.ts +15 -0
  246. package/lib/archive/populate-ref-tables/data-uri-url-refs-limit.js +15 -0
  247. package/lib/archive/populate-ref-tables/decode-data-uri.d.ts +21 -0
  248. package/lib/archive/populate-ref-tables/decode-data-uri.js +126 -0
  249. package/lib/archive/populate-ref-tables/decompose-header-set.d.ts +29 -0
  250. package/lib/archive/populate-ref-tables/decompose-header-set.js +157 -0
  251. package/lib/archive/populate-ref-tables/decompose-url.d.ts +25 -0
  252. package/lib/archive/populate-ref-tables/decompose-url.js +70 -0
  253. package/lib/archive/populate-ref-tables/header-stability.d.ts +19 -0
  254. package/lib/archive/populate-ref-tables/header-stability.js +22 -0
  255. package/lib/archive/populate-ref-tables/header-value-cache-key.d.ts +17 -0
  256. package/lib/archive/populate-ref-tables/header-value-cache-key.js +19 -0
  257. package/lib/archive/populate-ref-tables/normalize-mime.d.ts +24 -0
  258. package/lib/archive/populate-ref-tables/normalize-mime.js +36 -0
  259. package/lib/archive/populate-ref-tables/populate-blob-refs.d.ts +38 -0
  260. package/lib/archive/populate-ref-tables/populate-blob-refs.js +134 -0
  261. package/lib/archive/populate-ref-tables/populate-content-type-refs.d.ts +27 -0
  262. package/lib/archive/populate-ref-tables/populate-content-type-refs.js +70 -0
  263. package/lib/archive/populate-ref-tables/populate-header-tables.d.ts +35 -0
  264. package/lib/archive/populate-ref-tables/populate-header-tables.js +80 -0
  265. package/lib/archive/populate-ref-tables/populate-json-refs.d.ts +29 -0
  266. package/lib/archive/populate-ref-tables/populate-json-refs.js +101 -0
  267. package/lib/archive/populate-ref-tables/populate-refs.d.ts +51 -0
  268. package/lib/archive/populate-ref-tables/populate-refs.js +62 -0
  269. package/lib/archive/populate-ref-tables/populate-text-refs.d.ts +32 -0
  270. package/lib/archive/populate-ref-tables/populate-text-refs.js +133 -0
  271. package/lib/archive/populate-ref-tables/populate-url-refs.d.ts +28 -0
  272. package/lib/archive/populate-ref-tables/populate-url-refs.js +148 -0
  273. package/lib/archive/populate-ref-tables/test-utils/count-rows.d.ts +15 -0
  274. package/lib/archive/populate-ref-tables/test-utils/count-rows.js +17 -0
  275. package/lib/archive/populate-ref-tables/types.d.ts +197 -0
  276. package/lib/archive/populate-ref-tables/types.js +7 -0
  277. package/lib/archive/populate-ref-tables/upsert-one-header-set.d.ts +34 -0
  278. package/lib/archive/populate-ref-tables/upsert-one-header-set.js +208 -0
  279. package/lib/archive/populate-ref-tables/volatile-header-names.d.ts +20 -0
  280. package/lib/archive/populate-ref-tables/volatile-header-names.js +33 -0
  281. package/lib/archive/redirect-table.d.ts +4 -2
  282. package/lib/archive/redirect-table.js +15 -10
  283. package/lib/archive/resolve-redirect-chain.d.ts +3 -3
  284. package/lib/archive/resolve-redirect-chain.js +2 -2
  285. package/lib/archive/resource.d.ts +1 -1
  286. package/lib/archive/retarget-legacy-fk-tables.d.ts +47 -0
  287. package/lib/archive/retarget-legacy-fk-tables.js +107 -0
  288. package/lib/archive/test-utils/fk-parent-tables.d.ts +15 -0
  289. package/lib/archive/test-utils/fk-parent-tables.js +19 -0
  290. package/lib/archive/test-utils/seed-content-item.d.ts +35 -0
  291. package/lib/archive/test-utils/seed-content-item.js +42 -0
  292. package/lib/archive/test-utils/setup-legacy-fk-db.d.ts +33 -0
  293. package/lib/archive/test-utils/setup-legacy-fk-db.js +270 -0
  294. package/lib/archive/types.d.ts +151 -15
  295. package/lib/archive/verify-migration/capture-rejection.d.ts +24 -0
  296. package/lib/archive/verify-migration/capture-rejection.js +31 -0
  297. package/lib/archive/verify-migration/check-anchor-edges-count.d.ts +34 -0
  298. package/lib/archive/verify-migration/check-anchor-edges-count.js +72 -0
  299. package/lib/archive/verify-migration/check-anchor-edges-sum.d.ts +13 -0
  300. package/lib/archive/verify-migration/check-anchor-edges-sum.js +27 -0
  301. package/lib/archive/verify-migration/check-content-items-count.d.ts +16 -0
  302. package/lib/archive/verify-migration/check-content-items-count.js +30 -0
  303. package/lib/archive/verify-migration/check-content-type-preservation.d.ts +22 -0
  304. package/lib/archive/verify-migration/check-content-type-preservation.js +40 -0
  305. package/lib/archive/verify-migration/check-foreign-key-integrity.d.ts +31 -0
  306. package/lib/archive/verify-migration/check-foreign-key-integrity.js +47 -0
  307. package/lib/archive/verify-migration/check-image-items-count.d.ts +12 -0
  308. package/lib/archive/verify-migration/check-image-items-count.js +26 -0
  309. package/lib/archive/verify-migration/check-page-meta-count.d.ts +15 -0
  310. package/lib/archive/verify-migration/check-page-meta-count.js +31 -0
  311. package/lib/archive/verify-migration/check-reader-parity.d.ts +23 -0
  312. package/lib/archive/verify-migration/check-reader-parity.js +211 -0
  313. package/lib/archive/verify-migration/check-resource-items-count.d.ts +17 -0
  314. package/lib/archive/verify-migration/check-resource-items-count.js +33 -0
  315. package/lib/archive/verify-migration/check-url-round-trip.d.ts +43 -0
  316. package/lib/archive/verify-migration/check-url-round-trip.js +112 -0
  317. package/lib/archive/verify-migration/types.d.ts +70 -0
  318. package/lib/archive/verify-migration/types.js +63 -0
  319. package/lib/archive/verify-migration/verify-migration.d.ts +41 -0
  320. package/lib/archive/verify-migration/verify-migration.js +120 -0
  321. package/lib/classify-error-kind.d.ts +19 -0
  322. package/lib/classify-error-kind.js +122 -0
  323. package/lib/crawler/build-js-redirect-edge.d.ts +68 -0
  324. package/lib/crawler/build-js-redirect-edge.js +57 -0
  325. package/lib/crawler/build-redirect-event.d.ts +24 -0
  326. package/lib/crawler/build-redirect-event.js +28 -0
  327. package/lib/crawler/capture-image-dom-paths.d.ts +33 -0
  328. package/lib/crawler/capture-image-dom-paths.js +39 -0
  329. package/lib/crawler/clear-dns-burned-host-cache.d.ts +6 -0
  330. package/lib/crawler/clear-dns-burned-host-cache.js +11 -0
  331. package/lib/crawler/collect-image-dom-paths.d.ts +23 -0
  332. package/lib/crawler/collect-image-dom-paths.js +64 -0
  333. package/lib/crawler/crawler.d.ts +22 -1
  334. package/lib/crawler/crawler.js +679 -117
  335. package/lib/crawler/derive-js-redirect-target.d.ts +68 -0
  336. package/lib/crawler/derive-js-redirect-target.js +129 -0
  337. package/lib/crawler/derive-resource-source.d.ts +25 -15
  338. package/lib/crawler/derive-resource-source.js +28 -17
  339. package/lib/crawler/dns-burned-host-cache.d.ts +26 -0
  340. package/lib/crawler/dns-burned-host-cache.js +25 -0
  341. package/lib/crawler/dns-burned-host-short-circuit-counter.d.ts +13 -0
  342. package/lib/crawler/dns-burned-host-short-circuit-counter.js +11 -0
  343. package/lib/crawler/fetch-destination.d.ts +12 -4
  344. package/lib/crawler/fetch-destination.js +94 -16
  345. package/lib/crawler/inject-scope-auth.d.ts +1 -1
  346. package/lib/crawler/inject-scope-auth.js +1 -1
  347. package/lib/crawler/is-js-redirect-error-shape.d.ts +40 -0
  348. package/lib/crawler/is-js-redirect-error-shape.js +53 -0
  349. package/lib/crawler/is-puppeteer-fallback-candidate.d.ts +16 -0
  350. package/lib/crawler/is-puppeteer-fallback-candidate.js +63 -0
  351. package/lib/crawler/link-list.d.ts +21 -1
  352. package/lib/crawler/link-list.js +23 -3
  353. package/lib/crawler/normalize-content-type.d.ts +1 -1
  354. package/lib/crawler/normalize-content-type.js +1 -1
  355. package/lib/crawler/plan-sub-resource-emits.d.ts +63 -0
  356. package/lib/crawler/plan-sub-resource-emits.js +44 -0
  357. package/lib/crawler/preload-short-circuit-error.d.ts +22 -0
  358. package/lib/crawler/preload-short-circuit-error.js +25 -0
  359. package/lib/crawler/should-burn-host.d.ts +78 -0
  360. package/lib/crawler/should-burn-host.js +61 -0
  361. package/lib/crawler/should-get-fallback-on-head-failure.d.ts +38 -0
  362. package/lib/crawler/should-get-fallback-on-head-failure.js +46 -0
  363. package/lib/crawler/types.d.ts +108 -1
  364. package/lib/crawler-orchestrator.d.ts +22 -3
  365. package/lib/crawler-orchestrator.js +312 -73
  366. package/lib/crawler.d.ts +15 -2
  367. package/lib/crawler.js +24 -1
  368. package/lib/permanent-error-kinds.d.ts +43 -0
  369. package/lib/permanent-error-kinds.js +48 -0
  370. package/lib/types.d.ts +84 -0
  371. package/lib/utils/compute-file-sha256.d.ts +24 -0
  372. package/lib/utils/compute-file-sha256.js +56 -0
  373. package/lib/utils/error/emit-error-with-retry.d.ts +40 -0
  374. package/lib/utils/error/emit-error-with-retry.js +44 -0
  375. package/lib/utils/error/emit-error.d.ts +39 -0
  376. package/lib/utils/error/emit-error.js +41 -0
  377. package/package.json +12 -12
  378. package/lib/archive/migrate-crawl-errors.d.ts +0 -20
  379. package/lib/archive/migrate-crawl-errors.js +0 -38
  380. package/lib/archive/migrate-html-blob-tables.d.ts +0 -24
  381. package/lib/archive/migrate-html-blob-tables.js +0 -53
  382. package/lib/archive/migrate-page-errors.d.ts +0 -16
  383. package/lib/archive/migrate-page-errors.js +0 -35
  384. package/lib/archive/migrate-pages-resources-source.d.ts +0 -16
  385. package/lib/archive/migrate-pages-resources-source.js +0 -46
  386. package/lib/utils/error/error-emitter.d.ts +0 -18
  387. package/lib/utils/error/error-emitter.js +0 -29
@@ -0,0 +1,23 @@
1
+ import knex from 'knex';
2
+ /**
3
+ * Provisions an in-memory SQLite database with:
4
+ *
5
+ * - A minimal subset of the legacy write model (`pages`, `resources`,
6
+ * `anchors`, `images`, `resources-referrers`, `page_html_ref`,
7
+ * `page_html_blobs`) — only the columns the 0.13 populates
8
+ * actually read.
9
+ * - The 0.13 ref / header tables (via {@link createRefTables}).
10
+ * - The 0.13 entity tables (via {@link createEntityTables}).
11
+ *
12
+ * Every 0.13 populate spec calls this to obtain a fresh DB. The
13
+ * caller is responsible for `db.destroy()` (spec `afterEach`).
14
+ *
15
+ * `PRAGMA foreign_keys = ON` is enabled at setup time so specs mirror
16
+ * the migration script's execution mode. `content_items.redirect_dest_id`'s
17
+ * DEFERRABLE FK is enforced at COMMIT, so specs that exercise the
18
+ * self-reference must run their inserts inside a `db.transaction`
19
+ * boundary (see `populate-content-items.spec.ts`'s redirect test) —
20
+ * bare inserts would trip the FK immediately.
21
+ * @returns Connected Knex instance.
22
+ */
23
+ export declare function setupMigrationDb(): Promise<ReturnType<typeof knex>>;
@@ -0,0 +1,178 @@
1
+ import knex from 'knex';
2
+ import { createEntityTables } from '../../create-entity-tables.js';
3
+ import { createRefTables } from '../../create-ref-tables.js';
4
+ import { LibsqlDialect } from '../../libsql-dialect.js';
5
+ /**
6
+ * Provisions an in-memory SQLite database with:
7
+ *
8
+ * - A minimal subset of the legacy write model (`pages`, `resources`,
9
+ * `anchors`, `images`, `resources-referrers`, `page_html_ref`,
10
+ * `page_html_blobs`) — only the columns the 0.13 populates
11
+ * actually read.
12
+ * - The 0.13 ref / header tables (via {@link createRefTables}).
13
+ * - The 0.13 entity tables (via {@link createEntityTables}).
14
+ *
15
+ * Every 0.13 populate spec calls this to obtain a fresh DB. The
16
+ * caller is responsible for `db.destroy()` (spec `afterEach`).
17
+ *
18
+ * `PRAGMA foreign_keys = ON` is enabled at setup time so specs mirror
19
+ * the migration script's execution mode. `content_items.redirect_dest_id`'s
20
+ * DEFERRABLE FK is enforced at COMMIT, so specs that exercise the
21
+ * self-reference must run their inserts inside a `db.transaction`
22
+ * boundary (see `populate-content-items.spec.ts`'s redirect test) —
23
+ * bare inserts would trip the FK immediately.
24
+ * @returns Connected Knex instance.
25
+ */
26
+ export async function setupMigrationDb() {
27
+ const db = knex({
28
+ client: LibsqlDialect,
29
+ connection: { filename: ':memory:' },
30
+ useNullAsDefault: true,
31
+ });
32
+ await db.raw('PRAGMA foreign_keys = ON');
33
+ await db.schema.createTable('pages', (t) => {
34
+ t.increments('id');
35
+ t.string('url').notNullable();
36
+ t.integer('redirectDestId').nullable();
37
+ t.boolean('scraped').notNullable();
38
+ t.boolean('isTarget').notNullable();
39
+ t.boolean('isExternal');
40
+ t.integer('status');
41
+ t.string('statusText');
42
+ t.string('contentType').nullable();
43
+ t.integer('contentLength').nullable();
44
+ t.json('responseHeaders').nullable();
45
+ t.string('lang');
46
+ t.string('dir');
47
+ t.string('charset');
48
+ t.string('baseHref');
49
+ t.text('viewport_raw');
50
+ t.string('themeColor');
51
+ t.string('applicationName');
52
+ t.string('author');
53
+ t.string('generator');
54
+ t.string('publisher');
55
+ t.string('title');
56
+ t.text('description');
57
+ t.text('keywords');
58
+ t.text('robots_raw');
59
+ t.integer('robots_noindex');
60
+ t.integer('robots_nofollow');
61
+ t.integer('robots_noarchive');
62
+ t.integer('robots_noimageindex');
63
+ t.string('googlebot');
64
+ t.string('canonical');
65
+ t.string('amphtml');
66
+ t.string('manifest');
67
+ t.string('icon_href');
68
+ t.string('appleTouchIcon_href');
69
+ t.string('og_type');
70
+ t.string('og_title');
71
+ t.string('og_url');
72
+ t.string('og_site_name');
73
+ t.text('og_description');
74
+ t.string('og_image');
75
+ t.string('og_image_alt');
76
+ t.string('og_image_width');
77
+ t.string('og_image_height');
78
+ t.string('og_locale');
79
+ t.string('og_article_published_time');
80
+ t.string('og_article_modified_time');
81
+ t.string('twitter_card');
82
+ t.string('twitter_site');
83
+ t.string('twitter_creator');
84
+ t.string('twitter_title');
85
+ t.text('twitter_description');
86
+ t.string('twitter_image');
87
+ t.string('fb_app_id');
88
+ t.string('verification_google');
89
+ t.integer('formatDetection_telephone');
90
+ t.integer('firstCrawledAt');
91
+ t.integer('lastCrawledAt');
92
+ t.integer('tag_count');
93
+ t.integer('jsonld_count');
94
+ t.text('tags_providers_csv');
95
+ t.json('meta_extras');
96
+ t.boolean('isSkipped');
97
+ t.string('skipReason');
98
+ t.integer('order');
99
+ t.string('source').notNullable().defaultTo('crawled');
100
+ });
101
+ await db.schema.createTable('resources', (t) => {
102
+ t.increments('id');
103
+ t.string('url').notNullable();
104
+ t.boolean('isExternal');
105
+ t.integer('status');
106
+ t.string('statusText');
107
+ t.string('contentType').nullable();
108
+ t.integer('contentLength').nullable();
109
+ t.string('compress').nullable();
110
+ t.string('cdn').nullable();
111
+ t.json('responseHeaders').nullable();
112
+ t.string('source').notNullable().defaultTo('crawled');
113
+ });
114
+ await db.schema.createTable('anchors', (t) => {
115
+ t.increments('id');
116
+ t.integer('pageId').notNullable();
117
+ t.integer('hrefId').notNullable();
118
+ t.string('hash');
119
+ t.string('textContent').nullable();
120
+ });
121
+ await db.schema.createTable('images', (t) => {
122
+ t.increments('id');
123
+ t.integer('pageId').notNullable();
124
+ t.string('src').nullable();
125
+ t.string('currentSrc').nullable();
126
+ t.string('alt');
127
+ t.float('width');
128
+ t.float('height');
129
+ t.integer('naturalWidth');
130
+ t.integer('naturalHeight');
131
+ t.boolean('isLazy');
132
+ t.integer('viewportWidth');
133
+ t.string('sourceCode');
134
+ });
135
+ await db.schema.createTable('resources-referrers', (t) => {
136
+ t.increments('id');
137
+ t.integer('resourceId').notNullable();
138
+ t.integer('pageId').notNullable();
139
+ t.unique(['resourceId', 'pageId']);
140
+ });
141
+ // `analysis_violations` is populated by analyze plugins downstream of
142
+ // crawl; the migration itself does not create rows here, but
143
+ // `checkReaderParity` joins it to `pages` / `content_items` so the
144
+ // table must exist so the parity SELECTs return 0-vs-0 (which the
145
+ // parity check legitimately skips).
146
+ await db.schema.createTable('analysis_violations', (t) => {
147
+ t.increments('id');
148
+ t.integer('page_id').notNullable();
149
+ t.string('rule').notNullable();
150
+ t.string('severity').notNullable();
151
+ t.text('message');
152
+ });
153
+ // `populate-image-items.ts` reads HTML BLOBs via the same trx that
154
+ // owns the outer populate transaction (see that file's JSDoc for the
155
+ // deadlock the inline read avoids). Provide the two tables so specs
156
+ // can seed rows or leave them empty (the reader returns `null` on a
157
+ // missing row, matching the `getHtmlOfPageById` contract). Raw SQL
158
+ // so the schema mirrors `init-schema.ts` exactly (`WITHOUT ROWID`,
159
+ // `size_raw` + `size_stored`, `codec` CHECK).
160
+ await db.raw(`
161
+ CREATE TABLE page_html_blobs (
162
+ hash BLOB PRIMARY KEY,
163
+ body BLOB NOT NULL,
164
+ codec TEXT NOT NULL CHECK(codec IN ('zstd', 'none')),
165
+ size_raw INTEGER NOT NULL,
166
+ size_stored INTEGER NOT NULL
167
+ ) WITHOUT ROWID
168
+ `);
169
+ await db.raw(`
170
+ CREATE TABLE page_html_ref (
171
+ page_id INTEGER PRIMARY KEY,
172
+ hash BLOB NOT NULL REFERENCES page_html_blobs(hash)
173
+ ) WITHOUT ROWID
174
+ `);
175
+ await createRefTables(db);
176
+ await createEntityTables(db);
177
+ return db;
178
+ }
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Domain types for the 0.13 entity/edge population step (issue #193).
3
+ *
4
+ * The 0.13 populate helpers translate rows from the legacy write
5
+ * model (`pages`, `resources`, `anchors`, `images`, `resources-referrers`)
6
+ * into the normalised entity + edge tables (`content_items`, `page_meta`,
7
+ * `resource_items`, `anchor_edges`, `resource_ref_edges`, `image_items`)
8
+ * that 0.13 created. Every ref-id lookup goes through a small set of
9
+ * shared resolvers whose interfaces live here per the repo-wide
10
+ * `型は types.ts に集約` rule.
11
+ */
12
+ /**
13
+ * Mapping from `url_refs.url` (the natural key) to `url_refs.id`. Populated
14
+ * on demand from the DB by {@link ./resolve-url-refs.ts}. `null` on values
15
+ * that are stored in {@link ./resolve-blob-refs.ts} instead (large data
16
+ * URIs — see the routing rule in
17
+ * {@link ../populate-ref-tables/populate-url-refs.ts}) or on lookup miss.
18
+ */
19
+ export interface UrlRefResolution {
20
+ /** `url_refs.id` when the URL string is present in the dictionary. */
21
+ readonly urlId: number | null;
22
+ /** `blob_refs.id` when the value is a large data URI routed to blob_refs. */
23
+ readonly blobId: number | null;
24
+ }
25
+ /**
26
+ * Batch-resolved `text_refs.id` for a set of raw text strings. Keyed by
27
+ * the raw text verbatim so the caller does not need to re-hash for
28
+ * cache probes.
29
+ */
30
+ export type TextRefIdMap = ReadonlyMap<string, number>;
31
+ /**
32
+ * Batch-resolved `url_refs.id` for a set of URL strings. Keyed by the
33
+ * raw URL verbatim; missing entries mean the URL is either a large data
34
+ * URI (routed to `blob_refs`) or absent from the dictionary — the caller
35
+ * distinguishes via a separate `blob_refs` probe.
36
+ */
37
+ export type UrlRefIdMap = ReadonlyMap<string, number>;
38
+ /**
39
+ * Batch-resolved `blob_refs.id` for a set of large data URI values.
40
+ * Keyed by the raw value verbatim (the data URI string), consistent with
41
+ * how `populateBlobRefs` inserts one row per distinct data URI payload
42
+ * hash — the resolver looks up by SHA-256 of the decoded payload but
43
+ * returns the map keyed by the raw URI so callers do not have to keep
44
+ * the decoded bytes around.
45
+ */
46
+ export type BlobRefIdMap = ReadonlyMap<string, number>;
47
+ /**
48
+ * Batch-resolved `content_type_refs.id` for a set of raw content-type
49
+ * header values. Keyed by the raw value exactly as stored in
50
+ * `pages.contentType` / `resources.contentType`; missing entries mean
51
+ * the content type is null or absent from the dictionary (which should
52
+ * not happen after `populateContentTypeRefs` populates every distinct
53
+ * value).
54
+ */
55
+ export type ContentTypeRefIdMap = ReadonlyMap<string, number>;
56
+ /**
57
+ * Batch-resolved `header_sets.id` for a set of raw `responseHeaders`
58
+ * JSON strings. Keyed by the raw JSON string; the resolver hashes each
59
+ * value in JS and looks up `header_sets.raw_json_hash` because SQLite
60
+ * has no built-in BLAKE3 / SHA-256 (see
61
+ * {@link ../populate-ref-tables/compute-content-hash.ts} for the algorithm choice).
62
+ */
63
+ export type HeaderSetIdMap = ReadonlyMap<string, number>;
64
+ /**
65
+ * One collapsed anchor edge produced by the single-pass keyset scan in
66
+ * {@link ./populate-anchor-edges.ts}. Rows are emitted in `(page_id,
67
+ * href_page_id)` order; `first_text_id` is resolved in a second pass
68
+ * after `text_refs` lookups.
69
+ */
70
+ export interface AnchorEdgeRow {
71
+ /** `content_items.id` of the page containing the anchor. */
72
+ page_id: number;
73
+ /** `content_items.id` of the anchor target. */
74
+ href_page_id: number;
75
+ /** Number of `anchors` rows collapsed into this edge. */
76
+ count: number;
77
+ /** `first_hash` — the `anchors.hash` of the first (lowest-id) instance. */
78
+ first_hash: string | null;
79
+ /**
80
+ * `first_text_id` — resolved from `first_textContent` against
81
+ * `text_refs`. `null` when the first instance had no textContent (an
82
+ * empty `<a>` tag) or when the text failed to resolve.
83
+ */
84
+ first_text_id: number | null;
85
+ }
86
+ /**
87
+ * One input row for {@link ./collapse-anchor-rows.ts}. Every field
88
+ * mirrors the legacy `anchors` schema; the collapser does not depend on
89
+ * knex or the DB so it can be unit-tested with plain arrays.
90
+ */
91
+ export interface AnchorInputRow {
92
+ /** Legacy `anchors.id` — used only to sort input; not stored on the edge. */
93
+ id: number;
94
+ /** Legacy `anchors.pageId` — `content_items.id` of the source page. */
95
+ pageId: number;
96
+ /** Legacy `anchors.hrefId` — `content_items.id` of the anchor target. */
97
+ hrefId: number;
98
+ /** Legacy `anchors.hash` — verbatim SHA-256 hex from beholder. */
99
+ hash: string | null;
100
+ /** Legacy `anchors.textContent` — anchor visible text (empty for `<a>` with no content). */
101
+ textContent: string | null;
102
+ }
103
+ /**
104
+ * Intermediate shape yielded by {@link ./collapse-anchor-rows.ts}. Differs
105
+ * from the final {@link AnchorEdgeRow} in that `first_text_id` has not
106
+ * been resolved yet — the raw text is carried through as
107
+ * `first_textContent` so the second pass can batch-look up every
108
+ * distinct text against `text_refs`.
109
+ */
110
+ export interface AnchorEdgeRowInProgress {
111
+ /** `content_items.id` of the page. */
112
+ page_id: number;
113
+ /** `content_items.id` of the anchor target. */
114
+ href_page_id: number;
115
+ /** Number of collapsed `anchors` rows. */
116
+ count: number;
117
+ /** Verbatim `anchors.hash` of the first (lowest-id) instance. */
118
+ first_hash: string | null;
119
+ /**
120
+ * Verbatim `anchors.textContent` of the first instance — carried
121
+ * unresolved so the caller can batch-look up ids across every edge.
122
+ */
123
+ first_textContent: string | null;
124
+ }
125
+ /**
126
+ * Case discriminator for {@link ./match-images-to-dom-paths.ts}: which of
127
+ * the three resolution paths produced the returned `dom_path` string. The
128
+ * migration script's jsdom resolver emits a diagnostic warning log for
129
+ * `unknown` fallbacks so operators can audit reconstruction fidelity.
130
+ */
131
+ export type DomPathDerivationCase = 'single-match' | 'ordinal-match' | 'unknown';
132
+ /**
133
+ * Result of the DOM-path derivation for one legacy `images` row.
134
+ * `path` is the string to insert into `text_refs.text`; `case` records
135
+ * which branch produced it.
136
+ */
137
+ export interface DomPathResult {
138
+ /** The `dom_path` string, e.g. `html/body[1]/main[1]/img[3]`. */
139
+ path: string;
140
+ /** Which branch produced the string. */
141
+ case: DomPathDerivationCase;
142
+ }
143
+ /**
144
+ * One `<img>` observed in a rendered / parsed document, in document
145
+ * order: its `outerHTML` (the matching key against the crawler's stored
146
+ * `sourceCode`) and its pre-derived `dom_path` string. Produced either
147
+ * by a jsdom walk over an archived HTML snapshot (migration script) or
148
+ * by an in-browser walk over the live page (crawler write path) — both
149
+ * feed {@link ./match-images-to-dom-paths.ts}, which is DOM-free and
150
+ * only compares these strings.
151
+ */
152
+ export interface DomPathCandidate {
153
+ /** The element's `outerHTML`, verbatim. */
154
+ outerHTML: string;
155
+ /** The element's derived `dom_path` (see {@link ./derive-dom-path.ts}). */
156
+ path: string;
157
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Domain types for the 0.13 entity/edge population step (issue #193).
3
+ *
4
+ * The 0.13 populate helpers translate rows from the legacy write
5
+ * model (`pages`, `resources`, `anchors`, `images`, `resources-referrers`)
6
+ * into the normalised entity + edge tables (`content_items`, `page_meta`,
7
+ * `resource_items`, `anchor_edges`, `resource_ref_edges`, `image_items`)
8
+ * that 0.13 created. Every ref-id lookup goes through a small set of
9
+ * shared resolvers whose interfaces live here per the repo-wide
10
+ * `型は types.ts に集約` rule.
11
+ */
12
+ export {};
@@ -0,0 +1,38 @@
1
+ import type { TextRefIdMap } from './types.js';
2
+ import type { Knex } from 'knex';
3
+ /**
4
+ * Upserts a set of text strings into `text_refs` and returns their ids
5
+ * (issue #193).
6
+ *
7
+ * Unlike {@link ./resolve-text-refs.ts}, which only reads, this helper
8
+ * inserts every missing string first. It exists specifically for
9
+ * `dom_path` strings, which are synthesised by the image-items populate
10
+ * ({@link ./populate-image-items.ts}) and are not among the columns the
11
+ * `text_refs` populate scans
12
+ * ({@link ../populate-ref-tables/populate-text-refs.ts}) — the caller
13
+ * cannot rely on the dictionary already containing them.
14
+ *
15
+ * Strategy:
16
+ *
17
+ * 1. **Hash and INSERT OR IGNORE** every input string in bulk. New rows
18
+ * materialise; conflicts are silently skipped.
19
+ * 2. **Read back** by hash + text (the `(hash, text)` UNIQUE composite)
20
+ * to pick up both freshly-inserted and pre-existing ids.
21
+ *
22
+ * The read-back narrows on both hash and text (same defensive shape as
23
+ * {@link ../populate-ref-tables/populate-header-tables.ts}'s `resolveValueIds`) so
24
+ * an astronomically improbable hash collision cannot leak the wrong
25
+ * id back to the caller.
26
+ *
27
+ * Empty / null strings are ignored; duplicates in `texts` are deduped
28
+ * internally.
29
+ * @param trx - Knex instance or transaction connected to the archive DB.
30
+ * @param texts - Iterable of text strings to upsert.
31
+ * @returns Map keyed by the raw text string.
32
+ * @example
33
+ * const idMap = await upsertTextRefs(trx, [
34
+ * 'html/body[1]/img[1]',
35
+ * 'unknown/42',
36
+ * ]);
37
+ */
38
+ export declare function upsertTextRefs(trx: Knex, texts: Iterable<string>): Promise<TextRefIdMap>;
@@ -0,0 +1,78 @@
1
+ import { computeContentHash } from '../populate-ref-tables/compute-content-hash.js';
2
+ /**
3
+ * Rows sent per `INSERT INTO text_refs ... VALUES (...)` statement. Each
4
+ * row binds 2 params (hash + text) so 500 rows = 1 000 params — well
5
+ * under the SQLite variable limit.
6
+ */
7
+ const INSERT_CHUNK_SIZE = 500;
8
+ /**
9
+ * Rows sent per `SELECT ... WHERE hash IN (?, ...)` chunk on the
10
+ * post-insert read-back. Same reasoning as {@link ./resolve-text-refs.ts}.
11
+ */
12
+ const LOOKUP_CHUNK_SIZE = 800;
13
+ /**
14
+ * Upserts a set of text strings into `text_refs` and returns their ids
15
+ * (issue #193).
16
+ *
17
+ * Unlike {@link ./resolve-text-refs.ts}, which only reads, this helper
18
+ * inserts every missing string first. It exists specifically for
19
+ * `dom_path` strings, which are synthesised by the image-items populate
20
+ * ({@link ./populate-image-items.ts}) and are not among the columns the
21
+ * `text_refs` populate scans
22
+ * ({@link ../populate-ref-tables/populate-text-refs.ts}) — the caller
23
+ * cannot rely on the dictionary already containing them.
24
+ *
25
+ * Strategy:
26
+ *
27
+ * 1. **Hash and INSERT OR IGNORE** every input string in bulk. New rows
28
+ * materialise; conflicts are silently skipped.
29
+ * 2. **Read back** by hash + text (the `(hash, text)` UNIQUE composite)
30
+ * to pick up both freshly-inserted and pre-existing ids.
31
+ *
32
+ * The read-back narrows on both hash and text (same defensive shape as
33
+ * {@link ../populate-ref-tables/populate-header-tables.ts}'s `resolveValueIds`) so
34
+ * an astronomically improbable hash collision cannot leak the wrong
35
+ * id back to the caller.
36
+ *
37
+ * Empty / null strings are ignored; duplicates in `texts` are deduped
38
+ * internally.
39
+ * @param trx - Knex instance or transaction connected to the archive DB.
40
+ * @param texts - Iterable of text strings to upsert.
41
+ * @returns Map keyed by the raw text string.
42
+ * @example
43
+ * const idMap = await upsertTextRefs(trx, [
44
+ * 'html/body[1]/img[1]',
45
+ * 'unknown/42',
46
+ * ]);
47
+ */
48
+ export async function upsertTextRefs(trx, texts) {
49
+ const distinct = new Set();
50
+ for (const text of texts) {
51
+ if (typeof text === 'string' && text !== '') {
52
+ distinct.add(text);
53
+ }
54
+ }
55
+ if (distinct.size === 0) {
56
+ return new Map();
57
+ }
58
+ const values = [...distinct];
59
+ const hashes = values.map((text) => computeContentHash(text));
60
+ const inserts = values.map((text, index) => ({ hash: hashes[index], text }));
61
+ for (let index = 0; index < inserts.length; index += INSERT_CHUNK_SIZE) {
62
+ const chunk = inserts.slice(index, index + INSERT_CHUNK_SIZE);
63
+ await trx('text_refs').insert(chunk).onConflict(['hash', 'text']).ignore();
64
+ }
65
+ const result = new Map();
66
+ for (let index = 0; index < values.length; index += LOOKUP_CHUNK_SIZE) {
67
+ const chunkValues = values.slice(index, index + LOOKUP_CHUNK_SIZE);
68
+ const chunkHashes = hashes.slice(index, index + LOOKUP_CHUNK_SIZE);
69
+ const rows = await trx('text_refs')
70
+ .select('id', 'hash', 'text')
71
+ .whereIn('hash', chunkHashes)
72
+ .whereIn('text', chunkValues);
73
+ for (const row of rows) {
74
+ result.set(row.text, row.id);
75
+ }
76
+ }
77
+ return result;
78
+ }
@@ -0,0 +1,16 @@
1
+ import type { ContentTypeCategory } from './types.js';
2
+ /**
3
+ * Classifies a raw HTTP `Content-Type` header value into the same coarse
4
+ * categories used by the viewer read-model. The rule table in
5
+ * `content-type-rules.ts` is evaluated in declared order and the first
6
+ * matching rule wins (so `application/xhtml+xml` → `html` and
7
+ * `image/svg+xml` → `image`).
8
+ *
9
+ * `null` / empty / whitespace-only inputs map to `'unknown'`; MIMEs that
10
+ * fail every rule map to `'other'`. Behaviour mirrors
11
+ * `@nitpicker/query`'s `classifyContentType`; see the type header of
12
+ * `content-type-rules.ts` for the drift-warning contract.
13
+ * @param contentType - The raw `Content-Type` header value, or `null`.
14
+ * @returns The canonical category label.
15
+ */
16
+ export declare function classifyContentType(contentType: string | null): ContentTypeCategory;
@@ -0,0 +1,52 @@
1
+ import { CONTENT_TYPE_RULES } from './content-type-rules.js';
2
+ /**
3
+ * Classifies a raw HTTP `Content-Type` header value into the same coarse
4
+ * categories used by the viewer read-model. The rule table in
5
+ * `content-type-rules.ts` is evaluated in declared order and the first
6
+ * matching rule wins (so `application/xhtml+xml` → `html` and
7
+ * `image/svg+xml` → `image`).
8
+ *
9
+ * `null` / empty / whitespace-only inputs map to `'unknown'`; MIMEs that
10
+ * fail every rule map to `'other'`. Behaviour mirrors
11
+ * `@nitpicker/query`'s `classifyContentType`; see the type header of
12
+ * `content-type-rules.ts` for the drift-warning contract.
13
+ * @param contentType - The raw `Content-Type` header value, or `null`.
14
+ * @returns The canonical category label.
15
+ */
16
+ export function classifyContentType(contentType) {
17
+ if (contentType == null) {
18
+ return 'unknown';
19
+ }
20
+ const semi = contentType.indexOf(';');
21
+ const head = (semi === -1 ? contentType : contentType.slice(0, semi))
22
+ .trim()
23
+ .toLowerCase();
24
+ if (head === '') {
25
+ return 'unknown';
26
+ }
27
+ for (const rule of CONTENT_TYPE_RULES) {
28
+ for (const matcher of rule.matchers) {
29
+ switch (matcher.kind) {
30
+ case 'exact': {
31
+ if (head === matcher.value) {
32
+ return rule.category;
33
+ }
34
+ break;
35
+ }
36
+ case 'prefix': {
37
+ if (head.startsWith(matcher.value)) {
38
+ return rule.category;
39
+ }
40
+ break;
41
+ }
42
+ case 'suffix': {
43
+ if (head.endsWith(matcher.value)) {
44
+ return rule.category;
45
+ }
46
+ break;
47
+ }
48
+ }
49
+ }
50
+ }
51
+ return 'other';
52
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Computes a 32-byte content hash for a UTF-8 string or raw byte buffer.
3
+ *
4
+ * The hash columns on `text_refs`, `json_refs`, `blob_refs`,
5
+ * `header_value_refs`, and `header_sets` use **SHA-256** rather than a
6
+ * faster candidate such as BLAKE3, for three reasons:
7
+ *
8
+ * 1. **No new dependency**. `@nitpicker/crawler`'s dependency list is small
9
+ * and CLAUDE.md's supply-chain rules discourage adding a hash-only lib.
10
+ * 2. **Consistency**. `page_html_blobs.hash` — the existing content-addressable
11
+ * dictionary — is SHA-256 (see `Database.#writePageHtmlBlob`). Using the
12
+ * same algorithm keeps every content-hash column in the archive on one
13
+ * scheme.
14
+ * 3. **Column contract is length-only**. Every 0.13 hash column is typed
15
+ * `BLOB` (32 bytes when populated). SHA-256 satisfies that contract.
16
+ *
17
+ * If BLAKE3 is later required for throughput, this single function is the only
18
+ * edit point — every callsite in 0.13 routes through here.
19
+ * @param value - Value to hash. `string` inputs are encoded as UTF-8.
20
+ * @returns 32-byte hash as a `Buffer`, ready to insert into a `BLOB` column.
21
+ */
22
+ export declare function computeContentHash(value: string | Uint8Array): Buffer;
@@ -0,0 +1,26 @@
1
+ import { createHash } from 'node:crypto';
2
+ /**
3
+ * Computes a 32-byte content hash for a UTF-8 string or raw byte buffer.
4
+ *
5
+ * The hash columns on `text_refs`, `json_refs`, `blob_refs`,
6
+ * `header_value_refs`, and `header_sets` use **SHA-256** rather than a
7
+ * faster candidate such as BLAKE3, for three reasons:
8
+ *
9
+ * 1. **No new dependency**. `@nitpicker/crawler`'s dependency list is small
10
+ * and CLAUDE.md's supply-chain rules discourage adding a hash-only lib.
11
+ * 2. **Consistency**. `page_html_blobs.hash` — the existing content-addressable
12
+ * dictionary — is SHA-256 (see `Database.#writePageHtmlBlob`). Using the
13
+ * same algorithm keeps every content-hash column in the archive on one
14
+ * scheme.
15
+ * 3. **Column contract is length-only**. Every 0.13 hash column is typed
16
+ * `BLOB` (32 bytes when populated). SHA-256 satisfies that contract.
17
+ *
18
+ * If BLAKE3 is later required for throughput, this single function is the only
19
+ * edit point — every callsite in 0.13 routes through here.
20
+ * @param value - Value to hash. `string` inputs are encoded as UTF-8.
21
+ * @returns 32-byte hash as a `Buffer`, ready to insert into a `BLOB` column.
22
+ */
23
+ export function computeContentHash(value) {
24
+ const bytes = typeof value === 'string' ? Buffer.from(value, 'utf8') : value;
25
+ return createHash('sha256').update(bytes).digest();
26
+ }
@@ -0,0 +1,16 @@
1
+ import type { HeaderEntry, HeaderFlagsRow } from './types.js';
2
+ /**
3
+ * Computes the {@link HeaderFlagsRow} for one decomposed header set.
4
+ *
5
+ * Each `has_*` boolean is a straight "is this name present" check on the
6
+ * decomposed entries — semantically equivalent to `checkHeaders` /
7
+ * `headerPresenceExpression` in `@nitpicker/query`, but expressed in JS
8
+ * over the already-normalized `HeaderEntry.name` (lower-cased) so no
9
+ * `LIKE` pattern is needed. This drops the JSON-key-shape false-positive
10
+ * risk that `headerPresenceExpression`'s SQL guard against (a value that
11
+ * happens to mention another header's name won't fire here because names
12
+ * come from the parsed JSON's KEYS, not from a substring scan).
13
+ * @param entries - Every decomposed entry for one `header_sets` row.
14
+ * @returns The row-shaped flags to insert into `header_flags`.
15
+ */
16
+ export declare function computeHeaderFlags(entries: readonly HeaderEntry[]): HeaderFlagsRow;