@mailwoman/resolver-wof-sqlite 9.2.0 → 9.3.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 (488) hide show
  1. package/README.md +16 -19
  2. package/lib/address/index.ts +9 -0
  3. package/{address-point-interpolation.ts → lib/address/point-interpolation.ts} +24 -22
  4. package/{address-point-schema.ts → lib/address/point-schema.ts} +18 -4
  5. package/{address-point.ts → lib/address/point.ts} +89 -27
  6. package/{ancestry-backfill.ts → lib/ancestry/backfill.ts} +14 -19
  7. package/{ancestry.ts → lib/ancestry/index.ts} +5 -3
  8. package/{build-candidate.ts → lib/build-candidate.ts} +84 -77
  9. package/{build-slim.ts → lib/build-slim.ts} +150 -165
  10. package/{candidate → lib/candidate}/alias-bags.ts +8 -6
  11. package/{candidate → lib/candidate}/ancestors-sidecar.ts +13 -15
  12. package/{candidate → lib/candidate}/country-display-names.ts +2 -2
  13. package/{candidate/shard-fold.ts → lib/candidate/extract-fold.ts} +26 -25
  14. package/{candidate → lib/candidate}/name-roles.ts +17 -16
  15. package/{candidate → lib/candidate}/own-name.ts +1 -1
  16. package/{candidate → lib/candidate}/place-attrs.ts +3 -3
  17. package/{candidate-ancestors-schema.ts → lib/candidate-ancestors-schema.ts} +4 -4
  18. package/{candidate-fts.ts → lib/candidate-fts.ts} +3 -3
  19. package/{candidate-importance.ts → lib/candidate-importance.ts} +53 -57
  20. package/{candidate-lookup.ts → lib/candidate-lookup.ts} +76 -73
  21. package/{candidate-schema.ts → lib/candidate-schema.ts} +5 -5
  22. package/{candidate-scoring.ts → lib/candidate-scoring.ts} +15 -22
  23. package/{capital-schema.ts → lib/capital-schema.ts} +5 -6
  24. package/{capitals.ts → lib/capitals.ts} +2 -2
  25. package/{coincident-roles.ts → lib/coincident-roles.ts} +8 -11
  26. package/{convention.ts → lib/convention/index.ts} +3 -3
  27. package/{convention-schema.ts → lib/convention/schema.ts} +2 -2
  28. package/{coverage-manifest-schema.ts → lib/coverage-manifest-schema.ts} +9 -10
  29. package/{currency-backfill.ts → lib/currency-backfill.ts} +126 -41
  30. package/lib/env.ts +50 -0
  31. package/{exact-match.ts → lib/exact-match.ts} +23 -14
  32. package/{sharding.ts → lib/extracts.ts} +61 -58
  33. package/{fst-autocomplete.ts → lib/fst/autocomplete.ts} +4 -4
  34. package/{fst-builder.ts → lib/fst/builder.ts} +17 -16
  35. package/{fst-deserialize-web.ts → lib/fst/deserialize-web.ts} +27 -87
  36. package/lib/fst/format.ts +106 -0
  37. package/{fst-freshness.ts → lib/fst/freshness.ts} +41 -74
  38. package/lib/fst/index.ts +14 -0
  39. package/{fst-matcher.ts → lib/fst/matcher.ts} +1 -1
  40. package/{fst-serialize.ts → lib/fst/serialize.ts} +37 -115
  41. package/{fst-types.ts → lib/fst/types.ts} +4 -2
  42. package/{fts.ts → lib/fts/index.ts} +24 -19
  43. package/{fts-query.ts → lib/fts/query.ts} +1 -1
  44. package/{geonames-aliases.ts → lib/geonames/aliases.ts} +13 -13
  45. package/lib/geonames/index.ts +8 -0
  46. package/{geonames-postal.ts → lib/geonames/postal.ts} +14 -13
  47. package/{index.ts → lib/index.ts} +37 -37
  48. package/{interpolation.ts → lib/interpolation.ts} +27 -25
  49. package/{lookup.ts → lib/lookup.ts} +129 -141
  50. package/lib/nsul/index.ts +8 -0
  51. package/lib/nsul/lookup.ts +144 -0
  52. package/lib/nsul/schema.ts +130 -0
  53. package/{place-importance-schema.ts → lib/place-importance-schema.ts} +7 -8
  54. package/lib/poi/index.ts +8 -0
  55. package/{poi-lookup.ts → lib/poi/lookup.ts} +22 -28
  56. package/{poi-schema.ts → lib/poi/schema.ts} +3 -4
  57. package/{postal-city-alias-lookup.ts → lib/postal/city-alias-lookup.ts} +14 -20
  58. package/{postal-city-candidate-schema.ts → lib/postal/city-candidate-schema.ts} +2 -2
  59. package/lib/postal/index.ts +9 -0
  60. package/{postcode-point-lookup.ts → lib/postcode-point-lookup.ts} +17 -15
  61. package/{primary-preference.ts → lib/primary-preference.ts} +29 -10
  62. package/{proximity-rerank.ts → lib/proximity-rerank.ts} +2 -2
  63. package/{ranking-weights.ts → lib/ranking-weights.ts} +30 -4
  64. package/{region-keys.ts → lib/region-keys.ts} +9 -9
  65. package/{reverse.ts → lib/reverse.ts} +34 -46
  66. package/{schema.ts → lib/schema.ts} +10 -0
  67. package/{search-fetch.ts → lib/search-fetch.ts} +29 -28
  68. package/{sqlite-convention-source.ts → lib/sqlite-convention-source.ts} +9 -10
  69. package/{sqlite-utils.ts → lib/sqlite-utils.ts} +14 -18
  70. package/{street-centroid-schema.ts → lib/street/centroid-schema.ts} +5 -5
  71. package/{street-centroid.ts → lib/street/centroid.ts} +14 -21
  72. package/lib/street/index.ts +13 -0
  73. package/{street-morphology-fst-builder.ts → lib/street/morphology-fst-builder.ts} +24 -14
  74. package/{street-morphology-fst-loader.ts → lib/street/morphology-fst-loader.ts} +14 -12
  75. package/{street-name-lookup.ts → lib/street/name-lookup.ts} +14 -30
  76. package/{street-normalize.ts → lib/street/normalize.ts} +44 -19
  77. package/{street-segment-schema.ts → lib/street/segment-schema.ts} +7 -7
  78. package/{types.ts → lib/types.ts} +18 -12
  79. package/{unified-schema.ts → lib/unified-schema.ts} +20 -24
  80. package/lib/uprn/existence.ts +84 -0
  81. package/lib/uprn/index.ts +9 -0
  82. package/{uprn-lookup.ts → lib/uprn/lookup.ts} +14 -18
  83. package/{uprn-schema.ts → lib/uprn/schema.ts} +3 -3
  84. package/lib/weights-overlay-linker.ts +878 -0
  85. package/out/address/index.d.ts +9 -0
  86. package/out/address/index.d.ts.map +1 -0
  87. package/out/address/index.js +9 -0
  88. package/out/address/index.js.map +1 -0
  89. package/out/{address-point-interpolation.d.ts → address/point-interpolation.d.ts} +11 -10
  90. package/out/address/point-interpolation.d.ts.map +1 -0
  91. package/out/{address-point-interpolation.js → address/point-interpolation.js} +18 -18
  92. package/out/address/point-interpolation.js.map +1 -0
  93. package/out/{address-point-schema.d.ts → address/point-schema.d.ts} +16 -6
  94. package/out/address/point-schema.d.ts.map +1 -0
  95. package/out/{address-point-schema.js → address/point-schema.js} +7 -3
  96. package/out/address/point-schema.js.map +1 -0
  97. package/out/{address-point.d.ts → address/point.d.ts} +16 -8
  98. package/out/address/point.d.ts.map +1 -0
  99. package/out/{address-point.js → address/point.js} +71 -20
  100. package/out/address/point.js.map +1 -0
  101. package/out/{ancestry-backfill.d.ts → ancestry/backfill.d.ts} +7 -5
  102. package/out/ancestry/backfill.d.ts.map +1 -0
  103. package/out/{ancestry-backfill.js → ancestry/backfill.js} +12 -16
  104. package/out/ancestry/backfill.js.map +1 -0
  105. package/out/{ancestry.d.ts → ancestry/index.d.ts} +4 -3
  106. package/out/ancestry/index.d.ts.map +1 -0
  107. package/out/{ancestry.js → ancestry/index.js} +3 -2
  108. package/out/ancestry/index.js.map +1 -0
  109. package/out/build-candidate.d.ts +30 -24
  110. package/out/build-candidate.d.ts.map +1 -1
  111. package/out/build-candidate.js +50 -52
  112. package/out/build-candidate.js.map +1 -1
  113. package/out/build-slim.d.ts +4 -4
  114. package/out/build-slim.d.ts.map +1 -1
  115. package/out/build-slim.js +124 -139
  116. package/out/build-slim.js.map +1 -1
  117. package/out/candidate/alias-bags.d.ts +5 -3
  118. package/out/candidate/alias-bags.d.ts.map +1 -1
  119. package/out/candidate/alias-bags.js +2 -2
  120. package/out/candidate/alias-bags.js.map +1 -1
  121. package/out/candidate/ancestors-sidecar.d.ts +9 -10
  122. package/out/candidate/ancestors-sidecar.d.ts.map +1 -1
  123. package/out/candidate/ancestors-sidecar.js +7 -7
  124. package/out/candidate/ancestors-sidecar.js.map +1 -1
  125. package/out/candidate/country-display-names.d.ts +1 -1
  126. package/out/candidate/country-display-names.d.ts.map +1 -1
  127. package/out/candidate/country-display-names.js +1 -1
  128. package/out/candidate/country-display-names.js.map +1 -1
  129. package/out/candidate/extract-fold.d.ts +32 -0
  130. package/out/candidate/extract-fold.d.ts.map +1 -0
  131. package/out/candidate/{shard-fold.js → extract-fold.js} +20 -20
  132. package/out/candidate/extract-fold.js.map +1 -0
  133. package/out/candidate/name-roles.d.ts +13 -11
  134. package/out/candidate/name-roles.d.ts.map +1 -1
  135. package/out/candidate/name-roles.js +11 -10
  136. package/out/candidate/name-roles.js.map +1 -1
  137. package/out/candidate/own-name.d.ts +1 -1
  138. package/out/candidate/own-name.d.ts.map +1 -1
  139. package/out/candidate/own-name.js +1 -1
  140. package/out/candidate/own-name.js.map +1 -1
  141. package/out/candidate/place-attrs.d.ts +3 -3
  142. package/out/candidate/place-attrs.d.ts.map +1 -1
  143. package/out/candidate/place-attrs.js +1 -1
  144. package/out/candidate/place-attrs.js.map +1 -1
  145. package/out/candidate-ancestors-schema.d.ts +4 -4
  146. package/out/candidate-ancestors-schema.d.ts.map +1 -1
  147. package/out/candidate-ancestors-schema.js +2 -2
  148. package/out/candidate-ancestors-schema.js.map +1 -1
  149. package/out/candidate-fts.d.ts +3 -3
  150. package/out/candidate-fts.d.ts.map +1 -1
  151. package/out/candidate-fts.js +1 -1
  152. package/out/candidate-fts.js.map +1 -1
  153. package/out/candidate-importance.d.ts +16 -16
  154. package/out/candidate-importance.d.ts.map +1 -1
  155. package/out/candidate-importance.js +46 -51
  156. package/out/candidate-importance.js.map +1 -1
  157. package/out/candidate-lookup.d.ts +11 -9
  158. package/out/candidate-lookup.d.ts.map +1 -1
  159. package/out/candidate-lookup.js +61 -58
  160. package/out/candidate-lookup.js.map +1 -1
  161. package/out/candidate-schema.d.ts +5 -5
  162. package/out/candidate-schema.d.ts.map +1 -1
  163. package/out/candidate-schema.js.map +1 -1
  164. package/out/candidate-scoring.d.ts +7 -7
  165. package/out/candidate-scoring.d.ts.map +1 -1
  166. package/out/candidate-scoring.js +10 -14
  167. package/out/candidate-scoring.js.map +1 -1
  168. package/out/capital-schema.d.ts +3 -3
  169. package/out/capital-schema.d.ts.map +1 -1
  170. package/out/capital-schema.js +2 -2
  171. package/out/capital-schema.js.map +1 -1
  172. package/out/capitals.d.ts +1 -1
  173. package/out/capitals.d.ts.map +1 -1
  174. package/out/capitals.js +2 -2
  175. package/out/capitals.js.map +1 -1
  176. package/out/coincident-roles.d.ts +6 -5
  177. package/out/coincident-roles.d.ts.map +1 -1
  178. package/out/coincident-roles.js +2 -4
  179. package/out/coincident-roles.js.map +1 -1
  180. package/out/{convention.d.ts → convention/index.d.ts} +4 -4
  181. package/out/convention/index.d.ts.map +1 -0
  182. package/out/{convention.js → convention/index.js} +2 -2
  183. package/out/convention/index.js.map +1 -0
  184. package/out/{convention-schema.d.ts → convention/schema.d.ts} +2 -2
  185. package/out/convention/schema.d.ts.map +1 -0
  186. package/out/{convention-schema.js → convention/schema.js} +3 -3
  187. package/out/convention/schema.js.map +1 -0
  188. package/out/coverage-manifest-schema.d.ts +8 -8
  189. package/out/coverage-manifest-schema.d.ts.map +1 -1
  190. package/out/coverage-manifest-schema.js +4 -4
  191. package/out/coverage-manifest-schema.js.map +1 -1
  192. package/out/currency-backfill.d.ts +51 -7
  193. package/out/currency-backfill.d.ts.map +1 -1
  194. package/out/currency-backfill.js +65 -49
  195. package/out/currency-backfill.js.map +1 -1
  196. package/out/env.d.ts +43 -0
  197. package/out/env.d.ts.map +1 -0
  198. package/out/env.js +48 -0
  199. package/out/env.js.map +1 -0
  200. package/out/exact-match.d.ts +5 -5
  201. package/out/exact-match.d.ts.map +1 -1
  202. package/out/exact-match.js +10 -11
  203. package/out/exact-match.js.map +1 -1
  204. package/out/extracts.d.ts +114 -0
  205. package/out/extracts.d.ts.map +1 -0
  206. package/out/{sharding.js → extracts.js} +38 -38
  207. package/out/extracts.js.map +1 -0
  208. package/out/{fst-autocomplete.d.ts → fst/autocomplete.d.ts} +2 -2
  209. package/out/fst/autocomplete.d.ts.map +1 -0
  210. package/out/{fst-autocomplete.js → fst/autocomplete.js} +3 -3
  211. package/out/fst/autocomplete.js.map +1 -0
  212. package/out/{fst-builder.d.ts → fst/builder.d.ts} +5 -5
  213. package/out/fst/builder.d.ts.map +1 -0
  214. package/out/{fst-builder.js → fst/builder.js} +14 -13
  215. package/out/fst/builder.js.map +1 -0
  216. package/out/{fst-deserialize-web.d.ts → fst/deserialize-web.d.ts} +3 -3
  217. package/out/fst/deserialize-web.d.ts.map +1 -0
  218. package/out/{fst-deserialize-web.js → fst/deserialize-web.js} +10 -74
  219. package/out/fst/deserialize-web.js.map +1 -0
  220. package/out/fst/format.d.ts +80 -0
  221. package/out/fst/format.d.ts.map +1 -0
  222. package/out/fst/format.js +91 -0
  223. package/out/fst/format.js.map +1 -0
  224. package/out/{fst-freshness.d.ts → fst/freshness.d.ts} +10 -13
  225. package/out/fst/freshness.d.ts.map +1 -0
  226. package/out/{fst-freshness.js → fst/freshness.js} +41 -73
  227. package/out/fst/freshness.js.map +1 -0
  228. package/out/fst/index.d.ts +14 -0
  229. package/out/fst/index.d.ts.map +1 -0
  230. package/out/fst/index.js +14 -0
  231. package/out/fst/index.js.map +1 -0
  232. package/out/{fst-matcher.d.ts → fst/matcher.d.ts} +2 -2
  233. package/out/fst/matcher.d.ts.map +1 -0
  234. package/out/{fst-matcher.js → fst/matcher.js} +1 -1
  235. package/out/fst/matcher.js.map +1 -0
  236. package/out/{fst-serialize.d.ts → fst/serialize.d.ts} +5 -10
  237. package/out/fst/serialize.d.ts.map +1 -0
  238. package/out/{fst-serialize.js → fst/serialize.js} +18 -98
  239. package/out/fst/serialize.js.map +1 -0
  240. package/out/{fst-types.d.ts → fst/types.d.ts} +4 -3
  241. package/out/fst/types.d.ts.map +1 -0
  242. package/out/{fst-types.js → fst/types.js} +1 -1
  243. package/out/fst/types.js.map +1 -0
  244. package/out/{fts.d.ts → fts/index.d.ts} +16 -9
  245. package/out/fts/index.d.ts.map +1 -0
  246. package/out/{fts.js → fts/index.js} +16 -11
  247. package/out/fts/index.js.map +1 -0
  248. package/out/{fts-query.d.ts → fts/query.d.ts} +2 -2
  249. package/out/fts/query.d.ts.map +1 -0
  250. package/out/{fts-query.js → fts/query.js} +1 -1
  251. package/out/fts/query.js.map +1 -0
  252. package/out/{geonames-aliases.d.ts → geonames/aliases.d.ts} +8 -6
  253. package/out/geonames/aliases.d.ts.map +1 -0
  254. package/out/{geonames-aliases.js → geonames/aliases.js} +7 -7
  255. package/out/geonames/aliases.js.map +1 -0
  256. package/out/geonames/index.d.ts +8 -0
  257. package/out/geonames/index.d.ts.map +1 -0
  258. package/out/geonames/index.js +8 -0
  259. package/out/geonames/index.js.map +1 -0
  260. package/out/{geonames-postal.d.ts → geonames/postal.d.ts} +10 -8
  261. package/out/geonames/postal.d.ts.map +1 -0
  262. package/out/{geonames-postal.js → geonames/postal.js} +9 -9
  263. package/out/geonames/postal.js.map +1 -0
  264. package/out/index.d.ts +32 -32
  265. package/out/index.d.ts.map +1 -1
  266. package/out/index.js +24 -24
  267. package/out/index.js.map +1 -1
  268. package/out/interpolation.d.ts +10 -9
  269. package/out/interpolation.d.ts.map +1 -1
  270. package/out/interpolation.js +20 -20
  271. package/out/interpolation.js.map +1 -1
  272. package/out/lookup.d.ts +21 -20
  273. package/out/lookup.d.ts.map +1 -1
  274. package/out/lookup.js +102 -112
  275. package/out/lookup.js.map +1 -1
  276. package/out/name-score.d.ts.map +1 -1
  277. package/out/name-score.js.map +1 -1
  278. package/out/nsul/index.d.ts +8 -0
  279. package/out/nsul/index.d.ts.map +1 -0
  280. package/out/nsul/index.js +8 -0
  281. package/out/nsul/index.js.map +1 -0
  282. package/out/nsul/lookup.d.ts +83 -0
  283. package/out/nsul/lookup.d.ts.map +1 -0
  284. package/out/nsul/lookup.js +80 -0
  285. package/out/nsul/lookup.js.map +1 -0
  286. package/out/nsul/schema.d.ts +100 -0
  287. package/out/nsul/schema.d.ts.map +1 -0
  288. package/out/nsul/schema.js +78 -0
  289. package/out/nsul/schema.js.map +1 -0
  290. package/out/place-importance-schema.d.ts +5 -5
  291. package/out/place-importance-schema.d.ts.map +1 -1
  292. package/out/place-importance-schema.js +3 -3
  293. package/out/place-importance-schema.js.map +1 -1
  294. package/out/poi/index.d.ts +8 -0
  295. package/out/poi/index.d.ts.map +1 -0
  296. package/out/poi/index.js +8 -0
  297. package/out/poi/index.js.map +1 -0
  298. package/out/{poi-lookup.d.ts → poi/lookup.d.ts} +8 -10
  299. package/out/poi/lookup.d.ts.map +1 -0
  300. package/out/{poi-lookup.js → poi/lookup.js} +14 -18
  301. package/out/poi/lookup.js.map +1 -0
  302. package/out/{poi-schema.d.ts → poi/schema.d.ts} +4 -4
  303. package/out/poi/schema.d.ts.map +1 -0
  304. package/out/{poi-schema.js → poi/schema.js} +1 -1
  305. package/out/poi/schema.js.map +1 -0
  306. package/out/polygon-schema.d.ts.map +1 -1
  307. package/out/polygon-schema.js.map +1 -1
  308. package/out/{postal-city-alias-lookup.d.ts → postal/city-alias-lookup.d.ts} +6 -5
  309. package/out/postal/city-alias-lookup.d.ts.map +1 -0
  310. package/out/{postal-city-alias-lookup.js → postal/city-alias-lookup.js} +11 -15
  311. package/out/postal/city-alias-lookup.js.map +1 -0
  312. package/out/{postal-city-alias-schema.d.ts → postal/city-alias-schema.d.ts} +1 -1
  313. package/out/{postal-city-alias-schema.d.ts.map → postal/city-alias-schema.d.ts.map} +1 -1
  314. package/out/{postal-city-alias-schema.js → postal/city-alias-schema.js} +1 -1
  315. package/out/{postal-city-alias-schema.js.map → postal/city-alias-schema.js.map} +1 -1
  316. package/out/{postal-city-candidate-schema.d.ts → postal/city-candidate-schema.d.ts} +3 -3
  317. package/out/{postal-city-candidate-schema.d.ts.map → postal/city-candidate-schema.d.ts.map} +1 -1
  318. package/out/{postal-city-candidate-schema.js → postal/city-candidate-schema.js} +2 -2
  319. package/out/{postal-city-candidate-schema.js.map → postal/city-candidate-schema.js.map} +1 -1
  320. package/out/postal/index.d.ts +9 -0
  321. package/out/postal/index.d.ts.map +1 -0
  322. package/out/postal/index.js +9 -0
  323. package/out/postal/index.js.map +1 -0
  324. package/out/postcode-point-lookup.d.ts +10 -10
  325. package/out/postcode-point-lookup.d.ts.map +1 -1
  326. package/out/postcode-point-lookup.js +13 -13
  327. package/out/postcode-point-lookup.js.map +1 -1
  328. package/out/primary-preference.d.ts +13 -5
  329. package/out/primary-preference.d.ts.map +1 -1
  330. package/out/primary-preference.js +16 -8
  331. package/out/primary-preference.js.map +1 -1
  332. package/out/proximity-rerank.d.ts +2 -2
  333. package/out/proximity-rerank.d.ts.map +1 -1
  334. package/out/proximity-rerank.js +2 -2
  335. package/out/proximity-rerank.js.map +1 -1
  336. package/out/ranking-weights.d.ts +15 -3
  337. package/out/ranking-weights.d.ts.map +1 -1
  338. package/out/ranking-weights.js +21 -3
  339. package/out/ranking-weights.js.map +1 -1
  340. package/out/region-keys.d.ts +8 -8
  341. package/out/region-keys.d.ts.map +1 -1
  342. package/out/region-keys.js +9 -9
  343. package/out/region-keys.js.map +1 -1
  344. package/out/reverse.d.ts +6 -6
  345. package/out/reverse.d.ts.map +1 -1
  346. package/out/reverse.js +20 -29
  347. package/out/reverse.js.map +1 -1
  348. package/out/schema.d.ts +9 -0
  349. package/out/schema.d.ts.map +1 -1
  350. package/out/schema.js.map +1 -1
  351. package/out/search-fetch.d.ts +12 -10
  352. package/out/search-fetch.d.ts.map +1 -1
  353. package/out/search-fetch.js +21 -20
  354. package/out/search-fetch.js.map +1 -1
  355. package/out/sqlite-convention-source.d.ts +7 -7
  356. package/out/sqlite-convention-source.d.ts.map +1 -1
  357. package/out/sqlite-convention-source.js +5 -5
  358. package/out/sqlite-convention-source.js.map +1 -1
  359. package/out/sqlite-utils.d.ts +8 -8
  360. package/out/sqlite-utils.d.ts.map +1 -1
  361. package/out/sqlite-utils.js +7 -8
  362. package/out/sqlite-utils.js.map +1 -1
  363. package/out/{street-centroid-schema.d.ts → street/centroid-schema.d.ts} +6 -6
  364. package/out/{street-centroid-schema.d.ts.map → street/centroid-schema.d.ts.map} +1 -1
  365. package/out/{street-centroid-schema.js → street/centroid-schema.js} +5 -5
  366. package/out/{street-centroid-schema.js.map → street/centroid-schema.js.map} +1 -1
  367. package/out/{street-centroid.d.ts → street/centroid.d.ts} +6 -6
  368. package/out/street/centroid.d.ts.map +1 -0
  369. package/out/{street-centroid.js → street/centroid.js} +13 -19
  370. package/out/street/centroid.js.map +1 -0
  371. package/out/street/index.d.ts +13 -0
  372. package/out/street/index.d.ts.map +1 -0
  373. package/out/street/index.js +13 -0
  374. package/out/street/index.js.map +1 -0
  375. package/out/{street-morphology-fst-builder.d.ts → street/morphology-fst-builder.d.ts} +4 -4
  376. package/out/street/morphology-fst-builder.d.ts.map +1 -0
  377. package/out/{street-morphology-fst-builder.js → street/morphology-fst-builder.js} +18 -13
  378. package/out/street/morphology-fst-builder.js.map +1 -0
  379. package/out/{street-morphology-fst-loader.d.ts → street/morphology-fst-loader.d.ts} +5 -5
  380. package/out/street/morphology-fst-loader.d.ts.map +1 -0
  381. package/out/{street-morphology-fst-loader.js → street/morphology-fst-loader.js} +11 -10
  382. package/out/street/morphology-fst-loader.js.map +1 -0
  383. package/out/{street-name-lookup.d.ts → street/name-lookup.d.ts} +4 -7
  384. package/out/street/name-lookup.d.ts.map +1 -0
  385. package/out/{street-name-lookup.js → street/name-lookup.js} +9 -23
  386. package/out/street/name-lookup.js.map +1 -0
  387. package/out/{street-normalize.d.ts → street/normalize.d.ts} +25 -14
  388. package/out/street/normalize.d.ts.map +1 -0
  389. package/out/{street-normalize.js → street/normalize.js} +36 -17
  390. package/out/street/normalize.js.map +1 -0
  391. package/out/{street-segment-schema.d.ts → street/segment-schema.d.ts} +8 -8
  392. package/out/{street-segment-schema.d.ts.map → street/segment-schema.d.ts.map} +1 -1
  393. package/out/{street-segment-schema.js → street/segment-schema.js} +4 -4
  394. package/out/{street-segment-schema.js.map → street/segment-schema.js.map} +1 -1
  395. package/out/types.d.ts +18 -12
  396. package/out/types.d.ts.map +1 -1
  397. package/out/types.js.map +1 -1
  398. package/out/unified-schema.d.ts +5 -4
  399. package/out/unified-schema.d.ts.map +1 -1
  400. package/out/unified-schema.js +15 -18
  401. package/out/unified-schema.js.map +1 -1
  402. package/out/uprn/existence.d.ts +53 -0
  403. package/out/uprn/existence.d.ts.map +1 -0
  404. package/out/uprn/existence.js +61 -0
  405. package/out/uprn/existence.js.map +1 -0
  406. package/out/uprn/index.d.ts +9 -0
  407. package/out/uprn/index.d.ts.map +1 -0
  408. package/out/uprn/index.js +9 -0
  409. package/out/uprn/index.js.map +1 -0
  410. package/out/{uprn-lookup.d.ts → uprn/lookup.d.ts} +4 -4
  411. package/out/uprn/lookup.d.ts.map +1 -0
  412. package/out/{uprn-lookup.js → uprn/lookup.js} +11 -14
  413. package/out/uprn/lookup.js.map +1 -0
  414. package/out/{uprn-schema.d.ts → uprn/schema.d.ts} +4 -4
  415. package/out/uprn/schema.d.ts.map +1 -0
  416. package/out/{uprn-schema.js → uprn/schema.js} +4 -4
  417. package/out/uprn/schema.js.map +1 -0
  418. package/out/weights-overlay-linker.d.ts +184 -26
  419. package/out/weights-overlay-linker.d.ts.map +1 -1
  420. package/out/weights-overlay-linker.js +338 -86
  421. package/out/weights-overlay-linker.js.map +1 -1
  422. package/package.json +465 -269
  423. package/out/address-point-interpolation.d.ts.map +0 -1
  424. package/out/address-point-interpolation.js.map +0 -1
  425. package/out/address-point-schema.d.ts.map +0 -1
  426. package/out/address-point-schema.js.map +0 -1
  427. package/out/address-point.d.ts.map +0 -1
  428. package/out/address-point.js.map +0 -1
  429. package/out/ancestry-backfill.d.ts.map +0 -1
  430. package/out/ancestry-backfill.js.map +0 -1
  431. package/out/ancestry.d.ts.map +0 -1
  432. package/out/ancestry.js.map +0 -1
  433. package/out/candidate/shard-fold.d.ts +0 -31
  434. package/out/candidate/shard-fold.d.ts.map +0 -1
  435. package/out/candidate/shard-fold.js.map +0 -1
  436. package/out/convention-schema.d.ts.map +0 -1
  437. package/out/convention-schema.js.map +0 -1
  438. package/out/convention.d.ts.map +0 -1
  439. package/out/convention.js.map +0 -1
  440. package/out/fst-autocomplete.d.ts.map +0 -1
  441. package/out/fst-autocomplete.js.map +0 -1
  442. package/out/fst-builder.d.ts.map +0 -1
  443. package/out/fst-builder.js.map +0 -1
  444. package/out/fst-deserialize-web.d.ts.map +0 -1
  445. package/out/fst-deserialize-web.js.map +0 -1
  446. package/out/fst-freshness.d.ts.map +0 -1
  447. package/out/fst-freshness.js.map +0 -1
  448. package/out/fst-matcher.d.ts.map +0 -1
  449. package/out/fst-matcher.js.map +0 -1
  450. package/out/fst-serialize.d.ts.map +0 -1
  451. package/out/fst-serialize.js.map +0 -1
  452. package/out/fst-types.d.ts.map +0 -1
  453. package/out/fst-types.js.map +0 -1
  454. package/out/fts-query.d.ts.map +0 -1
  455. package/out/fts-query.js.map +0 -1
  456. package/out/fts.d.ts.map +0 -1
  457. package/out/fts.js.map +0 -1
  458. package/out/geonames-aliases.d.ts.map +0 -1
  459. package/out/geonames-aliases.js.map +0 -1
  460. package/out/geonames-postal.d.ts.map +0 -1
  461. package/out/geonames-postal.js.map +0 -1
  462. package/out/poi-lookup.d.ts.map +0 -1
  463. package/out/poi-lookup.js.map +0 -1
  464. package/out/poi-schema.d.ts.map +0 -1
  465. package/out/poi-schema.js.map +0 -1
  466. package/out/postal-city-alias-lookup.d.ts.map +0 -1
  467. package/out/postal-city-alias-lookup.js.map +0 -1
  468. package/out/sharding.d.ts +0 -114
  469. package/out/sharding.d.ts.map +0 -1
  470. package/out/sharding.js.map +0 -1
  471. package/out/street-centroid.d.ts.map +0 -1
  472. package/out/street-centroid.js.map +0 -1
  473. package/out/street-morphology-fst-builder.d.ts.map +0 -1
  474. package/out/street-morphology-fst-builder.js.map +0 -1
  475. package/out/street-morphology-fst-loader.d.ts.map +0 -1
  476. package/out/street-morphology-fst-loader.js.map +0 -1
  477. package/out/street-name-lookup.d.ts.map +0 -1
  478. package/out/street-name-lookup.js.map +0 -1
  479. package/out/street-normalize.d.ts.map +0 -1
  480. package/out/street-normalize.js.map +0 -1
  481. package/out/uprn-lookup.d.ts.map +0 -1
  482. package/out/uprn-lookup.js.map +0 -1
  483. package/out/uprn-schema.d.ts.map +0 -1
  484. package/out/uprn-schema.js.map +0 -1
  485. package/weights-overlay-linker.ts +0 -377
  486. /package/{name-score.ts → lib/name-score.ts} +0 -0
  487. /package/{polygon-schema.ts → lib/polygon-schema.ts} +0 -0
  488. /package/{postal-city-alias-schema.ts → lib/postal/city-alias-schema.ts} +0 -0
