@mailwoman/resolver-wof-sqlite 10.0.0 → 10.2.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 (477) hide show
  1. package/README.md +9 -8
  2. package/lib/address/point/interpolation.ts +45 -39
  3. package/lib/address/point/schema.ts +17 -40
  4. package/lib/address/point.ts +316 -0
  5. package/lib/{address/index.ts → address.ts} +1 -1
  6. package/lib/ancestry/backfill.ts +20 -86
  7. package/lib/{ancestry/index.ts → ancestry.ts} +19 -15
  8. package/lib/build/candidate.ts +122 -174
  9. package/lib/build/population-corrections.ts +64 -0
  10. package/lib/build/slim.ts +44 -114
  11. package/lib/candidate/alias-bags.ts +16 -17
  12. package/lib/candidate/ancestors/schema.ts +77 -61
  13. package/lib/candidate/ancestors/sidecar.ts +15 -22
  14. package/lib/candidate/country-display-names.ts +6 -20
  15. package/lib/candidate/extract-fold.ts +10 -55
  16. package/lib/candidate/fts.ts +5 -23
  17. package/lib/candidate/importance.ts +65 -68
  18. package/lib/candidate/lookup.ts +124 -415
  19. package/lib/candidate/name-roles.ts +15 -33
  20. package/lib/candidate/own-name.ts +35 -32
  21. package/lib/candidate/place-attrs.ts +20 -13
  22. package/lib/candidate/schema.ts +29 -65
  23. package/lib/candidate/scoring.ts +54 -93
  24. package/lib/capital-schema.ts +21 -17
  25. package/lib/capitals.ts +29 -27
  26. package/lib/coincident-roles.ts +85 -55
  27. package/lib/convention/schema.ts +15 -16
  28. package/lib/convention.ts +144 -0
  29. package/lib/coverage-manifest-schema.ts +40 -45
  30. package/lib/currency-backfill.ts +34 -79
  31. package/lib/env.ts +1 -1
  32. package/lib/exact-match.ts +32 -21
  33. package/lib/extracts.ts +97 -74
  34. package/lib/fst/autocomplete.ts +54 -37
  35. package/lib/fst/builder.ts +37 -41
  36. package/lib/fst/deserialize-web.ts +16 -17
  37. package/lib/fst/format.ts +41 -23
  38. package/lib/fst/freshness.ts +43 -120
  39. package/lib/fst/matcher.ts +7 -5
  40. package/lib/fst/serialize.ts +54 -74
  41. package/lib/fst/types.ts +78 -75
  42. package/lib/{fst/index.ts → fst.ts} +1 -0
  43. package/lib/fts/query.ts +5 -36
  44. package/lib/fts.ts +280 -0
  45. package/lib/geonames/aliases.ts +73 -144
  46. package/lib/geonames/postal.ts +162 -71
  47. package/lib/index.ts +9 -8
  48. package/lib/interpolation.ts +48 -100
  49. package/lib/lookup.ts +155 -270
  50. package/lib/name-score.ts +9 -7
  51. package/lib/nsul/lookup.ts +37 -54
  52. package/lib/nsul/schema.ts +16 -43
  53. package/lib/paths.ts +159 -0
  54. package/lib/place-importance-schema.ts +62 -169
  55. package/lib/poi/lookup.ts +104 -121
  56. package/lib/poi/schema.ts +42 -26
  57. package/lib/polygon-schema.ts +10 -6
  58. package/lib/postal/city/alias/lookup.ts +22 -40
  59. package/lib/postal/city/alias/schema.ts +14 -10
  60. package/lib/postal/city/candidate-schema.ts +26 -20
  61. package/lib/postcode-point-lookup.ts +8 -27
  62. package/lib/primary-preference.ts +46 -126
  63. package/lib/proximity-rerank.ts +44 -33
  64. package/lib/ranking-weights.ts +105 -78
  65. package/lib/region-keys.ts +70 -42
  66. package/lib/reverse.ts +149 -86
  67. package/lib/schema.ts +73 -50
  68. package/lib/search-fetch.ts +90 -68
  69. package/lib/sqlite/convention-source.ts +15 -23
  70. package/lib/sqlite/utils.ts +19 -22
  71. package/lib/street/centroid/schema.ts +37 -42
  72. package/lib/street/{centroid/index.ts → centroid.ts} +16 -25
  73. package/lib/street/morphology/fst/builder.ts +60 -42
  74. package/lib/street/morphology/fst/loader.ts +40 -32
  75. package/lib/street/name-lookup.ts +45 -41
  76. package/lib/street/normalize.ts +88 -219
  77. package/lib/street/segment-schema.ts +116 -43
  78. package/lib/{street/index.ts → street.ts} +1 -1
  79. package/lib/types.ts +109 -150
  80. package/lib/unified-schema.ts +29 -29
  81. package/lib/uprn/existence.ts +30 -19
  82. package/lib/uprn/lookup.ts +29 -68
  83. package/lib/uprn/schema.ts +18 -40
  84. package/lib/weights-overlay-linker.ts +236 -252
  85. package/out/address/point/interpolation.d.ts +20 -23
  86. package/out/address/point/interpolation.d.ts.map +1 -1
  87. package/out/address/point/interpolation.js +42 -39
  88. package/out/address/point/interpolation.js.map +1 -1
  89. package/out/address/point/schema.d.ts +12 -35
  90. package/out/address/point/schema.d.ts.map +1 -1
  91. package/out/address/point/schema.js +3 -19
  92. package/out/address/point/schema.js.map +1 -1
  93. package/out/address/point.d.ts +57 -0
  94. package/out/address/point.d.ts.map +1 -0
  95. package/out/address/point.js +206 -0
  96. package/out/address/point.js.map +1 -0
  97. package/out/{address/index.js → address.d.ts} +2 -2
  98. package/out/address.d.ts.map +1 -0
  99. package/out/{address/index.d.ts → address.js} +2 -2
  100. package/out/address.js.map +1 -0
  101. package/out/ancestry/backfill.d.ts +11 -64
  102. package/out/ancestry/backfill.d.ts.map +1 -1
  103. package/out/ancestry/backfill.js +14 -74
  104. package/out/ancestry/backfill.js.map +1 -1
  105. package/out/ancestry.d.ts +49 -0
  106. package/out/ancestry.d.ts.map +1 -0
  107. package/out/ancestry.js +59 -0
  108. package/out/ancestry.js.map +1 -0
  109. package/out/build/candidate.d.ts +82 -112
  110. package/out/build/candidate.d.ts.map +1 -1
  111. package/out/build/candidate.js +17 -100
  112. package/out/build/candidate.js.map +1 -1
  113. package/out/build/population-corrections.d.ts +52 -0
  114. package/out/build/population-corrections.d.ts.map +1 -0
  115. package/out/build/population-corrections.js +40 -0
  116. package/out/build/population-corrections.js.map +1 -0
  117. package/out/build/slim.d.ts +8 -44
  118. package/out/build/slim.d.ts.map +1 -1
  119. package/out/build/slim.js +33 -94
  120. package/out/build/slim.js.map +1 -1
  121. package/out/candidate/alias-bags.d.ts +6 -6
  122. package/out/candidate/alias-bags.d.ts.map +1 -1
  123. package/out/candidate/alias-bags.js +16 -17
  124. package/out/candidate/alias-bags.js.map +1 -1
  125. package/out/candidate/ancestors/schema.d.ts +73 -57
  126. package/out/candidate/ancestors/schema.d.ts.map +1 -1
  127. package/out/candidate/ancestors/schema.js +56 -48
  128. package/out/candidate/ancestors/schema.js.map +1 -1
  129. package/out/candidate/ancestors/sidecar.d.ts +3 -8
  130. package/out/candidate/ancestors/sidecar.d.ts.map +1 -1
  131. package/out/candidate/ancestors/sidecar.js +15 -22
  132. package/out/candidate/ancestors/sidecar.js.map +1 -1
  133. package/out/candidate/country-display-names.d.ts +5 -15
  134. package/out/candidate/country-display-names.d.ts.map +1 -1
  135. package/out/candidate/country-display-names.js +6 -20
  136. package/out/candidate/country-display-names.js.map +1 -1
  137. package/out/candidate/extract-fold.d.ts +7 -15
  138. package/out/candidate/extract-fold.d.ts.map +1 -1
  139. package/out/candidate/extract-fold.js +5 -47
  140. package/out/candidate/extract-fold.js.map +1 -1
  141. package/out/candidate/fts.d.ts +5 -23
  142. package/out/candidate/fts.d.ts.map +1 -1
  143. package/out/candidate/fts.js +5 -23
  144. package/out/candidate/fts.js.map +1 -1
  145. package/out/candidate/importance.d.ts +60 -65
  146. package/out/candidate/importance.d.ts.map +1 -1
  147. package/out/candidate/importance.js +56 -63
  148. package/out/candidate/importance.js.map +1 -1
  149. package/out/candidate/lookup.d.ts +18 -55
  150. package/out/candidate/lookup.d.ts.map +1 -1
  151. package/out/candidate/lookup.js +82 -385
  152. package/out/candidate/lookup.js.map +1 -1
  153. package/out/candidate/name-roles.d.ts +9 -21
  154. package/out/candidate/name-roles.d.ts.map +1 -1
  155. package/out/candidate/name-roles.js +15 -33
  156. package/out/candidate/name-roles.js.map +1 -1
  157. package/out/candidate/own-name.d.ts +23 -25
  158. package/out/candidate/own-name.d.ts.map +1 -1
  159. package/out/candidate/own-name.js +35 -32
  160. package/out/candidate/own-name.js.map +1 -1
  161. package/out/candidate/place-attrs.d.ts +20 -13
  162. package/out/candidate/place-attrs.d.ts.map +1 -1
  163. package/out/candidate/place-attrs.js +4 -5
  164. package/out/candidate/place-attrs.js.map +1 -1
  165. package/out/candidate/schema.d.ts +27 -62
  166. package/out/candidate/schema.d.ts.map +1 -1
  167. package/out/candidate/schema.js +10 -22
  168. package/out/candidate/schema.js.map +1 -1
  169. package/out/candidate/scoring.d.ts +7 -8
  170. package/out/candidate/scoring.d.ts.map +1 -1
  171. package/out/candidate/scoring.js +52 -89
  172. package/out/candidate/scoring.js.map +1 -1
  173. package/out/capital-schema.d.ts +21 -17
  174. package/out/capital-schema.d.ts.map +1 -1
  175. package/out/capital-schema.js +17 -15
  176. package/out/capital-schema.js.map +1 -1
  177. package/out/capitals.d.ts +27 -25
  178. package/out/capitals.d.ts.map +1 -1
  179. package/out/capitals.js +23 -21
  180. package/out/capitals.js.map +1 -1
  181. package/out/coincident-roles.d.ts +60 -43
  182. package/out/coincident-roles.d.ts.map +1 -1
  183. package/out/coincident-roles.js +72 -50
  184. package/out/coincident-roles.js.map +1 -1
  185. package/out/convention/schema.d.ts +14 -14
  186. package/out/convention/schema.d.ts.map +1 -1
  187. package/out/convention/schema.js +6 -4
  188. package/out/convention/schema.js.map +1 -1
  189. package/out/convention.d.ts +97 -0
  190. package/out/convention.d.ts.map +1 -0
  191. package/out/convention.js +81 -0
  192. package/out/convention.js.map +1 -0
  193. package/out/coverage-manifest-schema.d.ts +34 -39
  194. package/out/coverage-manifest-schema.d.ts.map +1 -1
  195. package/out/coverage-manifest-schema.js +25 -34
  196. package/out/coverage-manifest-schema.js.map +1 -1
  197. package/out/currency-backfill.d.ts +16 -38
  198. package/out/currency-backfill.d.ts.map +1 -1
  199. package/out/currency-backfill.js +19 -46
  200. package/out/currency-backfill.js.map +1 -1
  201. package/out/env.d.ts +1 -1
  202. package/out/env.js +1 -1
  203. package/out/exact-match.d.ts +19 -10
  204. package/out/exact-match.d.ts.map +1 -1
  205. package/out/exact-match.js +32 -21
  206. package/out/exact-match.js.map +1 -1
  207. package/out/extracts.d.ts +66 -55
  208. package/out/extracts.d.ts.map +1 -1
  209. package/out/extracts.js +63 -55
  210. package/out/extracts.js.map +1 -1
  211. package/out/fst/autocomplete.d.ts +29 -21
  212. package/out/fst/autocomplete.d.ts.map +1 -1
  213. package/out/fst/autocomplete.js +39 -28
  214. package/out/fst/autocomplete.js.map +1 -1
  215. package/out/fst/builder.d.ts.map +1 -1
  216. package/out/fst/builder.js +37 -41
  217. package/out/fst/builder.js.map +1 -1
  218. package/out/fst/deserialize-web.d.ts +4 -4
  219. package/out/fst/deserialize-web.d.ts.map +1 -1
  220. package/out/fst/deserialize-web.js +15 -16
  221. package/out/fst/deserialize-web.js.map +1 -1
  222. package/out/fst/format.d.ts +41 -23
  223. package/out/fst/format.d.ts.map +1 -1
  224. package/out/fst/format.js +41 -23
  225. package/out/fst/format.js.map +1 -1
  226. package/out/fst/freshness.d.ts +19 -81
  227. package/out/fst/freshness.d.ts.map +1 -1
  228. package/out/fst/freshness.js +31 -94
  229. package/out/fst/freshness.js.map +1 -1
  230. package/out/fst/matcher.d.ts +5 -4
  231. package/out/fst/matcher.d.ts.map +1 -1
  232. package/out/fst/matcher.js +2 -2
  233. package/out/fst/matcher.js.map +1 -1
  234. package/out/fst/serialize.d.ts +28 -28
  235. package/out/fst/serialize.d.ts.map +1 -1
  236. package/out/fst/serialize.js +53 -71
  237. package/out/fst/serialize.js.map +1 -1
  238. package/out/fst/types.d.ts +78 -74
  239. package/out/fst/types.d.ts.map +1 -1
  240. package/out/fst/types.js +1 -4
  241. package/out/fst/types.js.map +1 -1
  242. package/out/{fst/index.js → fst.d.ts} +2 -1
  243. package/out/fst.d.ts.map +1 -0
  244. package/out/{fst/index.d.ts → fst.js} +2 -1
  245. package/out/fst.js.map +1 -0
  246. package/out/fts/query.d.ts +2 -27
  247. package/out/fts/query.d.ts.map +1 -1
  248. package/out/fts/query.js +5 -36
  249. package/out/fts/query.js.map +1 -1
  250. package/out/fts.d.ts +126 -0
  251. package/out/fts.d.ts.map +1 -0
  252. package/out/fts.js +188 -0
  253. package/out/fts.js.map +1 -0
  254. package/out/geonames/aliases.d.ts +26 -62
  255. package/out/geonames/aliases.d.ts.map +1 -1
  256. package/out/geonames/aliases.js +45 -117
  257. package/out/geonames/aliases.js.map +1 -1
  258. package/out/geonames/postal.d.ts +84 -44
  259. package/out/geonames/postal.d.ts.map +1 -1
  260. package/out/geonames/postal.js +115 -73
  261. package/out/geonames/postal.js.map +1 -1
  262. package/out/{geonames/index.js → geonames.d.ts} +1 -1
  263. package/out/geonames.d.ts.map +1 -0
  264. package/out/{geonames/index.d.ts → geonames.js} +1 -1
  265. package/out/geonames.js.map +1 -0
  266. package/out/index.d.ts +9 -8
  267. package/out/index.d.ts.map +1 -1
  268. package/out/index.js +6 -5
  269. package/out/index.js.map +1 -1
  270. package/out/interpolation.d.ts +18 -55
  271. package/out/interpolation.d.ts.map +1 -1
  272. package/out/interpolation.js +27 -69
  273. package/out/interpolation.js.map +1 -1
  274. package/out/lookup.d.ts +23 -51
  275. package/out/lookup.d.ts.map +1 -1
  276. package/out/lookup.js +136 -234
  277. package/out/lookup.js.map +1 -1
  278. package/out/name-score.d.ts +2 -2
  279. package/out/name-score.d.ts.map +1 -1
  280. package/out/name-score.js +9 -7
  281. package/out/name-score.js.map +1 -1
  282. package/out/nsul/lookup.d.ts +33 -34
  283. package/out/nsul/lookup.d.ts.map +1 -1
  284. package/out/nsul/lookup.js +26 -40
  285. package/out/nsul/lookup.js.map +1 -1
  286. package/out/nsul/schema.d.ts +16 -43
  287. package/out/nsul/schema.d.ts.map +1 -1
  288. package/out/nsul/schema.js +9 -35
  289. package/out/nsul/schema.js.map +1 -1
  290. package/out/{nsul/index.d.ts → nsul.d.ts} +1 -1
  291. package/out/nsul.d.ts.map +1 -0
  292. package/out/{nsul/index.js → nsul.js} +1 -1
  293. package/out/nsul.js.map +1 -0
  294. package/out/paths.d.ts +124 -0
  295. package/out/paths.d.ts.map +1 -0
  296. package/out/paths.js +104 -0
  297. package/out/paths.js.map +1 -0
  298. package/out/place-importance-schema.d.ts +51 -143
  299. package/out/place-importance-schema.d.ts.map +1 -1
  300. package/out/place-importance-schema.js +28 -143
  301. package/out/place-importance-schema.js.map +1 -1
  302. package/out/poi/lookup.d.ts +40 -47
  303. package/out/poi/lookup.d.ts.map +1 -1
  304. package/out/poi/lookup.js +69 -96
  305. package/out/poi/lookup.js.map +1 -1
  306. package/out/poi/schema.d.ts +41 -25
  307. package/out/poi/schema.d.ts.map +1 -1
  308. package/out/poi/schema.js +25 -17
  309. package/out/poi/schema.js.map +1 -1
  310. package/out/{poi/index.js → poi.d.ts} +1 -1
  311. package/out/poi.d.ts.map +1 -0
  312. package/out/{poi/index.d.ts → poi.js} +1 -1
  313. package/out/poi.js.map +1 -0
  314. package/out/polygon-schema.d.ts +10 -6
  315. package/out/polygon-schema.d.ts.map +1 -1
  316. package/out/polygon-schema.js +2 -2
  317. package/out/polygon-schema.js.map +1 -1
  318. package/out/postal/city/alias/lookup.d.ts +20 -23
  319. package/out/postal/city/alias/lookup.d.ts.map +1 -1
  320. package/out/postal/city/alias/lookup.js +17 -30
  321. package/out/postal/city/alias/lookup.js.map +1 -1
  322. package/out/postal/city/alias/schema.d.ts +14 -10
  323. package/out/postal/city/alias/schema.d.ts.map +1 -1
  324. package/out/postal/city/alias/schema.js +10 -8
  325. package/out/postal/city/alias/schema.js.map +1 -1
  326. package/out/postal/city/candidate-schema.d.ts +25 -19
  327. package/out/postal/city/candidate-schema.d.ts.map +1 -1
  328. package/out/postal/city/candidate-schema.js +21 -17
  329. package/out/postal/city/candidate-schema.js.map +1 -1
  330. package/out/{postal/index.d.ts → postal.d.ts} +1 -1
  331. package/out/postal.d.ts.map +1 -0
  332. package/out/{postal/index.js → postal.js} +1 -1
  333. package/out/postal.js.map +1 -0
  334. package/out/postcode-point-lookup.d.ts +6 -24
  335. package/out/postcode-point-lookup.d.ts.map +1 -1
  336. package/out/postcode-point-lookup.js +5 -17
  337. package/out/postcode-point-lookup.js.map +1 -1
  338. package/out/primary-preference.d.ts +38 -92
  339. package/out/primary-preference.d.ts.map +1 -1
  340. package/out/primary-preference.js +15 -99
  341. package/out/primary-preference.js.map +1 -1
  342. package/out/proximity-rerank.d.ts +41 -30
  343. package/out/proximity-rerank.d.ts.map +1 -1
  344. package/out/proximity-rerank.js +38 -29
  345. package/out/proximity-rerank.js.map +1 -1
  346. package/out/ranking-weights.d.ts +98 -64
  347. package/out/ranking-weights.d.ts.map +1 -1
  348. package/out/ranking-weights.js +26 -25
  349. package/out/ranking-weights.js.map +1 -1
  350. package/out/region-keys.d.ts +50 -31
  351. package/out/region-keys.d.ts.map +1 -1
  352. package/out/region-keys.js +68 -40
  353. package/out/region-keys.js.map +1 -1
  354. package/out/reverse.d.ts +78 -50
  355. package/out/reverse.d.ts.map +1 -1
  356. package/out/reverse.js +98 -61
  357. package/out/reverse.js.map +1 -1
  358. package/out/schema.d.ts +72 -49
  359. package/out/schema.d.ts.map +1 -1
  360. package/out/schema.js +4 -5
  361. package/out/schema.js.map +1 -1
  362. package/out/search-fetch.d.ts +16 -12
  363. package/out/search-fetch.d.ts.map +1 -1
  364. package/out/search-fetch.js +83 -63
  365. package/out/search-fetch.js.map +1 -1
  366. package/out/sqlite/convention-source.d.ts +12 -16
  367. package/out/sqlite/convention-source.d.ts.map +1 -1
  368. package/out/sqlite/convention-source.js +13 -22
  369. package/out/sqlite/convention-source.js.map +1 -1
  370. package/out/sqlite/utils.d.ts +19 -19
  371. package/out/sqlite/utils.d.ts.map +1 -1
  372. package/out/sqlite/utils.js +14 -15
  373. package/out/sqlite/utils.js.map +1 -1
  374. package/out/street/centroid/schema.d.ts +37 -42
  375. package/out/street/centroid/schema.d.ts.map +1 -1
  376. package/out/street/centroid/schema.js +9 -21
  377. package/out/street/centroid/schema.js.map +1 -1
  378. package/out/street/centroid.d.ts +30 -0
  379. package/out/street/centroid.d.ts.map +1 -0
  380. package/out/street/{centroid/index.js → centroid.js} +13 -24
  381. package/out/street/centroid.js.map +1 -0
  382. package/out/street/morphology/fst/builder.d.ts +20 -10
  383. package/out/street/morphology/fst/builder.d.ts.map +1 -1
  384. package/out/street/morphology/fst/builder.js +44 -34
  385. package/out/street/morphology/fst/builder.js.map +1 -1
  386. package/out/street/morphology/fst/loader.d.ts +33 -26
  387. package/out/street/morphology/fst/loader.d.ts.map +1 -1
  388. package/out/street/morphology/fst/loader.js +23 -22
  389. package/out/street/morphology/fst/loader.js.map +1 -1
  390. package/out/street/name-lookup.d.ts +24 -18
  391. package/out/street/name-lookup.d.ts.map +1 -1
  392. package/out/street/name-lookup.js +34 -35
  393. package/out/street/name-lookup.js.map +1 -1
  394. package/out/street/normalize.d.ts +35 -136
  395. package/out/street/normalize.d.ts.map +1 -1
  396. package/out/street/normalize.js +77 -194
  397. package/out/street/normalize.js.map +1 -1
  398. package/out/street/segment-schema.d.ts +79 -39
  399. package/out/street/segment-schema.d.ts.map +1 -1
  400. package/out/street/segment-schema.js +71 -21
  401. package/out/street/segment-schema.js.map +1 -1
  402. package/out/{street/index.js → street.d.ts} +2 -2
  403. package/out/street.d.ts.map +1 -0
  404. package/out/{street/index.d.ts → street.js} +2 -2
  405. package/out/street.js.map +1 -0
  406. package/out/types.d.ts +84 -149
  407. package/out/types.d.ts.map +1 -1
  408. package/out/types.js +0 -6
  409. package/out/types.js.map +1 -1
  410. package/out/unified-schema.d.ts +8 -12
  411. package/out/unified-schema.d.ts.map +1 -1
  412. package/out/unified-schema.js +29 -29
  413. package/out/unified-schema.js.map +1 -1
  414. package/out/uprn/existence.d.ts +28 -17
  415. package/out/uprn/existence.d.ts.map +1 -1
  416. package/out/uprn/existence.js +26 -16
  417. package/out/uprn/existence.js.map +1 -1
  418. package/out/uprn/lookup.d.ts +14 -44
  419. package/out/uprn/lookup.d.ts.map +1 -1
  420. package/out/uprn/lookup.js +21 -57
  421. package/out/uprn/lookup.js.map +1 -1
  422. package/out/uprn/schema.d.ts +18 -40
  423. package/out/uprn/schema.d.ts.map +1 -1
  424. package/out/uprn/schema.js +10 -32
  425. package/out/uprn/schema.js.map +1 -1
  426. package/out/{uprn/index.d.ts → uprn.d.ts} +1 -1
  427. package/out/uprn.d.ts.map +1 -0
  428. package/out/{uprn/index.js → uprn.js} +1 -1
  429. package/out/uprn.js.map +1 -0
  430. package/out/weights-overlay-linker.d.ts +138 -144
  431. package/out/weights-overlay-linker.d.ts.map +1 -1
  432. package/out/weights-overlay-linker.js +105 -159
  433. package/out/weights-overlay-linker.js.map +1 -1
  434. package/package.json +91 -596
  435. package/lib/address/point/index.ts +0 -328
  436. package/lib/convention/index.ts +0 -154
  437. package/lib/fts/index.ts +0 -361
  438. package/out/address/index.d.ts.map +0 -1
  439. package/out/address/index.js.map +0 -1
  440. package/out/address/point/index.d.ts +0 -53
  441. package/out/address/point/index.d.ts.map +0 -1
  442. package/out/address/point/index.js +0 -222
  443. package/out/address/point/index.js.map +0 -1
  444. package/out/ancestry/index.d.ts +0 -45
  445. package/out/ancestry/index.d.ts.map +0 -1
  446. package/out/ancestry/index.js +0 -55
  447. package/out/ancestry/index.js.map +0 -1
  448. package/out/convention/index.d.ts +0 -106
  449. package/out/convention/index.d.ts.map +0 -1
  450. package/out/convention/index.js +0 -93
  451. package/out/convention/index.js.map +0 -1
  452. package/out/fst/index.d.ts.map +0 -1
  453. package/out/fst/index.js.map +0 -1
  454. package/out/fts/index.d.ts +0 -184
  455. package/out/fts/index.d.ts.map +0 -1
  456. package/out/fts/index.js +0 -277
  457. package/out/fts/index.js.map +0 -1
  458. package/out/geonames/index.d.ts.map +0 -1
  459. package/out/geonames/index.js.map +0 -1
  460. package/out/nsul/index.d.ts.map +0 -1
  461. package/out/nsul/index.js.map +0 -1
  462. package/out/poi/index.d.ts.map +0 -1
  463. package/out/poi/index.js.map +0 -1
  464. package/out/postal/index.d.ts.map +0 -1
  465. package/out/postal/index.js.map +0 -1
  466. package/out/street/centroid/index.d.ts +0 -40
  467. package/out/street/centroid/index.d.ts.map +0 -1
  468. package/out/street/centroid/index.js.map +0 -1
  469. package/out/street/index.d.ts.map +0 -1
  470. package/out/street/index.js.map +0 -1
  471. package/out/uprn/index.d.ts.map +0 -1
  472. package/out/uprn/index.js.map +0 -1
  473. /package/lib/{geonames/index.ts → geonames.ts} +0 -0
  474. /package/lib/{nsul/index.ts → nsul.ts} +0 -0
  475. /package/lib/{poi/index.ts → poi.ts} +0 -0
  476. /package/lib/{postal/index.ts → postal.ts} +0 -0
  477. /package/lib/{uprn/index.ts → uprn.ts} +0 -0
