@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
@@ -27,7 +27,7 @@
27
27
  * Warwick in America the fame of Warwick, Rhode Island, which is the fan-out defect
28
28
  * `importance-fanout.ts` documents one layer up, re-introduced at the join. So the group is
29
29
  * disambiguated GEOGRAPHICALLY: the nearest centroid wins, and only within
30
- * {@link IMPORTANCE_JOIN_GATE_KM}. Two artifacts describing the same settlement put its centroid in
30
+ * {@link IMPORTANCE_JOIN_RADIUS_KM}. Two artifacts describing the same settlement put its centroid in
31
31
  * almost the same place; two same-named towns in one country do not.
32
32
  *
33
33
  * ## What lands in the column
@@ -40,9 +40,9 @@
40
40
  * A place with no match gets NULL. NULL is UNMEASURED, never zero — the consumer
41
41
  * (`resolver/toponym-prior.ts`) leaves an unmeasured candidate exactly where population put it.
42
42
  */
43
- import { DatabaseSync } from "node:sqlite";
44
43
  import { haversineKm } from "@mailwoman/spatial";
45
- import { normalizeLocalityForKey } from "./street-normalize.js";
44
+ import { DatabaseClient } from "@mailwoman/sqlite/client";
45
+ import { normalizeLocalityForKey } from "#street/normalize";
46
46
  /**
47
47
  * How far apart two artifacts may put the same place's centroid and still be read as the same place.
48
48
  *
@@ -51,18 +51,18 @@ import { normalizeLocalityForKey } from "./street-normalize.js";
51
51
  * country, placetype)`). The nearest-centroid distance is **exactly 0.00 km for 577,080 of them (56.6%)** — the two
52
52
  * snapshots agree to the bit — and 656,755 (64.4%) are inside 500 m.
53
53
  *
54
- * What sets the gate is where that mode ENDS, and the per-kilometre density says so plainly. It falls from 1,076
55
- * places/km over 3–5 km to a trough of **441 places/km over 7–10 km**, then climbs back and flattens onto a plateau of
56
- * 760–780 places/km from 30 km out to 100 km and beyond. That plateau is the background rate of two DIFFERENT towns
57
- * wearing one name in one country, and it does not decay with distance because there is no reason it should. 10 km is
58
- * the floor between the two populations. Admitting it scores 679,163 places (66.6% of the matched set); pushing the
59
- * gate to 25 km buys 8,722 more, and by then better than half of each additional kilometre is the wrong town.
54
+ * What sets the radius is where that mode ENDS, and the per-kilometre density states. It falls from 1,076 places/km
55
+ * over 3–5 km to a trough of **441 places/km over 7–10 km**, then climbs back and flattens onto a plateau of 760–780
56
+ * places/km from 30 km out to 100 km and beyond. That plateau is the background rate of two DIFFERENT towns wearing one
57
+ * name in one country, and it does not decay with distance because there is no reason it should. 10 km is the floor
58
+ * between the two populations. Admitting it scores 679,163 places (66.6% of the matched set); pushing the radius to 25
59
+ * km buys 8,722 more, and by then better than half of each additional kilometre is the wrong town.
60
60
  *
61
61
  * The four-row bare-GB board is insensitive across this whole range — 5 km and 25 km were both measured and select
62
- * identical rows — so the value is chosen by what the join MEANS, not by what it scores. The gate is the definition of
63
- * "this is the same place"; widening it past the floor starts handing one town's fame to another.
62
+ * identical rows — so the value is chosen by what the join MEANS, not by what it scores. The radius is the definition
63
+ * of "this is the same place"; widening it past the floor starts handing one town's fame to another.
64
64
  */
65
- export const IMPORTANCE_JOIN_GATE_KM = 10;
65
+ export const IMPORTANCE_JOIN_RADIUS_KM = 10;
66
66
  /**
67
67
  * `(name_key, country, placetype)` → the scored places under it. The separator is U+0000, which no WOF name carries and
68
68
  * no fold can produce, so the three fields can't smear into one another.
@@ -77,24 +77,24 @@ export class ImportanceIndex {
77
77
  #groups;
78
78
  stats;
79
79
  /**
80
- * Places {@link find} matched inside the gate.
80
+ * Places {@link find} matched inside the radius.
81
81
  */
82
82
  matched = 0;
83
83
  /**
84
- * Places {@link find} REFUSED — the key matched a scored group, but the nearest member of it was outside the gate, so
85
- * it is a different place wearing the same name.
84
+ * Places {@link find} REFUSED — the key matched a scored group, but the nearest member of it was outside the radius,
85
+ * so it is a different place wearing the same name.
86
86
  *
87
87
  * This is the number worth watching across rebuilds. A jump means the score source and the admin source have drifted
88
- * apart and the join is being asked to guess; it does not mean the gate is too tight.
88
+ * apart and the join is being asked to guess; it does not mean the radius is too tight.
89
89
  */
