@mailwoman/corpus 9.0.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 (378) hide show
  1. package/README.md +1 -1
  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 +1 -1
  5. package/out/src/adapters/ban/adapter.d.ts.map +1 -1
  6. package/out/src/adapters/ban/adapter.js +2 -2
  7. package/out/src/adapters/ban/adapter.js.map +1 -1
  8. package/out/src/adapters/fcc-bdc/adapter.d.ts +1 -1
  9. package/out/src/adapters/fcc-bdc/adapter.d.ts.map +1 -1
  10. package/out/src/adapters/fcc-bdc/adapter.js +3 -3
  11. package/out/src/adapters/fcc-bdc/adapter.js.map +1 -1
  12. package/out/src/adapters/geonames/adapter.d.ts +1 -1
  13. package/out/src/adapters/geonames/adapter.d.ts.map +1 -1
  14. package/out/src/adapters/geonames/adapter.js +2 -2
  15. package/out/src/adapters/geonames/adapter.js.map +1 -1
  16. package/out/src/adapters/geonames-postal/adapter.d.ts +1 -1
  17. package/out/src/adapters/geonames-postal/adapter.d.ts.map +1 -1
  18. package/out/src/adapters/geonames-postal/adapter.js +2 -2
  19. package/out/src/adapters/geonames-postal/adapter.js.map +1 -1
  20. package/out/src/adapters/gnaf/adapter.d.ts +1 -1
  21. package/out/src/adapters/gnaf/adapter.d.ts.map +1 -1
  22. package/out/src/adapters/gnaf/adapter.js +2 -2
  23. package/out/src/adapters/gnaf/adapter.js.map +1 -1
  24. package/out/src/adapters/gnaf/assemble.js +1 -1
  25. package/out/src/adapters/gnaf/assemble.js.map +1 -1
  26. package/out/src/adapters/index.d.ts +1 -1
  27. package/out/src/adapters/index.d.ts.map +1 -1
  28. package/out/src/adapters/index.js +1 -1
  29. package/out/src/adapters/index.js.map +1 -1
  30. package/out/src/adapters/openaddresses/adapter.d.ts +1 -1
  31. package/out/src/adapters/openaddresses/adapter.d.ts.map +1 -1
  32. package/out/src/adapters/openaddresses/adapter.js +3 -3
  33. package/out/src/adapters/openaddresses/adapter.js.map +1 -1
  34. package/out/src/adapters/overture/adapter.d.ts +1 -1
  35. package/out/src/adapters/overture/adapter.d.ts.map +1 -1
  36. package/out/src/adapters/overture/adapter.js +2 -2
  37. package/out/src/adapters/overture/adapter.js.map +1 -1
  38. package/out/src/adapters/state-hi-schools/adapter.d.ts +1 -1
  39. package/out/src/adapters/state-hi-schools/adapter.d.ts.map +1 -1
  40. package/out/src/adapters/state-hi-schools/adapter.js +3 -3
  41. package/out/src/adapters/state-hi-schools/adapter.js.map +1 -1
  42. package/out/src/adapters/state-ia-contractors/adapter.d.ts +1 -1
  43. package/out/src/adapters/state-ia-contractors/adapter.d.ts.map +1 -1
  44. package/out/src/adapters/state-ia-contractors/adapter.js +3 -3
  45. package/out/src/adapters/state-ia-contractors/adapter.js.map +1 -1
  46. package/out/src/adapters/state-ny-notaries/adapter.d.ts +1 -1
  47. package/out/src/adapters/state-ny-notaries/adapter.d.ts.map +1 -1
  48. package/out/src/adapters/state-ny-notaries/adapter.js +3 -3
  49. package/out/src/adapters/state-ny-notaries/adapter.js.map +1 -1
  50. package/out/src/adapters/state-tx-notaries/adapter.d.ts +1 -1
  51. package/out/src/adapters/state-tx-notaries/adapter.d.ts.map +1 -1
  52. package/out/src/adapters/state-tx-notaries/adapter.js +3 -3
  53. package/out/src/adapters/state-tx-notaries/adapter.js.map +1 -1
  54. package/out/src/adapters/synth-po-box/adapter.d.ts +3 -3
  55. package/out/src/adapters/synth-po-box/adapter.d.ts.map +1 -1
  56. package/out/src/adapters/synth-po-box/adapter.js +3 -3
  57. package/out/src/adapters/synth-po-box/adapter.js.map +1 -1
  58. package/out/src/adapters/tiger/adapter.d.ts +1 -1
  59. package/out/src/adapters/tiger/adapter.d.ts.map +1 -1
  60. package/out/src/adapters/tiger/adapter.js +2 -2
  61. package/out/src/adapters/tiger/adapter.js.map +1 -1
  62. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +1 -1
  63. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +1 -1
  64. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js +3 -3
  65. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js.map +1 -1
  66. package/out/src/adapters/usgov-imls-pls/adapter.d.ts +1 -1
  67. package/out/src/adapters/usgov-imls-pls/adapter.d.ts.map +1 -1
  68. package/out/src/adapters/usgov-imls-pls/adapter.js +3 -3
  69. package/out/src/adapters/usgov-imls-pls/adapter.js.map +1 -1
  70. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +1 -1
  71. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts.map +1 -1
  72. package/out/src/adapters/usgov-irs-bmf/adapter.js +2 -2
  73. package/out/src/adapters/usgov-irs-bmf/adapter.js.map +1 -1
  74. package/out/src/adapters/usgov-nad/adapter.d.ts +1 -1
  75. package/out/src/adapters/usgov-nad/adapter.d.ts.map +1 -1
  76. package/out/src/adapters/usgov-nad/adapter.js +1 -1
  77. package/out/src/adapters/usgov-nad/adapter.js.map +1 -1
  78. package/out/src/adapters/usgov-nppes/adapter.d.ts +1 -1
  79. package/out/src/adapters/usgov-nppes/adapter.d.ts.map +1 -1
  80. package/out/src/adapters/usgov-nppes/adapter.js +3 -3
  81. package/out/src/adapters/usgov-nppes/adapter.js.map +1 -1
  82. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +1 -1
  83. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +1 -1
  84. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js +3 -3
  85. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js.map +1 -1
  86. package/out/src/{adapter.d.ts → adapters/utils/index.d.ts} +2 -2
  87. package/out/src/adapters/utils/index.d.ts.map +1 -0
  88. package/out/src/{adapter.js → adapters/utils/index.js} +1 -1
  89. package/out/src/adapters/utils/index.js.map +1 -0
  90. package/out/src/adapters/wof-admin-jp/adapter.d.ts +1 -1
  91. package/out/src/adapters/wof-admin-jp/adapter.d.ts.map +1 -1
  92. package/out/src/adapters/wof-admin-json/adapter.d.ts +2 -2
  93. package/out/src/adapters/wof-admin-json/adapter.d.ts.map +1 -1
  94. package/out/src/adapters/wof-admin-json/adapter.js +2 -2
  95. package/out/src/adapters/wof-admin-json/adapter.js.map +1 -1
  96. package/out/src/adapters/wof-postalcode-json/adapter.d.ts +2 -2
  97. package/out/src/adapters/wof-postalcode-json/adapter.d.ts.map +1 -1
  98. package/out/src/adapters/wof-postalcode-json/adapter.js +2 -2
  99. package/out/src/adapters/wof-postalcode-json/adapter.js.map +1 -1
  100. package/out/src/build.d.ts +3 -4
  101. package/out/src/build.d.ts.map +1 -1
  102. package/out/src/build.js +4 -7
  103. package/out/src/build.js.map +1 -1
  104. package/out/src/index.d.ts +3 -17
  105. package/out/src/index.d.ts.map +1 -1
  106. package/out/src/index.js +3 -17
  107. package/out/src/index.js.map +1 -1
  108. package/out/src/name-prone-us-suffixes.d.ts +12 -0
  109. package/out/src/name-prone-us-suffixes.d.ts.map +1 -0
  110. package/out/src/name-prone-us-suffixes.js +12 -0
  111. package/out/src/name-prone-us-suffixes.js.map +1 -0
  112. package/out/src/runner.d.ts +2 -2
  113. package/out/src/runner.d.ts.map +1 -1
  114. package/out/src/runner.js +1 -1
  115. package/out/src/runner.js.map +1 -1
  116. package/out/src/shard-recipes/anchor-absorption.js +3 -3
  117. package/out/src/shard-recipes/anchor-absorption.js.map +1 -1
  118. package/out/src/shard-recipes/boundary-stress.d.ts.map +1 -1
  119. package/out/src/shard-recipes/boundary-stress.js +2 -2
  120. package/out/src/shard-recipes/boundary-stress.js.map +1 -1
  121. package/out/src/shard-recipes/country-balanced.d.ts.map +1 -1
  122. package/out/src/shard-recipes/country-balanced.js +10 -18
  123. package/out/src/shard-recipes/country-balanced.js.map +1 -1
  124. package/out/src/shard-recipes/fr-admin-split.js +2 -2
  125. package/out/src/shard-recipes/fr-admin-split.js.map +1 -1
  126. package/out/src/shard-recipes/fr-lieudit.js +2 -2
  127. package/out/src/shard-recipes/fr-lieudit.js.map +1 -1
  128. package/out/src/shard-recipes/fr-order.d.ts.map +1 -1
  129. package/out/src/shard-recipes/fr-order.js +9 -19
  130. package/out/src/shard-recipes/fr-order.js.map +1 -1
  131. package/out/src/shard-recipes/german.d.ts.map +1 -1
  132. package/out/src/shard-recipes/german.js +8 -14
  133. package/out/src/shard-recipes/german.js.map +1 -1
  134. package/out/src/shard-recipes/house-venue.d.ts.map +1 -1
  135. package/out/src/shard-recipes/house-venue.js +1 -1
  136. package/out/src/shard-recipes/house-venue.js.map +1 -1
  137. package/out/src/shard-recipes/index.d.ts.map +1 -1
  138. package/out/src/shard-recipes/index.js +2 -1
  139. package/out/src/shard-recipes/index.js.map +1 -1
  140. package/out/src/shard-recipes/intersection.d.ts.map +1 -1
  141. package/out/src/shard-recipes/intersection.js +6 -12
  142. package/out/src/shard-recipes/intersection.js.map +1 -1
  143. package/out/src/shard-recipes/locale.d.ts +5 -5
  144. package/out/src/shard-recipes/locale.d.ts.map +1 -1
  145. package/out/src/shard-recipes/locale.js +11 -19
  146. package/out/src/shard-recipes/locale.js.map +1 -1
  147. package/out/src/shard-recipes/no-street.d.ts.map +1 -1
  148. package/out/src/shard-recipes/no-street.js +1 -1
  149. package/out/src/shard-recipes/no-street.js.map +1 -1
  150. package/out/src/shard-recipes/po-box-cedex.d.ts.map +1 -1
  151. package/out/src/shard-recipes/po-box-cedex.js +60 -43
  152. package/out/src/shard-recipes/po-box-cedex.js.map +1 -1
  153. package/out/src/shard-recipes/po-box.d.ts.map +1 -1
  154. package/out/src/shard-recipes/po-box.js +1 -1
  155. package/out/src/shard-recipes/po-box.js.map +1 -1
  156. package/out/src/shard-recipes/scaffold.d.ts +18 -19
  157. package/out/src/shard-recipes/scaffold.d.ts.map +1 -1
  158. package/out/src/shard-recipes/scaffold.js +56 -19
  159. package/out/src/shard-recipes/scaffold.js.map +1 -1
  160. package/out/src/shard-recipes/street-affix.d.ts +54 -0
  161. package/out/src/shard-recipes/street-affix.d.ts.map +1 -1
  162. package/out/src/shard-recipes/street-affix.js +203 -35
  163. package/out/src/shard-recipes/street-affix.js.map +1 -1
  164. package/out/src/shard-recipes/street-bare.d.ts.map +1 -1
  165. package/out/src/shard-recipes/street-bare.js +3 -3
  166. package/out/src/shard-recipes/street-bare.js.map +1 -1
  167. package/out/src/shard-recipes/street.d.ts.map +1 -1
  168. package/out/src/shard-recipes/street.js +2 -2
  169. package/out/src/shard-recipes/street.js.map +1 -1
  170. package/out/src/shard-recipes/sub-venue-sources.d.ts +3 -6
  171. package/out/src/shard-recipes/sub-venue-sources.d.ts.map +1 -1
  172. package/out/src/shard-recipes/sub-venue-sources.js +4 -9
  173. package/out/src/shard-recipes/sub-venue-sources.js.map +1 -1
  174. package/out/src/shard-recipes/sub-venue.d.ts +2 -2
  175. package/out/src/shard-recipes/sub-venue.d.ts.map +1 -1
  176. package/out/src/shard-recipes/sub-venue.js +2 -2
  177. package/out/src/shard-recipes/sub-venue.js.map +1 -1
  178. package/out/src/shard-recipes/unit.d.ts.map +1 -1
  179. package/out/src/shard-recipes/unit.js +6 -12
  180. package/out/src/shard-recipes/unit.js.map +1 -1
  181. package/out/src/{synthesize-anchor-absorption.d.ts → synthesizers/anchor-absorption.d.ts} +1 -1
  182. package/out/src/synthesizers/anchor-absorption.d.ts.map +1 -0
  183. package/out/src/{synthesize-anchor-absorption.js → synthesizers/anchor-absorption.js} +1 -1
  184. package/out/src/synthesizers/anchor-absorption.js.map +1 -0
  185. package/out/src/{synthesize-boundary-stress.d.ts → synthesizers/boundary-stress.d.ts} +3 -3
  186. package/out/src/synthesizers/boundary-stress.d.ts.map +1 -0
  187. package/out/src/{synthesize-boundary-stress.js → synthesizers/boundary-stress.js} +2 -2
  188. package/out/src/synthesizers/boundary-stress.js.map +1 -0
  189. package/out/src/{synthesize-german.d.ts → synthesizers/german.d.ts} +2 -2
  190. package/out/src/synthesizers/german.d.ts.map +1 -0
  191. package/out/src/{synthesize-german.js → synthesizers/german.js} +2 -2
  192. package/out/src/synthesizers/german.js.map +1 -0
  193. package/out/src/{synthesize-house-venue.d.ts → synthesizers/house-venue.d.ts} +4 -4
  194. package/out/src/synthesizers/house-venue.d.ts.map +1 -0
  195. package/out/src/{synthesize-house-venue.js → synthesizers/house-venue.js} +4 -4
  196. package/out/src/synthesizers/house-venue.js.map +1 -0
  197. package/out/src/{synthesize-intersection.d.ts → synthesizers/intersection.d.ts} +2 -2
  198. package/out/src/synthesizers/intersection.d.ts.map +1 -0
  199. package/out/src/{synthesize-intersection.js → synthesizers/intersection.js} +1 -1
  200. package/out/src/synthesizers/intersection.js.map +1 -0
  201. package/out/src/{synthesize-no-street.d.ts → synthesizers/no-street.d.ts} +3 -3
  202. package/out/src/synthesizers/no-street.d.ts.map +1 -0
  203. package/out/src/{synthesize-no-street.js → synthesizers/no-street.js} +2 -2
  204. package/out/src/synthesizers/no-street.js.map +1 -0
  205. package/out/src/{synthesize-po-box.d.ts → synthesizers/po-box.d.ts} +2 -2
  206. package/out/src/synthesizers/po-box.d.ts.map +1 -0
  207. package/out/src/{synthesize-po-box.js → synthesizers/po-box.js} +1 -1
  208. package/out/src/synthesizers/po-box.js.map +1 -0
  209. package/out/src/{synthesize-street.d.ts → synthesizers/street.d.ts} +2 -2
  210. package/out/src/synthesizers/street.d.ts.map +1 -0
  211. package/out/src/{synthesize-street.js → synthesizers/street.js} +2 -2
  212. package/out/src/synthesizers/street.js.map +1 -0
  213. package/out/src/{synthesize.d.ts → synthesizers/utils.d.ts} +3 -3
  214. package/out/src/synthesizers/utils.d.ts.map +1 -0
  215. package/out/src/{synthesize.js → synthesizers/utils.js} +3 -3
  216. package/out/src/synthesizers/utils.js.map +1 -0
  217. package/out/src/tools/align-shard.js +1 -1
  218. package/out/src/tools/align-shard.js.map +1 -1
  219. package/out/src/tools/fetch/imls-pls.d.ts.map +1 -1
  220. package/out/src/tools/fetch/imls-pls.js +3 -15
  221. package/out/src/tools/fetch/imls-pls.js.map +1 -1
  222. package/out/src/tools/fetch/nppes.d.ts.map +1 -1
  223. package/out/src/tools/fetch/nppes.js +8 -15
  224. package/out/src/tools/fetch/nppes.js.map +1 -1
  225. package/out/src/tools/golden-relabel-street.d.ts.map +1 -1
  226. package/out/src/tools/golden-relabel-street.js +2 -75
  227. package/out/src/tools/golden-relabel-street.js.map +1 -1
  228. package/out/src/tools/shard-kryptonite.d.ts.map +1 -1
  229. package/out/src/tools/shard-kryptonite.js +1 -2
  230. package/out/src/tools/shard-kryptonite.js.map +1 -1
  231. package/out/src/tools/shard-translit.d.ts.map +1 -1
  232. package/out/src/tools/shard-translit.js +1 -2
  233. package/out/src/tools/shard-translit.js.map +1 -1
  234. package/out/src/{align.d.ts → utils/align.d.ts} +1 -1
  235. package/out/src/utils/align.d.ts.map +1 -0
  236. package/out/src/utils/align.js.map +1 -0
  237. package/out/src/utils/golden.d.ts.map +1 -0
  238. package/out/src/{golden.js → utils/golden.js} +1 -1
  239. package/out/src/utils/golden.js.map +1 -0
  240. package/out/src/utils/index.d.ts +14 -0
  241. package/out/src/utils/index.d.ts.map +1 -0
  242. package/out/src/utils/index.js +14 -0
  243. package/out/src/utils/index.js.map +1 -0
  244. package/out/src/utils/license.d.ts.map +1 -0
  245. package/out/src/utils/license.js.map +1 -0
  246. package/out/src/{parquet.d.ts → utils/parquet.d.ts} +2 -2
  247. package/out/src/utils/parquet.d.ts.map +1 -0
  248. package/out/src/{parquet.js → utils/parquet.js} +1 -2
  249. package/out/src/utils/parquet.js.map +1 -0
  250. package/out/src/{split.d.ts → utils/split.d.ts} +1 -1
  251. package/out/src/utils/split.d.ts.map +1 -0
  252. package/out/src/utils/split.js.map +1 -0
  253. package/out/src/utils/tokenize.d.ts.map +1 -0
  254. package/out/src/utils/tokenize.js.map +1 -0
  255. package/out/src/utils/wof-json.d.ts.map +1 -0
  256. package/out/src/utils/wof-json.js.map +1 -0
  257. package/package.json +64 -18
  258. package/src/adapters/ban/adapter.ts +3 -3
  259. package/src/adapters/fcc-bdc/adapter.ts +4 -4
  260. package/src/adapters/geonames/adapter.ts +3 -4
  261. package/src/adapters/geonames-postal/adapter.ts +3 -4
  262. package/src/adapters/gnaf/adapter.ts +3 -4
  263. package/src/adapters/gnaf/assemble.ts +1 -1
  264. package/src/adapters/index.ts +3 -2
  265. package/src/adapters/openaddresses/adapter.ts +4 -5
  266. package/src/adapters/overture/adapter.ts +3 -4
  267. package/src/adapters/state-hi-schools/adapter.ts +4 -5
  268. package/src/adapters/state-ia-contractors/adapter.ts +4 -5
  269. package/src/adapters/state-ny-notaries/adapter.ts +4 -5
  270. package/src/adapters/state-tx-notaries/adapter.ts +4 -5
  271. package/src/adapters/synth-po-box/adapter.ts +5 -6
  272. package/src/adapters/tiger/adapter.ts +4 -3
  273. package/src/adapters/usgov-hrsa-fqhc/adapter.ts +4 -5
  274. package/src/adapters/usgov-imls-pls/adapter.ts +4 -5
  275. package/src/adapters/usgov-irs-bmf/adapter.ts +3 -4
  276. package/src/adapters/usgov-nad/adapter.ts +2 -3
  277. package/src/adapters/usgov-nppes/adapter.ts +4 -5
  278. package/src/adapters/usgov-samhsa-treatment-locator/adapter.ts +4 -5
  279. package/src/{adapter.ts → adapters/utils/index.ts} +1 -2
  280. package/src/adapters/wof-admin-jp/adapter.ts +1 -1
  281. package/src/adapters/wof-admin-json/adapter.ts +3 -4
  282. package/src/adapters/wof-postalcode-json/adapter.ts +3 -4
  283. package/src/build.ts +10 -10
  284. package/src/index.ts +3 -17
  285. package/src/name-prone-us-suffixes.ts +12 -0
  286. package/src/runner.ts +7 -2
  287. package/src/shard-recipes/anchor-absorption.ts +3 -3
  288. package/src/shard-recipes/boundary-stress.ts +6 -2
  289. package/src/shard-recipes/country-balanced.ts +11 -24
  290. package/src/shard-recipes/fr-admin-split.ts +3 -3
  291. package/src/shard-recipes/fr-lieudit.ts +3 -3
  292. package/src/shard-recipes/fr-order.ts +10 -25
  293. package/src/shard-recipes/german.ts +8 -18
  294. package/src/shard-recipes/house-venue.ts +2 -1
  295. package/src/shard-recipes/index.ts +2 -1
  296. package/src/shard-recipes/intersection.ts +7 -16
  297. package/src/shard-recipes/locale.ts +17 -23
  298. package/src/shard-recipes/no-street.ts +2 -1
  299. package/src/shard-recipes/po-box-cedex.ts +76 -59
  300. package/src/shard-recipes/po-box.ts +6 -1
  301. package/src/shard-recipes/scaffold.ts +64 -20
  302. package/src/shard-recipes/street-affix.ts +283 -45
  303. package/src/shard-recipes/street-bare.ts +4 -3
  304. package/src/shard-recipes/street.ts +3 -2
  305. package/src/shard-recipes/sub-venue-sources.ts +11 -11
  306. package/src/shard-recipes/sub-venue.ts +4 -4
  307. package/src/shard-recipes/unit.ts +7 -17
  308. package/src/{synthesize-boundary-stress.ts → synthesizers/boundary-stress.ts} +2 -2
  309. package/src/{synthesize-german.ts → synthesizers/german.ts} +2 -2
  310. package/src/{synthesize-house-venue.ts → synthesizers/house-venue.ts} +4 -4
  311. package/src/{synthesize-intersection.ts → synthesizers/intersection.ts} +1 -1
  312. package/src/{synthesize-no-street.ts → synthesizers/no-street.ts} +2 -2
  313. package/src/{synthesize-po-box.ts → synthesizers/po-box.ts} +1 -1
  314. package/src/{synthesize-street.ts → synthesizers/street.ts} +2 -2
  315. package/src/{synthesize.ts → synthesizers/utils.ts} +3 -3
  316. package/src/tools/align-shard.ts +1 -1
  317. package/src/tools/fetch/imls-pls.ts +4 -18
  318. package/src/tools/fetch/nppes.ts +9 -17
  319. package/src/tools/golden-relabel-street.ts +3 -66
  320. package/src/tools/shard-kryptonite.ts +3 -5
  321. package/src/tools/shard-translit.ts +10 -4
  322. package/src/{align.ts → utils/align.ts} +1 -1
  323. package/src/{golden.ts → utils/golden.ts} +1 -2
  324. package/src/utils/index.ts +14 -0
  325. package/src/{parquet.ts → utils/parquet.ts} +2 -3
  326. package/src/{split.ts → utils/split.ts} +1 -2
  327. package/out/src/adapter.d.ts.map +0 -1
  328. package/out/src/adapter.js.map +0 -1
  329. package/out/src/align.d.ts.map +0 -1
  330. package/out/src/align.js.map +0 -1
  331. package/out/src/format.d.ts +0 -14
  332. package/out/src/format.d.ts.map +0 -1
  333. package/out/src/format.js +0 -14
  334. package/out/src/format.js.map +0 -1
  335. package/out/src/golden.d.ts.map +0 -1
  336. package/out/src/golden.js.map +0 -1
  337. package/out/src/license.d.ts.map +0 -1
  338. package/out/src/license.js.map +0 -1
  339. package/out/src/parquet.d.ts.map +0 -1
  340. package/out/src/parquet.js.map +0 -1
  341. package/out/src/split.d.ts.map +0 -1
  342. package/out/src/split.js.map +0 -1
  343. package/out/src/synthesize-anchor-absorption.d.ts.map +0 -1
  344. package/out/src/synthesize-anchor-absorption.js.map +0 -1
  345. package/out/src/synthesize-boundary-stress.d.ts.map +0 -1
  346. package/out/src/synthesize-boundary-stress.js.map +0 -1
  347. package/out/src/synthesize-german.d.ts.map +0 -1
  348. package/out/src/synthesize-german.js.map +0 -1
  349. package/out/src/synthesize-house-venue.d.ts.map +0 -1
  350. package/out/src/synthesize-house-venue.js.map +0 -1
  351. package/out/src/synthesize-intersection.d.ts.map +0 -1
  352. package/out/src/synthesize-intersection.js.map +0 -1
  353. package/out/src/synthesize-no-street.d.ts.map +0 -1
  354. package/out/src/synthesize-no-street.js.map +0 -1
  355. package/out/src/synthesize-po-box.d.ts.map +0 -1
  356. package/out/src/synthesize-po-box.js.map +0 -1
  357. package/out/src/synthesize-street.d.ts.map +0 -1
  358. package/out/src/synthesize-street.js.map +0 -1
  359. package/out/src/synthesize.d.ts.map +0 -1
  360. package/out/src/synthesize.js.map +0 -1
  361. package/out/src/tokenize.d.ts.map +0 -1
  362. package/out/src/tokenize.js.map +0 -1
  363. package/out/src/wof-json.d.ts.map +0 -1
  364. package/out/src/wof-json.js.map +0 -1
  365. package/src/format.ts +0 -14
  366. /package/out/src/{align.js → utils/align.js} +0 -0
  367. /package/out/src/{golden.d.ts → utils/golden.d.ts} +0 -0
  368. /package/out/src/{license.d.ts → utils/license.d.ts} +0 -0
  369. /package/out/src/{license.js → utils/license.js} +0 -0
  370. /package/out/src/{split.js → utils/split.js} +0 -0
  371. /package/out/src/{tokenize.d.ts → utils/tokenize.d.ts} +0 -0
  372. /package/out/src/{tokenize.js → utils/tokenize.js} +0 -0
  373. /package/out/src/{wof-json.d.ts → utils/wof-json.d.ts} +0 -0
  374. /package/out/src/{wof-json.js → utils/wof-json.js} +0 -0
  375. /package/src/{synthesize-anchor-absorption.ts → synthesizers/anchor-absorption.ts} +0 -0
  376. /package/src/{license.ts → utils/license.ts} +0 -0
  377. /package/src/{tokenize.ts → utils/tokenize.ts} +0 -0
  378. /package/src/{wof-json.ts → utils/wof-json.ts} +0 -0