@@ -3,43 +3,49 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
- * Typed schema for the TIGER STREET-SEGMENT interpolation extracts (`street-segments-<cc>-<st>.db`,
7
- * built by `scripts/build-interpolation-extract.ts` from TIGER EDGES) — the #483 Method-3 fallback
8
- * the resolver drops to when the address-point tier (Method 2) can't bracket. Single source of
9
- * truth for the columns the BUILDER writes and the READER ({@link StreetInterpolator}) probes, so
10
- * a column rename in one is a compile error in the other.
11
- *
12
- * The builder reads geometry from shapefiles via DuckDB's spatial extension (raw `ST_Read` — see
13
- * AGENTS.md "Database / inline SQL") and writes here through `node:sqlite`. The hot positional
14
- * INSERT (a county's worth of edges) stays raw; its column list is derived from
15
- * {@link STREET_SEGMENT_COLUMNS} so it can't drift from the DDL.
6
+ * Typed schema for the tiger street-segment interpolation extracts (`street-segments-<cc>-<st>.db`,
7
+ * built by `scripts/build-interpolation-extract.ts` from tiger edges). This is the Method-3
8
+ * fallback the resolver drops to when the address-point tier (Method 2) cannot bracket. It is the
9
+ * definition of the columns the builder writes and the reader ({@link StreetInterpolator}) probes,
10
+ * so a column rename in one is a compile error in the other.
11
+ *
12
+ * The builder reads geometry from shapefiles via DuckDB's spatial extension (raw `ST_Read`, see
13
+ * agents.md "Database / inline SQL") and writes here through `node:sqlite`. The hot positional
14
+ * insert (a county's worth of edges) stays raw. Its column list derives from
15
+ * {@link STREET_SEGMENT_COLUMNS} so it cannot drift from the DDL.
16
16
  */
17
17
 
18
- import type { Kysely } from "kysely"
18
+ import { type Kysely, sql } from "kysely"
19
19
 
20
20
  import type { RouteKey } from "#street/normalize"
21
21
 
22
22
  /**
23
- * One TIGER street-segment edge: a `(from_hn, to_hn)` house-number range on one `side` of a named street, with the
24
- * geometry the interpolator walks. `min_hn`/`max_hn` are the sorted bounds (the probe filters on them); `parity` is
25
- * `odd`/`even`/`mixed`.
23
+ * One tiger street-segment edge: a `(from_hn, to_hn)` house-number range on one `side`
24
+ * of a street with a name, with the geometry the interpolator walks.
25
+ *
26
+ * `min_hn`/`max_hn` are the sorted bounds used by the probe.
27
+ * `parity` is `odd`, `even`, or `mixed`.
26
28
  */
27
29
  export interface StreetSegmentTable {
28
30
  /**
29
- * `canonicalizeRouteKey(normalizeStreetForKey(street))` — the build/query-consistent probe key. The column NAME says
30
- * `street_norm`, but the value carries the route fold on top of the street fold, which is why the brand is
31
- * {@link RouteKey}: builder and probe both apply both folds, and a plain street key bound here misses every
32
- * numbered-route row.
31
+ * `canonicalizeRouteKey(normalizeStreetForKey(street))`, the build/query-consistent probe key.
32
+ *
33
+ * The column name is `street_norm`, but the value includes the route fold on top of the street fold.
34
+ * The value therefore uses the {@link RouteKey} brand.
35
+ *
36
+ * The builder and probe apply both folds.
37
+ * A plain street key bound here misses every numbered-route row.
33
38
  */
34
39
  street_norm: RouteKey
35
40
  /**
36
- * `L` or `R` — the TIGER side the address range sits on.
41
+ * `L` or `R`, the tiger side the address range sits on.
37
42
  */
38
43
  side: string
39
44
  from_hn: number
40
45
  to_hn: number
41
46
  /**
42
- * Sorted lower bound of `(from_hn, to_hn)` — the probe filters `min_hn <= n <= max_hn`.
47
+ * Sorted lower bound of `(from_hn, to_hn)`.
48
+ * The probe filters `min_hn <= n <= max_hn`.
43
49
  */
44
50
  min_hn: number
45
51
  /**
@@ -47,7 +53,7 @@ export interface StreetSegmentTable {
47
53
  */
48
54
  max_hn: number
49
55
  /**
50
- * `odd` | `even` | `mixed` — the house-number parity along the range.
56
+ * `odd`, `even` or `mixed`, the house-number parity along the range.
51
57
  */
52
58
  parity: string
53
59
  postcode: string | null
@@ -56,11 +62,12 @@ export interface StreetSegmentTable {
56
62
  */
57
63
  county_fips: string
58
64
  /**
59
- * The street as it appeared in TIGER (kept for display / debugging).
65
+ * The street as it appeared in tiger (kept for display / debugging).
60
66
  */
61
67
  street_raw: string
62
68
  /**
63
- * GeoJSON LineString text (no SpatiaLite — read back with `JSON.parse`).
69
+ * GeoJSON LineString text without SpatiaLite.
70
+ * Read back with `JSON.parse`.
64
71
  */
65
72
  geometry: string
66
73
  /**
@@ -68,21 +75,27 @@ export interface StreetSegmentTable {
68
75
  */
69
76
  source: string
70
77
  /**
71
- * The pinned TIGER release the edge was ingested from.
78
+ * The pinned tiger release the edge was ingested from.
72
79
  */
73
80
  release: string
74
81
  }
75
82
 
76
83
  /**
77
- * The extract's single-row calibration metadata (#374 doctrine, 2026-07-26): the conformal radius multiplier is a
78
- * property of the CALIBRATION SET the artifact was built against — so it ships IN the artifact (the pair-index δ
79
- * precedent, `neural/pair-index-resolver.ts`), not in caller code. Written once by the builder; read at open time by
80
- * {@link StreetInterpolator}. Extracts built before this table exists simply lack it — the reader degrades to
81
- * `undefined` and callers fall back to the in-code per-region table (never patch shipped DBs — rebuild).
84
+ * The extract's single-row calibration metadata: the conformal radius multiplier
85
+ * is a property of the calibration set the artifact was built against,
86
+ * so it ships in the artifact rather than in caller code.
87
+ *
88
+ * See the pair-index precedent in `neural/pair-index-resolver.ts`.
89
+ *
90
+ * The builder writes this table once. {@link StreetInterpolator} reads it when opening the database.
91
+ *
92
+ * Extracts built before this table exists lack it.
93
+ * The reader degrades to `undefined`, and callers fall back to the in-code per-region table.
94
+ * Shipped DBs are rebuilt rather than patched.
82
95
  */
83
96
  export interface InterpCalibrationRow {
84
97
  /**
85
- * Conformal multiplier for the raw half-segment `uncertainty_m` radius (#374/#584) — ×Q̂ for a ~90% bound.
98
+ * Conformal multiplier for the raw half-segment `uncertainty_m` radius, ×Q̂ for a ~90% bound.
86
99
  */
87
100
  radius_multiplier: number
88
101
  /**
@@ -90,7 +103,8 @@ export interface InterpCalibrationRow {
90
103
  */
91
104
  method: string
92
105
  /**
93
- * The calibration-table key the multiplier was selected by (a USPS region code, or `default` for unmeasured).
106
+ * The calibration-table key the multiplier was selected by
107
+ * (a USPS region code, or `default` for unmeasured).
94
108
  */
95
109
  region: string
96
110
  }
@@ -104,8 +118,10 @@ export interface StreetSegmentDatabase {
104
118
  }
105
119
 
106
120
  /**
107
- * The `street_segment` columns in INSERT order. The builder's positional prepared statement derives its placeholder
108
- * list from this, so the positional order can't drift from the DDL / the reader.
121
+ * The `street_segment` columns in insert order.
122
+ *
123
+ * The builder's positional prepared statement derives its placeholder list from this,
124
+ * so the positional order can't drift from the DDL / the reader.
109
125
  */
110
126
  export const STREET_SEGMENT_COLUMNS = [
111
127
  "street_norm",
@@ -124,11 +140,20 @@ export const STREET_SEGMENT_COLUMNS = [
124
140
  ] as const
125
141
 
126
142
  /**
127
- * Create the `street_segment` table — called before the streaming bulk load.
143
+ * The staging table the builder bulk-loads in source order before {@link clusterStreetSegments}
144
+ * copies its rows into `street_segment` in probe-key order.
145
+ */
146
+ export const STREET_SEGMENT_STAGE_TABLE = "street_segment_stage"
147
+
148
+ /**
149
+ * Create the `street_segment` table, or the staging table with the same columns.
128
150
  */
129
- export async function createStreetSegmentTable(db: Kysely<StreetSegmentDatabase>): Promise<void> {
151
+ export async function createStreetSegmentTable(
152
+ db: Kysely<StreetSegmentDatabase>,
153
+ table: "street_segment" | typeof STREET_SEGMENT_STAGE_TABLE = "street_segment"
154
+ ): Promise<void> {
130
155
  await db.schema
131
- .createTable("street_segment")
156
+ .createTable(table)
132
157
  .addColumn("street_norm", "text", (c) => c.notNull())
133
158
  .addColumn("side", "text", (c) => c.notNull())
134
159
  .addColumn("from_hn", "integer", (c) => c.notNull())
@@ -146,10 +171,13 @@ export async function createStreetSegmentTable(db: Kysely<StreetSegmentDatabase>
146
171
  }
147
172
 
148
173
  /**
149
- * Create + populate the single-row `interp_calibration` metadata table (see {@link InterpCalibrationRow}) — called once
150
- * by the extract builder, after the value is selected from the calibration source of record. Build-time only (async
151
- * Kysely is fine here); the READ side is the raw sync probe in {@link StreetInterpolator}'s constructor, per the
152
- * sync-by-interface doctrine.
174
+ * Create and populate the single-row `interp_calibration` metadata table (see {@link InterpCalibrationRow}).
175
+ *
176
+ * Called once by the extract builder, after the value is selected from the calibration source of record.
177
+ *
178
+ * Build-time only, so async Kysely is fine here.
179
+ * The read side is the raw sync probe in {@link StreetInterpolator}'s constructor,
180
+ * per the sync-by-interface doctrine.
153
181
  */
154
182
  export async function writeInterpCalibration(
155
183
  db: Kysely<StreetSegmentDatabase>,
@@ -166,14 +194,59 @@ export async function writeInterpCalibration(
166
194
  }
167
195
 
168
196
  /**
169
- * Create the two probe indexes the reader relies on (postcode-scope, street-scope).
197
+ * The physical row order of `street_segment`: street first, then postcode and range.
198
+ *
199
+ * The browser reads the extract over HTTP range requests.
200
+ * Both probe forms fetch their matching rows from the table.
201
+ *
202
+ * In this order the postcode-scoped probe reads one contiguous run of rows.
203
+ * The street-only probe reads within one street's contiguous block.
204
+ *
205
+ * The staging rowid is the last key, so rows with equal keys keep their source order.
206
+ * The readers break span ties by that order.
207
+ */
208
+ const STREET_SEGMENT_CLUSTER_ORDER = "street_norm, postcode, min_hn, max_hn, rowid"
209
+
210
+ /**
211
+ * Copy the staged rows into `street_segment` in key order and drop the stage.
212
+ *
213
+ * The order is {@link STREET_SEGMENT_CLUSTER_ORDER}.
214
+ *
215
+ * `street_segment` stays a rowid table, because `postcode` is nullable.
216
+ * A `WITHOUT ROWID` primary key forbids a null column.
217
+ * A load in key order gives the same page locality.
218
+ *
219
+ * Run {@link createStreetSegmentIndexes} and `VACUUM` afterwards.
220
+ */
221
+ export async function clusterStreetSegments(db: Kysely<StreetSegmentDatabase>): Promise<void> {
222
+ const columns = STREET_SEGMENT_COLUMNS.join(", ")
223
+
224
+ await sql
225
+ .raw(
226
+ `INSERT INTO street_segment (${columns}) SELECT ${columns} FROM ${STREET_SEGMENT_STAGE_TABLE} ORDER BY ${STREET_SEGMENT_CLUSTER_ORDER}`
227
+ )
228
+ .execute(db)
229
+
230
+ await db.schema.dropTable(STREET_SEGMENT_STAGE_TABLE).execute()
231
+ }
232
+
233
+ /**
234
+ * Create the two probe indexes the readers use (postcode-scope, street-scope).
235
+ *
236
+ * Each index holds `max_hn`.
237
+ * SQLite therefore rejects a range ending below the house number from the index entry.
238
+ * The rejected row's table page is never fetched.
170
239
  */
171
240
  export async function createStreetSegmentIndexes(db: Kysely<StreetSegmentDatabase>): Promise<void> {
172
241
  await db.schema
173
242
  .createIndex("idx_seg_postcode")
174
243
  .on("street_segment")
175
- .columns(["postcode", "street_norm", "min_hn"])
244
+ .columns(["postcode", "street_norm", "min_hn", "max_hn"])
176
245
  .execute()
177
246
 
178
- await db.schema.createIndex("idx_seg_street").on("street_segment").columns(["street_norm", "min_hn"]).execute()
247
+ await db.schema
248
+ .createIndex("idx_seg_street")
249
+ .on("street_segment")
250
+ .columns(["street_norm", "min_hn", "max_hn"])
251
+ .execute()
179
252
  }
@@ -4,7 +4,7 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
 
7
- export * from "#street/centroid/index"
7
+ export * from "#street/centroid"
8
8
  export * from "#street/centroid/schema"
9
9
  export * from "#street/morphology/fst/builder"
10
10
  export * from "#street/morphology/fst/loader"
package/lib/types.ts CHANGED
@@ -2,19 +2,12 @@
2
2
  * @copyright Sister Software
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
- *
6
- * Public surface for the WOF SQLite resolver — types only, no runtime.
7
- *
8
- * These mirror the conceptual model described in `docs/plan/phases/PHASE_4_2_wof_sqlite.md`. Phase
9
- * 4.3 will extend `PlaceCandidate` with the resolver-decorated fields that flow into
10
- * `AddressNode.source` / `sourceID` (e.g. an explicit `wofURI: "wof-admin:101751113"` form).
11
5
  */
12
6
 
7
+ import type { LatLon, LatLonBounds } from "@mailwoman/spatial"
8
+
13
9
  /**
14
- * The placetype taxonomy used by Who's On First. Ordered roughly from coarsest (country) to finest (address). See
15
- * https://github.com/whosonfirst/whosonfirst-placetypes for the authoritative definitions of each.
16
- *
17
- * Phase 4.2 only emits the ones we actually look up; the union is open enough to extend later.
10
+ * Lists the Who's On First placetypes this resolver looks up, ordered roughly from coarsest to finest.
18
11
  */
19
12
  export type WOFPlacetype =
20
13
  | "country"
@@ -33,222 +26,188 @@ export type WOFPlacetype =
33
26
  | "address"
34
27
 
35
28
  /**
36
- * One candidate match for a place lookup.
37
- *
38
- * `score` is the post-boost ranking number — higher is better, but the scale is implementation- defined. Callers should
39
- * treat it as ordinal, not absolute.
40
- *
41
- * `id` is the WOF place id. It's named generically (not `wof_id`) so the shape stays structurally compatible with
42
- * `@mailwoman/resolver`'s `ResolvedPlace` — `WOFSQLitePlaceLookup` satisfies the generic `ResolverBackend` contract
43
- * without an adapter shim.
44
- *
45
- * `distanceKm` is populated only when the query carried `near` (and the place has a centroid). Useful for downstream
46
- * UIs that want to show "X km from you" alongside the result.
29
+ * Describes one ranked match for a place lookup, with `id` as the WOF id
30
+ * so the shape satisfies `ResolvedPlace`.
47
31
  */
48
32
  export interface PlaceCandidate {
49
33
  id: number
50
34
  name: string
51
35
  placetype: WOFPlacetype
36
+
52
37
  /**
53
- * ISO 3166-1 alpha-2 country code.
38
+ * The ISO 3166-1 alpha-2 country code.
54
39
  */
55
40
  country: string
56
41
  lat: number
57
42
  lon: number
58
- parent_id?: number
59
- score: number
60
- distanceKm?: number
43
+
61
44
  /**
62
- * True when this candidate's name OR an alias EXACTLY equals the query (the exact-match tier from
63
- * {@link RankingWeights.exactMatchTiering}). Surfaced so a downstream country re-rank (#369's postcode anchor in
64
- * `resolveTree`) can pin the country without crossing the tier — see the `exactMatch` field on `@mailwoman/core`'s
65
- * `ResolvedPlace`.
45
+ * The place's depth-1 ancestor id from the ancestors sidecar, absent when the
46
+ * artifact has no sidecar even for a place with a parent.
66
47
  */
67
- exactMatch?: boolean
48
+ parent_id: number | null
49
+ score: number
50
+ distanceKm: number | null
51
+
68
52
  /**
69
- * Combined prominence (population term + best proximity-bias term, same additive units) — populated by the FTS
70
- * lookup; the exact-tier sort orders by THIS instead of raw population when the query carried proximity hints
71
- * (`near`/`bias`).
53
+ * Whether the candidate's name or an alias exactly equals the query, used by a
54
+ * later re-rank to stay within the exact-match tier.
72
55
  */
73
- prominence?: number
56
+ exactMatch: boolean | null
57
+
74
58
  /**
75
- * Population from WOF's `wof:population` property. Only present when the candidate has it on record — WOF carries
76
- * population for ~15% of localities (mostly larger ones). Absent does NOT mean zero, just unknown.
59
+ * The population term plus the best proximity-bias term.
60
+ *
61
+ * The exact tier sorts by this value instead of population when the query has `near` or `bias`.
77
62
  */
78
- population?: number
63
+ prominence: number | null
64
+
79
65
  /**
80
- * REFERENTIAL likelihood in [0, 1] — `referentialFromPopulation(population)`, the named form of the prominence key
81
- * this resolver has always ranked namesakes by (ROAD_TO_V9 §2, ratified 2026-08-06).
82
- *
83
- * It is a strictly-increasing function of {@link PlaceCandidate.population} below `REFERENTIAL_SATURATION_POPULATION`
84
- * and constant above it, so ordering by it — via `compareReferential`, which restores the megacity order with a
85
- * population tiebreak — is the SAME ORDER as ordering by population. That equivalence is the point: naming the
86
- * ranking key costs nothing at the ranking.
87
- *
88
- * Absent when the candidate has no population on record, exactly as {@link PlaceCandidate.population} is.
66
+ * The WOF `wof:population` value, absent when the population is unknown.
89
67
  */
90
- referential?: number
68
+ population: number | null
69
+
91
70
  /**
92
- * STRICT encyclopedia-evidence importance in [0, 1], fan-out-guarded per #1497 — CARRIED, NEVER RANKED ON.
93
- *
94
- * RESERVED SLOT awaiting a strict-channel source: present only when a extract's `place_importance` table carries the
95
- * split columns, and no shipped extract does — the FTS lookup's clauses emit NULL for everything today. `undefined`
96
- * means either "no encyclopedia entry for this place" or "this gazetteer predates the split"; both are absence, and
97
- * neither is 0. The BLENDED prior the ranking reads is {@link PlaceCandidate.importance}.
98
- *
99
- * Saint-Denis is why this is not a ranking key: the Seine-Saint-Denis suburb (pop 96,128) scores 0.1173 while the
100
- * Aude hamlet (pop 418) scores 0.5683. Consumers that want to display salience read this; the ranking never does.
71
+ * The referential likelihood in [0, 1], derived from {@link PlaceCandidate.population}
72
+ * and absent whenever it is.
101
73
  */
102
- encyclopedic?: number
74
+ referential: number | null
75
+
103
76
  /**
104
- * BLENDED global toponym prior in [0, 1] (#28) — `candidate.importance` surfaced verbatim: the score source's legacy
105
- * blended importance (encyclopedia-derived where the concordance matched, a population-derived proxy elsewhere).
106
- * Emitted only by the candidate-table backend, and only when the artifact measured this place — absent is UNMEASURED,
107
- * never zero. Consumed by `rankByImportance` (`resolver/toponym-prior.ts`) for the bare-toponym class. See
108
- * `candidate-schema.ts` → `CandidateTable.importance` for why the blend, not the strict channel, is what ships.
77
+ * The encyclopedia-evidence importance in [0, 1], used for display only and present only
78
+ * when the extract's `place_importance` table has the split columns.
109
79
  */
110
- importance?: number
80
+ encyclopedic: number | null
81
+
111
82
  /**
112
- * Bounding box from WOF's `spr.{min,max}_{latitude,longitude}` columns. Coarse outline for the place — a city's bbox
113
- * is the city's full extent, a postcode's is roughly the postcode polygon's envelope. Optional because not all
114
- * callers ask for it; implementations are free to omit when the underlying schema lacks the columns.
83
+ * The blended toponym prior in [0, 1] that `rankByImportance` reads for bare toponyms,
84
+ * set only by the candidate-table backend.
115
85
  */
116
- bbox?: GeoBbox
86
+ importance: number | null
87
+
117
88
  /**
118
- * Set by the coordinate-first path when the chosen locality and the sibling postcode's containing locality are
119
- * geographically far apart — the postcode and the parsed city name disagree (a transposed / wrong-for-the-city
120
- * postcode). The candidate is still returned (the name wins for the locality), but the flag lets callers lower
121
- * confidence / surface the conflict rather than silently mislocate. A retrieval/BM25 geocoder can't raise this — it's
122
- * the falsehood-detection differentiator.
89
+ * The bounding box from the WOF `spr` extent columns, omitted when the schema lacks them.
123
90
  */
124
- mismatch?: boolean
91
+ bbox: LatLonBounds | null
92
+
125
93
  /**
126
- * Admin-containment stamp (#1717 stage 2) — TRI-STATE, mirroring `ResolvedPlace.containedByQualifier` in
127
- * `@mailwoman/core`: `true` = the ancestors sidecar vouches this candidate sits under the query's
128
- * {@link FindPlaceQuery.regionQualifier}; `false` = evaluated and not vouched for; absent = never evaluated (no
129
- * qualifier on the query, or an artifact without the sidecar). Absence is required — the resolver walk reads it as
130
- * `unavailable`, never as "not contained".
94
+ * Set by the postcode path when the chosen locality is far from the postcode's own
95
+ * locality. the candidate is still returned so callers can lower their confidence.
131
96
  */
132
- containedByQualifier?: boolean
97
+ mismatch: boolean | null
98
+
133
99
  /**
134
- * The #1882 exemption's firing mark (#1893), mirroring `ResolvedPlace.variantAliasExempted` in `@mailwoman/core`:
135
- * present only when this candidate's row would have taken the cross-country alias penalty and the exemption prevented
136
- * it. Emitted by the candidate-table backend alone — the WASM FTS lookup never runs the ranker, and its candidates
137
- * omit the field (not evaluated, never "did not fire").
100
+ * Whether the ancestors sidecar places this candidate under the query's
101
+ * {@link FindPlaceQuery.regionQualifier}, with `false` meaning the check ran
102
+ * and an absent value meaning it did not.
138
103
  */
139
- variantAliasExempted?: true
140
- }
104
+ containedByQualifier: boolean | null
141
105
 
142
- /**
143
- * A WGS-84 lat/lon point. Used as a proximity hint for `FindPlaceQuery.near`.
144
- */
145
- export interface GeoPoint {
146
- lat: number
147
- lon: number
148
- }
106
+ /**
107
+ * Set when the candidate lies outside the query's parent scope, so callers can demote it.
108
+ */
109
+ regionScopeMiss: boolean | null
149
110
 
150
- /**
151
- * A WGS-84 bounding box. Used as a hard filter via `FindPlaceQuery.bbox`.
152
- */
153
- export interface GeoBbox {
154
- minLat: number
155
- maxLat: number
156
- minLon: number
157
- maxLon: number
111
+ /**
112
+ * Set when the variant exemption spared the candidate from the cross-country
113
+ * alias penalty, by the candidate-table backend only.
114
+ */
115
+ variantAliasExempted: true | null
158
116
  }
159
117
 
160
118
  /**
161
- * Query against the resolver.
162
- *
163
- * `text` is the only required field; everything else narrows the search. When `country` and `parentID` are both set,
164
- * `parentID` wins (it's more specific).
165
- *
166
- * `near` and `bbox` are independent. `near` is a soft signal — candidates close to the point get a ranking boost but
167
- * distant candidates aren't dropped. `bbox` is a hard filter — only candidates whose bbox intersects the query bbox are
168
- * returned (uses the package-built R*Tree index when present; if the index is missing the option is silently ignored to
169
- * preserve backwards compatibility).
119
+ * Describes a place lookup.
170
120
  *
171
- * `near` may carry `maxDistanceKm` to escalate from a boost to a hard filter — candidates further than that distance
172
- * from the point are dropped at the SQL level via an R*Tree pre-filter.
121
+ * Every field except `text` narrows or ranks the search.
122
+ * An extract without the R*Tree index ignores `bbox` and `near.maxDistanceKm` without an error.
173
123
  */
174
124
  export interface FindPlaceQuery {
175
125
  text: string
176
126
  placetype?: WOFPlacetype | WOFPlacetype[]
127
+
177
128
  /**
178
- * ISO 3166-1 alpha-2 — narrows to one country.
129
+ * Restricts matches to one ISO 3166-1 alpha-2 country.
179
130
  */
180
131
  country?: string
132
+
181
133
  /**
182
- * ISO 3166-1 alpha-2 — narrows the TYPO-FUZZY tier only (#1585). Exact and qualifier-strip probes stay worldwide (a
183
- * locale hint is a prior, never a hard filter on exact matches), but a typo CORRECTION into a different country's
184
- * namespace is nearly always a scrape, so the corrected-key probes honor this scope and a scoped-empty ABSTAINS
185
- * rather than falling through to a world-fuzzy candidate. Ignored when `country` is set (already narrower).
134
+ * Restricts the typo-fuzzy tier to one ISO 3166-1 alpha-2 country, returning no
135
+ * result on a miss rather than falling back worldwide.
136
+ * Ignored when `country` is set.
186
137
  */
187
138
  fuzzyCountry?: string
139
+
188
140
  /**
189
- * Restrict name matching to PRIMARY-keyed rows (#1632) — set by probes whose surface is a RE-READING (a token taken
190
- * out of a longer classified span), which never named an alias. See the ResolverBackend contract in
191
- * `@mailwoman/core/resolver`.
141
+ * Whether to match only primary names, set by probes that re-read a token from
142
+ * a longer span because that token was never an alias.
192
143
  */
193
144
  primaryOnly?: boolean
145
+
194
146
  /**
195
- * Alias-row NAME ROLES the probe refuses to answer through (#1730) — the bare-toponym side races pass `abbr`/`gloss`.
196
- * Role-NULL alias rows (the exonym tier) stay open; backends/artifacts without a role column ignore it.
147
+ * Alias name roles, such as `abbr` or `gloss`, that the probe excludes.
148
+ *
149
+ * Rows with no role and artifacts without a role column are unaffected.
197
150
  */
198
151
  excludeNameRoles?: readonly string[]
152
+
199
153
  /**
200
- * WOF place id — narrows to descendants of this place.
154
+ * Restricts matches to descendants of this WOF place id.
201
155
  */
202
156
  parentID?: number
157
+
203
158
  /**
204
- * Sibling postcode. When set on a `locality` query AND a `postcode_locality` table is present, triggers the
205
- * coordinate-first soft-score path: postcode→candidate localities are injected and scored `0.6·S_pc + 0.3·S_name +
206
- * 0.1·S_pop` against the FTS name-match set, recovering small localities the name-match alone misses. Ignored when no
207
- * postcode_locality extract is present.
159
+ * The sibling postcode for a `locality` query.
160
+ *
161
+ * A `postcode_locality` table adds that postcode's localities and scores them on a
162
+ * weighted blend so small localities a name match misses are found.
208
163
  */
209
164
  postcode?: string
165
+
210
166
  /**
211
- * Postcode-containment coherence (#31, Mechanism 2) — when true on a locality query that also carries `postcode`,
212
- * candidate rows within `POSTCODE_CONTAINMENT_THRESHOLD_KM` of the postcode's own centroid sort by distance first,
213
- * the rest appended in their original order. Set by the resolver from `ResolveOpts.postcodeContainmentCoherence`;
214
- * absent → the population-first order is untouched (byte-identical).
167
+ * Whether a locality query with `postcode` moves candidates near the postcode's centroid
168
+ * to the front, sorted by distance, with the rest keeping their order.
215
169
  */
216
170
  postcodeContainmentCoherence?: boolean
171
+
217
172
  /**
218
- * The tree's parsed REGION qualifier (#1717 stage 2) — set by the resolver on locality lookups when
219
- * `ResolveOpts.adminContainmentRerank` is on. See the `ResolverBackend` contract in `@mailwoman/core/resolver`: a
220
- * capable backend stamps `containedByQualifier`, ranks contained candidates first, and may ADD contained same-key
221
- * candidates a country scope hid — additive only, never a filter. Ignored on an artifact without the ancestors
222
- * sidecar (candidates then carry no stamp).
173
+ * The parsed region qualifier for a locality lookup.
174
+ *
175
+ * A backend with the ancestors sidecar marks contained candidates.
176
+ * It ranks them first.
177
+ *
178
+ * It may add candidates hidden by a country scope.
179
+ * It never removes candidates.
223
180
  */
224
181
  regionQualifier?: string
182
+
225
183
  /**
226
- * Proximity hint — candidates close to this point get a ranking boost.
184
+ * A proximity hint that boosts nearby candidates and filters by radius only when `maxDistanceKm` is set.
227
185
  */
228
- near?: GeoPoint & { maxDistanceKm?: number }
186
+ near?: LatLon & { maxDistanceKm?: number }
187
+
229
188
  /**
230
- * Ordered proximity-bias points (viewport center, user location, …), each optionally weighted (default 1.0, first
231
- * entry strongest by convention). SOFT — a re-rank signal, never a filter: with bias present, exact-tier candidates
232
- * order by combined prominence (population + the best decayed-distance term over these points) instead of population
233
- * alone, which is how an ambiguous bare postcode ("48026": Fraser MI vs Russi IT) follows the map view / the user.
234
- * Absent (and no `near`) → ranking is byte-identical to today. `near` is treated as a weight-1.0 bias point for
235
- * back-compat.
189
+ * Ordered proximity-bias points with an optional weight defaulting to 1.
190
+ *
191
+ * The bias re-ranks exact-tier candidates by combined prominence.
192
+ * It keeps every candidate.
193
+ * It counts `near` as weight 1.
236
194
  */
237
- bias?: Array<GeoPoint & { weight?: number }>
195
+ bias?: Array<LatLon & { weight?: number }>
196
+
238
197
  /**
239
- * Bounding-box filter — only candidates whose bbox intersects this box are returned.
198
+ * Returns only candidates whose bounding box intersects this box.
240
199
  */
241
- bbox?: GeoBbox
200
+ bbox?: LatLonBounds
201
+
242
202
  /**
243
- * Default 10.
203
+ * The maximum number of candidates to return, defaulting to 10.
244
204
  */
245
205
  limit?: number
246
206
  }
247
207
 
248
208
  /**
249
- * The pull-based lookup surface. Implementations resolve a `FindPlaceQuery` to a ranked list of `PlaceCandidate`s. The
250
- * interface is async even though `node:sqlite` is sync — leaves room for `Worker`-backed implementations later without
251
- * a public API break.
209
+ * Resolves a {@link FindPlaceQuery} to ranked {@link PlaceCandidate}s, asynchronously
210
+ * so a worker-backed implementation can share the interface.
252
211
  */
253
212
  export interface PlaceLookup extends Disposable {
254
213
  findPlace(query: FindPlaceQuery): Promise<PlaceCandidate[]>