90
- gated = 0;
90
+ refused = 0;
91
91
  constructor(groups, stats) {
92
92
  this.#groups = groups;
93
93
  this.stats = stats;
94
94
  }
95
95
  /**
96
96
  * The importance of the scored place nearest `(lat, lon)` sharing `name`'s folded key, `country` and `placetype`, or
97
- * null when there is no such place within {@link IMPORTANCE_JOIN_GATE_KM}.
97
+ * null when there is no such place within {@link IMPORTANCE_JOIN_RADIUS_KM}.
98
98
  *
99
99
  * Null is UNMEASURED. Never substitute a zero, and never fall back to a population-derived value here — the source
100
100
  * column already carries that fallback where it has one, and inventing a second one would make an absence
@@ -116,8 +116,8 @@ export class ImportanceIndex {
116
116
  best = place;
117
117
  }
118
118
  }
119
- if (!best || bestKm > IMPORTANCE_JOIN_GATE_KM) {
120
- this.gated++;
119
+ if (!best || bestKm > IMPORTANCE_JOIN_RADIUS_KM) {
120
+ this.refused++;
121
121
  return null;
122
122
  }
123
123
  this.matched++;
@@ -137,38 +137,33 @@ export class ImportanceIndex {
137
137
  * 25 s.
138
138
  */
