@mailwoman/corpus 8.6.0 → 9.1.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 (497) hide show
  1. package/README.md +2 -2
  2. package/data/PROVENANCE.md +214 -0
  3. package/data/sub-venue-lexicon.json +18269 -0
  4. package/out/src/adapters/ban/adapter.d.ts +5 -4
  5. package/out/src/adapters/ban/adapter.d.ts.map +1 -1
  6. package/out/src/adapters/ban/adapter.js +62 -69
  7. package/out/src/adapters/ban/adapter.js.map +1 -1
  8. package/out/src/adapters/ban/street-decompose.d.ts.map +1 -1
  9. package/out/src/adapters/ban/street-decompose.js +18 -25
  10. package/out/src/adapters/ban/street-decompose.js.map +1 -1
  11. package/out/src/adapters/fcc-bdc/adapter.d.ts +1 -7
  12. package/out/src/adapters/fcc-bdc/adapter.d.ts.map +1 -1
  13. package/out/src/adapters/fcc-bdc/adapter.js +4 -26
  14. package/out/src/adapters/fcc-bdc/adapter.js.map +1 -1
  15. package/out/src/adapters/geonames/adapter.d.ts +1 -1
  16. package/out/src/adapters/geonames/adapter.d.ts.map +1 -1
  17. package/out/src/adapters/geonames/adapter.js +72 -78
  18. package/out/src/adapters/geonames/adapter.js.map +1 -1
  19. package/out/src/adapters/geonames-postal/adapter.d.ts +1 -1
  20. package/out/src/adapters/geonames-postal/adapter.d.ts.map +1 -1
  21. package/out/src/adapters/geonames-postal/adapter.js +46 -51
  22. package/out/src/adapters/geonames-postal/adapter.js.map +1 -1
  23. package/out/src/adapters/gnaf/adapter.d.ts +1 -1
  24. package/out/src/adapters/gnaf/adapter.d.ts.map +1 -1
  25. package/out/src/adapters/gnaf/adapter.js +6 -9
  26. package/out/src/adapters/gnaf/adapter.js.map +1 -1
  27. package/out/src/adapters/gnaf/assemble.d.ts.map +1 -1
  28. package/out/src/adapters/gnaf/assemble.js +7 -12
  29. package/out/src/adapters/gnaf/assemble.js.map +1 -1
  30. package/out/src/adapters/index.d.ts +1 -1
  31. package/out/src/adapters/index.d.ts.map +1 -1
  32. package/out/src/adapters/index.js +1 -1
  33. package/out/src/adapters/index.js.map +1 -1
  34. package/out/src/adapters/openaddresses/adapter.d.ts +1 -1
  35. package/out/src/adapters/openaddresses/adapter.d.ts.map +1 -1
  36. package/out/src/adapters/openaddresses/adapter.js +5 -10
  37. package/out/src/adapters/openaddresses/adapter.js.map +1 -1
  38. package/out/src/adapters/overture/adapter.d.ts +1 -1
  39. package/out/src/adapters/overture/adapter.d.ts.map +1 -1
  40. package/out/src/adapters/overture/adapter.js +5 -9
  41. package/out/src/adapters/overture/adapter.js.map +1 -1
  42. package/out/src/adapters/state-hi-schools/adapter.d.ts +1 -1
  43. package/out/src/adapters/state-hi-schools/adapter.d.ts.map +1 -1
  44. package/out/src/adapters/state-hi-schools/adapter.js +57 -75
  45. package/out/src/adapters/state-hi-schools/adapter.js.map +1 -1
  46. package/out/src/adapters/state-ia-contractors/adapter.d.ts +1 -1
  47. package/out/src/adapters/state-ia-contractors/adapter.d.ts.map +1 -1
  48. package/out/src/adapters/state-ia-contractors/adapter.js +60 -78
  49. package/out/src/adapters/state-ia-contractors/adapter.js.map +1 -1
  50. package/out/src/adapters/state-ny-notaries/adapter.d.ts +1 -1
  51. package/out/src/adapters/state-ny-notaries/adapter.d.ts.map +1 -1
  52. package/out/src/adapters/state-ny-notaries/adapter.js +69 -87
  53. package/out/src/adapters/state-ny-notaries/adapter.js.map +1 -1
  54. package/out/src/adapters/state-tx-notaries/adapter.d.ts +1 -1
  55. package/out/src/adapters/state-tx-notaries/adapter.d.ts.map +1 -1
  56. package/out/src/adapters/state-tx-notaries/adapter.js +71 -89
  57. package/out/src/adapters/state-tx-notaries/adapter.js.map +1 -1
  58. package/out/src/adapters/synth-po-box/adapter.d.ts +3 -3
  59. package/out/src/adapters/synth-po-box/adapter.d.ts.map +1 -1
  60. package/out/src/adapters/synth-po-box/adapter.js +10 -18
  61. package/out/src/adapters/synth-po-box/adapter.js.map +1 -1
  62. package/out/src/adapters/tiger/adapter.d.ts +1 -1
  63. package/out/src/adapters/tiger/adapter.d.ts.map +1 -1
  64. package/out/src/adapters/tiger/adapter.js +2 -2
  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 +18 -27
  68. package/out/src/adapters/tiger/street-decompose.js.map +1 -1
  69. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +4 -4
  70. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +1 -1
  71. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js +64 -82
  72. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js.map +1 -1
  73. package/out/src/adapters/usgov-imls-pls/adapter.d.ts +1 -1
  74. package/out/src/adapters/usgov-imls-pls/adapter.d.ts.map +1 -1
  75. package/out/src/adapters/usgov-imls-pls/adapter.js +62 -84
  76. package/out/src/adapters/usgov-imls-pls/adapter.js.map +1 -1
  77. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +1 -1
  78. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts.map +1 -1
  79. package/out/src/adapters/usgov-irs-bmf/adapter.js +59 -66
  80. package/out/src/adapters/usgov-irs-bmf/adapter.js.map +1 -1
  81. package/out/src/adapters/usgov-nad/adapter.d.ts +1 -1
  82. package/out/src/adapters/usgov-nad/adapter.d.ts.map +1 -1
  83. package/out/src/adapters/usgov-nad/adapter.js +6 -9
  84. package/out/src/adapters/usgov-nad/adapter.js.map +1 -1
  85. package/out/src/adapters/usgov-nppes/adapter.d.ts +1 -1
  86. package/out/src/adapters/usgov-nppes/adapter.d.ts.map +1 -1
  87. package/out/src/adapters/usgov-nppes/adapter.js +60 -78
  88. package/out/src/adapters/usgov-nppes/adapter.js.map +1 -1
  89. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +1 -1
  90. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +1 -1
  91. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js +53 -73
  92. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js.map +1 -1
  93. package/out/src/{adapter.d.ts → adapters/utils/index.d.ts} +43 -2
  94. package/out/src/adapters/utils/index.d.ts.map +1 -0
  95. package/out/src/{adapter.js → adapters/utils/index.js} +47 -2
  96. package/out/src/adapters/utils/index.js.map +1 -0
  97. package/out/src/adapters/wof-admin-jp/adapter.d.ts +1 -1
  98. package/out/src/adapters/wof-admin-jp/adapter.d.ts.map +1 -1
  99. package/out/src/adapters/wof-admin-jp/adapter.js +24 -6
  100. package/out/src/adapters/wof-admin-jp/adapter.js.map +1 -1
  101. package/out/src/adapters/wof-admin-json/adapter.d.ts +2 -2
  102. package/out/src/adapters/wof-admin-json/adapter.d.ts.map +1 -1
  103. package/out/src/adapters/wof-admin-json/adapter.js +2 -2
  104. package/out/src/adapters/wof-admin-json/adapter.js.map +1 -1
  105. package/out/src/adapters/wof-postalcode-json/adapter.d.ts +2 -2
  106. package/out/src/adapters/wof-postalcode-json/adapter.d.ts.map +1 -1
  107. package/out/src/adapters/wof-postalcode-json/adapter.js +2 -2
  108. package/out/src/adapters/wof-postalcode-json/adapter.js.map +1 -1
  109. package/out/src/build.d.ts +3 -4
  110. package/out/src/build.d.ts.map +1 -1
  111. package/out/src/build.js +6 -8
  112. package/out/src/build.js.map +1 -1
  113. package/out/src/index.d.ts +3 -17
  114. package/out/src/index.d.ts.map +1 -1
  115. package/out/src/index.js +3 -17
  116. package/out/src/index.js.map +1 -1
  117. package/out/src/name-prone-us-suffixes.d.ts +12 -0
  118. package/out/src/name-prone-us-suffixes.d.ts.map +1 -0
  119. package/out/src/name-prone-us-suffixes.js +12 -0
  120. package/out/src/name-prone-us-suffixes.js.map +1 -0
  121. package/out/src/parquet-wrapper/reader.d.ts +8 -0
  122. package/out/src/parquet-wrapper/reader.d.ts.map +1 -1
  123. package/out/src/parquet-wrapper/reader.js +16 -0
  124. package/out/src/parquet-wrapper/reader.js.map +1 -1
  125. package/out/src/parquet-wrapper/schema.d.ts +4 -0
  126. package/out/src/parquet-wrapper/schema.d.ts.map +1 -1
  127. package/out/src/parquet-wrapper/schema.js.map +1 -1
  128. package/out/src/runner.d.ts +2 -2
  129. package/out/src/runner.d.ts.map +1 -1
  130. package/out/src/runner.js +1 -1
  131. package/out/src/runner.js.map +1 -1
  132. package/out/src/shard-recipes/anchor-absorption.d.ts.map +1 -1
  133. package/out/src/shard-recipes/anchor-absorption.js +5 -4
  134. package/out/src/shard-recipes/anchor-absorption.js.map +1 -1
  135. package/out/src/shard-recipes/boundary-stress.d.ts.map +1 -1
  136. package/out/src/shard-recipes/boundary-stress.js +2 -2
  137. package/out/src/shard-recipes/boundary-stress.js.map +1 -1
  138. package/out/src/shard-recipes/country-balanced.d.ts.map +1 -1
  139. package/out/src/shard-recipes/country-balanced.js +75 -75
  140. package/out/src/shard-recipes/country-balanced.js.map +1 -1
  141. package/out/src/shard-recipes/fr-admin-split.js +2 -2
  142. package/out/src/shard-recipes/fr-admin-split.js.map +1 -1
  143. package/out/src/shard-recipes/fr-fragment.d.ts.map +1 -1
  144. package/out/src/shard-recipes/fr-fragment.js +8 -5
  145. package/out/src/shard-recipes/fr-fragment.js.map +1 -1
  146. package/out/src/shard-recipes/fr-lieudit.js +2 -2
  147. package/out/src/shard-recipes/fr-lieudit.js.map +1 -1
  148. package/out/src/shard-recipes/fr-order.d.ts.map +1 -1
  149. package/out/src/shard-recipes/fr-order.js +18 -72
  150. package/out/src/shard-recipes/fr-order.js.map +1 -1
  151. package/out/src/shard-recipes/german.d.ts.map +1 -1
  152. package/out/src/shard-recipes/german.js +17 -70
  153. package/out/src/shard-recipes/german.js.map +1 -1
  154. package/out/src/shard-recipes/house-venue.d.ts.map +1 -1
  155. package/out/src/shard-recipes/house-venue.js +1 -1
  156. package/out/src/shard-recipes/house-venue.js.map +1 -1
  157. package/out/src/shard-recipes/index.d.ts.map +1 -1
  158. package/out/src/shard-recipes/index.js +4 -1
  159. package/out/src/shard-recipes/index.js.map +1 -1
  160. package/out/src/shard-recipes/intersection.d.ts +2 -2
  161. package/out/src/shard-recipes/intersection.d.ts.map +1 -1
  162. package/out/src/shard-recipes/intersection.js +28 -72
  163. package/out/src/shard-recipes/intersection.js.map +1 -1
  164. package/out/src/shard-recipes/locale.d.ts +5 -5
  165. package/out/src/shard-recipes/locale.d.ts.map +1 -1
  166. package/out/src/shard-recipes/locale.js +25 -35
  167. package/out/src/shard-recipes/locale.js.map +1 -1
  168. package/out/src/shard-recipes/no-fragment.d.ts.map +1 -1
  169. package/out/src/shard-recipes/no-fragment.js +8 -5
  170. package/out/src/shard-recipes/no-fragment.js.map +1 -1
  171. package/out/src/shard-recipes/no-street-led.d.ts.map +1 -1
  172. package/out/src/shard-recipes/no-street-led.js +8 -5
  173. package/out/src/shard-recipes/no-street-led.js.map +1 -1
  174. package/out/src/shard-recipes/no-street.d.ts.map +1 -1
  175. package/out/src/shard-recipes/no-street.js +1 -1
  176. package/out/src/shard-recipes/no-street.js.map +1 -1
  177. package/out/src/shard-recipes/po-box-cedex.d.ts +3 -3
  178. package/out/src/shard-recipes/po-box-cedex.d.ts.map +1 -1
  179. package/out/src/shard-recipes/po-box-cedex.js +101 -127
  180. package/out/src/shard-recipes/po-box-cedex.js.map +1 -1
  181. package/out/src/shard-recipes/po-box.d.ts.map +1 -1
  182. package/out/src/shard-recipes/po-box.js +1 -1
  183. package/out/src/shard-recipes/po-box.js.map +1 -1
  184. package/out/src/shard-recipes/scaffold.d.ts +58 -9
  185. package/out/src/shard-recipes/scaffold.d.ts.map +1 -1
  186. package/out/src/shard-recipes/scaffold.js +87 -29
  187. package/out/src/shard-recipes/scaffold.js.map +1 -1
  188. package/out/src/shard-recipes/street-affix.d.ts +54 -0
  189. package/out/src/shard-recipes/street-affix.d.ts.map +1 -1
  190. package/out/src/shard-recipes/street-affix.js +253 -111
  191. package/out/src/shard-recipes/street-affix.js.map +1 -1
  192. package/out/src/shard-recipes/street-bare.d.ts.map +1 -1
  193. package/out/src/shard-recipes/street-bare.js +3 -3
  194. package/out/src/shard-recipes/street-bare.js.map +1 -1
  195. package/out/src/shard-recipes/street.d.ts.map +1 -1
  196. package/out/src/shard-recipes/street.js +2 -2
  197. package/out/src/shard-recipes/street.js.map +1 -1
  198. package/out/src/shard-recipes/sub-venue-sources.d.ts +228 -0
  199. package/out/src/shard-recipes/sub-venue-sources.d.ts.map +1 -0
  200. package/out/src/shard-recipes/sub-venue-sources.js +664 -0
  201. package/out/src/shard-recipes/sub-venue-sources.js.map +1 -0
  202. package/out/src/shard-recipes/sub-venue.d.ts +269 -0
  203. package/out/src/shard-recipes/sub-venue.d.ts.map +1 -0
  204. package/out/src/shard-recipes/sub-venue.js +709 -0
  205. package/out/src/shard-recipes/sub-venue.js.map +1 -0
  206. package/out/src/shard-recipes/unit.d.ts +1 -1
  207. package/out/src/shard-recipes/unit.d.ts.map +1 -1
  208. package/out/src/shard-recipes/unit.js +26 -74
  209. package/out/src/shard-recipes/unit.js.map +1 -1
  210. package/out/src/{synthesize-anchor-absorption.d.ts → synthesizers/anchor-absorption.d.ts} +1 -1
  211. package/out/src/synthesizers/anchor-absorption.d.ts.map +1 -0
  212. package/out/src/{synthesize-anchor-absorption.js → synthesizers/anchor-absorption.js} +1 -1
  213. package/out/src/synthesizers/anchor-absorption.js.map +1 -0
  214. package/out/src/{synthesize-boundary-stress.d.ts → synthesizers/boundary-stress.d.ts} +3 -3
  215. package/out/src/synthesizers/boundary-stress.d.ts.map +1 -0
  216. package/out/src/{synthesize-boundary-stress.js → synthesizers/boundary-stress.js} +2 -2
  217. package/out/src/synthesizers/boundary-stress.js.map +1 -0
  218. package/out/src/{synthesize-german.d.ts → synthesizers/german.d.ts} +2 -2
  219. package/out/src/synthesizers/german.d.ts.map +1 -0
  220. package/out/src/{synthesize-german.js → synthesizers/german.js} +2 -2
  221. package/out/src/synthesizers/german.js.map +1 -0
  222. package/out/src/{synthesize-house-venue.d.ts → synthesizers/house-venue.d.ts} +4 -4
  223. package/out/src/synthesizers/house-venue.d.ts.map +1 -0
  224. package/out/src/{synthesize-house-venue.js → synthesizers/house-venue.js} +4 -4
  225. package/out/src/synthesizers/house-venue.js.map +1 -0
  226. package/out/src/{synthesize-intersection.d.ts → synthesizers/intersection.d.ts} +2 -2
  227. package/out/src/synthesizers/intersection.d.ts.map +1 -0
  228. package/out/src/{synthesize-intersection.js → synthesizers/intersection.js} +1 -1
  229. package/out/src/synthesizers/intersection.js.map +1 -0
  230. package/out/src/{synthesize-no-street.d.ts → synthesizers/no-street.d.ts} +3 -3
  231. package/out/src/synthesizers/no-street.d.ts.map +1 -0
  232. package/out/src/{synthesize-no-street.js → synthesizers/no-street.js} +2 -2
  233. package/out/src/synthesizers/no-street.js.map +1 -0
  234. package/out/src/{synthesize-po-box.d.ts → synthesizers/po-box.d.ts} +2 -2
  235. package/out/src/synthesizers/po-box.d.ts.map +1 -0
  236. package/out/src/{synthesize-po-box.js → synthesizers/po-box.js} +1 -1
  237. package/out/src/synthesizers/po-box.js.map +1 -0
  238. package/out/src/{synthesize-street.d.ts → synthesizers/street.d.ts} +2 -2
  239. package/out/src/synthesizers/street.d.ts.map +1 -0
  240. package/out/src/{synthesize-street.js → synthesizers/street.js} +2 -2
  241. package/out/src/synthesizers/street.js.map +1 -0
  242. package/out/src/{synthesize.d.ts → synthesizers/utils.d.ts} +3 -3
  243. package/out/src/synthesizers/utils.d.ts.map +1 -0
  244. package/out/src/{synthesize.js → synthesizers/utils.js} +4 -15
  245. package/out/src/synthesizers/utils.js.map +1 -0
  246. package/out/src/tools/align-shard.d.ts.map +1 -1
  247. package/out/src/tools/align-shard.js +4 -8
  248. package/out/src/tools/align-shard.js.map +1 -1
  249. package/out/src/tools/audit.d.ts.map +1 -1
  250. package/out/src/tools/audit.js +4 -4
  251. package/out/src/tools/audit.js.map +1 -1
  252. package/out/src/tools/corpus-stats.d.ts +2 -2
  253. package/out/src/tools/corpus-stats.d.ts.map +1 -1
  254. package/out/src/tools/corpus-stats.js +18 -31
  255. package/out/src/tools/corpus-stats.js.map +1 -1
  256. package/out/src/tools/fetch/download.d.ts.map +1 -1
  257. package/out/src/tools/fetch/download.js +5 -6
  258. package/out/src/tools/fetch/download.js.map +1 -1
  259. package/out/src/tools/fetch/imls-pls.d.ts.map +1 -1
  260. package/out/src/tools/fetch/imls-pls.js +3 -15
  261. package/out/src/tools/fetch/imls-pls.js.map +1 -1
  262. package/out/src/tools/fetch/index.d.ts +14 -1
  263. package/out/src/tools/fetch/index.d.ts.map +1 -1
  264. package/out/src/tools/fetch/index.js +14 -1
  265. package/out/src/tools/fetch/index.js.map +1 -1
  266. package/out/src/tools/fetch/nad.d.ts +1 -1
  267. package/out/src/tools/fetch/nad.js +1 -1
  268. package/out/src/tools/fetch/nppes.d.ts.map +1 -1
  269. package/out/src/tools/fetch/nppes.js +8 -14
  270. package/out/src/tools/fetch/nppes.js.map +1 -1
  271. package/out/src/tools/fetch/openaddresses.d.ts +1 -1
  272. package/out/src/tools/fetch/openaddresses.js +1 -1
  273. package/out/src/tools/fetch/ourairports.d.ts +45 -0
  274. package/out/src/tools/fetch/ourairports.d.ts.map +1 -0
  275. package/out/src/tools/fetch/ourairports.js +123 -0
  276. package/out/src/tools/fetch/ourairports.js.map +1 -0
  277. package/out/src/tools/fetch/wikidata-subvenue.d.ts +171 -0
  278. package/out/src/tools/fetch/wikidata-subvenue.d.ts.map +1 -0
  279. package/out/src/tools/fetch/wikidata-subvenue.js +275 -0
  280. package/out/src/tools/fetch/wikidata-subvenue.js.map +1 -0
  281. package/out/src/tools/golden-expand.d.ts.map +1 -1
  282. package/out/src/tools/golden-expand.js +18 -16
  283. package/out/src/tools/golden-expand.js.map +1 -1
  284. package/out/src/tools/golden-promote.d.ts.map +1 -1
  285. package/out/src/tools/golden-promote.js +12 -6
  286. package/out/src/tools/golden-promote.js.map +1 -1
  287. package/out/src/tools/golden-relabel-street.d.ts +196 -0
  288. package/out/src/tools/golden-relabel-street.d.ts.map +1 -0
  289. package/out/src/tools/golden-relabel-street.js +440 -0
  290. package/out/src/tools/golden-relabel-street.js.map +1 -0
  291. package/out/src/tools/index.d.ts +4 -0
  292. package/out/src/tools/index.d.ts.map +1 -1
  293. package/out/src/tools/index.js +4 -0
  294. package/out/src/tools/index.js.map +1 -1
  295. package/out/src/tools/jsonl-to-parquet.d.ts.map +1 -1
  296. package/out/src/tools/jsonl-to-parquet.js +3 -2
  297. package/out/src/tools/jsonl-to-parquet.js.map +1 -1
  298. package/out/src/tools/lint-shard-vocab.d.ts.map +1 -1
  299. package/out/src/tools/lint-shard-vocab.js +3 -2
  300. package/out/src/tools/lint-shard-vocab.js.map +1 -1
  301. package/out/src/tools/lint-shard.d.ts +3 -3
  302. package/out/src/tools/lint-shard.d.ts.map +1 -1
  303. package/out/src/tools/lint-shard.js +23 -32
  304. package/out/src/tools/lint-shard.js.map +1 -1
  305. package/out/src/tools/overlay-manifest.d.ts.map +1 -1
  306. package/out/src/tools/overlay-manifest.js +2 -1
  307. package/out/src/tools/overlay-manifest.js.map +1 -1
  308. package/out/src/tools/overture-subvenue.d.ts +112 -0
  309. package/out/src/tools/overture-subvenue.d.ts.map +1 -0
  310. package/out/src/tools/overture-subvenue.js +144 -0
  311. package/out/src/tools/overture-subvenue.js.map +1 -0
  312. package/out/src/tools/shard-kryptonite.d.ts +1 -1
  313. package/out/src/tools/shard-kryptonite.d.ts.map +1 -1
  314. package/out/src/tools/shard-kryptonite.js +6 -6
  315. package/out/src/tools/shard-kryptonite.js.map +1 -1
  316. package/out/src/tools/shard-translit.d.ts +6 -3
  317. package/out/src/tools/shard-translit.d.ts.map +1 -1
  318. package/out/src/tools/shard-translit.js +9 -8
  319. package/out/src/tools/shard-translit.js.map +1 -1
  320. package/out/src/tools/sub-venue-lexicon.d.ts +507 -0
  321. package/out/src/tools/sub-venue-lexicon.d.ts.map +1 -0
  322. package/out/src/tools/sub-venue-lexicon.js +817 -0
  323. package/out/src/tools/sub-venue-lexicon.js.map +1 -0
  324. package/out/src/tools/sub-venue-promotions.d.ts +94 -0
  325. package/out/src/tools/sub-venue-promotions.d.ts.map +1 -0
  326. package/out/src/tools/sub-venue-promotions.js +266 -0
  327. package/out/src/tools/sub-venue-promotions.js.map +1 -0
  328. package/out/src/{align.d.ts → utils/align.d.ts} +1 -1
  329. package/out/src/utils/align.d.ts.map +1 -0
  330. package/out/src/utils/align.js.map +1 -0
  331. package/out/src/{golden.d.ts → utils/golden.d.ts} +5 -0
  332. package/out/src/utils/golden.d.ts.map +1 -0
  333. package/out/src/{golden.js → utils/golden.js} +24 -10
  334. package/out/src/utils/golden.js.map +1 -0
  335. package/out/src/utils/index.d.ts +14 -0
  336. package/out/src/utils/index.d.ts.map +1 -0
  337. package/out/src/utils/index.js +14 -0
  338. package/out/src/utils/index.js.map +1 -0
  339. package/out/src/utils/license.d.ts.map +1 -0
  340. package/out/src/utils/license.js.map +1 -0
  341. package/out/src/{parquet.d.ts → utils/parquet.d.ts} +2 -2
  342. package/out/src/utils/parquet.d.ts.map +1 -0
  343. package/out/src/{parquet.js → utils/parquet.js} +3 -15
  344. package/out/src/utils/parquet.js.map +1 -0
  345. package/out/src/{split.d.ts → utils/split.d.ts} +8 -1
  346. package/out/src/utils/split.d.ts.map +1 -0
  347. package/out/src/{split.js → utils/split.js} +7 -0
  348. package/out/src/utils/split.js.map +1 -0
  349. package/out/src/utils/tokenize.d.ts.map +1 -0
  350. package/out/src/utils/tokenize.js.map +1 -0
  351. package/out/src/{wof-json.d.ts → utils/wof-json.d.ts} +2 -2
  352. package/out/src/utils/wof-json.d.ts.map +1 -0
  353. package/out/src/{wof-json.js → utils/wof-json.js} +5 -8
  354. package/out/src/utils/wof-json.js.map +1 -0
  355. package/package.json +66 -20
  356. package/src/adapters/ban/adapter.ts +58 -68
  357. package/src/adapters/ban/street-decompose.ts +17 -25
  358. package/src/adapters/fcc-bdc/adapter.ts +5 -36
  359. package/src/adapters/geonames/adapter.ts +67 -76
  360. package/src/adapters/geonames-postal/adapter.ts +45 -54
  361. package/src/adapters/gnaf/adapter.ts +7 -11
  362. package/src/adapters/gnaf/assemble.ts +7 -11
  363. package/src/adapters/index.ts +3 -2
  364. package/src/adapters/openaddresses/adapter.ts +6 -12
  365. package/src/adapters/overture/adapter.ts +6 -10
  366. package/src/adapters/state-hi-schools/adapter.ts +53 -77
  367. package/src/adapters/state-ia-contractors/adapter.ts +55 -80
  368. package/src/adapters/state-ny-notaries/adapter.ts +64 -89
  369. package/src/adapters/state-tx-notaries/adapter.ts +63 -88
  370. package/src/adapters/synth-po-box/adapter.ts +12 -23
  371. package/src/adapters/tiger/adapter.ts +4 -3
  372. package/src/adapters/tiger/street-decompose.ts +21 -31
  373. package/src/adapters/usgov-hrsa-fqhc/adapter.ts +64 -88
  374. package/src/adapters/usgov-imls-pls/adapter.ts +57 -86
  375. package/src/adapters/usgov-irs-bmf/adapter.ts +55 -66
  376. package/src/adapters/usgov-nad/adapter.ts +7 -11
  377. package/src/adapters/usgov-nppes/adapter.ts +54 -79
  378. package/src/adapters/usgov-samhsa-treatment-locator/adapter.ts +48 -75
  379. package/src/{adapter.ts → adapters/utils/index.ts} +59 -3
  380. package/src/adapters/wof-admin-jp/adapter.ts +35 -9
  381. package/src/adapters/wof-admin-json/adapter.ts +3 -4
  382. package/src/adapters/wof-postalcode-json/adapter.ts +3 -4
  383. package/src/build.ts +12 -11
  384. package/src/index.ts +3 -17
  385. package/src/name-prone-us-suffixes.ts +12 -0
  386. package/src/parquet-wrapper/reader.ts +19 -0
  387. package/src/parquet-wrapper/schema.ts +4 -0
  388. package/src/runner.ts +7 -2
  389. package/src/shard-recipes/anchor-absorption.ts +5 -4
  390. package/src/shard-recipes/boundary-stress.ts +6 -2
  391. package/src/shard-recipes/country-balanced.ts +77 -91
  392. package/src/shard-recipes/fr-admin-split.ts +3 -3
  393. package/src/shard-recipes/fr-fragment.ts +10 -7
  394. package/src/shard-recipes/fr-lieudit.ts +3 -3
  395. package/src/shard-recipes/fr-order.ts +18 -83
  396. package/src/shard-recipes/german.ts +17 -80
  397. package/src/shard-recipes/house-venue.ts +2 -1
  398. package/src/shard-recipes/index.ts +4 -1
  399. package/src/shard-recipes/intersection.ts +37 -74
  400. package/src/shard-recipes/locale.ts +31 -39
  401. package/src/shard-recipes/no-fragment.ts +10 -7
  402. package/src/shard-recipes/no-street-led.ts +10 -7
  403. package/src/shard-recipes/no-street.ts +2 -1
  404. package/src/shard-recipes/po-box-cedex.ts +127 -161
  405. package/src/shard-recipes/po-box.ts +6 -1
  406. package/src/shard-recipes/scaffold.ts +125 -27
  407. package/src/shard-recipes/street-affix.ts +335 -134
  408. package/src/shard-recipes/street-bare.ts +4 -3
  409. package/src/shard-recipes/street.ts +3 -2
  410. package/src/shard-recipes/sub-venue-sources.ts +895 -0
  411. package/src/shard-recipes/sub-venue.ts +982 -0
  412. package/src/shard-recipes/unit.ts +27 -85
  413. package/src/{synthesize-boundary-stress.ts → synthesizers/boundary-stress.ts} +2 -2
  414. package/src/{synthesize-german.ts → synthesizers/german.ts} +2 -2
  415. package/src/{synthesize-house-venue.ts → synthesizers/house-venue.ts} +4 -4
  416. package/src/{synthesize-intersection.ts → synthesizers/intersection.ts} +1 -1
  417. package/src/{synthesize-no-street.ts → synthesizers/no-street.ts} +2 -2
  418. package/src/{synthesize-po-box.ts → synthesizers/po-box.ts} +1 -1
  419. package/src/{synthesize-street.ts → synthesizers/street.ts} +2 -2
  420. package/src/{synthesize.ts → synthesizers/utils.ts} +4 -18
  421. package/src/tools/align-shard.ts +4 -7
  422. package/src/tools/audit.ts +6 -5
  423. package/src/tools/corpus-stats.ts +25 -33
  424. package/src/tools/fetch/download.ts +7 -5
  425. package/src/tools/fetch/imls-pls.ts +4 -18
  426. package/src/tools/fetch/index.ts +14 -1
  427. package/src/tools/fetch/nad.ts +1 -1
  428. package/src/tools/fetch/nppes.ts +9 -16
  429. package/src/tools/fetch/openaddresses.ts +1 -1
  430. package/src/tools/fetch/ourairports.ts +166 -0
  431. package/src/tools/fetch/wikidata-subvenue.ts +386 -0
  432. package/src/tools/golden-expand.ts +18 -13
  433. package/src/tools/golden-promote.ts +15 -6
  434. package/src/tools/golden-relabel-street.ts +685 -0
  435. package/src/tools/index.ts +4 -0
  436. package/src/tools/jsonl-to-parquet.ts +3 -2
  437. package/src/tools/lint-shard-vocab.ts +3 -2
  438. package/src/tools/lint-shard.ts +33 -36
  439. package/src/tools/overlay-manifest.ts +2 -1
  440. package/src/tools/overture-subvenue.ts +215 -0
  441. package/src/tools/shard-kryptonite.ts +8 -9
  442. package/src/tools/shard-translit.ts +22 -11
  443. package/src/tools/sub-venue-lexicon.ts +1250 -0
  444. package/src/tools/sub-venue-promotions.ts +330 -0
  445. package/src/{align.ts → utils/align.ts} +1 -1
  446. package/src/{golden.ts → utils/golden.ts} +25 -11
  447. package/src/utils/index.ts +14 -0
  448. package/src/{parquet.ts → utils/parquet.ts} +5 -19
  449. package/src/{split.ts → utils/split.ts} +8 -2
  450. package/src/{wof-json.ts → utils/wof-json.ts} +5 -8
  451. package/out/src/adapter.d.ts.map +0 -1
  452. package/out/src/adapter.js.map +0 -1
  453. package/out/src/align.d.ts.map +0 -1
  454. package/out/src/align.js.map +0 -1
  455. package/out/src/format.d.ts +0 -14
  456. package/out/src/format.d.ts.map +0 -1
  457. package/out/src/format.js +0 -14
  458. package/out/src/format.js.map +0 -1
  459. package/out/src/golden.d.ts.map +0 -1
  460. package/out/src/golden.js.map +0 -1
  461. package/out/src/license.d.ts.map +0 -1
  462. package/out/src/license.js.map +0 -1
  463. package/out/src/parquet.d.ts.map +0 -1
  464. package/out/src/parquet.js.map +0 -1
  465. package/out/src/split.d.ts.map +0 -1
  466. package/out/src/split.js.map +0 -1
  467. package/out/src/synthesize-anchor-absorption.d.ts.map +0 -1
  468. package/out/src/synthesize-anchor-absorption.js.map +0 -1
  469. package/out/src/synthesize-boundary-stress.d.ts.map +0 -1
  470. package/out/src/synthesize-boundary-stress.js.map +0 -1
  471. package/out/src/synthesize-german.d.ts.map +0 -1
  472. package/out/src/synthesize-german.js.map +0 -1
  473. package/out/src/synthesize-house-venue.d.ts.map +0 -1
  474. package/out/src/synthesize-house-venue.js.map +0 -1
  475. package/out/src/synthesize-intersection.d.ts.map +0 -1
  476. package/out/src/synthesize-intersection.js.map +0 -1
  477. package/out/src/synthesize-no-street.d.ts.map +0 -1
  478. package/out/src/synthesize-no-street.js.map +0 -1
  479. package/out/src/synthesize-po-box.d.ts.map +0 -1
  480. package/out/src/synthesize-po-box.js.map +0 -1
  481. package/out/src/synthesize-street.d.ts.map +0 -1
  482. package/out/src/synthesize-street.js.map +0 -1
  483. package/out/src/synthesize.d.ts.map +0 -1
  484. package/out/src/synthesize.js.map +0 -1
  485. package/out/src/tokenize.d.ts.map +0 -1
  486. package/out/src/tokenize.js.map +0 -1
  487. package/out/src/wof-json.d.ts.map +0 -1
  488. package/out/src/wof-json.js.map +0 -1
  489. package/src/format.ts +0 -14
  490. /package/out/src/{align.js → utils/align.js} +0 -0
  491. /package/out/src/{license.d.ts → utils/license.d.ts} +0 -0
  492. /package/out/src/{license.js → utils/license.js} +0 -0
  493. /package/out/src/{tokenize.d.ts → utils/tokenize.d.ts} +0 -0
  494. /package/out/src/{tokenize.js → utils/tokenize.js} +0 -0
  495. /package/src/{synthesize-anchor-absorption.ts → synthesizers/anchor-absorption.ts} +0 -0
  496. /package/src/{license.ts → utils/license.ts} +0 -0
  497. /package/src/{tokenize.ts → utils/tokenize.ts} +0 -0
