@mailwoman/corpus 8.0.0 → 8.2.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 (483) hide show
  1. package/out/src/adapter.d.ts +15 -5
  2. package/out/src/adapter.d.ts.map +1 -1
  3. package/out/src/adapter.js +11 -9
  4. package/out/src/adapter.js.map +1 -1
  5. package/out/src/adapters/ban/adapter.d.ts +7 -0
  6. package/out/src/adapters/ban/adapter.d.ts.map +1 -1
  7. package/out/src/adapters/ban/adapter.js +9 -2
  8. package/out/src/adapters/ban/adapter.js.map +1 -1
  9. package/out/src/adapters/ban/street-decompose.d.ts.map +1 -1
  10. package/out/src/adapters/ban/street-decompose.js +5 -1
  11. package/out/src/adapters/ban/street-decompose.js.map +1 -1
  12. package/out/src/adapters/fcc-bdc/adapter.d.ts +14 -1
  13. package/out/src/adapters/fcc-bdc/adapter.d.ts.map +1 -1
  14. package/out/src/adapters/fcc-bdc/adapter.js +15 -2
  15. package/out/src/adapters/fcc-bdc/adapter.js.map +1 -1
  16. package/out/src/adapters/geonames/adapter.d.ts +11 -0
  17. package/out/src/adapters/geonames/adapter.d.ts.map +1 -1
  18. package/out/src/adapters/geonames/adapter.js +24 -5
  19. package/out/src/adapters/geonames/adapter.js.map +1 -1
  20. package/out/src/adapters/geonames-postal/adapter.d.ts +11 -0
  21. package/out/src/adapters/geonames-postal/adapter.d.ts.map +1 -1
  22. package/out/src/adapters/geonames-postal/adapter.js +14 -1
  23. package/out/src/adapters/geonames-postal/adapter.js.map +1 -1
  24. package/out/src/adapters/gnaf/adapter.d.ts +10 -1
  25. package/out/src/adapters/gnaf/adapter.d.ts.map +1 -1
  26. package/out/src/adapters/gnaf/adapter.js +11 -2
  27. package/out/src/adapters/gnaf/adapter.js.map +1 -1
  28. package/out/src/adapters/gnaf/assemble.d.ts +18 -6
  29. package/out/src/adapters/gnaf/assemble.d.ts.map +1 -1
  30. package/out/src/adapters/gnaf/assemble.js +16 -6
  31. package/out/src/adapters/gnaf/assemble.js.map +1 -1
  32. package/out/src/adapters/index.d.ts.map +1 -1
  33. package/out/src/adapters/index.js.map +1 -1
  34. package/out/src/adapters/openaddresses/adapter.d.ts +11 -0
  35. package/out/src/adapters/openaddresses/adapter.d.ts.map +1 -1
  36. package/out/src/adapters/openaddresses/adapter.js +18 -3
  37. package/out/src/adapters/openaddresses/adapter.js.map +1 -1
  38. package/out/src/adapters/overture/adapter.d.ts +11 -0
  39. package/out/src/adapters/overture/adapter.d.ts.map +1 -1
  40. package/out/src/adapters/overture/adapter.js +12 -1
  41. package/out/src/adapters/overture/adapter.js.map +1 -1
  42. package/out/src/adapters/state-hi-schools/adapter.d.ts +11 -0
  43. package/out/src/adapters/state-hi-schools/adapter.d.ts.map +1 -1
  44. package/out/src/adapters/state-hi-schools/adapter.js +11 -0
  45. package/out/src/adapters/state-hi-schools/adapter.js.map +1 -1
  46. package/out/src/adapters/state-ia-contractors/adapter.d.ts +11 -0
  47. package/out/src/adapters/state-ia-contractors/adapter.d.ts.map +1 -1
  48. package/out/src/adapters/state-ia-contractors/adapter.js +11 -0
  49. package/out/src/adapters/state-ia-contractors/adapter.js.map +1 -1
  50. package/out/src/adapters/state-ny-notaries/adapter.d.ts +11 -0
  51. package/out/src/adapters/state-ny-notaries/adapter.d.ts.map +1 -1
  52. package/out/src/adapters/state-ny-notaries/adapter.js +11 -0
  53. package/out/src/adapters/state-ny-notaries/adapter.js.map +1 -1
  54. package/out/src/adapters/state-tx-notaries/adapter.d.ts +11 -0
  55. package/out/src/adapters/state-tx-notaries/adapter.d.ts.map +1 -1
  56. package/out/src/adapters/state-tx-notaries/adapter.js +15 -2
  57. package/out/src/adapters/state-tx-notaries/adapter.js.map +1 -1
  58. package/out/src/adapters/synth-po-box/adapter.d.ts +11 -0
  59. package/out/src/adapters/synth-po-box/adapter.d.ts.map +1 -1
  60. package/out/src/adapters/synth-po-box/adapter.js +13 -2
  61. package/out/src/adapters/synth-po-box/adapter.js.map +1 -1
  62. package/out/src/adapters/tiger/adapter.d.ts +14 -1
  63. package/out/src/adapters/tiger/adapter.d.ts.map +1 -1
  64. package/out/src/adapters/tiger/adapter.js +19 -4
  65. package/out/src/adapters/tiger/adapter.js.map +1 -1
  66. package/out/src/adapters/tiger/street-decompose.d.ts.map +1 -1
  67. package/out/src/adapters/tiger/street-decompose.js.map +1 -1
  68. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +11 -0
  69. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +1 -1
  70. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js +12 -1
  71. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js.map +1 -1
  72. package/out/src/adapters/usgov-imls-pls/adapter.d.ts +11 -0
  73. package/out/src/adapters/usgov-imls-pls/adapter.d.ts.map +1 -1
  74. package/out/src/adapters/usgov-imls-pls/adapter.js +11 -0
  75. package/out/src/adapters/usgov-imls-pls/adapter.js.map +1 -1
  76. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +11 -0
  77. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts.map +1 -1
  78. package/out/src/adapters/usgov-irs-bmf/adapter.js +17 -2
  79. package/out/src/adapters/usgov-irs-bmf/adapter.js.map +1 -1
  80. package/out/src/adapters/usgov-nad/adapter.d.ts +11 -0
  81. package/out/src/adapters/usgov-nad/adapter.d.ts.map +1 -1
  82. package/out/src/adapters/usgov-nad/adapter.js +12 -1
  83. package/out/src/adapters/usgov-nad/adapter.js.map +1 -1
  84. package/out/src/adapters/usgov-nppes/adapter.d.ts +11 -0
  85. package/out/src/adapters/usgov-nppes/adapter.d.ts.map +1 -1
  86. package/out/src/adapters/usgov-nppes/adapter.js +11 -0
  87. package/out/src/adapters/usgov-nppes/adapter.js.map +1 -1
  88. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +11 -0
  89. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +1 -1
  90. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js +15 -2
  91. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js.map +1 -1
  92. package/out/src/adapters/wof-admin-jp/adapter.d.ts +7 -0
  93. package/out/src/adapters/wof-admin-jp/adapter.d.ts.map +1 -1
  94. package/out/src/adapters/wof-admin-jp/adapter.js +18 -3
  95. package/out/src/adapters/wof-admin-jp/adapter.js.map +1 -1
  96. package/out/src/adapters/wof-admin-json/adapter.d.ts +13 -3
  97. package/out/src/adapters/wof-admin-json/adapter.d.ts.map +1 -1
  98. package/out/src/adapters/wof-admin-json/adapter.js +15 -5
  99. package/out/src/adapters/wof-admin-json/adapter.js.map +1 -1
  100. package/out/src/adapters/wof-postalcode-json/adapter.d.ts +7 -0
  101. package/out/src/adapters/wof-postalcode-json/adapter.d.ts.map +1 -1
  102. package/out/src/adapters/wof-postalcode-json/adapter.js +9 -2
  103. package/out/src/adapters/wof-postalcode-json/adapter.js.map +1 -1
  104. package/out/src/align.d.ts +12 -4
  105. package/out/src/align.d.ts.map +1 -1
  106. package/out/src/align.js +9 -5
  107. package/out/src/align.js.map +1 -1
  108. package/out/src/build.d.ts +24 -8
  109. package/out/src/build.d.ts.map +1 -1
  110. package/out/src/build.js +3 -3
  111. package/out/src/build.js.map +1 -1
  112. package/out/src/codex/us-fips-state.d.ts +6 -2
  113. package/out/src/codex/us-fips-state.d.ts.map +1 -1
  114. package/out/src/codex/us-fips-state.js +3 -1
  115. package/out/src/codex/us-fips-state.js.map +1 -1
  116. package/out/src/golden.d.ts +21 -7
  117. package/out/src/golden.d.ts.map +1 -1
  118. package/out/src/golden.js +18 -10
  119. package/out/src/golden.js.map +1 -1
  120. package/out/src/license.d.ts +3 -1
  121. package/out/src/license.d.ts.map +1 -1
  122. package/out/src/license.js +4 -2
  123. package/out/src/license.js.map +1 -1
  124. package/out/src/parquet-wrapper/reader.d.ts +4 -2
  125. package/out/src/parquet-wrapper/reader.d.ts.map +1 -1
  126. package/out/src/parquet-wrapper/reader.js +5 -4
  127. package/out/src/parquet-wrapper/reader.js.map +1 -1
  128. package/out/src/parquet-wrapper/schema.d.ts +14 -10
  129. package/out/src/parquet-wrapper/schema.d.ts.map +1 -1
  130. package/out/src/parquet-wrapper/schema.js +6 -2
  131. package/out/src/parquet-wrapper/schema.js.map +1 -1
  132. package/out/src/parquet-wrapper/writer.d.ts +12 -4
  133. package/out/src/parquet-wrapper/writer.d.ts.map +1 -1
  134. package/out/src/parquet-wrapper/writer.js +12 -4
  135. package/out/src/parquet-wrapper/writer.js.map +1 -1
  136. package/out/src/parquet.d.ts +21 -7
  137. package/out/src/parquet.d.ts.map +1 -1
  138. package/out/src/parquet.js +15 -4
  139. package/out/src/parquet.js.map +1 -1
  140. package/out/src/runner.d.ts +39 -13
  141. package/out/src/runner.d.ts.map +1 -1
  142. package/out/src/runner.js +7 -3
  143. package/out/src/runner.js.map +1 -1
  144. package/out/src/shard-recipes/anchor-absorption.d.ts +4 -0
  145. package/out/src/shard-recipes/anchor-absorption.d.ts.map +1 -1
  146. package/out/src/shard-recipes/anchor-absorption.js +14 -5
  147. package/out/src/shard-recipes/anchor-absorption.js.map +1 -1
  148. package/out/src/shard-recipes/boundary-stress.d.ts +4 -0
  149. package/out/src/shard-recipes/boundary-stress.d.ts.map +1 -1
  150. package/out/src/shard-recipes/boundary-stress.js +13 -7
  151. package/out/src/shard-recipes/boundary-stress.js.map +1 -1
  152. package/out/src/shard-recipes/country-balanced.d.ts +4 -0
  153. package/out/src/shard-recipes/country-balanced.d.ts.map +1 -1
  154. package/out/src/shard-recipes/country-balanced.js +39 -11
  155. package/out/src/shard-recipes/country-balanced.js.map +1 -1
  156. package/out/src/shard-recipes/cz-pcfirst-preposition.d.ts +4 -0
  157. package/out/src/shard-recipes/cz-pcfirst-preposition.d.ts.map +1 -1
  158. package/out/src/shard-recipes/cz-pcfirst-preposition.js +4 -0
  159. package/out/src/shard-recipes/cz-pcfirst-preposition.js.map +1 -1
  160. package/out/src/shard-recipes/fr-admin-split.d.ts +4 -0
  161. package/out/src/shard-recipes/fr-admin-split.d.ts.map +1 -1
  162. package/out/src/shard-recipes/fr-admin-split.js +14 -3
  163. package/out/src/shard-recipes/fr-admin-split.js.map +1 -1
  164. package/out/src/shard-recipes/fr-bare-street.d.ts +4 -0
  165. package/out/src/shard-recipes/fr-bare-street.d.ts.map +1 -1
  166. package/out/src/shard-recipes/fr-bare-street.js +4 -0
  167. package/out/src/shard-recipes/fr-bare-street.js.map +1 -1
  168. package/out/src/shard-recipes/fr-fragment.d.ts +4 -0
  169. package/out/src/shard-recipes/fr-fragment.d.ts.map +1 -1
  170. package/out/src/shard-recipes/fr-fragment.js +25 -8
  171. package/out/src/shard-recipes/fr-fragment.js.map +1 -1
  172. package/out/src/shard-recipes/fr-lieudit.d.ts +4 -0
  173. package/out/src/shard-recipes/fr-lieudit.d.ts.map +1 -1
  174. package/out/src/shard-recipes/fr-lieudit.js +21 -8
  175. package/out/src/shard-recipes/fr-lieudit.js.map +1 -1
  176. package/out/src/shard-recipes/fr-order.d.ts +4 -0
  177. package/out/src/shard-recipes/fr-order.d.ts.map +1 -1
  178. package/out/src/shard-recipes/fr-order.js +27 -8
  179. package/out/src/shard-recipes/fr-order.js.map +1 -1
  180. package/out/src/shard-recipes/german.d.ts +4 -0
  181. package/out/src/shard-recipes/german.d.ts.map +1 -1
  182. package/out/src/shard-recipes/german.js +16 -6
  183. package/out/src/shard-recipes/german.js.map +1 -1
  184. package/out/src/shard-recipes/house-venue.d.ts +4 -0
  185. package/out/src/shard-recipes/house-venue.d.ts.map +1 -1
  186. package/out/src/shard-recipes/house-venue.js +4 -0
  187. package/out/src/shard-recipes/house-venue.js.map +1 -1
  188. package/out/src/shard-recipes/index.d.ts +9 -3
  189. package/out/src/shard-recipes/index.d.ts.map +1 -1
  190. package/out/src/shard-recipes/index.js +12 -4
  191. package/out/src/shard-recipes/index.js.map +1 -1
  192. package/out/src/shard-recipes/intersection.d.ts +4 -0
  193. package/out/src/shard-recipes/intersection.d.ts.map +1 -1
  194. package/out/src/shard-recipes/intersection.js +27 -13
  195. package/out/src/shard-recipes/intersection.js.map +1 -1
  196. package/out/src/shard-recipes/locale.d.ts +4 -0
  197. package/out/src/shard-recipes/locale.d.ts.map +1 -1
  198. package/out/src/shard-recipes/locale.js +9 -4
  199. package/out/src/shard-recipes/locale.js.map +1 -1
  200. package/out/src/shard-recipes/nl-postcode.d.ts +4 -0
  201. package/out/src/shard-recipes/nl-postcode.d.ts.map +1 -1
  202. package/out/src/shard-recipes/nl-postcode.js +8 -2
  203. package/out/src/shard-recipes/nl-postcode.js.map +1 -1
  204. package/out/src/shard-recipes/no-fragment.d.ts +4 -0
  205. package/out/src/shard-recipes/no-fragment.d.ts.map +1 -1
  206. package/out/src/shard-recipes/no-fragment.js +8 -2
  207. package/out/src/shard-recipes/no-fragment.js.map +1 -1
  208. package/out/src/shard-recipes/no-street-led.d.ts +4 -0
  209. package/out/src/shard-recipes/no-street-led.d.ts.map +1 -1
  210. package/out/src/shard-recipes/no-street-led.js +5 -1
  211. package/out/src/shard-recipes/no-street-led.js.map +1 -1
  212. package/out/src/shard-recipes/no-street.d.ts +4 -0
  213. package/out/src/shard-recipes/no-street.d.ts.map +1 -1
  214. package/out/src/shard-recipes/no-street.js +4 -0
  215. package/out/src/shard-recipes/no-street.js.map +1 -1
  216. package/out/src/shard-recipes/po-box-cedex.d.ts +4 -0
  217. package/out/src/shard-recipes/po-box-cedex.d.ts.map +1 -1
  218. package/out/src/shard-recipes/po-box-cedex.js +99 -43
  219. package/out/src/shard-recipes/po-box-cedex.js.map +1 -1
  220. package/out/src/shard-recipes/po-box.d.ts +4 -0
  221. package/out/src/shard-recipes/po-box.d.ts.map +1 -1
  222. package/out/src/shard-recipes/po-box.js +4 -0
  223. package/out/src/shard-recipes/po-box.js.map +1 -1
  224. package/out/src/shard-recipes/scaffold.d.ts +48 -16
  225. package/out/src/shard-recipes/scaffold.d.ts.map +1 -1
  226. package/out/src/shard-recipes/scaffold.js +10 -6
  227. package/out/src/shard-recipes/scaffold.js.map +1 -1
  228. package/out/src/shard-recipes/si-bare-village.d.ts +4 -0
  229. package/out/src/shard-recipes/si-bare-village.d.ts.map +1 -1
  230. package/out/src/shard-recipes/si-bare-village.js +4 -0
  231. package/out/src/shard-recipes/si-bare-village.js.map +1 -1
  232. package/out/src/shard-recipes/street-affix.d.ts +4 -0
  233. package/out/src/shard-recipes/street-affix.d.ts.map +1 -1
  234. package/out/src/shard-recipes/street-affix.js +29 -10
  235. package/out/src/shard-recipes/street-affix.js.map +1 -1
  236. package/out/src/shard-recipes/street-bare.d.ts +4 -0
  237. package/out/src/shard-recipes/street-bare.d.ts.map +1 -1
  238. package/out/src/shard-recipes/street-bare.js +4 -0
  239. package/out/src/shard-recipes/street-bare.js.map +1 -1
  240. package/out/src/shard-recipes/street.d.ts +4 -0
  241. package/out/src/shard-recipes/street.d.ts.map +1 -1
  242. package/out/src/shard-recipes/street.js +4 -0
  243. package/out/src/shard-recipes/street.js.map +1 -1
  244. package/out/src/shard-recipes/unit.d.ts +4 -0
  245. package/out/src/shard-recipes/unit.d.ts.map +1 -1
  246. package/out/src/shard-recipes/unit.js +45 -14
  247. package/out/src/shard-recipes/unit.js.map +1 -1
  248. package/out/src/split.d.ts +18 -6
  249. package/out/src/split.d.ts.map +1 -1
  250. package/out/src/split.js +4 -2
  251. package/out/src/split.js.map +1 -1
  252. package/out/src/synthesize-anchor-absorption.d.ts +7 -1
  253. package/out/src/synthesize-anchor-absorption.d.ts.map +1 -1
  254. package/out/src/synthesize-anchor-absorption.js +28 -14
  255. package/out/src/synthesize-anchor-absorption.js.map +1 -1
  256. package/out/src/synthesize-boundary-stress.d.ts +3 -1
  257. package/out/src/synthesize-boundary-stress.d.ts.map +1 -1
  258. package/out/src/synthesize-boundary-stress.js +35 -28
  259. package/out/src/synthesize-boundary-stress.js.map +1 -1
  260. package/out/src/synthesize-german.d.ts +15 -5
  261. package/out/src/synthesize-german.d.ts.map +1 -1
  262. package/out/src/synthesize-german.js +9 -3
  263. package/out/src/synthesize-german.js.map +1 -1
  264. package/out/src/synthesize-house-venue.d.ts.map +1 -1
  265. package/out/src/synthesize-house-venue.js +15 -15
  266. package/out/src/synthesize-house-venue.js.map +1 -1
  267. package/out/src/synthesize-intersection.d.ts +9 -3
  268. package/out/src/synthesize-intersection.d.ts.map +1 -1
  269. package/out/src/synthesize-intersection.js +25 -6
  270. package/out/src/synthesize-intersection.js.map +1 -1
  271. package/out/src/synthesize-no-street.d.ts +3 -1
  272. package/out/src/synthesize-no-street.d.ts.map +1 -1
  273. package/out/src/synthesize-no-street.js +5 -6
  274. package/out/src/synthesize-no-street.js.map +1 -1
  275. package/out/src/synthesize-po-box.d.ts +15 -5
  276. package/out/src/synthesize-po-box.d.ts.map +1 -1
  277. package/out/src/synthesize-po-box.js +21 -7
  278. package/out/src/synthesize-po-box.js.map +1 -1
  279. package/out/src/synthesize-street.d.ts +3 -1
  280. package/out/src/synthesize-street.d.ts.map +1 -1
  281. package/out/src/synthesize-street.js +6 -1
  282. package/out/src/synthesize-street.js.map +1 -1
  283. package/out/src/synthesize.d.ts +39 -13
  284. package/out/src/synthesize.d.ts.map +1 -1
  285. package/out/src/synthesize.js +66 -36
  286. package/out/src/synthesize.js.map +1 -1
  287. package/out/src/tokenize.d.ts +15 -5
  288. package/out/src/tokenize.d.ts.map +1 -1
  289. package/out/src/tokenize.js.map +1 -1
  290. package/out/src/tools/align-shard.d.ts.map +1 -1
  291. package/out/src/tools/align-shard.js +3 -1
  292. package/out/src/tools/align-shard.js.map +1 -1
  293. package/out/src/tools/audit.d.ts.map +1 -1
  294. package/out/src/tools/audit.js +20 -8
  295. package/out/src/tools/audit.js.map +1 -1
  296. package/out/src/tools/corpus-stats.d.ts.map +1 -1
  297. package/out/src/tools/corpus-stats.js.map +1 -1
  298. package/out/src/tools/fetch/ban.d.ts.map +1 -1
  299. package/out/src/tools/fetch/ban.js +17 -10
  300. package/out/src/tools/fetch/ban.js.map +1 -1
  301. package/out/src/tools/fetch/download.d.ts +30 -10
  302. package/out/src/tools/fetch/download.d.ts.map +1 -1
  303. package/out/src/tools/fetch/download.js +26 -6
  304. package/out/src/tools/fetch/download.js.map +1 -1
  305. package/out/src/tools/fetch/hrsa.d.ts.map +1 -1
  306. package/out/src/tools/fetch/hrsa.js.map +1 -1
  307. package/out/src/tools/fetch/imls-pls.d.ts.map +1 -1
  308. package/out/src/tools/fetch/imls-pls.js +18 -18
  309. package/out/src/tools/fetch/imls-pls.js.map +1 -1
  310. package/out/src/tools/fetch/index.d.ts +3 -1
  311. package/out/src/tools/fetch/index.d.ts.map +1 -1
  312. package/out/src/tools/fetch/index.js +3 -1
  313. package/out/src/tools/fetch/index.js.map +1 -1
  314. package/out/src/tools/fetch/nad.d.ts +21 -7
  315. package/out/src/tools/fetch/nad.d.ts.map +1 -1
  316. package/out/src/tools/fetch/nad.js +5 -5
  317. package/out/src/tools/fetch/nad.js.map +1 -1
  318. package/out/src/tools/fetch/nppes.d.ts.map +1 -1
  319. package/out/src/tools/fetch/nppes.js +9 -15
  320. package/out/src/tools/fetch/nppes.js.map +1 -1
  321. package/out/src/tools/fetch/openaddresses.d.ts +3 -1
  322. package/out/src/tools/fetch/openaddresses.d.ts.map +1 -1
  323. package/out/src/tools/fetch/openaddresses.js +32 -23
  324. package/out/src/tools/fetch/openaddresses.js.map +1 -1
  325. package/out/src/tools/fetch/ppd.d.ts +3 -1
  326. package/out/src/tools/fetch/ppd.d.ts.map +1 -1
  327. package/out/src/tools/fetch/ppd.js +14 -3
  328. package/out/src/tools/fetch/ppd.js.map +1 -1
  329. package/out/src/tools/fetch/state-hi-schools.d.ts.map +1 -1
  330. package/out/src/tools/fetch/state-hi-schools.js +13 -6
  331. package/out/src/tools/fetch/state-hi-schools.js.map +1 -1
  332. package/out/src/tools/fetch/state-sources.d.ts.map +1 -1
  333. package/out/src/tools/fetch/state-sources.js +8 -3
  334. package/out/src/tools/fetch/state-sources.js.map +1 -1
  335. package/out/src/tools/fetch/tiger-full.d.ts +9 -3
  336. package/out/src/tools/fetch/tiger-full.d.ts.map +1 -1
  337. package/out/src/tools/fetch/tiger-full.js +35 -20
  338. package/out/src/tools/fetch/tiger-full.js.map +1 -1
  339. package/out/src/tools/gb-title-case.d.ts.map +1 -1
  340. package/out/src/tools/gb-title-case.js.map +1 -1
  341. package/out/src/tools/golden-expand.d.ts +24 -8
  342. package/out/src/tools/golden-expand.d.ts.map +1 -1
  343. package/out/src/tools/golden-expand.js +20 -12
  344. package/out/src/tools/golden-expand.js.map +1 -1
  345. package/out/src/tools/golden-promote.d.ts +18 -6
  346. package/out/src/tools/golden-promote.d.ts.map +1 -1
  347. package/out/src/tools/golden-promote.js +22 -7
  348. package/out/src/tools/golden-promote.js.map +1 -1
  349. package/out/src/tools/ingest-csv.d.ts +3 -1
  350. package/out/src/tools/ingest-csv.d.ts.map +1 -1
  351. package/out/src/tools/ingest-csv.js +17 -19
  352. package/out/src/tools/ingest-csv.js.map +1 -1
  353. package/out/src/tools/jsonl-to-parquet.d.ts +18 -6
  354. package/out/src/tools/jsonl-to-parquet.d.ts.map +1 -1
  355. package/out/src/tools/jsonl-to-parquet.js +11 -5
  356. package/out/src/tools/jsonl-to-parquet.js.map +1 -1
  357. package/out/src/tools/lint-shard-vocab.d.ts +36 -12
  358. package/out/src/tools/lint-shard-vocab.d.ts.map +1 -1
  359. package/out/src/tools/lint-shard-vocab.js +25 -11
  360. package/out/src/tools/lint-shard-vocab.js.map +1 -1
  361. package/out/src/tools/lint-shard.d.ts +30 -10
  362. package/out/src/tools/lint-shard.d.ts.map +1 -1
  363. package/out/src/tools/lint-shard.js +33 -20
  364. package/out/src/tools/lint-shard.js.map +1 -1
  365. package/out/src/tools/overlay-manifest.d.ts.map +1 -1
  366. package/out/src/tools/overlay-manifest.js +6 -4
  367. package/out/src/tools/overlay-manifest.js.map +1 -1
  368. package/out/src/tools/shard-kryptonite.d.ts +6 -2
  369. package/out/src/tools/shard-kryptonite.d.ts.map +1 -1
  370. package/out/src/tools/shard-kryptonite.js +1 -1
  371. package/out/src/tools/shard-kryptonite.js.map +1 -1
  372. package/out/src/tools/shard-translit.d.ts +9 -3
  373. package/out/src/tools/shard-translit.d.ts.map +1 -1
  374. package/out/src/tools/shard-translit.js +2 -2
  375. package/out/src/tools/shard-translit.js.map +1 -1
  376. package/out/src/types.d.ts +51 -17
  377. package/out/src/types.d.ts.map +1 -1
  378. package/out/src/wof-json.d.ts +9 -3
  379. package/out/src/wof-json.d.ts.map +1 -1
  380. package/out/src/wof-json.js +6 -4
  381. package/out/src/wof-json.js.map +1 -1
  382. package/package.json +7 -6
  383. package/src/adapter.ts +24 -13
  384. package/src/adapters/ban/adapter.ts +12 -2
  385. package/src/adapters/ban/street-decompose.ts +7 -1
  386. package/src/adapters/fcc-bdc/adapter.ts +19 -3
  387. package/src/adapters/geonames/adapter.ts +28 -5
  388. package/src/adapters/geonames-postal/adapter.ts +17 -1
  389. package/src/adapters/gnaf/adapter.ts +15 -2
  390. package/src/adapters/gnaf/assemble.ts +40 -10
  391. package/src/adapters/index.ts +13 -0
  392. package/src/adapters/openaddresses/adapter.ts +22 -3
  393. package/src/adapters/overture/adapter.ts +18 -2
  394. package/src/adapters/state-hi-schools/adapter.ts +15 -0
  395. package/src/adapters/state-ia-contractors/adapter.ts +15 -0
  396. package/src/adapters/state-ny-notaries/adapter.ts +15 -0
  397. package/src/adapters/state-tx-notaries/adapter.ts +18 -2
  398. package/src/adapters/synth-po-box/adapter.ts +19 -2
  399. package/src/adapters/tiger/adapter.ts +23 -4
  400. package/src/adapters/tiger/street-decompose.ts +1 -0
  401. package/src/adapters/usgov-hrsa-fqhc/adapter.ts +18 -2
  402. package/src/adapters/usgov-imls-pls/adapter.ts +15 -0
  403. package/src/adapters/usgov-irs-bmf/adapter.ts +19 -2
  404. package/src/adapters/usgov-nad/adapter.ts +14 -1
  405. package/src/adapters/usgov-nppes/adapter.ts +13 -0
  406. package/src/adapters/usgov-samhsa-treatment-locator/adapter.ts +21 -3
  407. package/src/adapters/wof-admin-jp/adapter.ts +20 -3
  408. package/src/adapters/wof-admin-json/adapter.ts +22 -7
  409. package/src/adapters/wof-postalcode-json/adapter.ts +10 -2
  410. package/src/align.ts +21 -8
  411. package/src/build.ts +48 -11
  412. package/src/codex/us-fips-state.ts +6 -2
  413. package/src/golden.ts +28 -13
  414. package/src/license.ts +4 -2
  415. package/src/parquet-wrapper/reader.ts +6 -4
  416. package/src/parquet-wrapper/schema.ts +14 -10
  417. package/src/parquet-wrapper/writer.ts +12 -4
  418. package/src/parquet.ts +39 -8
  419. package/src/runner.ts +49 -15
  420. package/src/shard-recipes/anchor-absorption.ts +21 -5
  421. package/src/shard-recipes/boundary-stress.ts +20 -7
  422. package/src/shard-recipes/country-balanced.ts +78 -13
  423. package/src/shard-recipes/cz-pcfirst-preposition.ts +9 -0
  424. package/src/shard-recipes/fr-admin-split.ts +30 -5
  425. package/src/shard-recipes/fr-bare-street.ts +10 -0
  426. package/src/shard-recipes/fr-fragment.ts +33 -8
  427. package/src/shard-recipes/fr-lieudit.ts +35 -9
  428. package/src/shard-recipes/fr-order.ts +47 -9
  429. package/src/shard-recipes/german.ts +32 -6
  430. package/src/shard-recipes/house-venue.ts +7 -0
  431. package/src/shard-recipes/index.ts +12 -4
  432. package/src/shard-recipes/intersection.ts +63 -14
  433. package/src/shard-recipes/locale.ts +37 -4
  434. package/src/shard-recipes/nl-postcode.ts +12 -2
  435. package/src/shard-recipes/no-fragment.ts +12 -2
  436. package/src/shard-recipes/no-street-led.ts +11 -1
  437. package/src/shard-recipes/no-street.ts +7 -0
  438. package/src/shard-recipes/po-box-cedex.ts +145 -45
  439. package/src/shard-recipes/po-box.ts +7 -0
  440. package/src/shard-recipes/scaffold.ts +52 -20
  441. package/src/shard-recipes/si-bare-village.ts +9 -0
  442. package/src/shard-recipes/street-affix.ts +88 -13
  443. package/src/shard-recipes/street-bare.ts +10 -0
  444. package/src/shard-recipes/street.ts +7 -0
  445. package/src/shard-recipes/unit.ts +79 -16
  446. package/src/split.ts +28 -7
  447. package/src/synthesize-anchor-absorption.ts +41 -14
  448. package/src/synthesize-boundary-stress.ts +57 -30
  449. package/src/synthesize-german.ts +30 -7
  450. package/src/synthesize-house-venue.ts +22 -16
  451. package/src/synthesize-intersection.ts +34 -7
  452. package/src/synthesize-no-street.ts +18 -10
  453. package/src/synthesize-po-box.ts +42 -10
  454. package/src/synthesize-street.ts +10 -2
  455. package/src/synthesize.ts +81 -38
  456. package/src/tokenize.ts +15 -5
  457. package/src/tools/align-shard.ts +6 -1
  458. package/src/tools/audit.ts +57 -11
  459. package/src/tools/corpus-stats.ts +9 -0
  460. package/src/tools/fetch/ban.ts +32 -10
  461. package/src/tools/fetch/download.ts +49 -12
  462. package/src/tools/fetch/hrsa.ts +3 -0
  463. package/src/tools/fetch/imls-pls.ts +28 -18
  464. package/src/tools/fetch/index.ts +3 -1
  465. package/src/tools/fetch/nad.ts +39 -12
  466. package/src/tools/fetch/nppes.ts +17 -15
  467. package/src/tools/fetch/openaddresses.ts +52 -24
  468. package/src/tools/fetch/ppd.ts +22 -3
  469. package/src/tools/fetch/state-hi-schools.ts +17 -6
  470. package/src/tools/fetch/state-sources.ts +16 -3
  471. package/src/tools/fetch/tiger-full.ts +66 -23
  472. package/src/tools/gb-title-case.ts +1 -0
  473. package/src/tools/golden-expand.ts +64 -20
  474. package/src/tools/golden-promote.ts +53 -13
  475. package/src/tools/ingest-csv.ts +41 -26
  476. package/src/tools/jsonl-to-parquet.ts +30 -10
  477. package/src/tools/lint-shard-vocab.ts +75 -24
  478. package/src/tools/lint-shard.ts +75 -31
  479. package/src/tools/overlay-manifest.ts +7 -4
  480. package/src/tools/shard-kryptonite.ts +11 -3
  481. package/src/tools/shard-translit.ts +20 -5
  482. package/src/types.ts +51 -17
  483. package/src/wof-json.ts +18 -7