@@ -30,24 +30,32 @@
30
30
  * reproduces the legacy run byte-for-byte.
31
31
  */
32
32
 
33
- import { spawnSync } from "node:child_process"
33
+ import { existsSync } from "node:fs"
34
34
 
35
35
  import { isAuDeliveryService, isAuPostcode, isAuStateAbbreviation } from "@mailwoman/codex/au"
36
36
  import { FSA_LETTER_TO_PROVINCE, normalizeCaPostalCode } from "@mailwoman/codex/ca"
37
37
  import { isCedex } from "@mailwoman/codex/fr"
38
38
  import { isNZDeliveryService, isNZPostcode } from "@mailwoman/codex/nz"
39
39
  import { isPOBox } from "@mailwoman/codex/us"
40
+ import { readZipEntry } from "@mailwoman/core/fs/zip"
40
41
  import { dataRootPath } from "@mailwoman/core/utils"
41
- import { TextSpliterator } from "spliterator"
42
-
43
- import { alignRow } from "../align.ts"
44
42
  import {
45
43
  maybeNoisifyBoxNumber,
46
44
  PO_BOX_LOCALE_TEMPLATES,
47
45
  synthesizeMilitaryPoBoxRow,
48
46
  type LocaleTemplate,
49
- } from "../synthesize-po-box.ts"
50
- import { makeMulberry32, readCSVRecords, shardSourceID, type CanonicalShardRow, type ShardRecipe } from "./scaffold.ts"
47
+ } from "@mailwoman/corpus/synthesizers/po-box"
48
+ import { alignRow } from "@mailwoman/corpus/utils"
49
+ import { TextSpliterator, TSVSpliterator } from "spliterator"
50
+
51
+ import {
52
+ makeMulberry32,
53
+ readCSVRecords,
54
+ readZippedCSVRecords,
55
+ shardSourceID,
56
+ type CanonicalShardRow,
57
+ type ShardRecipe,
58
+ } from "./scaffold.ts"
51
59
 