@@ -8,9 +8,9 @@
8
8
  * updated at gazetteer REBUILD, not by a hand-edited code PR after someone remembers:
9
9
  *
10
10
  * - `country_coverage`: the hard-country-filter coverage record (#743/#194) — per-country
11
- * promote-gate verdicts + the measured hard-resolve rates that used to live in a code comment on
11
+ * promotion-eval verdicts + the measured hard-resolve rates that used to live in a code comment on
12
12
  * `HARD_PLACE_COUNTRY_SAFELIST`. Presence = measured; `hard_filter_safe = 0` = measured and
13
- * FAILED the gate (FI 69.5%, PL 77.8%) — distinguishable from a country never measured at all
13
+ * FAILED the check (FI 69.5%, PL 77.8%) — distinguishable from a country never measured at all
14
14
  * (the meaning-of-zero rule, `docs/engineering/reference/layer-contract.mdx`).
15
15
  * - `country_bbox`: the coarse guard-B plausibility boxes that used to live in
16
16
  * `resolver/plausibility.ts`'s `COUNTRY_BBOX`. An absent row fails open (never trips the guard),
@@ -23,17 +23,16 @@
23
23
  * manifest returns `undefined` and every consumer falls back to the code constants byte-identically.
24
24
  */
25
25
 
26
- import type { DatabaseSync } from "node:sqlite"
27
-
28
26
  import {
29
27
  hardCountrySafelistFromCoverage,
30
28
  type CountryBBoxFact,
31
29
  type CountryCoverageFact,
32
30
  type GazetteerArtifactCoverage,
33
31
  } from "@mailwoman/core/resolver"
32
+ import type { DatabaseClient } from "@mailwoman/sqlite/client"
34
33
  import { sql, type Kysely } from "kysely"
35
34
 
36
- import { allRows, hasTable } from "./sqlite-utils.ts"
35
+ import { allRows, hasTable } from "#sqlite-utils"
37
36
 
38
37
  /**
39
38
  * One country's hard-filter coverage measurement — the storage form of {@link CountryCoverageFact}.
@@ -44,7 +43,7 @@ export interface CountryCoverageTable {
44
43
  */
45
44
  country: string
46
45
  /**
47
- * 0/1 — the promote-gate verdict (a verdict column, NOT re-derived from the rate; see the fact type's docstring).
46
+ * 0/1 — the promotion-eval verdict (a verdict column, NOT re-derived from the rate; see the fact type's docstring).
48
47
  */
49
48
  hard_filter_safe: number
50
49
  /**
@@ -56,11 +55,11 @@ export interface CountryCoverageTable {
56
55
  */
57
56
  sample_size: number | null
58
57
  /**
59
- * ISO-8601 date of the measurement / promote gate.
58
+ * ISO-8601 date of the measurement / promote eval.
60
59
  */
61
60
  measured_at: string
62
61
  /**
63
- * The receipt: which panel/gate produced this row.
62
+ * The receipt: which panel/check produced this row.
64
63
  */
65
64
  source: string
66
65
  }