@@ -38,6 +38,21 @@ import { readJSONL, sha256File, writeJSONL } from "@mailwoman/core/utils"
38
38
 
39
39
  // ── Types ──────────────────────────────────────────────────────────────────
40
40
 
41
+ /**
42
+ * Components a candidate needs before it is rich enough to be worth a golden-set slot.
43
+ */
44
+ const MIN_GOLDEN_COMPONENTS = 5
45
+
46
+ /**
47
+ * Components an existing entry must still carry to survive promotion.
48
+ */
49
+ const MIN_PROMOTABLE_COMPONENTS = 4
50
+
51
+ /**
52
+ * Quote-delimited segments above which the raw line is malformed rather than merely quoted.
53
+ */
54
+ const MAX_QUOTE_SEGMENTS = 3
55
+
41
56
  interface GoldenEntry {
42
57
  raw: string
43
58
  components: Record<string, string>
@@ -58,24 +73,36 @@ export interface PromoteStats {
58
73
  }
59
74
 
60
75
  export interface PromoteGoldenOptions {
61
- /** Candidates JSONL (required). */
76
+ /**
77
+ * Candidates JSONL (required).
78
+ */
62
79
  input: string
63
- /** Target golden version dir (required, e.g. `v0.1.1`). */
80
+ /**
81
+ * Target golden version dir (required, e.g. `v0.1.1`).
82
+ */
64
83
  bumpTo: string
65
- /** Previous version to forward-copy + dedup against. Default `v0.1.0`. */
84
+ /**
85
+ * Previous version to forward-copy + dedup against. Default `v0.1.0`.
86
+ */
66
87
  prior?: string
67
- /** Golden dir root. Default `data/eval/golden`. */
88
+ /**
89
+ * Golden dir root. Default `data/eval/golden`.
90
+ */
68
91
  goldenRoot?: string
69
- /** Skip the human-typed-likelihood filters (keep everything that passed expand-golden's validator). */
92
+ /**
93
+ * Skip the human-typed-likelihood filters (keep everything that passed expand-golden's validator).
94
+ */
70
95
  noFilters?: boolean
71
- /** Report what would be written but don't touch disk. */
96
+ /**
97
+ * Report what would be written but don't touch disk.
98
+ */
72
99
  dryRun?: boolean
73
100
  }
74
101
 
75
102
  // ── Filters ───────────────────────────────────────────────────────────────
76
103
 
77
104
  function normalize(s: string): string {
78
- return s.toLowerCase().replace(/\s+/g, " ").trim()
105
+ return s.toLowerCase().replaceAll(/\s+/g, " ").trim()
79
106
  }
80
107
 
81
108
  /**
@@ -85,7 +112,7 @@ function normalize(s: string): string {
85
112
  function isComponentsGlued(entry: GoldenEntry): boolean {
86
113
  const componentCount = Object.keys(entry.components).length
87
114
 
88
- if (componentCount < 5) return false
115
+ if (componentCount < MIN_GOLDEN_COMPONENTS) return false
89
116
  const separators = (entry.raw.match(/[,\n;]/g) ?? []).length
90
117
 
91
118
  return separators < 2
@@ -97,7 +124,7 @@ function isComponentsGlued(entry: GoldenEntry): boolean {
97
124
  * often precedes locality there).
98
125
  */
99
126
  function isPostcodeBadlyLeading(entry: GoldenEntry): boolean {
100
- if (Object.keys(entry.components).length < 4) return false
127
+ if (Object.keys(entry.components).length < MIN_PROMOTABLE_COMPONENTS) return false
101
128
 
102
129
  if (entry.country === "FR" || entry.country === "France") return false
103
130
  const postcode = entry.components.postcode
@@ -118,13 +145,13 @@ function isSuspicious(entry: GoldenEntry): boolean {
118
145
  const raw = entry.raw
119
146
 
120
147
  // eslint-disable-next-line no-control-regex
121
- if (/[\x00-\x1f\x7f]/.test(raw)) return true
148
+ if (/[\u0000-\u001F\u007F]/.test(raw)) return true
122
149
  const openBrackets = (raw.match(/[[({<]/g) ?? []).length
123
150
  const closeBrackets = (raw.match(/[\])}>]/g) ?? []).length
124
151
 
125
152
  if (openBrackets !== closeBrackets) return true
126
153
 
127
- if (raw.split('"').length > 3) return true
154
+ if (raw.split('"').length > MAX_QUOTE_SEGMENTS) return true
128
155
 
129
156
  // too many quote marks
130
157
  return false
@@ -132,7 +159,9 @@ function isSuspicious(entry: GoldenEntry): boolean {
132
159
 
133
160
  // ── IO ─────────────────────────────────────────────────────────────────────
134
161
 
135
- /** Read a JSONL, tolerating a missing file (returns `[]`) — prior golden dirs may lack a bucket. */
162
+ /**
163
+ * Read a JSONL, tolerating a missing file (returns `[]`) — prior golden dirs may lack a bucket.
164
+ */
136
165
  function readJSONLIfPresent<T>(path: string): T[] {
137
166
  if (!existsSync(path)) return []
138
167
 
@@ -169,6 +198,7 @@ export async function promoteGolden(
169
198
  for (const e of entries) {
170
199
  seenNormalized.add(normalize(e.raw))
171
200
  }
201
+
172
202
  report?.(` prior ${country}: ${entries.length} entries (forward-copy base)`)
173
203
  }
174
204
  } else {
@@ -182,6 +212,7 @@ export async function promoteGolden(
182
212
  kept: 0,
183
213
  perCountry: {},
184
214
  }
215
+
185
216
  const accepted: GoldenEntry[] = []
186
217
  const seenInBatch = new Set<string>()
187
218
 
@@ -191,34 +222,40 @@ export async function promoteGolden(
191
222
  // Dedup pass 1: against prior versioned golden
192
223
  if (seenNormalized.has(norm)) {
193
224
  stats.filteredOut.forwardDup++
225
+
194
226
  continue
195
227
  }
196
228
 
197
229
  // Dedup pass 2: against this batch
198
230
  if (seenInBatch.has(norm)) {
199
231
  stats.filteredOut.duplicate++
232
+
200
233
  continue
201
234
  }
202
235
 
203
236
  if (applyFilters) {
204
237
  if (isComponentsGlued(cand)) {
205
238
  stats.filteredOut.glued++
239
+
206
240
  continue
207
241
  }
208
242
 
209
243
  if (isPostcodeBadlyLeading(cand)) {
210
244
  stats.filteredOut.postcodeLeading++
245
+
211
246
  continue
212
247
  }
213
248
 
214
249
  if (isSuspicious(cand)) {
215
250
  stats.filteredOut.suspicious++
251
+
216
252
  continue
217
253
  }
218
254
  }
219
255
 
220
256
  accepted.push(cand)
221
257
  seenInBatch.add(norm)
258
+
222
259
  stats.kept++
223
260
  const country = cand.country || "OTHER"
224
261
  stats.perCountry[country] = (stats.perCountry[country] ?? 0) + 1
@@ -238,6 +275,7 @@ export async function promoteGolden(
238
275
  if (!buckets.has(key)) {
239
276
  buckets.set(key, [])
240
277
  }
278
+
241
279
  buckets.get(key)!.push(cand)
242
280
  }
243
281
 
@@ -249,6 +287,7 @@ export async function promoteGolden(
249
287
  for (const [key, entries] of buckets) {
250
288
  report?.(` ${key.toLowerCase()}.jsonl: ${entries.length} entries`)
251
289
  }
290
+
252
291
  report?.(`=== filter stats ===`)
253
292
  report?.(`candidates in: ${stats.candidatesIn}`)
254
293
  report?.(` filtered (glued): ${stats.filteredOut.glued}`)
@@ -259,7 +298,7 @@ export async function promoteGolden(
259
298
  report?.(` kept: ${stats.kept}`)
260
299
  report?.(`per-country (kept):`)
261
300
 
262
- for (const [c, n] of Object.entries(stats.perCountry).sort((a, b) => b[1] - a[1])) {
301
+ for (const [c, n] of Object.entries(stats.perCountry).toSorted((a, b) => b[1] - a[1])) {
263
302
  report?.(` ${c}: ${n}`)
264
303
  }
265
304
 
@@ -270,6 +309,7 @@ export async function promoteGolden(
270
309
  }
271
310
 
272
311
  mkdirSync(outDir, { recursive: true })
312
+
273
313
  const manifest: {
274
314
  promoted_at: string
275
315
  from: string
@@ -31,9 +31,7 @@ import type { SQLInputValue } from "node:sqlite"
31
31
 
32
32
  import { TextSpliterator } from "spliterator"
33
33
 
34
- // ---------------------------------------------------------------------------
35
- // Core: quote-aware CSV field splitting
36
- // ---------------------------------------------------------------------------
34
+ //#region Core: quote-aware CSV field splitting
37
35
 
38
36
  const COMMA = 44
39
37
  const DOUBLE_QUOTE = 34
@@ -59,6 +57,7 @@ function splitCSVLine(line: string, separator: number = COMMA): string[] {
59
57
  start = i + 1
60
58
  }
61
59
  }
60
+
62
61
  fields.push(line.slice(start))
63
62
 
64
63
  return fields
@@ -68,24 +67,24 @@ function stripQuotes(field: string): string {
68
67
  const trimmed = field.trim()
69
68
 
70
69
  if (trimmed.length >= 2 && trimmed.startsWith('"') && trimmed.endsWith('"')) {
71
- return trimmed.slice(1, -1).replace(/""/g, '"')
70
+ return trimmed.slice(1, -1).replaceAll('""', '"')
72
71
  }
73
72
 
74
73
  return trimmed
75
74
  }
76
75
 
77
- // ---------------------------------------------------------------------------
78
- // Column name normalization
79
- // ---------------------------------------------------------------------------
76
+ //#endregion
77
+
78
+ //#region Column name normalization
80
79
 
81
80
  function normalizeColumnName(raw: string): string {
82
81
  return (
83
82
  raw
84
83
  .trim()
85
- .replace(/^"+|"+$/g, "")
84
+ .replaceAll(/^"+|"+$/g, "")
86
85
  .toLowerCase()
87
- .replace(/[^a-z0-9]+/g, "_")
88
- .replace(/^_|_$/g, "") || "unnamed"
86
+ .replaceAll(/[^a-z0-9]+/g, "_")
87
+ .replaceAll(/^_|_$/g, "") || "unnamed"
89
88
  )
90
89
  }
91
90
 
@@ -100,9 +99,9 @@ function dedupColumns(names: string[]): string[] {
100
99
  })
101
100
  }
102
101
 
103
- // ---------------------------------------------------------------------------
104
- // Type inference
105
- // ---------------------------------------------------------------------------
102
+ //#endregion
103
+
104
+ //#region Type inference
106
105
 
107
106
  type SQLiteColType = "INTEGER" | "REAL" | "TEXT"
108
107
 
@@ -116,7 +115,7 @@ function normalizeField(raw: string): string | null {
116
115
  let s = raw.trim()
117
116
 
118
117
  if (s.length >= 2 && s.startsWith('"') && s.endsWith('"')) {
119
- s = s.slice(1, -1).replace(/""/g, '"')
118
+ s = s.slice(1, -1).replaceAll('""', '"')
120
119
  }
121
120
 
122
121
  // Normalize common null-like values
@@ -136,6 +135,7 @@ function inferColumnType(samples: (string | null)[]): ColumnInfo {
136
135
  for (const s of samples) {
137
136
  if (s === null) {
138
137
  nullCount++
138
+
139
139
  continue
140
140
  }
141
141
 
@@ -154,9 +154,9 @@ function inferColumnType(samples: (string | null)[]): ColumnInfo {
154
154
  return { name: "", type, nullable: nullCount / total >= 0.5 }
155
155
  }
156
156
 
157
- // ---------------------------------------------------------------------------
158
- // Main: read CSV, infer schema, produce SQL
159
- // ---------------------------------------------------------------------------
157
+ //#endregion
158
+
159
+ //#region Main: read CSV, infer schema, produce SQL
160
160
 
161
161
  interface IngestOptions {
162
162
  inputPath: string
@@ -192,6 +192,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
192
192
 
193
193
  if (!headerLine && opts.hasHeader) {
194
194
  headerLine = line
195
+
195
196
  continue
196
197
  }
197
198
 
@@ -226,6 +227,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
226
227
 
227
228
  return normalizeField(raw)
228
229
  })
230
+
229
231
  const info = inferColumnType(samples)
230
232
  info.name = name
231
233
 
@@ -263,6 +265,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
263
265
  // Use the .import approach via a temp table, then INSERT INTO ... SELECT to handle
264
266
  // NULL normalization and type coercion.
265
267
  const csvBasename = basename(opts.inputPath)
268
+
266
269
  const importSQL = [
267
270
  `CREATE TEMP TABLE "${opts.tableName}_source" (${colDefs});`,
268
271
  `.mode csv`,
@@ -291,15 +294,16 @@ async function runIngest(opts: IngestOptions): Promise<void> {
291
294
  for (const row of batch) {
292
295
  insertStmt.run(...row)
293
296
  }
297
+
294
298
  db.exec("COMMIT")
295
- } catch (err) {
299
+ } catch (error) {
296
300
  db.exec("ROLLBACK")
297
- throw err
301
+ throw error
298
302
  }
299
303
  }
300
304
 
301
305
  const batch: SQLInputValue[][] = []
302
- const BATCH_SIZE = 10000
306
+ const BATCH_SIZE = 10_000
303
307
 
304
308
  for await (const line of TextSpliterator.fromAsync(opts.inputPath)) {
305
309
  lineNum++
@@ -308,19 +312,21 @@ async function runIngest(opts: IngestOptions): Promise<void> {
308
312
 
309
313
  if (opts.hasHeader && !headerSkipped) {
310
314
  headerSkipped = true
315
+
311
316
  continue
312
317
  }
313
318
 
314
319
  const fields = splitCSVLine(line, sep).map(stripQuotes)
320
+
315
321
  const values = fields.map((f, i) => {
316
322
  const v = normalizeField(f)
317
323
 
318
324
  if (v === null) return null
319
325
  const col = columns[i]
320
326
 
321
- if (col?.type === "INTEGER" && /^-?\d+$/.test(v)) return parseInt(v, 10)
327
+ if (col?.type === "INTEGER" && /^-?\d+$/.test(v)) return Number.parseInt(v, 10)
322
328
 
323
- if (col?.type === "REAL" && /^-?\d+\.?\d+$/.test(v)) return parseFloat(v)
329
+ if (col?.type === "REAL" && /^-?\d+\.?\d+$/.test(v)) return Number.parseFloat(v)
324
330
 
325
331
  return v
326
332
  })
@@ -329,6 +335,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
329
335
  while (values.length < columns.length) {
330
336
  values.push(null)
331
337
  }
338
+
332
339
  values.length = columns.length
333
340
 
334
341
  batch.push(values)
@@ -338,14 +345,14 @@ async function runIngest(opts: IngestOptions): Promise<void> {
338
345
  imported += batch.length
339
346
  batch.length = 0
340
347
 
341
- if (imported % 100000 === 0) {
348
+ if (imported % 100_000 === 0) {
342
349
  process.stderr.write(` ${(imported / 1_000_000).toFixed(1)}M rows...\n`)
343
350
  }
344
351
  }
345
352
  }
346
353
 
347
354
  // Flush remaining
348
- if (batch.length > 0) {
355
+ if (batch.length) {
349
356
  doInsert()
350
357
  imported += batch.length
351
358
  }
@@ -357,6 +364,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
357
364
 
358
365
  if (firstTextCol) {
359
366
  process.stderr.write(`Building index on "${firstTextCol.name}"...\n`)
367
+
360
368
  db.exec(
361
369
  `CREATE INDEX IF NOT EXISTS idx_${opts.tableName}_${firstTextCol.name} ON "${opts.tableName}"("${firstTextCol.name}");`
362
370
  )
@@ -367,6 +375,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
367
375
  // Write MANIFEST
368
376
  const fileSize = (await import("node:fs/promises")).stat
369
377
  const stat = await (await import("node:fs/promises")).stat(opts.outputPath)
378
+
370
379
  const manifest = {
371
380
  ingested_at: new Date().toISOString(),
372
381
  source_csv: basename(opts.inputPath),
@@ -375,6 +384,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
375
384
  row_count: imported,
376
385
  db_bytes: stat.size,
377
386
  }
387
+
378
388
  const manifestPath = opts.outputPath.replace(/\.db$/, ".manifest.json")
379
389
  writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n")
380
390
 
@@ -383,7 +393,9 @@ async function runIngest(opts: IngestOptions): Promise<void> {
383
393
  )
384
394
  }
385
395
 
386
- /** Flag-shaped options for {@linkcode ingestCSV} — `table`/`output` derive from `input` when omitted. */
396
+ /**
397
+ * Flag-shaped options for {@linkcode ingestCSV} — `table`/`output` derive from `input` when omitted.
398
+ */
387
399
  export interface IngestCSVOptions {
388
400
  input: string
389
401
  table?: string
@@ -405,11 +417,12 @@ export async function ingestCSV(options: IngestCSVOptions): Promise<void> {
405
417
  if (!existsSync(options.input)) {
406
418
  throw new Error(`File not found: ${options.input}`)
407
419
  }
420
+
408
421
  const csvName = basename(options.input, extname(options.input))
409
422
 
410
423
  await runIngest({
411
424
  inputPath: options.input,
412
- tableName: options.table ?? csvName.replace(/[^a-zA-Z0-9_]/g, "_"),
425
+ tableName: options.table ?? csvName.replaceAll(/[^a-zA-Z0-9_]/g, "_"),
413
426
  outputPath: options.output ?? join(dirname(options.input), csvName + ".db"),
414
427
  sampleSize: options.sample ?? 100,
415
428
  separator: options.separator ?? ",",
@@ -418,3 +431,5 @@ export async function ingestCSV(options: IngestCSVOptions): Promise<void> {
418
431
  dryRun: options.dryRun ?? false,
419
432
  })
420
433
  }
434
+
435
+ //#endregion
@@ -82,17 +82,27 @@ const COLUMN_TYPES: Record<(typeof REQUIRED_COLUMNS)[number], string> = {
82
82
  synth_base_id: "VARCHAR",
83
83
  }
84
84
 
85
- /** Options for {@linkcode jsonlToParquet}. */
85
+ /**
86
+ * Options for {@linkcode jsonlToParquet}.
87
+ */
86
88
  export interface JSONLToParquetOptions {
87
- /** The labeled-row JSONL to convert. */
89
+ /**
90
+ * The labeled-row JSONL to convert.
91
+ */
88
92
  input: string
89
- /** The parquet shard to write. */
93
+ /**
94
+ * The parquet shard to write.
95
+ */
90
96
  output: string
91
- /** Parquet row-group size. Default 50000. */
97
+ /**
98
+ * Parquet row-group size. Default 50000.
99
+ */
92
100
  rowGroupSize?: number
93
101
  }
94
102
 
95
- /** Summary returned by {@linkcode jsonlToParquet}. */
103
+ /**
104
+ * Summary returned by {@linkcode jsonlToParquet}.
105
+ */
96
106
  export interface JSONLToParquetSummary {
97
107
  read: number
98
108
  written: number
@@ -115,6 +125,7 @@ function assertSpanTriple(row: Record<string, unknown>, lineNo: number): void {
115
125
  "must carry span_starts/span_ends/span_tags; re-emit this shard through alignRow."
116
126
  )
117
127
  }
128
+
118
129
  const n = (row.span_starts as unknown[]).length
119
130
 
120
131
  if ((row.span_ends as unknown[]).length !== n || (row.span_tags as unknown[]).length !== n) {
@@ -126,17 +137,21 @@ function assertSpanTriple(row: Record<string, unknown>, lineNo: number): void {
126
137
  }
127
138
  }
128
139
 
129
- /** Escape a path for single-quoted SQL string literals. */
140
+ /**
141
+ * Escape a path for single-quoted SQL string literals.
142
+ */
130
143
  function sqlString(value: string): string {
131
- return value.replace(/'/g, "''")
144
+ return value.replaceAll("'", "''")
132
145
  }
133
146
 
134
- /** Convert a labeled-row JSONL to a v0.5.0-schema Parquet shard. */
147
+ /**
148
+ * Convert a labeled-row JSONL to a v0.5.0-schema Parquet shard.
149
+ */
135
150
  export async function jsonlToParquet(
136
151
  options: JSONLToParquetOptions,
137
152
  report?: (line: string) => void
138
153
  ): Promise<JSONLToParquetSummary> {
139
- const rowGroupSize = options.rowGroupSize ?? 50000
154
+ const rowGroupSize = options.rowGroupSize ?? 50_000
140
155
 
141
156
  if (!Number.isInteger(rowGroupSize) || rowGroupSize <= 0) {
142
157
  throw new Error(`rowGroupSize must be a positive integer (got ${JSON.stringify(rowGroupSize)})`)
@@ -166,9 +181,13 @@ export async function jsonlToParquet(
166
181
  // Write the validated line verbatim; DuckDB's `read_json` projects to the explicit `columns`
167
182
  // map below (extra keys dropped, absent keys → NULL — matching the Python `row.get(c)`).
168
183
  stage.write(line + "\n")
184
+
169
185
  rows++
170
186
  }
171
- await new Promise<void>((resolve, reject) => stage.end((err?: Error | null) => (err ? reject(err) : resolve())))
187
+
188
+ await new Promise<void>((resolve, reject) => {
189
+ stage.end((err?: Error | null) => (err ? reject(err) : resolve()))
190
+ })
172
191
 
173
192
  report?.(`Read ${rows} rows from ${options.input}`)
174
193
 
@@ -182,6 +201,7 @@ export async function jsonlToParquet(
182
201
  // Row order is load-bearing: the overlay-manifest assembler records first/last source_id from
183
202
  // shard order. `preserve_insertion_order` (DuckDB default) keeps output order = input order.
184
203
  await db.run("SET preserve_insertion_order=true")
204
+
185
205
  await db.run(
186
206
  `COPY (SELECT ${selectList} FROM read_json('${sqlString(stagePath)}', ` +
187
207
  `columns = ${columnsLiteral}, format = 'newline_delimited')) ` +