@@ -15,14 +15,11 @@
15
15
  * License: stamped `"Public Domain"` per Texas state government open-data terms.
16
16
  */
17
17
 
18
- import { createReadStream } from "node:fs"
19
-
20
- import { parse as csvParse } from "csv-parse"
21
-
22
- import { stableSourceID } from "../../adapter.ts"
23
- import { lookupStateAbbreviation } from "../../codex/us-fips-state.ts"
24
- import { reconcileComponents } from "../../format.ts"
25
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
18
+ import { splitStreetLine, stableSourceID } from "@mailwoman/corpus/adapters/utils"
19
+ import { lookupStateAbbreviation } from "@mailwoman/corpus/codex/us-fips-state"
20
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
21
+ import { reconcileComponents } from "@mailwoman/formatter"
22
+ import { CSVSpliterator } from "spliterator"
26
23
 
27
24
  /**
28
25
  * Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
@@ -35,8 +32,6 @@ export const STATE_TX_NOTARIES_ADAPTER_ID = "state-tx-notaries"
35
32
  */
36
33
  export const STATE_TX_NOTARIES_DEFAULT_LICENSE = "Public Domain"
37
34
 
38
- const HOUSE_NUMBER_PREFIX = /^(\d+(?:-\d+)?[A-Za-z]?)\s+(.+)$/
39
-
40
35
  /**
41
36
  * Match trailing "CITY, ST ZIP" or "CITY, ST" at the end of an address line.
42
37
  */