139
139
  export function loadImportanceIndex(databasePath) {
140
- const db = new DatabaseSync(databasePath, { readOnly: true });
141
- try {
142
- const groups = new Map();
143
- let places = 0;
144
- let unkeyable = 0;
145
- for (const row of db
146
- .prepare(`SELECT s.name AS name, s.country AS country, s.placetype AS placetype,
147
- s.latitude AS latitude, s.longitude AS longitude, i.importance AS importance
148
- FROM place_importance i JOIN spr s ON s.id = i.id
149
- WHERE s.is_current != 0 AND s.is_deprecated = 0`)
150
- .iterate()) {
151
- const importance = Number(row.importance);
152
- if (!Number.isFinite(importance))
153
- continue;
154
- const nameKey = normalizeLocalityForKey(String(row.name ?? ""));
155
- if (!nameKey) {
156
- unkeyable++;
157
- continue;
158
- }
159
- const key = groupKey(nameKey, row.country, row.placetype);
160
- let group = groups.get(key);
161
- if (!group) {
162
- group = [];
163
- groups.set(key, group);
164
- }
165
- group.push({ lat: Number(row.latitude), lon: Number(row.longitude), importance });
166
- places++;
140
+ using db = new DatabaseClient(databasePath, { readOnly: true });
141
+ const groups = new Map();
142
+ let places = 0;
143
+ let unkeyable = 0;
144
+ for (const row of db
145
+ .prepare(`SELECT s.name AS name, s.country AS country, s.placetype AS placetype,
146
+ s.latitude AS latitude, s.longitude AS longitude, i.importance AS importance
147
+ FROM place_importance i JOIN spr s ON s.id = i.id
148
+ WHERE s.is_current != 0 AND s.is_deprecated = 0`)
149
+ .iterate()) {
150
+ const importance = Number(row.importance);
151
+ if (!Number.isFinite(importance))
152
+ continue;
153
+ const nameKey = normalizeLocalityForKey(String(row.name ?? ""));
154
+ if (!nameKey) {
155
+ unkeyable++;
156
+ continue;
167
157
  }
168
- return new ImportanceIndex(groups, { places, keys: groups.size, unkeyable });
169
- }
170
- finally {
171
- db.close();
158
+ const key = groupKey(nameKey, row.country, row.placetype);
159
+ let group = groups.get(key);
160
+ if (!group) {
161
+ group = [];
162
+ groups.set(key, group);
163
+ }
164
+ group.push({ lat: Number(row.latitude), lon: Number(row.longitude), importance });
165
+ places++;
172
166
  }
167
+ return new ImportanceIndex(groups, { places, keys: groups.size, unkeyable });
173
168
  }
174
169
  //# sourceMappingURL=candidate-importance.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"candidate-importance.js","sourceRoot":"","sources":["../candidate-importance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"candidate-importance.js","sourceRoot":"","sources":["../lib/candidate-importance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAGzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAA;AA8B3C;;;GAGG;AACH,SAAS,QAAQ,CAAC,OAAe,EAAE,OAAsB,EAAE,SAAwB;IAClF,OAAO,GAAG,OAAO,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,SAAS,SAAS,IAAI,EAAE,EAAE,CAAA;AAClF,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,eAAe;IAClB,OAAO,CAA4B;IACnC,KAAK,CAAsB;IACpC;;OAEG;IACH,OAAO,GAAG,CAAC,CAAA;IACX;;;;;;OAMG;IACH,OAAO,GAAG,CAAC,CAAA;IAEX,YAAY,MAAkC,EAAE,KAA2B;QAC1E,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACnB,CAAC;IAED;;;;;;;OAOG;IACH,IAAI,CAAC,IAAY,EAAE,OAAsB,EAAE,SAAwB,EAAE,GAAW,EAAE,GAAW;QAC5F,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;QAE7C,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAA;QAEzB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAA;QAErE,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAEvB,IAAI,IAA6B,CAAA;QACjC,IAAI,MAAM,GAAG,QAAQ,CAAA;QAErB,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;YAEtD,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;gBACjB,MAAM,GAAG,EAAE,CAAA;gBACX,IAAI,GAAG,KAAK,CAAA;YACb,CAAC;QACF,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,MAAM,GAAG,yBAAyB,EAAE,CAAC;YACjD,IAAI,CAAC,OAAO,EAAE,CAAA;YAEd,OAAO,IAAI,CAAA;QACZ,CAAC;QAED,IAAI,CAAC,OAAO,EAAE,CAAA;QAEd,OAAO,IAAI,CAAC,UAAU,CAAA;IACvB,CAAC;CACD;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,YAAoB;IACvD,MAAM,EAAE,GAAG,IAAI,cAAc,CAAoB,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IAElF,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAA;IAC/C,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,IAAI,SAAS,GAAG,CAAC,CAAA;IAEjB,KAAK,MAAM,GAAG,IAAI,EAAE;SAClB,OAAO,CACP;;;oDAGiD,CACjD;SACA,OAAO,EAAE,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QAEzC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,SAAQ;QAC1C,MAAM,OAAO,GAAG,uBAAuB,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAA;QAE/D,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,SAAS,EAAE,CAAA;YAEX,SAAQ;QACT,CAAC;QAED,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,OAAwB,EAAE,GAAG,CAAC,SAA0B,CAAC,CAAA;QAC3F,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAE3B,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,KAAK,GAAG,EAAE,CAAA;YACV,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACvB,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,CAAC,CAAA;QAEjF,MAAM,EAAE,CAAA;IACT,CAAC;IAED,OAAO,IAAI,eAAe,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAA;AAC7E,CAAC"}
@@ -22,20 +22,22 @@
22
22
  * stored bbox and the locality query is point-in-bbox-filtered on the candidate centroid (the
23
23
  * `bbox` field on {@link FindPlaceQuery}).
24
24
  */
25
- import { DatabaseSync } from "node:sqlite";
26
25
  import { type Ancestor, type GazetteerArtifactCoverage } from "@mailwoman/resolver";
27
- import type { FindPlaceQuery, PlaceCandidate, PlaceLookup } from "./types.ts";
28
- export { rankByPrimaryPreference } from "./primary-preference.ts";
29
- export type { RankedRow } from "./primary-preference.ts";
26
+ import { DatabaseClient } from "@mailwoman/sqlite/client";
27
+ import type { PathBuilderLike } from "path-ts";
28
+ import type { CandidateDatabase } from "#candidate-schema";
29
+ import type { FindPlaceQuery, PlaceCandidate, PlaceLookup } from "#types";
30
+ export { rankByPrimaryPreference } from "#primary-preference";
31
+ export type { RankedRow } from "#primary-preference";
30
32
  export interface WOFCandidateTableLookupOpts {
31
33
  /**
32
34
  * Path to a `candidate.db` built by `build-candidate.ts`. Opened read-only.
33
35
  */
34
- databasePath?: string;
36
+ databasePath?: PathBuilderLike;
35
37
  /**
36
38
  * Pre-opened handle (tests / shared connections). Mutually exclusive with `databasePath`.
37
39
  */
38
- database?: DatabaseSync;
40
+ database?: DatabaseClient<CandidateDatabase>;
39
41
  /**
40
42
  * #1882 opt-in: exempt `name_role = 'variant'` aliases — the holder's own primary name in another orthography,
41
43
  * stamped by the build's own-name detector — from the cross-country primary-preference penalty. No-ops on an artifact
@@ -47,12 +49,12 @@ export interface WOFCandidateTableLookupOpts {
47
49
  * Node {@link PlaceLookup} over `candidate.db`. Drop-in for {@link WOFSQLitePlaceLookup} in `createWOFResolver(backend)`
48
50
  * — same `findPlace` contract, population-first ranking.
49
51
  */
50
- export declare class WOFCandidateTableLookup implements PlaceLookup {
52
+ export declare class WOFCandidateTableLookup implements PlaceLookup, Disposable {
51
53
  #private;
52
54
  /**
53
55
  * Facts this candidate DB declares about itself — the coverage manifest (`country_coverage` + `country_bbox`) the
54
56
  * gazetteer build emits, read once at open. `undefined` when the artifact predates the manifest, so every consumer
55
- * (the hard-country coverage gate, guard-B plausibility) falls back to its code constants byte-identically.
57
+ * (the hard-country coverage check, guard-B plausibility) falls back to its code constants byte-identically.
56
58
  */
57
59
  readonly artifactCoverage: GazetteerArtifactCoverage | undefined;
58
60
  /**
@@ -69,6 +71,6 @@ export declare class WOFCandidateTableLookup implements PlaceLookup {
69
71
  readonly ancestors: ((id: number | string) => Ancestor[]) | undefined;
70
72
  constructor(opts: WOFCandidateTableLookupOpts);
71
73
  findPlace(query: FindPlaceQuery): Promise<PlaceCandidate[]>;
72
- close(): void;
74
+ [Symbol.dispose](): void;
73
75
  }
74
76
  //# sourceMappingURL=candidate-lookup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"candidate-lookup.d.ts","sourceRoot":"","sources":["../candidate-lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG1C,OAAO,EAGN,KAAK,QAAQ,EACb,KAAK,yBAAyB,EAC9B,MAAM,qBAAqB,CAAA;AAoB5B,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAgB,MAAM,YAAY,CAAA;AAE3F,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACjE,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD,MAAM,WAAW,2BAA2B;IAC3C;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAiFD;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,WAAW;;IAyB1D;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,yBAAyB,GAAG,SAAS,CAAA;IAsChE;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAA;gBAEzD,IAAI,EAAE,2BAA2B;IAwVvC,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAgYjE,KAAK,IAAI,IAAI;CAKb"}
1
+ {"version":3,"file":"candidate-lookup.d.ts","sourceRoot":"","sources":["../lib/candidate-lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAGN,KAAK,QAAQ,EACb,KAAK,yBAAyB,EAC9B,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAU9C,OAAO,KAAK,EAAE,iBAAiB,EAAwD,MAAM,mBAAmB,CAAA;AAShH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAgB,MAAM,QAAQ,CAAA;AAEvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAEpD,MAAM,WAAW,2BAA2B;IAC3C;;OAEG;IACH,YAAY,CAAC,EAAE,eAAe,CAAA;IAC9B;;OAEG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAA;IAC5C;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAiFD;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,WAAW,EAAE,UAAU;;IA6BtE;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,yBAAyB,GAAG,SAAS,CAAA;IAsChE;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAA;gBAEzD,IAAI,EAAE,2BAA2B;IAsVvC,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAmYjE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAGxB"}
@@ -22,21 +22,21 @@
22
22
  * stored bbox and the locality query is point-in-bbox-filtered on the candidate centroid (the
23
23
  * `bbox` field on {@link FindPlaceQuery}).
24
24
  */
25
- import { DatabaseSync } from "node:sqlite";
26
25
  import { jaroWinkler, levenshteinSimilarity } from "@mailwoman/match/comparators";
27
26
  import { expandPlacetypeFilter, partitionByContainment, } from "@mailwoman/resolver";
28
27
  import { haversineKm } from "@mailwoman/spatial";
29
- import { CANDIDATE_ANCESTOR_TABLE, CANDIDATE_INTERVAL_TABLE, intervalContains, } from "./candidate-ancestors-schema.js";
30
- import { CANDIDATE_FTS_TABLE } from "./candidate-fts.js";
31
- import { readGazetteerCoverageManifest } from "./coverage-manifest-schema.js";
32
- import { referentialFromPopulation } from "./place-importance-schema.js";
33
- import { POSTAL_CITY_CANDIDATE_TABLE } from "./postal-city-candidate-schema.js";
34
- import { rankByPrimaryPreference, RERANK_FETCH } from "./primary-preference.js";
35
- import { applyProximityRerank } from "./proximity-rerank.js";
36
- import { REGION_CLASS_PLACETYPES, regionQualifierProbeKeys } from "./region-keys.js";
37
- import { allRows, hasColumn, hasTable } from "./sqlite-utils.js";
38
- import { normalizeLocalityForKey, stripLocalityQualifier } from "./street-normalize.js";
39
- export { rankByPrimaryPreference } from "./primary-preference.js";
28
+ import { DatabaseClient } from "@mailwoman/sqlite/client";
29
+ import { CANDIDATE_ANCESTOR_TABLE, CANDIDATE_INTERVAL_TABLE, intervalContains, } from "#candidate-ancestors-schema";
30
+ import { CANDIDATE_FTS_TABLE } from "#candidate-fts";
31
+ import { readGazetteerCoverageManifest } from "#coverage-manifest-schema";
32
+ import { referentialFromPopulation } from "#place-importance-schema";
33
+ import { POSTAL_CITY_CANDIDATE_TABLE } from "#postal/city-candidate-schema";
34
+ import { rankByPrimaryPreference, RERANK_FETCH } from "#primary-preference";
35
+ import { applyProximityRerank } from "#proximity-rerank";
36
+ import { REGION_CLASS_PLACETYPES, regionQualifierProbeKeys } from "#region-keys";
37
+ import { allRows, hasColumn, hasTable } from "#sqlite-utils";
38
+ import { normalizeLocalityForKey, stripLocalityQualifier } from "#street/normalize";
39
+ export { rankByPrimaryPreference } from "#primary-preference";
40
40
  /**
41
41
  * FTS5-trigram over-fetch before the WORD-LEVEL re-rank. The trigram index stays the candidate GENERATOR (it is what
42
42
  * the artifact carries); the scoring moved off trigram-Jaccard on 2026-08-12 (#1614), which the aucklnad receipts
@@ -60,12 +60,12 @@ function wordFuzzySimilarity(a, b) {
60
60
  return Math.max(jaroWinkler(a, b), levenshteinSimilarity(a, b));
61
61
  }
62
62
  /**
63
- * Postcode-containment re-rank gate radius (km) — the SAME value the resolver's country pass measures at
64
- * (`POSTCODE_COUNTRY_COHERENCE_GATE_KM`, resolver/postcode-country-coherence.ts): a locality within this distance of
65
- * the postcode's own centroid counts as "containing" it. One number, two passes — a divergence here would make the two
66
- * mechanisms disagree about what is proximal.
63
+ * Postcode-containment re-rank check radius (km) — the SAME value the resolver's country pass measures at
64
+ * (`POSTCODE_COUNTRY_COHERENCE_THRESHOLD_KM`, resolver/postcode-country-coherence.ts): a locality within this distance
65
+ * of the postcode's own centroid counts as "containing" it. One number, two passes — a divergence here would make the
66
+ * two mechanisms disagree about what is proximal.
67
67
  */
68
- const POSTCODE_CONTAINMENT_GATE_KM = 25;
68
+ const POSTCODE_CONTAINMENT_THRESHOLD_KM = 25;
69
69
  /**
70
70
  * Unpadded character-trigrams of `s`, OR'd into an FTS5 trigram MATCH query (each quoted so FTS treats it as a literal
71
71
  * term). Returns "" when `s` is shorter than a trigram or yields no clean grams — the caller then skips the fuzzy
@@ -87,7 +87,11 @@ function ftsTrigramQuery(s) {
87
87
  */
88
88
  export class WOFCandidateTableLookup {
89
89
  #db;
90
- #ownsDB;
90
+ /**
91
+ * Resources this instance opened. A connection handed in by a caller is NOT in here, so disposal cannot reach it —
92
+ * ownership is membership rather than a flag a later branch has to check.
93
+ */
94
+ #resources = new DisposableStack();
91
95
  #countryToID = new Map();
92
96
  #idToCountry = new Map();
93
97
  #placetypeToID = new Map();
@@ -103,22 +107,22 @@ export class WOFCandidateTableLookup {
103
107
  */
104
108
  #ftsProbe;
105
109
  /**
106
- * Prepared UNFILTERED existence probe (`name_key` present anywhere, ignoring country/placetype/bbox). Gates the fuzzy
107
- * fallback: fuzzy is a TYPO corrector, so it engages only when the name doesn't exist in the gazetteer at all. A name
108
- * that DOES exist but missed under the active filter is a filter miss (e.g. a placer misroute "Vienna, Austria"→IT),
109
- * not a spelling miss — fuzzing it would scrape an unrelated same-country place and defeat the cascade's
110
- * country-agnostic retry. Prepared only alongside `#ftsProbe`.
110
+ * Prepared UNFILTERED existence probe (`name_key` present anywhere, ignoring country/placetype/bbox). Checks the
111
+ * fuzzy fallback: fuzzy is a TYPO corrector, so it engages only when the name doesn't exist in the gazetteer at all.
112
+ * A name that DOES exist but missed under the active filter is a filter miss (e.g. a placer misroute "Vienna,
113
+ * Austria"→IT), not a spelling miss — fuzzing it would scrape an unrelated same-country place and defeat the
114
+ * cascade's country-agnostic retry. Prepared only alongside `#ftsProbe`.
111
115
  */
112
116
  #nameKeyExistsProbe;
113
117
  /**
114
118
  * Facts this candidate DB declares about itself — the coverage manifest (`country_coverage` + `country_bbox`) the
115
119
  * gazetteer build emits, read once at open. `undefined` when the artifact predates the manifest, so every consumer
116
- * (the hard-country coverage gate, guard-B plausibility) falls back to its code constants byte-identically.
120
+ * (the hard-country coverage check, guard-B plausibility) falls back to its code constants byte-identically.
117
121
  */
118
122
  artifactCoverage;
119
123
  /**
120
124
  * `", importance"` when this artifact carries the #28 fame column, `""` when it does not — spliced into the probe's
121
- * SELECT list. Existence-gated exactly like `#ftsProbe` and `#postalCityProbe` above, and for the same reason: a
125
+ * SELECT list. Existence-restricted exactly like `#ftsProbe` and `#postalCityProbe` above, and for the same reason: a
122
126
  * candidate.db built before the column is a valid artifact, and naming a column it lacks would turn a stale gazetteer
123
127
  * into `no such column` on the first keystroke rather than into "no fame signal", which is what it is.
124
128
  */
@@ -141,9 +145,9 @@ export class WOFCandidateTableLookup {
141
145
  #ancestorsCache = new Map();
142
146
  /**
143
147
  * Prepared interval-label probe over `candidate_interval` — `undefined` when the artifact predates the sidecar, which
144
- * is what makes the admin-containment re-rank (#1717 stage 2) capability-gated: without it,
148
+ * is what makes the admin-containment re-rank (#1717 stage 2) capability-restricted: without it,
145
149
  * `FindPlaceQuery.regionQualifier` is ignored, no candidate carries a `containedByQualifier` stamp, and the resolver
146
- * walk reports the lever `unavailable` instead of silently dead.
150
+ * walk reports the change `unavailable` instead of silently dead.
147
151
  */
148
152
  #intervalProbe;
149
153
  #intervalCache = new Map();
@@ -168,11 +172,9 @@ export class WOFCandidateTableLookup {
168
172
  constructor(opts) {
169
173
  if (opts.database) {
170
174
  this.#db = opts.database;
171
- this.#ownsDB = false;
172
175
  }
173
176
  else if (opts.databasePath) {
174
- this.#db = new DatabaseSync(opts.databasePath, { readOnly: true });
175
- this.#ownsDB = true;
177
+ this.#db = this.#resources.use(new DatabaseClient(opts.databasePath, { readOnly: true }));
176
178
  }
177
179
  else {
178
180
  throw new Error("WOFCandidateTableLookup needs `databasePath` or `database`");
@@ -204,7 +206,7 @@ export class WOFCandidateTableLookup {
204
206
  this.#hasNameRole = hasColumn(this.#db, "candidate", "name_role");
205
207
  this.#variantAliasExemption = opts.variantAliasExemption === true;
206
208
  this.#roleSelect = this.#hasNameRole ? ", name_role" : "";
207
- // Ancestors sidecar (#1717): existence-gated like the probes above, and the CAPABILITY gates with
209
+ // Ancestors sidecar (#1717): existence-restricted like the probes above, and the CAPABILITY checks with
208
210
  // it — see the `ancestors` property doc for why an older artifact must read as "no ancestors()"
209
211
  // rather than as a method that answers [] everywhere.
210
212
  if (hasTable(this.#db, CANDIDATE_ANCESTOR_TABLE)) {
@@ -212,7 +214,7 @@ export class WOFCandidateTableLookup {
212
214
  " WHERE spr_id = ? ORDER BY depth ASC");
213
215
  this.ancestors = (id) => this.#ancestorLineage(id);
214
216
  }
215
- // Admin-containment re-rank (#1717 stage 2): gated on the interval half of the sidecar (built in
217
+ // Admin-containment re-rank (#1717 stage 2): conditioned on the interval half of the sidecar (built in
216
218
  // the same pass as the closure rows; probed separately so a hand-degraded artifact degrades
217
219
  // truthfully) AND on the placetype dictionary carrying the qualifier band at all.
218
220
  if (this.#ancestorsProbe && hasTable(this.#db, CANDIDATE_INTERVAL_TABLE)) {
@@ -224,7 +226,7 @@ export class WOFCandidateTableLookup {
224
226
  this.#qualifierProbe = this.#db.prepare(`SELECT DISTINCT spr_id FROM candidate WHERE name_key = ? AND placetype_id IN (${bandIDs.join(",")}) LIMIT 8`);
225
227
  }
226
228
  }
227
- // Coverage manifest (survey candidate #2): the artifact's own coverage facts, existence-gated like
229
+ // Coverage manifest (survey candidate #2): the artifact's own coverage facts, existence-restricted like
228
230
  // the probes above — a candidate.db built before the manifest reads `undefined` and consumers keep
229
231
  // their code-constant fallbacks byte-identically.
230
232
  this.artifactCoverage = readGazetteerCoverageManifest(this.#db);
@@ -289,7 +291,7 @@ export class WOFCandidateTableLookup {
289
291
  * Is `sprID` contained by ANY of the qualifier's rows? Interval first — {@link intervalContains}, O(1), reflexive —
290
292
  * then the closure rows where intervals abstain: the interval forest encodes only the CANONICAL parent per place, so
291
293
  * a `false` there means "not contained along the canonical hierarchy", and the chain probe (one clustered read of
292
- * ≤{@link MAX_ANCESTOR_DEPTH} rows) is the complete record that settles it.
294
+ * ≤{@link MAX_ANCESTOR_DEPTH} rows) is the complete record that determines the result.
293
295
  */
294
296
  #containedByQualifier(sprID, qualifierIDs, qualifierLabels) {
295
297
  if (qualifierIDs.has(sprID))
@@ -353,7 +355,7 @@ export class WOFCandidateTableLookup {
353
355
  // cannot reach a neighbourhood-tier namesake, so a CONTAINED one is structurally invisible no matter
354
356
  // how the list reorders — the Astoria class: Queens' Astoria is a WOF neighbourhood, and the walk
355
357
  // answered the Oregon locality under `qualifier="NY"` because nothing in the pool sat under NY. The
356
- // widening is injection-only and triple-gated: the band is explicit (neighbourhood/macrohood/microhood
358
+ // widening is injection-only and triple-conditioned: the band is explicit (neighbourhood/macrohood/microhood
357
359
  // — never region or country tiers), admission still requires the sidecar's containment proof, and only
358
360
  // primary-keyed rows enter (an alias-keyed neighbourhood is the #1626 scrape class). Recall can only
359
361
  // widen, and only toward rows the qualifier vouches for. `opts.shapeFilters`' bbox clause is
@@ -439,7 +441,7 @@ export class WOFCandidateTableLookup {
439
441
  return [];
440
442
  // #741: postcode-keyed postal-city alias. An exact `(name_key, postcode)` hit resolves a
441
443
  // user-typed POSTAL city ("Antioch", 37013) to the geographic locality the postcode sits in
442
- // ("Nashville"), bypassing the population/region ranking that can't see the postcode. Gated on
444
+ // ("Nashville"), bypassing the population/region ranking that can't see the postcode. Conditioned on
443
445
  // the side-index being present, a postcode in the query, and a locality-tier request — so the
444
446
  // common (no-postcode / non-locality) path is untouched. A hit short-circuits: the postcode is
445
447
  // an exact, high-confidence disambiguator, so we return the single geographic locality.
@@ -465,7 +467,7 @@ export class WOFCandidateTableLookup {
465
467
  // SHAPE subset (placetype/bbox/primary — everything but the country scope) is kept separately
466
468
  // because the admin-containment injection probe (#1717 stage 2) runs under the shape conds
467
469
  // WITHOUT the country: bypassing a locale-inferred country scope for a qualifier-vouched
468
- // candidate is the lever's whole point, and it is the one filter injection may cross.
470
+ // candidate is the change's whole point and the one filter injection may cross.
469
471
  const filters = [];
470
472
  const filterParams = [];
471
473
  const shapeFilters = [];
@@ -495,7 +497,7 @@ export class WOFCandidateTableLookup {
495
497
  shapeParams.push(b.minLat, b.maxLat, b.minLon, b.maxLon);
496
498
  }
497
499
  // The re-reading guard (#1632, the #1626 rationale generalized to the caller): a probe whose surface
498
- // is a token cut out of a longer classified span never NAMED an alias, so alias-keyed rows must not
500
+ // is a token taken out of a longer classified span never NAMED an alias, so alias-keyed rows must not
499
501
  // answer it — 'Savile Row''s token 'Row' resolved Rhu, Scotland (585 km) through the village's
500
502
  // historical-name alias key. Whole-input bare probes never set this, keeping the exonym recall the
501
503
  // #1546 note protects (Москва's alias rows answer 'Moscow').
@@ -577,7 +579,7 @@ export class WOFCandidateTableLookup {
577
579
  // the same on either backend. The country/placetype/bbox/region filters still apply via `probe`.
578
580
  // Skipped when the index is absent (byte-stable for an older candidate.db).
579
581
  //
580
- // Gate: only when the name doesn't exist in the gazetteer AT ALL (unfiltered). A name that exists
582
+ // Condition: only when the name doesn't exist in the gazetteer AT ALL (unfiltered). A name that exists
581
583
  // but missed under the active country/placetype/bbox filter is a FILTER miss, not a spelling miss
582
584
  // — fuzzing it scrapes an unrelated same-filter place ("Vienna, Austria" misrouted to IT would
583
585
  // pull a tiny Italian name_key near Siena) and masks the cascade's country-agnostic retry that
@@ -624,7 +626,7 @@ export class WOFCandidateTableLookup {
624
626
  };
625
627
  let rows = cascade(regionParentID);
626
628
  // #1731: whether the rows the caller receives came from the UNSCOPED fallback below — the backend's
627
- // interior gate the resolver-side trace (#1721) cannot otherwise see. Stamped onto every returned
629
+ // interior check the resolver-side trace (#1721) cannot otherwise see. Stamped onto every returned
628
630
  // place, because the re-admission path is exactly where a wrong-instance namesake enters.
629
631
  let regionScopeMiss = false;
630
632
  // Region-scope fallback: if scoping to the parent region found nothing across the whole cascade, retry
@@ -639,8 +641,8 @@ export class WOFCandidateTableLookup {
639
641
  // holds 75001, not the one that holds a 75001-free namesake). The resolver sends this flag on locality
640
642
  // lookups when `ResolveOpts.postcodeContainmentCoherence` is on. Strictly beneath the #741 postal-city
641
643
  // short-circuit above — an exact (name, postcode) hit IS the answer and outranks any re-rank — and after
642
- // the region-scope fallback, so it sees the final row set. Rows within the gate sort by distance first;
643
- // the out-gate tail keeps its original population-first order. No in-gate row, or no postcode row in
644
+ // the region-scope fallback, so it sees the final row set. Rows within the radius sort by distance first;
645
+ // the out-of-radius tail keeps its original population-first order. No in-radius row, or no postcode row in
644
646
  // the candidate table → unchanged (byte-identical to the flag-off path).
645
647
  if (query.postcode &&
646
648
  query.postcodeContainmentCoherence === true &&
@@ -648,29 +650,29 @@ export class WOFCandidateTableLookup {
648
650
  rows.length > 1) {
649
651
  const anchor = this.#postcodeAnchor(query.postcode, query.country);
650
652
  if (anchor) {
651
- const inGate = [];
652
- const outGate = [];
653
+ const insideThreshold = [];
654
+ const outsideThreshold = [];
653
655
  for (const row of rows) {
654
656
  const distanceKm = haversineKm(anchor.lat, anchor.lon, Number(row.latitude), Number(row.longitude));
655
- if (distanceKm <= POSTCODE_CONTAINMENT_GATE_KM) {
656
- inGate.push({ row, distanceKm });
657
+ if (distanceKm <= POSTCODE_CONTAINMENT_THRESHOLD_KM) {
658
+ insideThreshold.push({ row, distanceKm });
657
659
  }
658
660
  else {
659
- outGate.push(row);
661
+ outsideThreshold.push(row);
660
662
  }
661
663
  }
662
- if (inGate.length) {
664
+ if (insideThreshold.length) {
663
665
  // oxlint-disable-next-line unicorn/no-array-sort -- sorts a freshly-built array; toSorted would double-allocate on a hot path
664
- inGate.sort((a, b) => a.distanceKm - b.distanceKm);
665
- rows = [...inGate.map(({ row }) => row), ...outGate];
666
+ insideThreshold.sort((a, b) => a.distanceKm - b.distanceKm);
667
+ rows = [...insideThreshold.map(({ row }) => row), ...outsideThreshold];
666
668
  }
667
669
  }
668
670
  }
669
671
  // Admin-containment re-rank (#1717 stage 2): LAST, on the final row set — the qualifier is the
670
672
  // address's outermost explicit statement, so its partition outranks the postcode-proximity order
671
- // above (contained rows keep that order among themselves). Capability-gated on the sidecar
673
+ // above (contained rows keep that order among themselves). Capability-conditioned on the sidecar
672
674
  // (`#qualifierProbe`); when the artifact predates it, `regionQualifier` is ignored, no stamp is
673
- // written, and the resolver walk reports the lever `unavailable`.
675
+ // written, and the resolver walk reports the change `unavailable`.
674
676
  if (query.regionQualifier?.trim() && this.#qualifierProbe && this.#wantsLocality(query.placetype)) {
675
677
  rows = this.#applyAdminContainment(rows, query.regionQualifier.trim(), query.country, {
676
678
  nameKey,
@@ -686,13 +688,13 @@ export class WOFCandidateTableLookup {
686
688
  id: Number(row.spr_id),
687
689
  name: String(row.name ?? ""),
688
690
  placetype: (this.#idToPlacetype.get(Number(row.placetype_id)) ?? ""),
689
- // Surfaced so the cascade can country-gate a postcode by the resolved locality (an ambiguous
691
+ // Surfaced so the cascade can country-restrict a postcode by the resolved locality (an ambiguous
690
692
  // international postcode like 10115 = Berlin DE AND New York US must not out-resolve the city).
691
693
  country: this.#idToCountry.get(Number(row.country_id)) ?? "",
692
694
  lat: Number(row.latitude),
693
695
  lon: Number(row.longitude),
694
696
  // `score` stays the RAW population rank (`-neg_rank`) — it feeds the resolver walk's absolute
695
- // `minWinningScore` gate (`resolve.ts`), which must see real prominence, never a penalized value.
697
+ // `minWinningScore` floor (`resolve.ts`), which must see real prominence, never a penalized value.
696
698
  score: -Number(row.neg_rank),
697
699
  // `prominence` carries the bounded cross-country primary preference (the effective, penalty-adjusted
698
700
  // rank). The walk ORDERS candidates by `prominence ?? score` (`resolve.ts`), so this is what makes the
@@ -714,6 +716,9 @@ export class WOFCandidateTableLookup {
714
716
  // asked (a `regionQualifier` query over a sidecar-bearing artifact); its absence is what
715
717
  // the resolver walk reports as `unavailable` (meaning-of-zero).
716
718
  ...(row.containedByQualifier === undefined ? {} : { containedByQualifier: row.containedByQualifier }),
719
+ // #1893 — the exemption's firing mark, carried only when the ranker actually spared this row
720
+ // the cross-country penalty (see RankedRow.variantExempted).
721
+ ...(row.variantExempted ? { variantAliasExempted: true } : {}),
717
722
  // The two-score split's carry (ROAD_TO_V9 §2). `referential` names the prominence this
718
723
  // backend has always ordered by — `neg_rank` IS `-log10(population + 1)`, so the score and
719
724
  // the sort key are two readings of the same number.
@@ -755,10 +760,8 @@ export class WOFCandidateTableLookup {
755
760
  }
756
761
  return candidates;
757
762
  }
758
- close() {
759
- if (this.#ownsDB) {
760
- this.#db.close();
761
- }
763
+ [Symbol.dispose]() {
764
+ this.#resources[Symbol.dispose]();
762
765
  }
763
766
  }
764
767
  //# sourceMappingURL=candidate-lookup.js.map