@@ -92,7 +91,7 @@ export interface GazetteerCoverageDatabase {
92
91
  }
93
92
 
94
93
  /**
95
- * Table names the lookup probes (existence-gated, so a candidate.db built before the manifest is byte-stable).
94
+ * Table names the lookup probes (existence-restricted, so a candidate.db built before the manifest is byte-stable).
96
95
  */
97
96
  export const COUNTRY_COVERAGE_TABLE = "country_coverage"
98
97
  /**
@@ -185,7 +184,7 @@ export async function writeGazetteerCoverageManifest(
185
184
  * purpose: this runs inside {@link WOFCandidateTableLookup}'s synchronous constructor (the sync-reader carve-out in
186
185
  * `AGENTS.md`), and the tables are a few dozen rows read once per open.
187
186
  */
188
- export function readGazetteerCoverageManifest(db: DatabaseSync): GazetteerArtifactCoverage | undefined {
187
+ export function readGazetteerCoverageManifest<DB>(db: DatabaseClient<DB>): GazetteerArtifactCoverage | undefined {
189
188
  const hasCoverage = hasTable(db, COUNTRY_COVERAGE_TABLE)
190
189
  const hasBBox = hasTable(db, COUNTRY_BBOX_TABLE)
191
190
 
@@ -4,22 +4,23 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
6
  * Pass 1c of the candidate build (#1737): resurrect deprecated-with-no-successor WOF localities that a second
7
- * source independently attests. Extracted from `build-candidate.ts` as a cohesive unit — the gates, their measured
7
+ * source independently attests. Extracted from `build-candidate.ts` as a cohesive unit — the checks, their measured
8
8
  * constants, and the GeoNames dump reader live together here; the build calls {@link resurrectCurrencyHoles} once,
9
9
  * between the primaries pass and the alias pass.
10
10
  */
11
11
 
12
- import { existsSync } from "node:fs"
13
- import { resolve } from "node:path"
14
- import type { DatabaseSync } from "node:sqlite"
15
-
12
+ import { pathExists } from "@mailwoman/core/fs/readers"
16
13
  import { isStrictlyFiner } from "@mailwoman/core/resources/whosonfirst"
17
14
  import { haversineKm } from "@mailwoman/spatial"
15
+ import type { DatabaseClient } from "@mailwoman/sqlite/client"
16
+ import { resolvePath } from "path-ts"
18
17
  import { TSVSpliterator } from "spliterator"
19
18
 
20
- import type { loadImportanceIndex } from "./candidate-importance.ts"
21
- import type { PlaceAttrs, StageRow } from "./candidate/place-attrs.ts"
22
- import { normalizeLocalityForKey } from "./street-normalize.ts"
19
+ import type { loadImportanceIndex } from "#candidate-importance"
20
+ import type { CandidateDatabase } from "#candidate-schema"
21
+ import type { PlaceAttrs, StageRow } from "#candidate/place-attrs"
22
+ import type { WOFDatabase } from "#schema"
23
+ import { normalizeLocalityForKey } from "#street/normalize"
23
24
 
24
25
  /**
25
26
  * Corroboration radius for the currency backfill (#1737), km — both for the live-near blocker and the GeoNames
@@ -43,7 +44,7 @@ const CURRENCY_BACKFILL_POP_FLOOR = 1000
43
44
  * WOF deprecations WITH a successor need nothing — the successor indexes. A deprecation with `is_superseded = 0` on a
44
45
  * populated place is the shape of an upstream mistake (Rochester Kent, Aldershot, Telford; 120 GB localities alone),
45
46
  * and it is indistinguishable from a correct pruning at this layer without outside evidence. So every resurrection
46
- * requires all three gates, positive evidence only:
47
+ * requires all three conditions, positive evidence only:
47
48
  *
48
49
  * 1. NO live same-name spr row of any placetype within {@link CURRENCY_BACKFILL_RADIUS_KM} of the dead record — a live row
49
50
  * means the place is alive (possibly under another placetype) and there is no hole. A DISTANT same-name row is a
@@ -56,9 +57,48 @@ const CURRENCY_BACKFILL_POP_FLOOR = 1000
56
57
  * lets the row stand in prominence races (the dead record's own population is absent). Each name is judged once per
57
58
  * country; the resurrected place joins `attrs`, so the alias pass explodes its alt names like any primary's.
58
59
  */
60
+ export interface CurrencyBackfillOutcomes {
61
+ judged: number
62
+ blocked: number
63
+ unattested: number
64
+ floored: number
65
+ resurrected: number
66
+ }
67
+
68
+ /**
69
+ * One country's read of the check — every dead name judged, by outcome and by the dead row's placetype — so a census
70
+ * can say what a wider dead-row query admits before a build carries it.
71
+ */
72
+ export interface CurrencyBackfillCountryReport extends CurrencyBackfillOutcomes {
73
+ country: string
74
+ deadPlacetypes: readonly string[]
75
+ dumpPresent: boolean
76
+ byDeadPlacetype: Record<string, CurrencyBackfillOutcomes>
77
+ /**
78
+ * The first resurrected names, `placetype:name`, so a census reads what a wider query admits — capped, because the
79
+ * report is a receipt and not the table.
80
+ */
81
+ sample: string[]
82
+ }
83
+
84
+ const REPORT_SAMPLE_SIZE = 25
85
+
86
+ /**
87
+ * The placetypes a dead row may carry to be judged at all. `locality` is the shipped default; `localadmin` is the
88
+ * second cause #1746 named (one GB row of seventeen) and is admitted through this option once its census is read.
89
+ */
90
+ export const DEFAULT_DEAD_PLACETYPES: readonly string[] = ["locality"]
91
+
92
+ function emptyOutcomes(): CurrencyBackfillOutcomes {
93
+ return { judged: 0, blocked: 0, unattested: 0, floored: 0, resurrected: 0 }
94
+ }
95
+
59
96
  export async function resurrectCurrencyHoles(ctx: {
60
- src: DatabaseSync
61
- tx: DatabaseSync
97
+ src: DatabaseClient<WOFDatabase>
98
+ /**
99
+ * The candidate build's transaction. Required unless `dryRun` — a dry run judges every row and stages nothing.
100
+ */
101
+ tx?: DatabaseClient<CandidateDatabase>
62
102
  geonamesDir: string
63
103
  countries: readonly string[]
64
104
  attrs: Map<number, PlaceAttrs>
@@ -68,11 +108,32 @@ export async function resurrectCurrencyHoles(ctx: {
68
108
  importance: ReturnType<typeof loadImportanceIndex> | undefined
69
109
  stageRow: StageRow
70
110
  progress: (phase: string, message: string) => void
111
+ /**
112
+ * Which dead placetypes are judged. Default {@link DEFAULT_DEAD_PLACETYPES}.
113
+ */
114
+ deadPlacetypes?: readonly string[]
115
+ /**
116
+ * Judge and count, stage nothing — the census mode. No transaction is opened.
117
+ */
118
+ dryRun?: boolean
119
+ /**
120
+ * Receives one report per country judged (a country with no dump or no dead rows reports zero outcomes).
121
+ */
122
+ onCountry?: (report: CurrencyBackfillCountryReport) => void
71
123
  }): Promise<number> {
124
+ const deadPlacetypes = ctx.deadPlacetypes ?? DEFAULT_DEAD_PLACETYPES
125
+ const dryRun = ctx.dryRun === true
126
+
127
+ if (!dryRun && !ctx.tx) {
128
+ throw new Error(
129
+ "resurrectCurrencyHoles: a build run needs the candidate transaction (tx); pass dryRun to judge only"
130
+ )
131
+ }
132
+
72
133
  const deadStmt = ctx.src.prepare(
73
134
  `SELECT id, name, placetype, latitude, longitude, min_latitude, min_longitude, max_latitude, max_longitude
74
135
  FROM spr
75
- WHERE country = ? AND placetype = 'locality'
136
+ WHERE country = ? AND placetype IN (${deadPlacetypes.map(() => "?").join(", ")})
76
137
  AND is_current = 0 AND is_deprecated = 1 AND is_superseded = 0`
77
138
  )
78
139
 
@@ -84,10 +145,20 @@ export async function resurrectCurrencyHoles(ctx: {
84
145
 
85
146
  for (const country of ctx.countries) {
86
147
  const cc = country.toUpperCase()
87
- const dumpPath = resolve(ctx.geonamesDir, `${cc}.txt`)
148
+ const dumpPath = resolvePath(ctx.geonamesDir, `${cc}.txt`)
149
+
150
+ const report: CurrencyBackfillCountryReport = {
151
+ country: cc,
152
+ deadPlacetypes,
153
+ dumpPresent: await pathExists(dumpPath),
154
+ ...emptyOutcomes(),
155
+ byDeadPlacetype: {},
156
+ sample: [],
157
+ }
88
158
 
89
- if (!existsSync(dumpPath)) {
159
+ if (!report.dumpPresent) {
90
160
  ctx.progress("currency-backfill", `${cc}: no GeoNames dump at ${dumpPath} — holes stay dead`)
161
+ ctx.onCountry?.(report)
91
162
 
92
163
  continue
93
164
  }
@@ -95,10 +166,11 @@ export async function resurrectCurrencyHoles(ctx: {
95
166
  // Dead rows FIRST: a country with no deprecated-no-successor localities needs no attestors at all, and
96
167
  // loading a national dump to judge zero rows is pure heap pressure on a build already near its ceiling
97
168
  // (the first live run OOM'd in a later pass with JP/KR dumps loaded for 0 dead names each).
98
- const dead = deadStmt.all(cc)
169
+ const dead = deadStmt.all(cc, ...deadPlacetypes)
99
170
 
100
171
  if (!dead.length) {
101
172
  ctx.progress("currency-backfill", `${cc}: 0 dead names — dump not loaded`)
173
+ ctx.onCountry?.(report)
102
174
 
103
175
  continue
104
176
  }
@@ -141,14 +213,18 @@ export async function resurrectCurrencyHoles(ctx: {
141
213
  }
142
214
  }
143
215
 
144
- let judged = 0
145
- let blocked = 0
146
- let unattested = 0
147
- let floored = 0
148
- let resurrected = 0
149
216
  const seen = new Set<string>()
150
217
 
151
- ctx.tx.exec("BEGIN")
218
+ const count = (deadPlacetype: string, outcome: keyof CurrencyBackfillOutcomes): void => {
219
+ report[outcome] += 1
220
+ const bucket = (report.byDeadPlacetype[deadPlacetype] ??= emptyOutcomes())
221
+
222
+ bucket[outcome] += 1
223
+ }
224
+
225
+ if (!dryRun) {
226
+ ctx.tx!.exec("BEGIN")
227
+ }
152
228
 
153
229
  for (const d of dead) {
154
230
  const name = String(d.name ?? "")
@@ -156,23 +232,22 @@ export async function resurrectCurrencyHoles(ctx: {
156
232
 
157
233
  if (!pkey || seen.has(pkey)) continue
158
234
  seen.add(pkey)
235
+ // Read from the row: the query admits whatever `deadPlacetypes` names, and the rank comparison below must
236
+ // judge each candidate against ITS dead rung, never a hardcoded one.
237
+ const deadPlacetype = String(d.placetype ?? "locality")
159
238
 
160
- judged++
161
-
239
+ count(deadPlacetype, "judged")
162
240
  const dLat = Number(d.latitude)
163
241
  const dLon = Number(d.longitude)
164
- // The dead-row query is scoped to `locality` today; read it from the row anyway so widening that query
165
- // cannot silently start comparing every candidate against a hardcoded rung.
166
- const deadPlacetype = String(d.placetype ?? "locality")
167
242
 
168
- // A live row blocks only when it is AT LEAST AS COARSE as the dead one. The original gate compared name and
243
+ // A live row blocks only when it is AT LEAST AS COARSE as the dead one. The original check compared name and
169
244
  // distance alone, on the premise that a nearby same-name row means "the place is alive under another
170
245
  // placetype" — true for a place recorded twice, false for a placetype DEMOTION, which is the shape that
171
246
  // actually occurs: WOF retired `Gillingham` the locality (pop 101,187) and kept `Gillingham` the
172
- // neighbourhood 3.2 km away, and the gate read the surviving CHILD as covering its own dead parent.
247
+ // neighbourhood 3.2 km away, and the check read the surviving CHILD as covering its own dead parent.
173
248
  // Sixteen of seventeen GB refusals had exactly that shape (#1746).
174
249
  //
175
- // An UNRANKED placetype blocks, which is the conservative direction: this gate's failure mode is inventing
250
+ // An UNRANKED placetype blocks, which is the conservative direction: this check's failure mode is inventing
176
251
  // a place, so a row we cannot rank is treated as covering rather than waved through.
177
252
  const liveNear = liveStmt.all(cc, name).some((row) => {
178
253
  if (haversineKm(dLat, dLon, Number(row.latitude), Number(row.longitude)) > CURRENCY_BACKFILL_RADIUS_KM) {
@@ -180,13 +255,13 @@ export async function resurrectCurrencyHoles(ctx: {
180
255
  }
181
256
 
182
257
  // Blocks UNLESS the live row is strictly finer. The equal rung must still block — a live `locality`
183
- // covers a dead `locality` — and an unranked placetype blocks too, since this gate's failure mode
258
+ // covers a dead `locality` — and an unranked placetype blocks too, since this check's failure mode
184
259
  // is inventing a place.
185
260
  return isStrictlyFiner(String(row.placetype ?? ""), deadPlacetype) !== true
186
261
  })
187
262
 
188
263
  if (liveNear) {
189
- blocked++
264
+ count(deadPlacetype, "blocked")
190
265
 
191
266
  continue
192
267
  }
@@ -196,7 +271,7 @@ export async function resurrectCurrencyHoles(ctx: {
196
271
  )
197
272
 
198
273
  if (!near.length) {
199
- unattested++
274
+ count(deadPlacetype, "unattested")
200
275
 
201
276
  continue
202
277
  }
@@ -204,17 +279,25 @@ export async function resurrectCurrencyHoles(ctx: {
204
279
  const pop = Math.max(...near.map((g) => g.pop))
205
280
 
206
281
  if (pop < CURRENCY_BACKFILL_POP_FLOOR) {
207
- floored++
282
+ count(deadPlacetype, "floored")
208
283
 
209
284
  continue
210
285
  }
211
286
 
287
+ count(deadPlacetype, "resurrected")
288
+
289
+ if (report.sample.length < REPORT_SAMPLE_SIZE) {
290
+ report.sample.push(`${deadPlacetype}:${name}`)
291
+ }
292
+
293
+ if (dryRun) continue
294
+
212
295
  const sid = Number(d.id)
213
296
 
214
297
  const a: PlaceAttrs = {
215
298
  cid: ctx.ccID(cc),
216
299
  rid: ctx.regionOf.get(sid) ?? 0,
217
- ptid: ctx.ptID("locality"),
300
+ ptid: ctx.ptID(deadPlacetype),
218
301
  name,
219
302
  lat: dLat,
220
303
  lon: dLon,
@@ -225,24 +308,26 @@ export async function resurrectCurrencyHoles(ctx: {
225
308
  pop,
226
309
  neg: -Math.log10(pop + 1),
227
310
  pkey,
228
- imp: ctx.importance?.find(name, cc, "locality", dLat, dLon) ?? null,
311
+ imp: ctx.importance?.find(name, cc, deadPlacetype, dLat, dLon) ?? null,
229
312
  }
230
313
 
231
314
  ctx.attrs.set(sid, a)
232
315
  ctx.stageRow(pkey, a, sid, 1)
233
-
234
- resurrected++
235
316
  }
236
317
 
237
- ctx.tx.exec("COMMIT")
318
+ if (!dryRun) {
319
+ ctx.tx!.exec("COMMIT")
320
+ }
238
321
 
239
322
  ctx.progress(
240
323
  "currency-backfill",
241
- `${cc}: ${resurrected} resurrected of ${judged} dead names ` +
242
- `(${blocked} blocked by a live near row, ${unattested} unattested, ${floored} under the population floor)`
324
+ `${cc}: ${report.resurrected} resurrected of ${report.judged} dead names ` +
325
+ `(${report.blocked} blocked by a live near row, ${report.unattested} unattested, ` +
326
+ `${report.floored} under the population floor)${dryRun ? " — dry run, nothing staged" : ""}`
243
327
  )
244
328
 
245
- total += resurrected
329
+ ctx.onCountry?.(report)
330
+ total += report.resurrected
246
331
  }
247
332
 
248
333
  return total
package/lib/env.ts ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Environment variables naming the WOF SQLite artifacts this resolver opens, and the development weights the overlay
7
+ * linker materializes. CLI flags (`--resolve-db`, …) override these at the call site.
8
+ */
9
+
10
+ import { $public as corePublic, liveEnv } from "@mailwoman/core/env"
11
+ import { z } from "zod"
12
+
13
+ /**
14
+ * Gazetteer and resolver database paths, plus the development weights overlay.
15
+ */
16
+ export const PublicWOFSQLiteEnvSchema = z.object({
17
+ MAILWOMAN_WOF_DB: z.string().optional().meta({
18
+ title: "Who's On First database",
19
+ description: "Path to a full Who's On First SQLite distribution used by the search resolver backend.",
20
+ }),
21
+ MAILWOMAN_WOF_ADMIN_DB: z.string().optional().meta({
22
+ title: "Who's On First admin database",
23
+ description: "Path to the full Who's On First distribution used for reverse geocoding.",
24
+ }),
25
+ MAILWOMAN_WOF_POLYGONS_DB: z.string().optional().meta({
26
+ title: "Who's On First polygon database",
27
+ description: "Path to the polygon sidecar used for exact reverse-geocode containment.",
28
+ }),
29
+ MAILWOMAN_CANDIDATE_DB: z.string().optional().meta({
30
+ title: "Candidate database",
31
+ description: "Path to candidate.db; set to `none` to pin the full-distribution search backend.",
32
+ }),
33
+ MAILWOMAN_POSTAL_CITY_ALIAS_DB: z.string().optional().meta({
34
+ title: "Postal city alias database",
35
+ description: "Path to postal-city alias data used for alias-aware resolution of U.S. mailing addresses.",
36
+ }),
37
+ MAILWOMAN_DEV_MODEL: z.string().optional().meta({
38
+ title: "Development model",
39
+ description: "Path to the model artifact linked for local neural-weights development.",
40
+ }),
41
+ MAILWOMAN_DEV_TOKENIZER: z.string().optional().meta({
42
+ title: "Development tokenizer",
43
+ description: "Path to the tokenizer artifact linked for local neural-weights development.",
44
+ }),
45
+ })
46
+
47
+ /**
48
+ * Live resolver settings over core's, sharing core's getters and cached values.
49
+ */
50
+ export const $public = liveEnv(PublicWOFSQLiteEnvSchema, corePublic)
@@ -7,18 +7,23 @@
7
7
  * candidate holds the query text as its own name, an alias, or an official name.
8
8
  */
9
9
 
10
- import type { DatabaseSync } from "node:sqlite"
10
+ import type { DatabaseClient } from "@mailwoman/sqlite/client"
11
11
 
12
- import { aliasBagExactMatch } from "./fts.ts"
12
+ import { aliasBagExactMatch, foldQueryText } from "#fts/index"
13
13
 
14
14
  /**
15
15
  * Among `ids`, return the subset whose name OR any alias equals `text` case-insensitively — the exact-match tier for
16
- * ranking. One indexed query over `<schema>.names`. When the shard has no `names` table (a slim DB built with
17
- * `dropNames`, or a postcode-only shard), fall back to the self-contained `place_search` FTS content: its `alt_names`
16
+ * ranking. One indexed query over `<schema>.names`. When the extract has no `names` table (a slim DB built with
17
+ * `dropNames`, or a postcode-only extract), fall back to the self-contained `place_search` FTS content: its `alt_names`
18
18
  * column is the same alias set joined on the boundary-preserving `ALIAS_SEPARATOR` (#523), so `aliasBagExactMatch`
19
19
  * recovers the exact alias tier ("New York City" → New York) that the dropped `names` table used to provide.
20
20
  */
21
- export function exactMatchIDs(db: DatabaseSync, schemaName: string, ids: number[], text: string): Set<number> {
21
+ export function exactMatchIDs<DB>(
22
+ db: DatabaseClient<DB>,
23
+ schemaName: string,
24
+ ids: number[],
25
+ text: string
26
+ ): Set<number> {
22
27
  const out = new Set<number>()
23
28
  const trimmed = text.trim()
24
29
 
@@ -36,7 +41,7 @@ export function exactMatchIDs(db: DatabaseSync, schemaName: string, ids: number[
36
41
 
37
42
  return out
38
43
  } catch {
39
- // No `names` table on this shard — fall through to the place_search alias bag.
44
+ // No `names` table on this extract — fall through to the place_search alias bag.
40
45
  }
41
46
 
42
47
  try {
@@ -44,19 +49,18 @@ export function exactMatchIDs(db: DatabaseSync, schemaName: string, ids: number[
44
49
  .prepare(`SELECT wof_id AS id, name, alt_names FROM ${schemaName}.place_search WHERE wof_id IN (${placeholders})`)
45
50
  .all(...ids) as Array<{ id: number; name: string | null; alt_names: string | null }>
46
51
 
47
- const norm = (s: string): string => s.toLowerCase().trim().replaceAll(/\s+/g, " ")
48
- const needle = norm(trimmed)
52
+ const needle = foldQueryText(trimmed)
49
53
 
50
54
  for (const r of rows) {
51
- if (r.name !== null && norm(r.name) === needle) {
55
+ if (r.name !== null && foldQueryText(r.name) === needle) {
52
56
  out.add(r.id)
53
57
  }
54
58
  }
55
59
 
56
60
  // Alias pass via the shared bag parser (#523). Separated bags (built since #523) get a true
57
- // per-alias equality check, ungated — matching the `names`-table branch above, where an
61
+ // per-alias equality check, unrestricted — matching the `names`-table branch above, where an
58
62
  // alias match counts as exact regardless of other candidates. Legacy bags (no separator)
59
- // fall back to padded containment, gated on "no canonical exact in the pool" because their
63
+ // fall back to padded containment, conditioned on "no canonical exact in the pool" because their
60
64
  // lost boundaries would otherwise false-promote interior fragments ("York" inside the alias
61
65
  // "New York City") or cross-alias fragments ("York New" across "…York" + "New City…").
62
66
  const anyCanonicalExact = out.size > 0
@@ -67,7 +71,7 @@ export function exactMatchIDs(db: DatabaseSync, schemaName: string, ids: number[
67
71
  }
68
72
  }
69
73
  } catch {
70
- // Shard without place_search either → no exact-match tier. Falls back to weighted-sum order.
74
+ // Extract without place_search either → no exact-match tier. Falls back to weighted-sum order.
71
75
  }
72
76
 
73
77
  return out
@@ -79,7 +83,12 @@ export function exactMatchIDs(db: DatabaseSync, schemaName: string, ids: number[
79
83
  * agree on what "equals the query" means. Fails soft on gazetteers built before #940 (no `official` column) — the
80
84
  * sub-tier then behaves exactly as if `officialNameExact` were off.
81
85
  */
82
- export function officialNameIDs(db: DatabaseSync, schemaName: string, ids: number[], text: string): Set<number> {
86
+ export function officialNameIDs<DB>(
87
+ db: DatabaseClient<DB>,
88
+ schemaName: string,
89
+ ids: number[],
90
+ text: string
91
+ ): Set<number> {
83
92
  const out = new Set<number>()
84
93
  const trimmed = text.trim()
85
94
 
@@ -97,7 +106,7 @@ export function officialNameIDs(db: DatabaseSync, schemaName: string, ids: numbe
97
106
  out.add(r.id)
98
107
  }
99
108
  } catch {
100
- // Pre-#940 gazetteer (no `official` column) or a names-less slim shard — feature inert.
109
+ // Pre-#940 gazetteer (no `official` column) or a names-less slim extract — feature inert.
101
110
  }
102
111
 
103
112
  return out