@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
@@ -28,14 +28,11 @@
28
28
  * distribution terms.
29
29
  */
30
30
 
31
- import { createReadStream } from "node:fs"
32
-
33
- import { parse as csvParse } from "csv-parse"
34
-
35
- import { stableSourceID } from "../../adapter.ts"
36
- import { lookupStateAbbreviation } from "../../codex/us-fips-state.ts"
37
- import { reconcileComponents } from "../../format.ts"
38
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
31
+ import { splitStreetLine, stableSourceID } from "@mailwoman/corpus/adapters/utils"
32
+ import { lookupStateAbbreviation } from "@mailwoman/corpus/codex/us-fips-state"
33
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
34
+ import { reconcileComponents } from "@mailwoman/formatter"
35
+ import { CSVSpliterator } from "spliterator"
39
36
 
40
37
  /**
41
38
  * Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
@@ -66,19 +63,6 @@ interface SamhsaSiteRow {
66
63
  frid?: string
67
64
  }
68
65
 
69
- const HOUSE_NUMBER_PREFIX = /^(\d+(?:-\d+)?[A-Za-z]?)\s+(.+)$/
70
-
71
- function splitAddress(address: string): { house_number?: string; street: string } | null {
72
- const trimmed = address.trim()
73
-
74
- if (!trimmed) return null
75
- const m = HOUSE_NUMBER_PREFIX.exec(trimmed)
76
-
77
- if (m) return { house_number: m[1], street: m[2]!.trim() }
78
-
79
- return { street: trimmed }
80
- }
81
-
82
66
  /**
83
67
  * Join the SAMHSA two-line street: primary street + optional secondary line (suite / unit / floor / "behind main
84
68
  * building") on `", "`. The combined value is the `street` component surface form. Phase 1 does not break this out into
@@ -148,76 +132,65 @@ export function createUsgovSamhsaTreatmentLocatorAdapter(): CorpusAdapter {
148
132
  throw new Error(`usgov-samhsa adapter: only US supported, got country=${opts.country}`)
149
133
  }
150
134
 
151
- const stream = createReadStream(opts.inputPath, { encoding: "utf8" })
152
-
153
- const parser = stream.pipe(
154
- csvParse({
155
- columns: true,
156
- skip_empty_lines: true,
157
- relax_quotes: true,
158
- relax_column_count: true,
159
- })
160
- )
135
+ const rows = CSVSpliterator.fromAsync(opts.inputPath, {
136
+ mode: "object",
137
+ normalizeKeys: false,
138
+ enableQuoteHandling: true,
139
+ })
161
140
 
162
141
  let emitted = 0
163
142
 
164
- try {
165
- for await (const record of parser as AsyncIterable<SamhsaSiteRow>) {
166
- if (opts.signal?.aborted) break
143
+ for await (const record of rows as AsyncIterable<SamhsaSiteRow>) {
144
+ if (opts.signal?.aborted) break
167
145
 
168
- if (opts.limit !== undefined && emitted >= opts.limit) break
146
+ if (opts.limit !== undefined && emitted >= opts.limit) break
169
147
 
170
- const venue = composeVenue(record.name1 ?? "", record.name2)
171
- const street = joinTwoLineStreet(record.street1 ?? "", record.street2)
172
- const split = splitAddress(street)
173
- const city = (record.city ?? "").trim()
174
- const stateAbbr = (record.state ?? "").trim()
175
- const postcode = (record.zip ?? "").trim()
148
+ const venue = composeVenue(record.name1 ?? "", record.name2)
149
+ const street = joinTwoLineStreet(record.street1 ?? "", record.street2)
150
+ const split = splitStreetLine(street)
151
+ const city = (record.city ?? "").trim()
152
+ const stateAbbr = (record.state ?? "").trim()
153
+ const postcode = (record.zip ?? "").trim()
176
154
 
177
- if (!venue || !split || !city || !postcode) continue
178
- const state = lookupStateAbbreviation(stateAbbr)
155
+ if (!venue || !split || !city || !postcode) continue
156
+ const state = lookupStateAbbreviation(stateAbbr)
179
157
 
180
- if (!state) continue
158
+ if (!state) continue
181
159
 
182
- // venue first — same kryptonite-defending insertion order as HRSA.
183
- const components: CanonicalRow["components"] = {
184
- venue,
185
- ...(split.house_number ? { house_number: split.house_number } : {}),
186
- street: split.street,
187
- locality: city,
188
- region: state.abbreviation,
189
- postcode,
190
- }
191
-
192
- const raw = composeRaw(venue, split.house_number, split.street, city, state.abbreviation, postcode)
160
+ // venue first — same kryptonite-defending insertion order as HRSA.
161
+ const components: CanonicalRow["components"] = {
162
+ venue,
163
+ ...(split.house_number ? { house_number: split.house_number } : {}),
164
+ street: split.street,
165
+ locality: city,
166
+ region: state.abbreviation,
167
+ postcode,
168
+ }
193
169
 
194
- if (!raw) continue
170
+ const raw = composeRaw(venue, split.house_number, split.street, city, state.abbreviation, postcode)
195
171
 
196
- const aligned = reconcileComponents(components, raw)
172
+ if (!raw) continue
197
173
 
198
- if (!Object.keys(aligned).length) continue
174
+ const aligned = reconcileComponents(components, raw)
199
175
 
200
- const frID = (record.frid ?? "").trim()
176
+ if (!Object.keys(aligned).length) continue
201
177
 
202
- const sourceID = frID
203
- ? `${USGOV_SAMHSA_ADAPTER_ID}-${frID}`
204
- : stableSourceID(USGOV_SAMHSA_ADAPTER_ID, aligned)
178
+ const frID = (record.frid ?? "").trim()
205
179
 
206
- yield {
207
- raw,
208
- components: aligned,
209
- country: "US",
210
- locale: "en-US",
211
- source: USGOV_SAMHSA_ADAPTER_ID,
212
- source_id: sourceID,
213
- corpus_version: "",
214
- license: USGOV_SAMHSA_DEFAULT_LICENSE,
215
- }
180
+ const sourceID = frID ? `${USGOV_SAMHSA_ADAPTER_ID}-${frID}` : stableSourceID(USGOV_SAMHSA_ADAPTER_ID, aligned)
216
181
 
217
- emitted++
182
+ yield {
183
+ raw,
184
+ components: aligned,
185
+ country: "US",
186
+ locale: "en-US",
187
+ source: USGOV_SAMHSA_ADAPTER_ID,
188
+ source_id: sourceID,
189
+ corpus_version: "",
190
+ license: USGOV_SAMHSA_DEFAULT_LICENSE,
218
191
  }
219
- } finally {
220
- stream.destroy()
192
+
193
+ emitted++
221
194
  }
222
195
  },
223
196
  }
@@ -12,6 +12,8 @@
12
12
  * - `InMemoryAdapterRegistry`: the default implementation.
13
13
  * - `stableSourceID(adapterID, components)`: deterministic content-addressed id for adapters whose
14
14
  * source data has no native primary key (CSV, GeoJSON).
15
+ * - `HOUSE_NUMBER_PREFIX` + `splitStreetLine(line)`: the one house-number/street split every
16
+ * US CSV adapter uses.
15
17
  * - `canonicalDedupKey(row)`: normalized signature used to drop near-identical rows during a run.
16
18
  * Adapter-internal dedup; cross-adapter dedup is the runner's job.
17
19
  * - `streamingSha256()`: thin wrapper around `node:crypto` so the runner can hash JSONL output as it
@@ -23,8 +25,8 @@
23
25
  import { createHash, type Hash } from "node:crypto"
24
26
 
25
27
  import type { ComponentTag } from "@mailwoman/core/types"
26
-
27
- import type { CanonicalRow, CorpusAdapter } from "./types.ts"
28
+ import { sha256Hex } from "@mailwoman/core/utils"
29
+ import type { CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
28
30
 
29
31
  /**
30
32
  * Lookup table for corpus adapters.
@@ -103,11 +105,60 @@ export const defaultAdapterRegistry = new InMemoryAdapterRegistry()
103
105
  export function stableSourceID(adapterID: string, components: Partial<Record<ComponentTag, string>>): string {
104
106
  const sortedKeys = Object.keys(components).toSorted() as ComponentTag[]
105
107
  const payload = sortedKeys.map((k) => `${k}=${components[k] ?? ""}`).join("\u001F")
106
- const digest = createHash("sha256").update(adapterID).update("\u001E").update(payload).digest("hex")
108
+ // One `update` over the joined string, not three chained ones — identical byte stream either way,
109
+ // but the separator has to stay inline or every id in every shard changes.
110
+ const digest = sha256Hex(`${adapterID}\u001E${payload}`)
107
111
 
108
112
  return `${adapterID}-${digest.slice(0, 12)}`
109
113
  }
110
114
 
115
+ /**
116
+ * Leading house number on a US-style street line: digits, an optional hyphenated range (Queens `40-12`), an optional
117
+ * single alpha suffix (`101A`), then whitespace, then the rest.
118
+ *
119
+ * This decides where the house number ends and the street begins for every US CSV adapter, so an edge case fixed here
120
+ * is fixed for all of them.
121
+ *
122
+ * The remainder must stay `(\S.*)` and must NOT become `(.+)`: `\s+` and `.` both match a tab, so `\s+(.+)$` lets the
123
+ * engine split a run of tabs between the two groups every possible way before failing — quadratic backtracking on
124
+ * attacker-shaped input. Requiring a non-space start removes the overlap. Group 2 is trimmed by the caller either way,
125
+ * so the two forms are indistinguishable on real input; only the failure cost differs.
126
+ */
127
+ export const HOUSE_NUMBER_PREFIX = /^(\d+(?:-\d+)?[A-Za-z]?)\s+(\S.*)$/
128
+
129
+ /**
130
+ * A street line split into its house number and the remainder.
131
+ */
132
+ export interface SplitStreetLine {
133
+ house_number?: string
134
+ street: string
135
+ }
136
+
137
+ /**
138
+ * Split a US-style street line on {@link HOUSE_NUMBER_PREFIX}.
139
+ *
140
+ * The US CSV sources follow USPS Publication 28 conventions with hand-entry drift. The leading digit run is the house
141
+ * number (`"123 Main St"`, `"6450 W Indian School Rd"`), and the regex tolerates one trailing letter (`"123A Main St"`)
142
+ * plus an optional hyphenated half (`"40-12 Bell Blvd"`, common in NYC and suburban garden-apartment numbering; Hawaii
143
+ * uses it island-wide — `"47-470 Hui Aeko Place"`).
144
+ *
145
+ * Returns `null` for blank input. Anything that does not match the prefix shape (`"PO Box 1234"`, `"RR 2 Box 67"`, `"HC
146
+ * 1"`) becomes a single `street` value rather than being mangled — the model sees the original surface form and
147
+ * downstream classifiers pick it up. Callers that need those forms recognized as something other than a street (see
148
+ * `usgov-irs-bmf`) test for them BEFORE calling this.
149
+ */
150
+ export function splitStreetLine(line: string): SplitStreetLine | null {
151
+ const trimmed = line.trim()
152
+
153
+ if (!trimmed) return null
154
+
155
+ const match = HOUSE_NUMBER_PREFIX.exec(trimmed)
156
+
157
+ if (match) return { house_number: match[1], street: match[2]!.trim() }
158
+
159
+ return { street: trimmed }
160
+ }
161
+
111
162
  /**
112
163
  * Canonical dedup key for a row.
113
164
  *
@@ -142,6 +193,11 @@ export interface StreamingHasher {
142
193
  /**
143
194
  * Default `StreamingHasher` (SHA-256, hex).
144
195
  */