52
60
  // ── Base-skeleton sources ────────────────────────────────────────────────────────────────────────
53
61
  // Same OA cache as the unit/affix shards. US train = every NON-Vermont state; US eval = Vermont (the
@@ -233,19 +241,11 @@ const cleanLocality = (loc: string) =>
233
241
  /**
234
242
  * Stream real US tuples (number/street/city/postcode) out of a cached OA zip.
235
243
  */
236
- function readUsTuples(source: { zip: string; csv: string; region: string }): USTuple[] {
237
- const r = spawnSync("unzip", ["-p", source.zip, source.csv], { maxBuffer: 1024 * 1024 * 1024, encoding: "buffer" })
238
-
239
- if (r.status !== 0) {
240
- console.error(` WARN: unzip failed for ${source.zip} (status ${r.status})`)
241
-
242
- return []
243
- }
244
-
244
+ async function readUsTuples(source: { zip: string; csv: string; region: string }): Promise<USTuple[]> {
245
245
  const tuples: USTuple[] = []
246
246
  const seen = new Set<string>()
247
247
 
248
- for (const row of readCSVRecords(r.stdout)) {
248
+ for await (const row of readZippedCSVRecords(source.zip, source.csv)) {
249
249
  const locality = row.city ?? ""
250
250
 
251
251
  if (!cleanLocality(locality)) continue
@@ -265,31 +265,47 @@ function readUsTuples(source: { zip: string; csv: string; region: string }): UST
265
265
  return tuples
266
266
  }
267
267
 
268
+ /**
269
+ * The FR stride: keep line 3, then every 211th. Both numbers are the awk pre-filter's, kept exactly — they select which
270
+ * rows land in the shard, so changing either re-rolls the sample.
271
+ */
272
+ const FR_STRIDE = 211
273
+ const FR_STRIDE_OFFSET = 3
274
+
275
+ /**
276
+ * GeoNames population floor for a Canadian locality to enter the pool.
277
+ */
278
+ const CA_LOCALITY_MIN_POPULATION = 1000
279
+
268
280
  /**
269
281
  * Stride-sampled FR tuples (number/street/city/postcode). The countrywide CSV is 2.5 GB and insee-ordered; `awk NR%K`
270
282
  * strides the whole country instead of reading one département.
271
283
  *
272
- * The stride counts PHYSICAL lines, so a record carrying a newline inside a quoted field is two lines to awk and can be
273
- * cut in half by the stride. That is a sampling artefact of the awk pre-filter, not of the parse: whichever lines
274
- * survive are re-assembled into records by {@link readCSVRecords}, and a halved record fails the field checks below.
284
+ * The stride counts PHYSICAL lines, so a record carrying a newline inside a quoted field is two lines to the stride and
285
+ * can be cut in half by it. That is a sampling artefact of striding before the parse, not of the parse: whichever lines
286
+ * survive are re-assembled into records by the CSV reader, and a halved record fails the field checks below. Hence
287
+ * `skipEmpty: false` and no quote handling on the line split — a blank line still advances the count, exactly as it did
288
+ * when this was `awk NR`, and the rows the stride selects are the rows every existing FR shard was built from.
275
289
  */
276
- function readFrTuples(limit: number): FRTuple[] {
277
- const r = spawnSync(
278
- "bash",
279
- ["-c", `unzip -p "${FR_SOURCE.zip}" "${FR_SOURCE.csv}" | awk 'NR==1 || NR%211==3' | head -n ${limit + 1}`],
280
- { maxBuffer: 1024 * 1024 * 1024, encoding: "buffer" }
281
- )
282
-
283
- if (r.status !== 0 && !r.stdout.length) {
284
- console.error(` WARN: unzip failed for ${FR_SOURCE.zip}`)
290
+ async function readFrTuples(limit: number): Promise<FRTuple[]> {
291
+ if (!existsSync(FR_SOURCE.zip)) {
292
+ console.error(` WARN: ${FR_SOURCE.zip} is not cached — skipping ${FR_SOURCE.csv}`)
285
293
 
286
294
  return []
287
295
  }
288
296
 
297
+ const encoder = new TextEncoder()
298
+
299
+ const strided = TextSpliterator.fromAsync(readZipEntry(FR_SOURCE.zip, FR_SOURCE.csv), { skipEmpty: false })
300
+ // `index` is 0-based where awk's NR is 1-based, hence the +1: keep the header, then every 211th line at offset 3.
301
+ .filter((_line, index) => index === 0 || (index + 1) % FR_STRIDE === FR_STRIDE_OFFSET)
302
+ .take(limit + 1)
303
+ .map((line) => encoder.encode(line + "\n"))
304
+
289
305
  const tuples: FRTuple[] = []
290
306
  const seen = new Set<string>()
291
307
 
292
- for (const row of readCSVRecords(r.stdout)) {
308
+ for await (const row of readCSVRecords(strided)) {
293
309
  const locality = row.city ?? "",
294
310
  postcode = row.postcode ?? "",
295
311
  street = row.street ?? "",
@@ -310,23 +326,29 @@ function readFrTuples(limit: number): FRTuple[] {
310
326
  * Canadian locality pools from the GeoNames dump (CC-BY 4.0): feature class P, admin1 10 (Québec) / 08 (Ontario),
311
327
  * population > 1000. GeoNames is the provenance-tracked source — no hand list.
312
328
  */
313
- function readCaLocalities(admin1: string): string[] {
314
- const r = spawnSync(
315
- "bash",
316
- [
317
- "-c",
318
- `unzip -p "${GEONAMES_CA}" CA.txt | awk -F'\\t' '$7=="P" && $9=="CA" && $11=="${admin1}" && $15>1000 {print $2}'`,
319
- ],
320
- { maxBuffer: 1024 * 1024 * 256, encoding: "utf8" }
321
- )
322
-
323
- if (r.status !== 0) {
324
- console.error(` WARN: GeoNames read failed (admin1=${admin1}) — is ${GEONAMES_CA} present?`)
329
+ async function readCaLocalities(admin1: string): Promise<string[]> {
330
+ if (!existsSync(GEONAMES_CA)) {
331
+ console.error(` WARN: ${GEONAMES_CA} is not cached — skipping CA localities (admin1=${admin1})`)
325
332
 
326
333
  return []
327
334
  }
328
335
 
329
- return [...new Set([...TextSpliterator.from(r.stdout)].filter(cleanLocality))]
336
+ const localities = new Set<string>()
337
+
338
+ // GeoNames main dump columns, 0-based: 1 name, 6 feature class, 8 country, 10 admin1, 14 population.
339
+ for await (const columns of TSVSpliterator.fromAsync(readZipEntry(GEONAMES_CA, "CA.txt"), { header: false })) {
340
+ if (columns[6] !== "P" || columns[8] !== "CA" || columns[10] !== admin1) continue
341
+
342
+ if (Number(columns[14]) <= CA_LOCALITY_MIN_POPULATION) continue
343
+
344
+ const name = columns[1] ?? ""
345
+
346
+ if (cleanLocality(name)) {
347
+ localities.add(name)
348
+ }
349
+ }
350
+
351
+ return [...localities]
330
352
  }
331
353
 
332
354
  /**
@@ -336,14 +358,12 @@ function readCaLocalities(admin1: string): string[] {
336
358
  * validated against the codex 4-digit shape — a dump row that fails the contract is skipped, not emitted as a junk
337
359
  * label.
338
360
  */
339
- function readPostalTuples(
361
+ async function readPostalTuples(
340
362
  source: { zip: string; txt: string },
341
363
  opts: { withState: boolean }
342
- ): Array<AUTuple | NZTuple> {
343
- const r = spawnSync("unzip", ["-p", source.zip, source.txt], { maxBuffer: 1024 * 1024 * 64, encoding: "utf8" })
344
-
345
- if (r.status !== 0) {
346
- console.error(` WARN: unzip failed for ${source.zip} (status ${r.status})`)
364
+ ): Promise<Array<AUTuple | NZTuple>> {
365
+ if (!existsSync(source.zip)) {
366
+ console.error(` WARN: ${source.zip} is not cached — skipping ${source.txt}`)
347
367
 
348
368
  return []
349
369
  }
@@ -352,11 +372,8 @@ function readPostalTuples(
352
372
  const seen = new Set<string>()
353
373
  const validPostcode = opts.withState ? isAuPostcode : isNZPostcode
354
374
 
355
- for (const line of TextSpliterator.from(r.stdout)) {
356
- if (!line) continue
357
-
358
- // oxlint-disable-next-line mailwoman/prefer-spliterator -- One row already streamed off the line above.
359
- const cols = line.split("\t")
375
+ // A GeoNames dump carries no header row, so every line is data.
376
+ for await (const cols of TSVSpliterator.fromAsync(readZipEntry(source.zip, source.txt), { header: false })) {
360
377
  const postcode = (cols[1] ?? "").trim()
361
378
  const locality = (cols[2] ?? "").trim()
362
379
  const region = (cols[4] ?? "").trim()
@@ -744,7 +761,7 @@ export const poBoxCedexRecipe: ShardRecipe = {
744
761
  const usPool: USTuple[] = []
745
762
 
746
763
  for (const s of opts.golden ? [US_EVAL_SOURCE] : US_TRAIN_SOURCES) {
747
- const t = readUsTuples(s)
764
+ const t = await readUsTuples(s)
748
765
 
749
766
  console.error(` ${s.csv}: ${t.length} tuples`)
750
767
 
@@ -754,21 +771,21 @@ export const poBoxCedexRecipe: ShardRecipe = {
754
771
  }
755
772
 
756
773
  // FR + CA pools: stable locality-hash holdout (golden gets hash%10==0, train the rest).
757
- const frAll = readFrTuples(80_000)
774
+ const frAll = await readFrTuples(80_000)
758
775
  const frPool = frAll.filter((t) => isHoldoutLocality(t.locality) === opts.golden)
759
776
 
760
777
  console.error(` ${FR_SOURCE.csv}: ${frAll.length} tuples (${frPool.length} after holdout split)`)
761
778
 
762
- const qcAll = readCaLocalities("10")
763
- const onAll = readCaLocalities("08")
779
+ const qcAll = await readCaLocalities("10")
780
+ const onAll = await readCaLocalities("08")
764
781
  const qcPool = qcAll.filter((l) => isHoldoutLocality(l) === opts.golden)
765
782
  const onPool = onAll.filter((l) => isHoldoutLocality(l) === opts.golden)
766
783
 
767
784
  console.error(` GeoNames CA: QC ${qcAll.length}→${qcPool.length}, ON ${onAll.length}→${onPool.length}`)
768
785
 
769
786
  // AU/NZ pools: same stable locality-hash holdout as FR/CA.
770
- const auAll = readPostalTuples(GEONAMES_POSTAL_AU, { withState: true }) as AUTuple[]
771
- const nzAll = readPostalTuples(GEONAMES_POSTAL_NZ, { withState: false }) as NZTuple[]
787
+ const auAll = (await readPostalTuples(GEONAMES_POSTAL_AU, { withState: true })) as AUTuple[]
788
+ const nzAll = (await readPostalTuples(GEONAMES_POSTAL_NZ, { withState: false })) as NZTuple[]
772
789
  const auPool = auAll.filter((t) => isHoldoutLocality(t.locality) === opts.golden)
773
790
  const nzPool = nzAll.filter((t) => isHoldoutLocality(t.locality) === opts.golden)
774
791
 
@@ -9,7 +9,12 @@
9
9
  * scripts/build-po-box-shard.mjs.
10
10
  */
11
11
 
12
- import { synthesizeMilitaryPoBoxRow, synthesizePoBoxRow, type PoBoxBaseTuple } from "../synthesize-po-box.ts"
12
+ import {
13
+ synthesizeMilitaryPoBoxRow,
14
+ synthesizePoBoxRow,
15
+ type PoBoxBaseTuple,
16
+ } from "@mailwoman/corpus/synthesizers/po-box"
17
+
13
18
  import { alignAndWrite, makeLcg, readTuples, shardSourceID, type ShardRecipe } from "./scaffold.ts"
14
19
 
15
20
  const LICENSE = "Synthetic — derived from CC-BY / public-domain input tuples"
@@ -9,11 +9,15 @@
9
9
  * only its synthesis + filter; the `mailwoman corpus shard <recipe>` command supplies the I/O.
10
10
  */
11
11
 
12
- import { tryParsingJSON } from "@mailwoman/core/objects"
13
- import { CSVSpliterator } from "spliterator"
12
+ import { existsSync } from "node:fs"
14
13
 
15
- import { stableSourceID } from "../adapter.ts"
16
- import { alignRow } from "../align.ts"
14
+ import { readZipEntry } from "@mailwoman/core/fs/zip"
15
+ import { tryParsingJSON } from "@mailwoman/core/objects"
16
+ import { stableSourceID } from "@mailwoman/corpus/adapters/utils"
17
+ import { alignRow } from "@mailwoman/corpus/utils"
18
+ import type { PathBuilderLike } from "path-ts"
19
+ import type { AsyncChunkIterator, AsyncDataResource } from "spliterator"
20
+ import { AsyncSequence, CSVSpliterator } from "spliterator"
17
21
 
18
22
  /**
19
23
  * {@link stableSourceID}, but accepting arbitrary disambiguator keys (e.g. a variant index `v`) that aren't
@@ -55,17 +59,26 @@ export { makeLcg, mulberry32 as makeMulberry32, makeLcg as makeRandom } from "@m
55
59
  export type CSVRecord = Record<string, string | undefined>
56
60
 
57
61
  /**
58
- * Read an in-memory CSV (an `unzip -p` buffer, say) as header-keyed records.
59
- *
60
62
  * Quote handling spans the ROW split, not only the column split: a newline inside a quoted field belongs to a single
61
63
  * record, so the record boundaries can only be found by a scanner that already knows where the quotes are. Find the
62
64
  * lines first and unquote afterwards and such a record splits in two — the first half short by however many columns
63
65
  * followed the newline, which is how a `street` value comes to be read as `city`.
64
66
  *
67
+ * `header: false` keeps the first record in the stream, so this module owns the lower-casing rather than
68
+ * `normalizeKeys` — see {@link toHeader}.
69
+ */
70
+ const CSV_INIT = { header: false, enableQuoteHandling: true } as const
71
+
72
+ /**
65
73
  * Header names are lower-cased on the way in. `normalizeKeys` will not do it: it leaves an ALL CAPS header alone, and
66
74
  * OpenAddresses ships `LON,LAT,NUMBER,STREET` while other extracts ship the same names lower-case. A recipe names its
67
75
  * columns in lower case either way.
68
- *
76
+ */
77
+ function toHeader(cells: readonly string[]): string[] {
78
+ return cells.map((name) => name.trim().toLowerCase())
79
+ }
80
+
81
+ /**
69
82
  * Line breaks inside a value become single spaces. A quote-aware parse is the first thing here able to return a value
70
83
  * CONTAINING one — `us/ia/statewide.csv` has 12, all unit designators like `"#2\n#2"` — and every consumer synthesizes
71
84
  * one-line address text from these cells with no guard, because until that parse landed no value could carry one.
@@ -75,27 +88,58 @@ export type CSVRecord = Record<string, string | undefined>
75
88
  * Only `\r` and `\n`, deliberately — NOT `\s`. Runs of spaces and tabs pass through exactly as the source wrote them
76
89
  * (OA's IA extract writes `NORTH`, three spaces, `MAIN STREET`), because those could always appear and every shard
77
90
  * built to date contains them. Widening this to `\s+` silently rewrites values on rows with no line break at all.
78
- * `scaffold.test.ts` pins both halves.
91
+ * `scaffold.test.ts` pins both halves, against both readers.
79
92
  */
80
- export function* readCSVRecords(source: Uint8Array): Generator<CSVRecord> {
93
+ function toRecord(header: readonly string[], cells: readonly string[]): CSVRecord {
94
+ const record: CSVRecord = {}
95
+
96
+ for (let i = 0; i < header.length; i++) {
97
+ record[header[i]!] = (cells[i] ?? "").replaceAll(/[\r\n]+/g, " ").trim()
98
+ }
99
+
100
+ return record
101
+ }
102
+
103
+ /**
104
+ * Read a CSV as header-keyed records.
105
+ *
106
+ * Returns the spliterator's own {@linkcode AsyncSequence}, so a caller composes `take`/`drop`/`filter` onto it — those
107
+ * ops fuse into one pull loop, and a `take` that is satisfied closes the source's file handle on the way out. Wrapping
108
+ * this in an `async function*` costs an async frame per row and takes those ops away; don't.
109
+ *
110
+ * A source at or below the spliterator's 128 KiB bulk threshold is read whole and parsed by the synchronous engine, so
111
+ * this is also the right reader for small sources — there is no buffered variant to reach for.
112
+ */
113
+ export function readCSVRecords(source: AsyncDataResource | AsyncChunkIterator): AsyncSequence<CSVRecord> {
81
114
  let header: string[] | null = null
82
115
 
83
- // `header: false` keeps the first record in the stream so this reader owns the lower-casing.
84
- for (const cells of CSVSpliterator.from(source, { header: false, enableQuoteHandling: true })) {
85
- if (!header) {
86
- header = cells.map((name) => name.trim().toLowerCase())
116
+ return CSVSpliterator.fromAsync<string[]>(source, CSV_INIT)
117
+ .filter((cells) => {
118
+ if (header) return true
87
119
 
88
- continue
89
- }
120
+ header = toHeader(cells)
90
121
 
91
- const record: CSVRecord = {}
122
+ return false
123
+ })
124
+ .map((cells) => toRecord(header!, cells))
125
+ }
92
126
 
93
- for (let i = 0; i < header.length; i++) {
94
- record[header[i]!] = (cells[i] ?? "").replaceAll(/[\r\n]+/g, " ").trim()
95
- }
127
+ /**
128
+ * {@link readCSVRecords} over one member of a zip archive — what every recipe reading a cached OA source wants.
129
+ *
130
+ * A source a checkout has not cached yields nothing, after saying so. A lab holds the archives for the countries it has
131
+ * built, so a recipe naming ten sources routinely finds three, and the `unzip -p` subprocesses these replaced behaved
132
+ * the same way by accident — a non-zero exit warned and returned no rows. A recipe that ends up with NO tuples at all
133
+ * still throws; that is the case where the cache, not the recipe, is the problem.
134
+ */
135
+ export function readZippedCSVRecords(archivePath: PathBuilderLike, entryName: string): AsyncSequence<CSVRecord> {
136
+ if (!existsSync(String(archivePath))) {
137
+ console.error(` WARN: ${archivePath} is not cached — skipping ${entryName}`)
96
138
 
97
- yield record
139
+ return AsyncSequence.from<CSVRecord>([])
98
140
  }
141
+
142
+ return readCSVRecords(readZipEntry(archivePath, entryName))
99
143
  }
100
144
 
101
145
  /**