@@ -49,17 +44,6 @@ interface TxNotaryRow {
49
44
  Address: string
50
45
  }
51
46
 
52
- function splitAddress(address: string): { house_number?: string; street: string } | null {
53
- const trimmed = address.trim()
54
-
55
- if (!trimmed) return null
56
- const m = HOUSE_NUMBER_PREFIX.exec(trimmed)
57
-
58
- if (m) return { house_number: m[1], street: m[2]!.trim() }
59
-
60
- return { street: trimmed }
61
- }
62
-
63
47
  export function createStateTxNotariesAdapter(): CorpusAdapter {
64
48
  return {
65
49
  id: STATE_TX_NOTARIES_ADAPTER_ID,
@@ -72,99 +56,90 @@ export function createStateTxNotariesAdapter(): CorpusAdapter {
72
56
  throw new Error(`state-tx-notaries adapter: only US supported, got country=${opts.country}`)
73
57
  }
74
58
 
75
- const stream = createReadStream(opts.inputPath, { encoding: "utf8" })
76
-
77
- const parser = stream.pipe(
78
- csvParse({
79
- columns: true,
80
- skip_empty_lines: true,
81
- relax_quotes: true,
82
- relax_column_count: true,
83
- })
84
- )
59
+ const rows = CSVSpliterator.fromAsync(opts.inputPath, {
60
+ mode: "object",
61
+ normalizeKeys: false,
62
+ enableQuoteHandling: true,
63
+ })
85
64
 
86
65
  let emitted = 0
87
66
 
88
- try {
89
- for await (const record of parser as AsyncIterable<TxNotaryRow>) {
90
- if (opts.signal?.aborted) break
67
+ for await (const record of rows as AsyncIterable<TxNotaryRow>) {
68
+ if (opts.signal?.aborted) break
91
69
 
92
- if (opts.limit !== undefined && emitted >= opts.limit) break
70
+ if (opts.limit !== undefined && emitted >= opts.limit) break
93
71
 
94
- const rawAddress = (record.Address ?? "").trim()
72
+ const rawAddress = (record.Address ?? "").trim()
95
73
 
96
- if (!rawAddress) continue
74
+ if (!rawAddress) continue
97
75
 
98
- const firstName = (record["First Name"] ?? "").trim()
99
- const lastName = (record["Last Name"] ?? "").trim()
100
- const notaryID = (record["Notary ID"] ?? "").trim()
76
+ const firstName = (record["First Name"] ?? "").trim()
77
+ const lastName = (record["Last Name"] ?? "").trim()
78
+ const notaryID = (record["Notary ID"] ?? "").trim()
101
79
 
102
- // Parse embedded city/state/zip from the trailing portion of the address.
103
- // Addresses look like: "1215 MCMILLAN DR\nCEDAR HILL, TX 75104"
104
- const addrSingleLine = rawAddress.replaceAll("\n", ", ")
105
- const cszMatch = CITY_STATE_ZIP_SUFFIX.exec(addrSingleLine)
80
+ // Parse embedded city/state/zip from the trailing portion of the address.
81
+ // Addresses look like: "1215 MCMILLAN DR\nCEDAR HILL, TX 75104"
82
+ const addrSingleLine = rawAddress.replaceAll("\n", ", ")
83
+ const cszMatch = CITY_STATE_ZIP_SUFFIX.exec(addrSingleLine)
106
84
 
107
- if (!cszMatch) continue
85
+ if (!cszMatch) continue
108
86
 
109
- const city = (cszMatch[1] ?? "").trim()
110
- const stateAbbr = (cszMatch[2] ?? "").trim()
111
- const zip = (cszMatch[3] ?? "").trim()
87
+ const city = (cszMatch[1] ?? "").trim()
88
+ const stateAbbr = (cszMatch[2] ?? "").trim()
89
+ const zip = (cszMatch[3] ?? "").trim()
112
90
 
113
- if (!city || !stateAbbr) continue
91
+ if (!city || !stateAbbr) continue
114
92
 
115
- const state = lookupStateAbbreviation(stateAbbr)
93
+ const state = lookupStateAbbreviation(stateAbbr)
116
94
 
117
- if (!state) continue
95
+ if (!state) continue
118
96
 
119
- // Extract the street portion (everything before the city/state/zip)
120
- const streetPortion = addrSingleLine.slice(0, cszMatch.index).replace(/,\s*$/, "").trim()
97
+ // Extract the street portion (everything before the city/state/zip)
98
+ const streetPortion = addrSingleLine.slice(0, cszMatch.index).replace(/,\s*$/, "").trim()
121
99
 
122
- if (!streetPortion) continue
100
+ if (!streetPortion) continue
123
101
 
124
- const split = splitAddress(streetPortion)
102
+ const split = splitStreetLine(streetPortion)
125
103
 
126
- if (!split) continue
104
+ if (!split) continue
127
105
 
128
- const venue = [firstName, lastName].filter(Boolean).join(" ") || undefined
106
+ const venue = [firstName, lastName].filter(Boolean).join(" ") || undefined
129
107
 
130
- const components: CanonicalRow["components"] = {
131
- ...(venue ? { venue } : {}),
132
- ...(split.house_number ? { house_number: split.house_number } : {}),
133
- street: split.street,
134
- locality: city,
135
- region: state.abbreviation,
136
- ...(zip ? { postcode: zip } : {}),
137
- }
138
-
139
- const streetPart = [split.house_number, split.street].filter(Boolean).join(" ").trim()
108
+ const components: CanonicalRow["components"] = {
109
+ ...(venue ? { venue } : {}),
110
+ ...(split.house_number ? { house_number: split.house_number } : {}),
111
+ street: split.street,
112
+ locality: city,
113
+ region: state.abbreviation,
114
+ ...(zip ? { postcode: zip } : {}),
115
+ }
140
116
 
141
- const raw = [venue, streetPart, [city, [stateAbbr, zip].filter(Boolean).join(" ")].filter(Boolean).join(", ")]
142
- .filter(Boolean)
143
- .join(", ")
117
+ const streetPart = [split.house_number, split.street].filter(Boolean).join(" ").trim()
144
118
 
145
- const aligned = reconcileComponents(components, raw)
119
+ const raw = [venue, streetPart, [city, [stateAbbr, zip].filter(Boolean).join(" ")].filter(Boolean).join(", ")]
120
+ .filter(Boolean)
121
+ .join(", ")
146
122
 
147
- if (Object.keys(aligned).length <= 2) continue
123
+ const aligned = reconcileComponents(components, raw)
148
124
 
149
- const sourceID = notaryID
150
- ? `${STATE_TX_NOTARIES_ADAPTER_ID}-${notaryID}`
151
- : stableSourceID(STATE_TX_NOTARIES_ADAPTER_ID, aligned)
125
+ if (Object.keys(aligned).length <= 2) continue
152
126
 
153
- yield {
154
- raw,
155
- components: aligned,
156
- country: "US",
157
- locale: "en-US",
158
- source: STATE_TX_NOTARIES_ADAPTER_ID,
159
- source_id: sourceID,
160
- corpus_version: "",
161
- license: STATE_TX_NOTARIES_DEFAULT_LICENSE,
162
- }
127
+ const sourceID = notaryID
128
+ ? `${STATE_TX_NOTARIES_ADAPTER_ID}-${notaryID}`
129
+ : stableSourceID(STATE_TX_NOTARIES_ADAPTER_ID, aligned)
163
130
 
164
- emitted++
131
+ yield {
132
+ raw,
133
+ components: aligned,
134
+ country: "US",
135
+ locale: "en-US",
136
+ source: STATE_TX_NOTARIES_ADAPTER_ID,
137
+ source_id: sourceID,
138
+ corpus_version: "",
139
+ license: STATE_TX_NOTARIES_DEFAULT_LICENSE,
165
140
  }
166
- } finally {
167
- stream.destroy()
141
+
142
+ emitted++
168
143
  }
169
144
  },
170
145
  }
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * Consumes a JSONL stream of (locality, region, postcode, country) tuples — typically extracted
9
9
  * from existing corpus output (TIGER/NAD/BAN/WOF) — and emits synthetic PO box training rows. See
10
- * `../../synthesize-po-box.ts` for the per-locale templates and number-noise logic.
10
+ * `@mailwoman/corpus/synthesizers/po-box` for the per-locale templates and number-noise logic.
11
11
  *
12
12
  * Why an adapter and not an augmenter:
13
13
  *
@@ -20,17 +20,18 @@
20
20
  * carries a `street` field.
21
21
  */
22
22
 
23
- import { TextSpliterator } from "spliterator"
24
-
25
- import { stableSourceID } from "../../adapter.ts"
23
+ import { tryParsingJSON } from "@mailwoman/core/objects"
24
+ import { makeLcg } from "@mailwoman/core/utils"
25
+ import { stableSourceID } from "@mailwoman/corpus/adapters/utils"
26
26
  import {
27
27
  countryToLocale,
28
28
  REGION_OPTIONAL_LOCALES,
29
29
  synthesizeMilitaryPoBoxRow,
30
30
  synthesizePoBoxRow,
31
31
  type PoBoxBaseTuple,
32
- } from "../../synthesize-po-box.ts"
33
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
32
+ } from "@mailwoman/corpus/synthesizers/po-box"
33
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
34
+ import { TextSpliterator } from "spliterator"
34
35
 
35
36
  /**
36
37
  * Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
@@ -73,16 +74,6 @@ export interface SynthPoBoxAdapterOptions {
73
74
  militaryRatio?: number
74
75
  }
75
76
 
76
- function makeRandom(seed: number): () => number {
77
- let s = seed
78
-
79
- return () => {
80
- s = (s * 1_664_525 + 1_013_904_223) % 4_294_967_296
81
-
82
- return s / 4_294_967_296
83
- }
84
- }
85
-
86
77
  export function createSynthPoBoxAdapter(opts: SynthPoBoxAdapterOptions = {}): CorpusAdapter {
87
78
  const variantsPerInput = opts.variantsPerInput ?? 1
88
79
  const pmbRatio = opts.pmbRatio ?? 0.15
@@ -95,10 +86,10 @@ export function createSynthPoBoxAdapter(opts: SynthPoBoxAdapterOptions = {}): Co
95
86
  "Synthetic PO box / PMB / Apartado / Boîte Postale rows. Consumes JSONL of (locality, region, postcode, country) tuples and emits locale-appropriate PO box variants.",
96
87
 
97
88
  async *rows(options: AdapterOptions): AsyncIterable<CanonicalRow> {
98
- const random = makeRandom(opts.seed ?? Date.now())
89
+ const random = makeLcg(opts.seed ?? Date.now())
99
90
 
100
- // TextSpliterator streams string lines; the per-line try/catch below keeps this reader
101
- // tolerant of malformed rows (skipped++), so TextSpliterator + explicit JSON.parse — not
91
+ // TextSpliterator streams string lines; the per-line tryParsingJSON below keeps this reader
92
+ // tolerant of malformed rows (skipped++), so TextSpliterator + a non-throwing parse — not
102
93
  // JSONSpliterator, which would throw on the first bad line.
103
94
  const lines = TextSpliterator.fromAsync(options.inputPath)
104
95
 
@@ -115,11 +106,9 @@ export function createSynthPoBoxAdapter(opts: SynthPoBoxAdapterOptions = {}): Co
115
106
 
116
107
  if (!trimmed) continue
117
108
 
118
- let input: PoBoxInputRow
109
+ const input = tryParsingJSON<PoBoxInputRow>(trimmed)
119
110
 
120
- try {
121
- input = JSON.parse(trimmed) as PoBoxInputRow
122
- } catch {
111
+ if (input === null) {
123
112
  skipped++
124
113
 
125
114
  continue
@@ -36,9 +36,10 @@
36
36
 
37
37
  import { DatabaseSync } from "node:sqlite"
38
38
 
39
- import { lookupFipsState } from "../../codex/us-fips-state.ts"
40
- import { formatAddress, reconcileComponents } from "../../format.ts"
41
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
39
+ import { lookupFipsState } from "@mailwoman/corpus/codex/us-fips-state"
40
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
41
+ import { formatAddress, reconcileComponents } from "@mailwoman/formatter"
42
+
42
43
  import { decomposeStreet } from "./street-decompose.ts"
43
44
 
44
45
  /**
@@ -17,45 +17,35 @@
17
17
  */
18
18
 
19
19
  import { readFileSync } from "node:fs"
20
- import { resolve } from "node:path"
21
20
 
22
21
  import { resourceDictionaryPath } from "@mailwoman/core/utils"
22
+ import { TextSpliterator } from "spliterator"
23
23
 
24
24
  function loadDictionary(filename: string): Set<string> {
25
- // Resolve via the @mailwoman/core data directory.
26
- const candidates = [
27
- resourceDictionaryPath("libpostal", "en", filename),
28
- resourceDictionaryPath("libpostal", "en", filename),
29
- resolve(process.cwd(), "core/data/libpostal/dictionaries/en", filename),
30
- ]
31
-
32
- for (const path of candidates) {
33
- try {
34
- const text = readFileSync(path, "utf8")
35
- const set = new Set<string>()
36
-
37
- for (const line of text.split("\n")) {
38
- const trimmed = line.trim()
39
-
40
- if (!trimmed || trimmed.startsWith("#")) continue
41
-
42
- // libpostal format: canonical|abbr|abbr|... — index all forms
43
- for (const form of trimmed.split("|")) {
44
- const f = form.trim().toLowerCase()
45
-
46
- if (f) {
47
- set.add(f)
48
- }
49
- }
50
- }
25
+ // `resourceDictionaryPath` already resolves both layouts — `core/data/...` from source and from the
26
+ // packaged `out/` tree. The candidate list this replaced named it TWICE and then guessed a third path
27
+ // off `process.cwd()`, and swallowed every error while probing, so a corrupt dictionary reported as a
28
+ // missing one.
29
+ const text = readFileSync(resourceDictionaryPath("libpostal", "en", filename), "utf8")
30
+ const set = new Set<string>()
31
+
32
+ // The largest libpostal dictionary is 8.4 KB, and this runs once per process at module load.
33
+ for (const line of TextSpliterator.from(text)) {
34
+ const trimmed = line.trim()
35
+
36
+ if (!trimmed || trimmed.startsWith("#")) continue
51
37
 
52
- return set
53
- } catch {
54
- // try next candidate
38
+ // libpostal format: canonical|abbr|abbr|... — index all forms
39
+ for (const form of trimmed.split("|")) {
40
+ const f = form.trim().toLowerCase()
41
+
42
+ if (f) {
43
+ set.add(f)
44
+ }
55
45
  }
56
46
  }
57
47
 
58
- throw new Error(`Could not load libpostal dictionary: ${filename}`)
48
+ return set
59
49
  }
60
50
 
61
51
  const DIRECTIONALS = loadDictionary("directionals.txt")
@@ -8,9 +8,9 @@
8
8
  * Federally Qualified Health Centers (FQHCs) are HRSA-funded community health programs that
9
9
  * self-report site addresses to the HRSA Data Warehouse. The published CSV (`data.hrsa.gov`)
10
10
  * carries the site name, the postal-formatted street address, and the locality/region/postcode
11
- * quad. Phase 1.6 §1.2 (#22) selects this source for its adversarial-value-per-row: every
12
- * facility name is a human-typed venue string and the addresses pass through enough hands to
13
- * accumulate the abbreviation drift + suite designator chaos that pure gazetteer data does not.
11
+ * quad. The source earns its place on adversarial-value-per-row (#22): every facility name is a
12
+ * human-typed venue string and the addresses pass through enough hands to accumulate the
13
+ * abbreviation drift + suite designator chaos that pure gazetteer data does not.
14
14
  *
15
15
  * The adapter consumes a CSV file the operator pre-downloads. The HRSA data is published as a
16
16
  * single national CSV (~10K rows), small enough that the operator can re-fetch on every corpus
@@ -29,14 +29,11 @@
29
29
  * terms.
30
30
  */
31
31
 
32
- import { createReadStream } from "node:fs"
33
-
34
- import { parse as csvParse } from "csv-parse"
35
-
36
- import { stableSourceID } from "../../adapter.ts"
37
- import { lookupStateAbbreviation } from "../../codex/us-fips-state.ts"
38
- import { reconcileComponents } from "../../format.ts"
39
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
32
+ import { splitStreetLine, stableSourceID } from "@mailwoman/corpus/adapters/utils"
33
+ import { lookupStateAbbreviation } from "@mailwoman/corpus/codex/us-fips-state"
34
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
35
+ import { reconcileComponents } from "@mailwoman/formatter"
36
+ import { CSVSpliterator } from "spliterator"
40
37
 
41
38
  /**
42
39
  * Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
@@ -70,23 +67,11 @@ interface HrsaSiteRow {
70
67
  * Split a "123 Main St Suite 4" surface form into `(house_number, street)`. The regex tolerates one trailing letter on
71
68
  * the number (`"123A Main St"`) and a hyphenated form (`"40-12 Bell Blvd"`); anything else falls back to street-only.
72
69
  *
73
- * Suite / Apt / Unit designators stay on `street` for Phase 1 — Mailwoman's `unit` component exists but the
74
- * address-formatter does not have a clean slot for it, and HRSA addresses do not separate the suite into its own
75
- * column. Leaving the surface form intact in `street` preserves the adversarial training signal (the model learns that
76
- * a trailing "Suite 4" is part of the road line in this distribution).
70
+ * Suite / Apt / Unit designators stay on `street` — Mailwoman's `unit` component exists but the address-formatter does
71
+ * not have a clean slot for it, and HRSA addresses do not separate the suite into its own column. Leaving the surface
72
+ * form intact in `street` preserves the adversarial training signal (the model learns that a trailing "Suite 4" is part
73
+ * of the road line in this distribution).
77
74
  */
78
- const HOUSE_NUMBER_PREFIX = /^(\d+(?:-\d+)?[A-Za-z]?)\s+(.+)$/
79
-
80
- function splitAddress(address: string): { house_number?: string; street: string } | null {
81
- const trimmed = address.trim()
82
-
83
- if (!trimmed) return null
84
- const m = HOUSE_NUMBER_PREFIX.exec(trimmed)
85
-
86
- if (m) return { house_number: m[1], street: m[2]!.trim() }
87
-
88
- return { street: trimmed }
89
- }
90
75
 
91
76
  /**
92
77
  * Compose the raw envelope-style address line. Format:
@@ -122,78 +107,69 @@ export function createUsgovHrsaFqhcAdapter(): CorpusAdapter {
122
107
  throw new Error(`usgov-hrsa-fqhc adapter: only US supported, got country=${opts.country}`)
123
108
  }
124
109
 
125
- const stream = createReadStream(opts.inputPath, { encoding: "utf8" })
126
-
127
- const parser = stream.pipe(
128
- csvParse({
129
- columns: true,
130
- skip_empty_lines: true,
131
- relax_quotes: true,
132
- relax_column_count: true,
133
- })
134
- )
110
+ const rows = CSVSpliterator.fromAsync(opts.inputPath, {
111
+ mode: "object",
112
+ normalizeKeys: false,
113
+ enableQuoteHandling: true,
114
+ })
135
115
 
136
116
  let emitted = 0
137
117
 
138
- try {
139
- for await (const record of parser as AsyncIterable<HrsaSiteRow>) {
140
- if (opts.signal?.aborted) break
141
-
142
- if (opts.limit !== undefined && emitted >= opts.limit) break
143
-
144
- const venue = (record["Site Name"] ?? "").trim()
145
- const split = splitAddress(record["Site Address"] ?? "")
146
- const city = (record["Site City"] ?? "").trim()
147
- const stateAbbr = (record["Site State Abbreviation"] ?? "").trim()
148
- const postcode = (record["Site Postal Code"] ?? "").trim()
149
-
150
- if (!venue || !split || !city || !postcode) continue
151
- const state = lookupStateAbbreviation(stateAbbr)
152
-
153
- if (!state) continue
154
-
155
- // Insertion order matters here. `venue` first so alignment claims its span
156
- // (which may contain a token like "Buffalo") before `locality` runs its
157
- // search — the kryptonite case `Buffalo Health Clinic, Buffalo NY`
158
- // otherwise mis-labels the venue's "Buffalo" as locality.
159
- const components: CanonicalRow["components"] = {
160
- venue,
161
- ...(split.house_number ? { house_number: split.house_number } : {}),
162
- street: split.street,
163
- locality: city,
164
- region: state.abbreviation,
165
- postcode,
166
- }
167
-
168
- const raw = composeRaw(venue, split.house_number, split.street, city, state.abbreviation, postcode)
118
+ for await (const record of rows as AsyncIterable<HrsaSiteRow>) {
119
+ if (opts.signal?.aborted) break
120
+
121
+ if (opts.limit !== undefined && emitted >= opts.limit) break
122
+
123
+ const venue = (record["Site Name"] ?? "").trim()
124
+ const split = splitStreetLine(record["Site Address"] ?? "")
125
+ const city = (record["Site City"] ?? "").trim()
126
+ const stateAbbr = (record["Site State Abbreviation"] ?? "").trim()
127
+ const postcode = (record["Site Postal Code"] ?? "").trim()
128
+
129
+ if (!venue || !split || !city || !postcode) continue
130
+ const state = lookupStateAbbreviation(stateAbbr)
131
+
132
+ if (!state) continue
133
+
134
+ // Insertion order matters here. `venue` first so alignment claims its span
135
+ // (which may contain a token like "Buffalo") before `locality` runs its
136
+ // search — the kryptonite case `Buffalo Health Clinic, Buffalo NY`
137
+ // otherwise mis-labels the venue's "Buffalo" as locality.
138
+ const components: CanonicalRow["components"] = {
139
+ venue,
140
+ ...(split.house_number ? { house_number: split.house_number } : {}),
141
+ street: split.street,
142
+ locality: city,
143
+ region: state.abbreviation,
144
+ postcode,
145
+ }
169
146
 
170
- if (!raw) continue
147
+ const raw = composeRaw(venue, split.house_number, split.street, city, state.abbreviation, postcode)
171
148
 
172
- const aligned = reconcileComponents(components, raw)
149
+ if (!raw) continue
173
150
 
174
- if (!Object.keys(aligned).length) continue
151
+ const aligned = reconcileComponents(components, raw)
175
152
 
176
- const siteID = (record["Site ID"] ?? "").trim()
153
+ if (!Object.keys(aligned).length) continue
177
154
 
178
- const sourceID = siteID
179
- ? `${USGOV_HRSA_FQHC_ADAPTER_ID}-${siteID}`
180
- : stableSourceID(USGOV_HRSA_FQHC_ADAPTER_ID, aligned)
155
+ const siteID = (record["Site ID"] ?? "").trim()
181
156
 
182
- yield {
183
- raw,
184
- components: aligned,
185
- country: "US",
186
- locale: "en-US",
187
- source: USGOV_HRSA_FQHC_ADAPTER_ID,
188
- source_id: sourceID,
189
- corpus_version: "",
190
- license: USGOV_HRSA_FQHC_DEFAULT_LICENSE,
191
- }
157
+ const sourceID = siteID
158
+ ? `${USGOV_HRSA_FQHC_ADAPTER_ID}-${siteID}`
159
+ : stableSourceID(USGOV_HRSA_FQHC_ADAPTER_ID, aligned)
192
160
 
193
- emitted++
161
+ yield {
162
+ raw,
163
+ components: aligned,
164
+ country: "US",
165
+ locale: "en-US",
166
+ source: USGOV_HRSA_FQHC_ADAPTER_ID,
167
+ source_id: sourceID,
168
+ corpus_version: "",
169
+ license: USGOV_HRSA_FQHC_DEFAULT_LICENSE,
194
170
  }
195
- } finally {
196
- stream.destroy()
171
+
172
+ emitted++
197
173
  }
198
174
  },
199
175
  }