196
+ /**
197
+ * @see {@link StreamingHasher} — this is the incremental counterpart to `sha256Hex`, not a copy of
198
+ * it. `@mailwoman/core/utils` exposes one-shot digests (`sha256Hex`) and whole-file digests
199
+ * (`sha256File`); the runner needs neither, because it hashes JSONL lines as they stream past.
200
+ */
145
201
  export function streamingSha256(): StreamingHasher {
146
202
  const h: Hash = createHash("sha256")
147
203
  let finalized = false
@@ -31,7 +31,7 @@
31
31
 
32
32
  import { DatabaseSync } from "node:sqlite"
33
33
 
34
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
34
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
35
35
 
36
36
  /**
37
37
  * Ancestry hops walked upward from a WOF record before giving up — deeper than any real JP admin chain.
@@ -59,15 +59,21 @@ interface NameRow {
59
59
  }
60
60
 
61
61
  /**
62
- * Walk parent chain up to 6 levels.
62
+ * Walk parent chain up to 6 levels, over a place table already resident in memory.
63
+ *
64
+ * `resolve` is the escape hatch for a parent outside the preloaded set (a chain that leaves the country); it is a point
65
+ * query, so keeping the common case out of it is the whole point.
63
66
  */
64
- function chainOf(db: DatabaseSync, startID: number, _jpnNames: Map<number, string>): PlaceRow[] {
65
- const stmt = db.prepare(`SELECT id, name, placetype, parent_id, country FROM spr WHERE id = ?`)
67
+ function chainOf(
68
+ byID: Map<number, PlaceRow>,
69
+ resolve: (id: number) => PlaceRow | undefined,
70
+ startID: number
71
+ ): PlaceRow[] {
66
72
  const out: PlaceRow[] = []
67
73
  let id = startID
68
74
 
69
75
  for (let i = 0; i < MAX_ANCESTRY_DEPTH && id > 0; i++) {
70
- const row = stmt.get(id) as PlaceRow | undefined
76
+ const row = byID.get(id) ?? resolve(id)
71
77
 
72
78
  if (!row) break
73
79
  out.push(row)
@@ -151,9 +157,29 @@ export function createWOFAdminJpAdapter(): CorpusAdapter {
151
157
  }
152
158
  }
153
159
 
154
- const seeds = db.prepare(`SELECT id FROM spr WHERE country='JP' AND placetype='neighbourhood'`).all() as {
155
- id: number
156
- }[]
160
+ // One read of the JP place table instead of a fresh `prepare` + up to six point queries per
161
+ // seed; there are tens of thousands of neighbourhood seeds.
162
+ const byID = new Map<number, PlaceRow>()
163
+
164
+ for (const row of db
165
+ .prepare(`SELECT id, name, placetype, parent_id, country FROM spr WHERE country='JP'`)
166
+ .all() as unknown as PlaceRow[]) {
167
+ byID.set(row.id, row)
168
+ }
169
+
170
+ const outsideStmt = db.prepare(`SELECT id, name, placetype, parent_id, country FROM spr WHERE id = ?`)
171
+
172
+ const resolveOutside = (id: number): PlaceRow | undefined => {
173
+ const row = outsideStmt.get(id) as unknown as PlaceRow | undefined
174
+
175
+ if (row) {
176
+ byID.set(id, row)
177
+ }
178
+
179
+ return row
180
+ }
181
+
182
+ const seeds = [...byID.values()].filter((row) => row.placetype === "neighbourhood")
157
183
 
158
184
  let emitted = 0
159
185
 
@@ -162,7 +188,7 @@ export function createWOFAdminJpAdapter(): CorpusAdapter {
162
188
 
163
189
  if (opts.limit !== undefined && emitted >= opts.limit) break
164
190
 
165
- const chain = chainOf(db, seed.id, jpnNames)
191
+ const chain = chainOf(byID, resolveOutside, seed.id)
166
192
  const synth = synthesizeJpAddress(chain, jpnNames)
167
193
 
168
194
  if (!synth) continue
@@ -41,10 +41,9 @@
41
41
 
42
42
  import type { WhosOnFirstPlacetype } from "@mailwoman/core/resources/whosonfirst"
43
43
  import type { ComponentTag } from "@mailwoman/core/types"
44
-
45
- import { formatAddress, reconcileComponents } from "../../format.ts"
46
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
47
- import { buildAncestryIndex, normalizeNameKey, walkFeatures, type WOFRecord } from "../../wof-json.ts"
44
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
45
+ import { buildAncestryIndex, normalizeNameKey, walkFeatures, type WOFRecord } from "@mailwoman/corpus/utils"
46
+ import { formatAddress, reconcileComponents } from "@mailwoman/formatter"
48
47
 
49
48
  /**
50
49
  * Display name for the country, keyed by ISO 3166-1 alpha-2.
@@ -39,10 +39,9 @@
39
39
 
40
40
  import type { WhosOnFirstPlacetype } from "@mailwoman/core/resources/whosonfirst"
41
41
  import type { ComponentTag } from "@mailwoman/core/types"
42
-
43
- import { formatAddress, reconcileComponents } from "../../format.ts"
44
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
45
- import { buildAncestryIndex, normalizeNameKey, walkFeatures, type WOFRecord } from "../../wof-json.ts"
42
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
43
+ import { buildAncestryIndex, normalizeNameKey, walkFeatures, type WOFRecord } from "@mailwoman/corpus/utils"
44
+ import { formatAddress, reconcileComponents } from "@mailwoman/formatter"
46
45
 
47
46
  const COUNTRY_DISPLAY_NAME: Record<string, string> = {
48
47
  US: "United States of America",
package/src/build.ts CHANGED
@@ -52,22 +52,23 @@ import { mkdir, writeFile } from "node:fs/promises"
52
52
  import { join } from "node:path"
53
53
 
54
54
  import { $public } from "@mailwoman/core/env"
55
- import { JSONSpliterator } from "spliterator"
56
-
57
- import { defaultAdapterRegistry } from "./adapter.ts"
58
- import { alignRow } from "./align.ts"
59
- import { licenseExcluded } from "./license.ts"
60
- import { writeShards, type ShardManifest } from "./parquet.ts"
61
- import { runAdapter, type AdapterRunManifest } from "./runner.ts"
55
+ import { parseJSONStrict } from "@mailwoman/core/objects"
56
+ import { defaultAdapterRegistry } from "@mailwoman/corpus/adapters/utils"
57
+ import { runAdapter, type AdapterRunManifest } from "@mailwoman/corpus/runner"
58
+ import { defaultAugmentationsForCountry, synthesizeRow } from "@mailwoman/corpus/synthesizers/utils"
59
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter, LabeledRow } from "@mailwoman/corpus/types"
62
60
  import {
61
+ alignRow,
62
+ licenseExcluded,
63
+ writeShards,
63
64
  defaultHoldouts,
64
65
  splitForRow,
65
66
  writeSplitManifestsFromLabeledFiles,
67
+ type ShardManifest,
66
68
  type SplitManifest,
67
69
  type SplitName,
68
- } from "./split.ts"
69
- import { defaultAugmentationsForCountry, synthesizeRow } from "./synthesize.ts"
70
- import type { AdapterOptions, CanonicalRow, CorpusAdapter, LabeledRow } from "./types.ts"
70
+ } from "@mailwoman/corpus/utils"
71
+ import { JSONSpliterator } from "spliterator"
71
72
 
72
73
  /**
73
74
  * Stage tags surfaced to `onProgress`.
@@ -188,7 +189,7 @@ export async function buildCorpus(opts: BuildCorpusOptions): Promise<BuildCorpus
188
189
  existsSync(cachedManifest) &&
189
190
  existsSync(join(adapterDir, "canonical.jsonl"))
190
191
  ) {
191
- const cached = JSON.parse(readFileSync(cachedManifest, "utf8")) as AdapterRunManifest
192
+ const cached = parseJSONStrict<AdapterRunManifest>(readFileSync(cachedManifest, "utf8"))
192
193
  opts.onProgress?.("adapter-run", `resumed ${adapter.id} (reused ${cached.yielded} canonical rows)`)
193
194
  adapterRuns.push(cached)
194
195
 
package/src/index.ts CHANGED
@@ -4,25 +4,11 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
 
7
- export * from "./adapter.ts"
7
+ export * from "./adapters/utils/index.ts"
8
8
  export * from "./adapters/gnaf/assemble.ts"
9
9
  export * from "./adapters/index.ts"
10
- export * from "./align.ts"
11
10
  export * from "./build.ts"
12
- export * from "./format.ts"
13
- export * from "./golden.ts"
14
- export * from "./parquet.ts"
15
- export * from "./parquet-wrapper/index.ts"
16
11
  export * from "./runner.ts"
12
+ export * from "./parquet-wrapper/index.ts"
17
13
  export * from "./shard-recipes/index.ts"
18
- export * from "./split.ts"
19
- export * from "./synthesize-anchor-absorption.ts"
20
- export * from "./synthesize-german.ts"
21
- export * from "./synthesize-house-venue.ts"
22
- export * from "./synthesize-intersection.ts"
23
- export * from "./synthesize-no-street.ts"
24
- export * from "./synthesize-po-box.ts"
25
- export * from "./synthesize-street.ts"
26
- export * from "./synthesize.ts"
27
- export * from "./tokenize.ts"
28
- export * from "./types.ts"
14
+ export * from "@mailwoman/corpus/types"
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Re-export shim: the name-prone set moved to `@mailwoman/codex/us` (data in
7
+ * `codex/us/street-suffix.json`, 2026-08-10) so the golden relabel flags, the #1569 shard
8
+ * recipe, AND the Python relabel pass (via the `gazetteer affix-relabel` v2 lexicon) all read
9
+ * one record. Import from `@mailwoman/codex/us` in new code.
10
+ */
11
+
12
+ export { NAME_PRONE_US_SUFFIXES } from "@mailwoman/codex/us"
@@ -59,6 +59,25 @@ export class ParquetReader<T extends ParquetRecordLike> extends BaseParquetReade
59
59
  return super[Symbol.asyncIterator]() as AsyncGenerator<T, void, unknown>
60
60
  }
61
61
 
62
+ /**
63
+ * Iterate a subset of the columns, narrowed to the keys asked for.
64
+ *
65
+ * Parquet is columnar, so a projection is read avoided rather than read-then-discarded: on a 14-column corpus shard,
66
+ * two columns cost 93 ms against 253 ms for the whole row. The default iterator reads every column, which is what a
67
+ * caller wanting the whole record should use.
68
+ */
69
+ public async *project<K extends keyof T>(...columns: K[]): AsyncGenerator<Pick<T, K>, void, unknown> {
70
+ const cursor = this.getCursor(columns.map((column) => [column as string]))
71
+
72
+ for (;;) {
73
+ const row = (await cursor.next()) as Pick<T, K> | null
74
+
75
+ if (!row) return
76
+
77
+ yield row
78
+ }
79
+ }
80
+
62
81
  public async [Symbol.asyncDispose]() {
63
82
  return this.close()
64
83
  }
@@ -24,6 +24,10 @@ import { LRUCache } from "lru-cache"
24
24
  /**
25
25
  * A Parquet record-like object, i.e. a record with string keys and JSON-serializable values.
26
26
  */
27
+ /**
28
+ * Shape a row type must satisfy. Declare yours as a `type` alias — TypeScript gives an alias an implicit index
29
+ * signature and an `interface` none, so an otherwise-identical interface does not satisfy this.
30
+ */
27
31
  export type ParquetRecordLike = Record<string, unknown | undefined>
28
32
 
29
33
  /**
package/src/runner.ts CHANGED
@@ -31,8 +31,13 @@ import { createWriteStream, type WriteStream } from "node:fs"
31
31
  import { mkdir, writeFile } from "node:fs/promises"
32
32
  import { dirname, join } from "node:path"
33
33
 
34
- import { canonicalDedupKey, streamingSha256, type AdapterRegistry, type StreamingHasher } from "./adapter.ts"
35
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "./types.ts"
34
+ import {
35
+ canonicalDedupKey,
36
+ streamingSha256,
37
+ type AdapterRegistry,
38
+ type StreamingHasher,
39
+ } from "@mailwoman/corpus/adapters/utils"
40
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
36
41
 
37
42
  /**
38
43
  * Snapshot of the runner's state, emitted on every progress tick.
@@ -14,11 +14,12 @@
14
14
 
15
15
  import { readFileSync } from "node:fs"
16
16
 
17
+ import { parseJSONStrict } from "@mailwoman/core/objects"
17
18
  import { dataRootPath } from "@mailwoman/core/utils"
19
+ import { stableSourceID } from "@mailwoman/corpus/adapters/utils"
20
+ import { synthesizeAnchorAbsorptionRow } from "@mailwoman/corpus/synthesizers/anchor-absorption"
21
+ import { alignRow } from "@mailwoman/corpus/utils"
18
22
 
19
- import { stableSourceID } from "../adapter.ts"
20
- import { alignRow } from "../align.ts"
21
- import { synthesizeAnchorAbsorptionRow } from "../synthesize-anchor-absorption.ts"
22
23
  import { makeLcg, type ShardRecipe } from "./scaffold.ts"
23
24
 
24
25
  /**
@@ -31,7 +32,7 @@ const ANCHOR_LOOKUP = dataRootPath("anchor", "pilot-anchor-lookup.json")
31
32
  * The real US ZIPs in the anchor lookup (entries whose value is a `[{ US: … }]` candidate list).
32
33
  */
33
34
  function loadRealUsZips(path: string): string[] {
34
- const d = JSON.parse(readFileSync(path, "utf8")) as Record<string, unknown>
35
+ const d = parseJSONStrict<Record<string, unknown>>(readFileSync(path, "utf8"))
35
36
  const zips: string[] = []
36
37
 
37
38
  for (const [pc, v] of Object.entries(d)) {
@@ -12,8 +12,12 @@
12
12
  * `synthesizeBoundaryStressRow` is NOT re-exported from the corpus index — imported directly here.
13
13
  */
14
14
 
15
- import { alignRow } from "../align.ts"
16
- import { type BoundaryStressTemplate, synthesizeBoundaryStressRow } from "../synthesize-boundary-stress.ts"
15
+ import {
16
+ type BoundaryStressTemplate,
17
+ synthesizeBoundaryStressRow,
18
+ } from "@mailwoman/corpus/synthesizers/boundary-stress"
19
+ import { alignRow } from "@mailwoman/corpus/utils"
20
+
17
21
  import { makeMulberry32, type ShardRecipe, shardSourceID } from "./scaffold.ts"
18
22
 
19
23
  /**