@mailwoman/resolver-wof-sqlite 9.4.0 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (548) hide show
  1. package/README.md +8 -8
  2. package/lib/address/{point-interpolation.ts → point/interpolation.ts} +40 -38
  3. package/lib/address/point/schema.ts +132 -0
  4. package/lib/address/point.ts +68 -81
  5. package/lib/{address/index.ts → address.ts} +2 -2
  6. package/lib/ancestry/backfill.ts +24 -88
  7. package/lib/{ancestry/index.ts → ancestry.ts} +19 -15
  8. package/lib/build/candidate.ts +608 -0
  9. package/lib/build/population-corrections.ts +64 -0
  10. package/lib/build/slim.ts +338 -0
  11. package/lib/candidate/alias-bags.ts +74 -14
  12. package/lib/candidate/ancestors/schema.ts +211 -0
  13. package/lib/candidate/{ancestors-sidecar.ts → ancestors/sidecar.ts} +17 -24
  14. package/lib/candidate/country-display-names.ts +6 -20
  15. package/lib/candidate/extract-fold.ts +12 -57
  16. package/lib/candidate/fts.ts +28 -0
  17. package/lib/candidate/importance.ts +221 -0
  18. package/lib/candidate/lookup.ts +669 -0
  19. package/lib/candidate/name-roles.ts +16 -34
  20. package/lib/candidate/own-name.ts +34 -31
  21. package/lib/candidate/place-attrs.ts +20 -13
  22. package/lib/candidate/schema.ts +211 -0
  23. package/lib/candidate/scoring.ts +222 -0
  24. package/lib/capital-schema.ts +21 -17
  25. package/lib/capitals.ts +26 -24
  26. package/lib/coincident-roles.ts +74 -55
  27. package/lib/convention/schema.ts +13 -7
  28. package/lib/convention.ts +144 -0
  29. package/lib/coverage-manifest-schema.ts +34 -39
  30. package/lib/currency-backfill.ts +24 -69
  31. package/lib/env.ts +1 -1
  32. package/lib/exact-match.ts +31 -20
  33. package/lib/extracts.ts +96 -73
  34. package/lib/fst/autocomplete.ts +52 -35
  35. package/lib/fst/builder.ts +30 -36
  36. package/lib/fst/deserialize-web.ts +8 -9
  37. package/lib/fst/format.ts +41 -23
  38. package/lib/fst/freshness.ts +17 -95
  39. package/lib/fst/matcher.ts +2 -2
  40. package/lib/fst/serialize.ts +45 -60
  41. package/lib/fst/types.ts +71 -59
  42. package/lib/fts/query.ts +5 -36
  43. package/lib/fts.ts +280 -0
  44. package/lib/geonames/aliases.ts +72 -149
  45. package/lib/geonames/postal.ts +162 -77
  46. package/lib/index.ts +20 -27
  47. package/lib/interpolation.ts +43 -96
  48. package/lib/lookup.ts +137 -257
  49. package/lib/name-score.ts +9 -7
  50. package/lib/nsul/lookup.ts +36 -53
  51. package/lib/nsul/schema.ts +16 -43
  52. package/lib/paths.ts +159 -0
  53. package/lib/place-importance-schema.ts +57 -164
  54. package/lib/poi/lookup.ts +100 -109
  55. package/lib/poi/schema.ts +42 -26
  56. package/lib/polygon-schema.ts +10 -6
  57. package/lib/postal/city/alias/lookup.ts +79 -0
  58. package/lib/postal/{city-alias-schema.ts → city/alias/schema.ts} +14 -10
  59. package/lib/postal/{city-candidate-schema.ts → city/candidate-schema.ts} +26 -20
  60. package/lib/postal.ts +9 -0
  61. package/lib/postcode-point-lookup.ts +9 -19
  62. package/lib/primary-preference.ts +45 -125
  63. package/lib/proximity-rerank.ts +43 -32
  64. package/lib/ranking-weights.ts +98 -76
  65. package/lib/region-keys.ts +68 -40
  66. package/lib/reverse.ts +108 -72
  67. package/lib/schema.ts +74 -42
  68. package/lib/search-fetch.ts +90 -68
  69. package/lib/sqlite/convention-source.ts +57 -0
  70. package/lib/sqlite/utils.ts +79 -0
  71. package/lib/street/centroid/schema.ts +149 -0
  72. package/lib/street/centroid.ts +16 -25
  73. package/lib/street/{morphology-fst-builder.ts → morphology/fst/builder.ts} +56 -41
  74. package/lib/street/{morphology-fst-loader.ts → morphology/fst/loader.ts} +36 -29
  75. package/lib/street/name-lookup.ts +43 -35
  76. package/lib/street/normalize.ts +85 -216
  77. package/lib/street/segment-schema.ts +116 -43
  78. package/lib/{street/index.ts → street.ts} +3 -3
  79. package/lib/types.ts +94 -140
  80. package/lib/unified-schema.ts +29 -29
  81. package/lib/uprn/existence.ts +30 -19
  82. package/lib/uprn/lookup.ts +28 -67
  83. package/lib/uprn/schema.ts +18 -40
  84. package/lib/weights-overlay-linker.ts +204 -232
  85. package/out/address/point/interpolation.d.ts +45 -0
  86. package/out/address/point/interpolation.d.ts.map +1 -0
  87. package/out/address/{point-interpolation.js → point/interpolation.js} +38 -38
  88. package/out/address/point/interpolation.js.map +1 -0
  89. package/out/address/point/schema.d.ts +74 -0
  90. package/out/address/point/schema.d.ts.map +1 -0
  91. package/out/address/{point-schema.js → point/schema.js} +4 -20
  92. package/out/address/point/schema.js.map +1 -0
  93. package/out/address/point.d.ts +24 -21
  94. package/out/address/point.d.ts.map +1 -1
  95. package/out/address/point.js +60 -77
  96. package/out/address/point.js.map +1 -1
  97. package/out/{address/index.js → address.d.ts} +3 -3
  98. package/out/address.d.ts.map +1 -0
  99. package/out/{address/index.d.ts → address.js} +3 -3
  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 +18 -76
  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 +170 -0
  110. package/out/build/candidate.d.ts.map +1 -0
  111. package/out/{build-candidate.js → build/candidate.js} +33 -102
  112. package/out/build/candidate.js.map +1 -0
  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 +44 -0
  118. package/out/build/slim.d.ts.map +1 -0
  119. package/out/{build-slim.js → build/slim.js} +33 -94
  120. package/out/build/slim.js.map +1 -0
  121. package/out/candidate/alias-bags.d.ts +13 -5
  122. package/out/candidate/alias-bags.d.ts.map +1 -1
  123. package/out/candidate/alias-bags.js +55 -12
  124. package/out/candidate/alias-bags.js.map +1 -1
  125. package/out/candidate/ancestors/schema.d.ts +166 -0
  126. package/out/candidate/ancestors/schema.d.ts.map +1 -0
  127. package/out/candidate/ancestors/schema.js +131 -0
  128. package/out/candidate/ancestors/schema.js.map +1 -0
  129. package/out/candidate/ancestors/sidecar.d.ts +27 -0
  130. package/out/candidate/ancestors/sidecar.d.ts.map +1 -0
  131. package/out/candidate/{ancestors-sidecar.js → ancestors/sidecar.js} +17 -24
  132. package/out/candidate/ancestors/sidecar.js.map +1 -0
  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 +8 -16
  138. package/out/candidate/extract-fold.d.ts.map +1 -1
  139. package/out/candidate/extract-fold.js +6 -48
  140. package/out/candidate/extract-fold.js.map +1 -1
  141. package/out/candidate/fts.d.ts +19 -0
  142. package/out/candidate/fts.d.ts.map +1 -0
  143. package/out/candidate/fts.js +22 -0
  144. package/out/candidate/fts.js.map +1 -0
  145. package/out/candidate/importance.d.ts +127 -0
  146. package/out/candidate/importance.d.ts.map +1 -0
  147. package/out/candidate/importance.js +162 -0
  148. package/out/candidate/importance.js.map +1 -0
  149. package/out/candidate/lookup.d.ts +36 -0
  150. package/out/candidate/lookup.d.ts.map +1 -0
  151. package/out/candidate/lookup.js +456 -0
  152. package/out/candidate/lookup.js.map +1 -0
  153. package/out/candidate/name-roles.d.ts +10 -22
  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 +34 -31
  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 +120 -0
  166. package/out/candidate/schema.d.ts.map +1 -0
  167. package/out/{candidate-schema.js → candidate/schema.js} +11 -23
  168. package/out/candidate/schema.js.map +1 -0
  169. package/out/{candidate-scoring.d.ts → candidate/scoring.d.ts} +8 -9
  170. package/out/candidate/scoring.d.ts.map +1 -0
  171. package/out/candidate/scoring.js +157 -0
  172. package/out/candidate/scoring.js.map +1 -0
  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 +26 -24
  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 +61 -50
  184. package/out/coincident-roles.js.map +1 -1
  185. package/out/convention/schema.d.ts +12 -6
  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 +33 -38
  194. package/out/coverage-manifest-schema.d.ts.map +1 -1
  195. package/out/coverage-manifest-schema.js +20 -29
  196. package/out/coverage-manifest-schema.js.map +1 -1
  197. package/out/currency-backfill.d.ts +13 -35
  198. package/out/currency-backfill.d.ts.map +1 -1
  199. package/out/currency-backfill.js +12 -39
  200. package/out/currency-backfill.js.map +1 -1
  201. package/out/env.d.ts +2 -2
  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 +31 -20
  206. package/out/exact-match.js.map +1 -1
  207. package/out/extracts.d.ts +65 -54
  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 +28 -20
  212. package/out/fst/autocomplete.d.ts.map +1 -1
  213. package/out/fst/autocomplete.js +38 -27
  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 +30 -36
  217. package/out/fst/builder.js.map +1 -1
  218. package/out/fst/deserialize-web.d.ts +3 -3
  219. package/out/fst/deserialize-web.d.ts.map +1 -1
  220. package/out/fst/deserialize-web.js +8 -9
  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 +11 -73
  227. package/out/fst/freshness.d.ts.map +1 -1
  228. package/out/fst/freshness.js +12 -76
  229. package/out/fst/freshness.js.map +1 -1
  230. package/out/fst/matcher.d.ts +1 -1
  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 +30 -26
  235. package/out/fst/serialize.d.ts.map +1 -1
  236. package/out/fst/serialize.js +44 -58
  237. package/out/fst/serialize.js.map +1 -1
  238. package/out/fst/types.d.ts +71 -59
  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} +1 -1
  243. package/out/fst.d.ts.map +1 -0
  244. package/out/{fst/index.d.ts → fst.js} +1 -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 -67
  255. package/out/geonames/aliases.d.ts.map +1 -1
  256. package/out/geonames/aliases.js +44 -121
  257. package/out/geonames/aliases.js.map +1 -1
  258. package/out/geonames/postal.d.ts +84 -50
  259. package/out/geonames/postal.d.ts.map +1 -1
  260. package/out/geonames/postal.js +115 -78
  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 +20 -21
  267. package/out/index.d.ts.map +1 -1
  268. package/out/index.js +14 -15
  269. package/out/index.js.map +1 -1
  270. package/out/interpolation.d.ts +15 -52
  271. package/out/interpolation.d.ts.map +1 -1
  272. package/out/interpolation.js +25 -68
  273. package/out/interpolation.js.map +1 -1
  274. package/out/lookup.d.ts +24 -53
  275. package/out/lookup.d.ts.map +1 -1
  276. package/out/lookup.js +117 -223
  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 +49 -141
  299. package/out/place-importance-schema.d.ts.map +1 -1
  300. package/out/place-importance-schema.js +25 -140
  301. package/out/place-importance-schema.js.map +1 -1
  302. package/out/poi/lookup.d.ts +38 -42
  303. package/out/poi/lookup.d.ts.map +1 -1
  304. package/out/poi/lookup.js +67 -90
  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 → city/alias/lookup.d.ts} +22 -25
  319. package/out/postal/city/alias/lookup.d.ts.map +1 -0
  320. package/out/postal/city/alias/lookup.js +49 -0
  321. package/out/postal/city/alias/lookup.js.map +1 -0
  322. package/out/postal/{city-alias-schema.d.ts → city/alias/schema.d.ts} +15 -11
  323. package/out/postal/city/alias/schema.d.ts.map +1 -0
  324. package/out/postal/{city-alias-schema.js → city/alias/schema.js} +11 -9
  325. package/out/postal/city/alias/schema.js.map +1 -0
  326. package/out/postal/city/candidate-schema.d.ts +72 -0
  327. package/out/postal/city/candidate-schema.d.ts.map +1 -0
  328. package/out/postal/city/candidate-schema.js +60 -0
  329. package/out/postal/city/candidate-schema.js.map +1 -0
  330. package/out/postal.d.ts +9 -0
  331. package/out/postal.d.ts.map +1 -0
  332. package/out/postal.js +9 -0
  333. package/out/postal.js.map +1 -0
  334. package/out/postcode-point-lookup.d.ts +9 -19
  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 +39 -93
  339. package/out/primary-preference.d.ts.map +1 -1
  340. package/out/primary-preference.js +13 -97
  341. package/out/primary-preference.js.map +1 -1
  342. package/out/proximity-rerank.d.ts +40 -29
  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 +91 -62
  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 +48 -29
  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 +75 -50
  355. package/out/reverse.d.ts.map +1 -1
  356. package/out/reverse.js +61 -49
  357. package/out/reverse.js.map +1 -1
  358. package/out/schema.d.ts +74 -42
  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 +25 -0
  367. package/out/sqlite/convention-source.d.ts.map +1 -0
  368. package/out/sqlite/convention-source.js +48 -0
  369. package/out/sqlite/convention-source.js.map +1 -0
  370. package/out/sqlite/utils.d.ts +45 -0
  371. package/out/sqlite/utils.d.ts.map +1 -0
  372. package/out/sqlite/utils.js +56 -0
  373. package/out/sqlite/utils.js.map +1 -0
  374. package/out/street/centroid/schema.d.ts +100 -0
  375. package/out/street/centroid/schema.d.ts.map +1 -0
  376. package/out/street/centroid/schema.js +66 -0
  377. package/out/street/centroid/schema.js.map +1 -0
  378. package/out/street/centroid.d.ts +9 -19
  379. package/out/street/centroid.d.ts.map +1 -1
  380. package/out/street/centroid.js +11 -22
  381. package/out/street/centroid.js.map +1 -1
  382. package/out/street/{morphology-fst-builder.d.ts → morphology/fst/builder.d.ts} +21 -11
  383. package/out/street/morphology/fst/builder.d.ts.map +1 -0
  384. package/out/street/{morphology-fst-builder.js → morphology/fst/builder.js} +40 -34
  385. package/out/street/morphology/fst/builder.js.map +1 -0
  386. package/out/street/morphology/fst/loader.d.ts +74 -0
  387. package/out/street/morphology/fst/loader.d.ts.map +1 -0
  388. package/out/street/{morphology-fst-loader.js → morphology/fst/loader.js} +21 -21
  389. package/out/street/morphology/fst/loader.js.map +1 -0
  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 +32 -31
  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 +74 -191
  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.d.ts → street.d.ts} +4 -4
  403. package/out/street.d.ts.map +1 -0
  404. package/out/{street/index.js → street.js} +4 -4
  405. package/out/street.js.map +1 -0
  406. package/out/types.d.ts +69 -138
  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 +20 -56
  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 +132 -141
  431. package/out/weights-overlay-linker.d.ts.map +1 -1
  432. package/out/weights-overlay-linker.js +86 -154
  433. package/out/weights-overlay-linker.js.map +1 -1
  434. package/package.json +94 -599
  435. package/lib/address/point-schema.ts +0 -155
  436. package/lib/build-candidate.ts +0 -632
  437. package/lib/build-slim.ts +0 -408
  438. package/lib/candidate-ancestors-schema.ts +0 -195
  439. package/lib/candidate-fts.ts +0 -46
  440. package/lib/candidate-importance.ts +0 -224
  441. package/lib/candidate-lookup.ts +0 -977
  442. package/lib/candidate-schema.ts +0 -247
  443. package/lib/candidate-scoring.ts +0 -261
  444. package/lib/convention/index.ts +0 -154
  445. package/lib/fts/index.ts +0 -361
  446. package/lib/postal/city-alias-lookup.ts +0 -97
  447. package/lib/postal/index.ts +0 -9
  448. package/lib/sqlite-convention-source.ts +0 -65
  449. package/lib/sqlite-utils.ts +0 -82
  450. package/lib/street/centroid-schema.ts +0 -154
  451. package/out/address/index.d.ts.map +0 -1
  452. package/out/address/index.js.map +0 -1
  453. package/out/address/point-interpolation.d.ts +0 -49
  454. package/out/address/point-interpolation.d.ts.map +0 -1
  455. package/out/address/point-interpolation.js.map +0 -1
  456. package/out/address/point-schema.d.ts +0 -97
  457. package/out/address/point-schema.d.ts.map +0 -1
  458. package/out/address/point-schema.js.map +0 -1
  459. package/out/ancestry/index.d.ts +0 -45
  460. package/out/ancestry/index.d.ts.map +0 -1
  461. package/out/ancestry/index.js +0 -55
  462. package/out/ancestry/index.js.map +0 -1
  463. package/out/build-candidate.d.ts +0 -184
  464. package/out/build-candidate.d.ts.map +0 -1
  465. package/out/build-candidate.js.map +0 -1
  466. package/out/build-slim.d.ts +0 -80
  467. package/out/build-slim.d.ts.map +0 -1
  468. package/out/build-slim.js.map +0 -1
  469. package/out/candidate/ancestors-sidecar.d.ts +0 -32
  470. package/out/candidate/ancestors-sidecar.d.ts.map +0 -1
  471. package/out/candidate/ancestors-sidecar.js.map +0 -1
  472. package/out/candidate-ancestors-schema.d.ts +0 -150
  473. package/out/candidate-ancestors-schema.d.ts.map +0 -1
  474. package/out/candidate-ancestors-schema.js +0 -123
  475. package/out/candidate-ancestors-schema.js.map +0 -1
  476. package/out/candidate-fts.d.ts +0 -37
  477. package/out/candidate-fts.d.ts.map +0 -1
  478. package/out/candidate-fts.js +0 -40
  479. package/out/candidate-fts.js.map +0 -1
  480. package/out/candidate-importance.d.ts +0 -132
  481. package/out/candidate-importance.d.ts.map +0 -1
  482. package/out/candidate-importance.js +0 -169
  483. package/out/candidate-importance.js.map +0 -1
  484. package/out/candidate-lookup.d.ts +0 -76
  485. package/out/candidate-lookup.d.ts.map +0 -1
  486. package/out/candidate-lookup.js +0 -768
  487. package/out/candidate-lookup.js.map +0 -1
  488. package/out/candidate-schema.d.ts +0 -155
  489. package/out/candidate-schema.d.ts.map +0 -1
  490. package/out/candidate-schema.js.map +0 -1
  491. package/out/candidate-scoring.d.ts.map +0 -1
  492. package/out/candidate-scoring.js +0 -196
  493. package/out/candidate-scoring.js.map +0 -1
  494. package/out/convention/index.d.ts +0 -106
  495. package/out/convention/index.d.ts.map +0 -1
  496. package/out/convention/index.js +0 -93
  497. package/out/convention/index.js.map +0 -1
  498. package/out/fst/index.d.ts.map +0 -1
  499. package/out/fst/index.js.map +0 -1
  500. package/out/fts/index.d.ts +0 -184
  501. package/out/fts/index.d.ts.map +0 -1
  502. package/out/fts/index.js +0 -277
  503. package/out/fts/index.js.map +0 -1
  504. package/out/geonames/index.d.ts.map +0 -1
  505. package/out/geonames/index.js.map +0 -1
  506. package/out/nsul/index.d.ts.map +0 -1
  507. package/out/nsul/index.js.map +0 -1
  508. package/out/poi/index.d.ts.map +0 -1
  509. package/out/poi/index.js.map +0 -1
  510. package/out/postal/city-alias-lookup.d.ts.map +0 -1
  511. package/out/postal/city-alias-lookup.js +0 -62
  512. package/out/postal/city-alias-lookup.js.map +0 -1
  513. package/out/postal/city-alias-schema.d.ts.map +0 -1
  514. package/out/postal/city-alias-schema.js.map +0 -1
  515. package/out/postal/city-candidate-schema.d.ts +0 -66
  516. package/out/postal/city-candidate-schema.d.ts.map +0 -1
  517. package/out/postal/city-candidate-schema.js +0 -56
  518. package/out/postal/city-candidate-schema.js.map +0 -1
  519. package/out/postal/index.d.ts +0 -9
  520. package/out/postal/index.d.ts.map +0 -1
  521. package/out/postal/index.js +0 -9
  522. package/out/postal/index.js.map +0 -1
  523. package/out/sqlite-convention-source.d.ts +0 -29
  524. package/out/sqlite-convention-source.d.ts.map +0 -1
  525. package/out/sqlite-convention-source.js +0 -57
  526. package/out/sqlite-convention-source.js.map +0 -1
  527. package/out/sqlite-utils.d.ts +0 -45
  528. package/out/sqlite-utils.d.ts.map +0 -1
  529. package/out/sqlite-utils.js +0 -57
  530. package/out/sqlite-utils.js.map +0 -1
  531. package/out/street/centroid-schema.d.ts +0 -105
  532. package/out/street/centroid-schema.d.ts.map +0 -1
  533. package/out/street/centroid-schema.js +0 -78
  534. package/out/street/centroid-schema.js.map +0 -1
  535. package/out/street/index.d.ts.map +0 -1
  536. package/out/street/index.js.map +0 -1
  537. package/out/street/morphology-fst-builder.d.ts.map +0 -1
  538. package/out/street/morphology-fst-builder.js.map +0 -1
  539. package/out/street/morphology-fst-loader.d.ts +0 -67
  540. package/out/street/morphology-fst-loader.d.ts.map +0 -1
  541. package/out/street/morphology-fst-loader.js.map +0 -1
  542. package/out/uprn/index.d.ts.map +0 -1
  543. package/out/uprn/index.js.map +0 -1
  544. /package/lib/{fst/index.ts → fst.ts} +0 -0
  545. /package/lib/{geonames/index.ts → geonames.ts} +0 -0
  546. /package/lib/{nsul/index.ts → nsul.ts} +0 -0
  547. /package/lib/{poi/index.ts → poi.ts} +0 -0
  548. /package/lib/{uprn/index.ts → uprn.ts} +0 -0
@@ -0,0 +1,456 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { expandPlacetypeFilter } from "@mailwoman/codex/placetype-map";
7
+ import { referentialFromPopulation } from "@mailwoman/core/resolver";
8
+ import { allRows } from "@mailwoman/core/utils";
9
+ import { jaroWinkler, levenshteinSimilarity } from "@mailwoman/match/comparators";
10
+ import { partitionByContainment } from "@mailwoman/resolver";
11
+ import { haversineKm } from "@mailwoman/spatial";
12
+ import { SQLiteLookup } from "@mailwoman/sqlite/lookup";
13
+ import { CANDIDATE_ANCESTOR_TABLE, CANDIDATE_INTERVAL_TABLE, intervalContains, } from "#candidate/ancestors/schema";
14
+ import { CANDIDATE_FTS_TABLE } from "#candidate/fts";
15
+ import { readGazetteerCoverageManifest } from "#coverage-manifest-schema";
16
+ import { POSTAL_CITY_CANDIDATE_TABLE } from "#postal/city/candidate-schema";
17
+ import { rankByPrimaryPreference, RERANK_FETCH } from "#primary-preference";
18
+ import { applyProximityRerank } from "#proximity-rerank";
19
+ import { REGION_CLASS_PLACETYPES, regionQualifierProbeKeys } from "#region-keys";
20
+ import { hasColumn, hasTable } from "#sqlite-utils";
21
+ import { normalizeLocalityForKey, stripLocalityQualifier } from "#street/normalize";
22
+ export { rankByPrimaryPreference } from "#primary-preference";
23
+ const FUZZY_FETCH = 40;
24
+ const WORD_FUZZY_MIN = 0.85;
25
+ function wordFuzzySimilarity(a, b) {
26
+ return Math.max(jaroWinkler(a, b), levenshteinSimilarity(a, b));
27
+ }
28
+ const POSTCODE_CONTAINMENT_THRESHOLD_KM = 25;
29
+ function ftsTrigramQuery(s) {
30
+ const grams = new Set();
31
+ for (let i = 0; i + 3 <= s.length; i++) {
32
+ const g = s.slice(i, i + 3);
33
+ if (/^[\p{L}\p{N} ]{3}$/u.test(g)) {
34
+ grams.add(g);
35
+ }
36
+ }
37
+ return [...grams].map((g) => `"${g}"`).join(" OR ");
38
+ }
39
+ /**
40
+ * Node {@link PlaceLookup} over `candidate.db`.
41
+ */
42
+ export class WOFCandidateTableLookup extends SQLiteLookup {
43
+ #countryToID = new Map();
44
+ #idToCountry = new Map();
45
+ #placetypeToID = new Map();
46
+ #idToPlacetype = new Map();
47
+ #postalCityProbe;
48
+ #ftsProbe;
49
+ /**
50
+ * Prepared unfiltered `name_key` existence probe, so fuzzy fallback runs only for true name misses.
51
+ */
52
+ #nameKeyExistsProbe;
53
+ artifactCoverage;
54
+ #importanceSelect;
55
+ #hasNameRole;
56
+ #variantAliasExemption;
57
+ #roleSelect;
58
+ #ancestorsProbe;
59
+ #ancestorsCache = new Map();
60
+ #intervalProbe;
61
+ #intervalCache = new Map();
62
+ #qualifierProbe;
63
+ /**
64
+ * Ancestor lineage accessor, nearest-first, present only when the artifact supports it.
65
+ */
66
+ ancestors;
67
+ constructor(opts) {
68
+ super(opts);
69
+ for (const r of allRows(this.database.prepare("SELECT id, code FROM country_codes"))) {
70
+ const code = String(r.code).toUpperCase();
71
+ this.#countryToID.set(code, Number(r.id));
72
+ this.#idToCountry.set(Number(r.id), code);
73
+ }
74
+ for (const r of allRows(this.database.prepare("SELECT id, placetype FROM placetype_codes"))) {
75
+ this.#placetypeToID.set(String(r.placetype), Number(r.id));
76
+ this.#idToPlacetype.set(Number(r.id), String(r.placetype));
77
+ }
78
+ if (hasTable(this.database, POSTAL_CITY_CANDIDATE_TABLE)) {
79
+ this.#postalCityProbe = this.database.prepare(`SELECT spr_id, name, latitude, longitude FROM ${POSTAL_CITY_CANDIDATE_TABLE} WHERE name_key = ? AND postcode = ? LIMIT 1`);
80
+ }
81
+ if (hasTable(this.database, CANDIDATE_FTS_TABLE)) {
82
+ this.#ftsProbe = this.database.prepare(`SELECT name_key FROM ${CANDIDATE_FTS_TABLE} WHERE ${CANDIDATE_FTS_TABLE} MATCH ? ORDER BY bm25(${CANDIDATE_FTS_TABLE}) LIMIT ?`);
83
+ this.#nameKeyExistsProbe = this.database.prepare("SELECT 1 FROM candidate WHERE name_key = ? LIMIT 1");
84
+ }
85
+ // Optional columns are detected once here for hot-path reads.
86
+ this.#importanceSelect = hasColumn(this.database, "candidate", "importance") ? ", importance" : "";
87
+ this.#hasNameRole = hasColumn(this.database, "candidate", "name_role");
88
+ this.#variantAliasExemption = opts.variantAliasExemption === true;
89
+ this.#roleSelect = this.#hasNameRole ? ", name_role" : "";
90
+ if (hasTable(this.database, CANDIDATE_ANCESTOR_TABLE)) {
91
+ this.#ancestorsProbe = this.database.prepare(`SELECT parent_spr_id, parent_placetype_id, parent_name FROM ${CANDIDATE_ANCESTOR_TABLE}` +
92
+ " WHERE spr_id = ? ORDER BY depth ASC");
93
+ this.ancestors = (id) => this.#ancestorLineage(id);
94
+ }
95
+ if (this.#ancestorsProbe && hasTable(this.database, CANDIDATE_INTERVAL_TABLE)) {
96
+ this.#intervalProbe = this.database.prepare(`SELECT pre, post FROM ${CANDIDATE_INTERVAL_TABLE} WHERE spr_id = ?`);
97
+ const bandIDs = [...REGION_CLASS_PLACETYPES, "country"]
98
+ .map((placetype) => this.#placetypeToID.get(placetype))
99
+ .filter((id) => id !== undefined);
100
+ if (bandIDs.length) {
101
+ this.#qualifierProbe = this.database.prepare(`SELECT DISTINCT spr_id FROM candidate WHERE name_key = ? AND placetype_id IN (${bandIDs.join(",")}) LIMIT 8`);
102
+ }
103
+ }
104
+ this.artifactCoverage = readGazetteerCoverageManifest(this.database);
105
+ }
106
+ #ancestorLineage(id) {
107
+ const pid = typeof id === "number" ? id : Number(id);
108
+ if (!Number.isFinite(pid) || !this.#ancestorsProbe)
109
+ return [];
110
+ const cached = this.#ancestorsCache.get(pid);
111
+ if (cached)
112
+ return cached;
113
+ const rows = allRows(this.#ancestorsProbe, pid);
114
+ const lineage = rows.map((r) => ({
115
+ id: Number(r.parent_spr_id),
116
+ placetype: this.#idToPlacetype.get(Number(r.parent_placetype_id)) ?? "",
117
+ name: String(r.parent_name ?? ""),
118
+ }));
119
+ this.#ancestorsCache.set(pid, lineage);
120
+ return lineage;
121
+ }
122
+ #intervalLabel(sprID) {
123
+ if (!this.#intervalProbe)
124
+ return null;
125
+ const cached = this.#intervalCache.get(sprID);
126
+ if (cached !== undefined)
127
+ return cached;
128
+ const row = this.#intervalProbe.get(sprID);
129
+ const label = row ? { pre: Number(row.pre), post: Number(row.post) } : null;
130
+ this.#intervalCache.set(sprID, label);
131
+ return label;
132
+ }
133
+ #qualifierRegionIDs(qualifier, country) {
134
+ const ids = new Set();
135
+ if (!this.#qualifierProbe)
136
+ return ids;
137
+ for (const key of regionQualifierProbeKeys(qualifier, country)) {
138
+ if (!key)
139
+ continue;
140
+ for (const row of allRows(this.#qualifierProbe, key)) {
141
+ ids.add(Number(row.spr_id));
142
+ }
143
+ }
144
+ return ids;
145
+ }
146
+ /**
147
+ * Whether `sprID` is contained by any qualifier row, using interval labels first
148
+ * and the ancestor chain as fallback.
149
+ */
150
+ #containedByQualifier(sprID, qualifierIDs, qualifierLabels) {
151
+ if (qualifierIDs.has(sprID))
152
+ return true;
153
+ const label = this.#intervalLabel(sprID);
154
+ if (label && qualifierLabels.some((outer) => intervalContains(outer, label)))
155
+ return true;
156
+ return this.#ancestorLineage(sprID).some((ancestor) => qualifierIDs.has(Number(ancestor.id)));
157
+ }
158
+ /**
159
+ * Apply admin-containment re-rank: stamp containment, inject contained misses,
160
+ * then partition contained-first.
161
+ */
162
+ #applyAdminContainment(rows, qualifier, country, opts) {
163
+ const qualifierIDs = this.#qualifierRegionIDs(qualifier, country);
164
+ if (!qualifierIDs.size) {
165
+ for (const row of rows) {
166
+ row.containedByQualifier = false;
167
+ }
168
+ return rows;
169
+ }
170
+ const qualifierLabels = [...qualifierIDs]
171
+ .map((id) => this.#intervalLabel(id))
172
+ .filter((label) => label !== null);
173
+ const contained = (sprID) => this.#containedByQualifier(sprID, qualifierIDs, qualifierLabels);
174
+ for (const row of rows) {
175
+ row.containedByQualifier = contained(Number(row.spr_id));
176
+ }
177
+ const present = new Set(rows.map((row) => Number(row.spr_id)));
178
+ const injected = [];
179
+ const injectSQL = (primaryOnly) => "SELECT spr_id, name, country_id, placetype_id, latitude, longitude, min_lat, min_lon, max_lat, max_lon, neg_rank, is_primary, population" +
180
+ `${this.#importanceSelect} FROM candidate WHERE ${["name_key = ?", ...opts.shapeFilters, ...(primaryOnly ? ["is_primary = 1"] : [])].join(" AND ")} ` +
181
+ "ORDER BY neg_rank ASC LIMIT ?";
182
+ const injectFrom = (key, primaryOnly) => {
183
+ const fetched = allRows(this.database.prepare(injectSQL(primaryOnly)), key, ...opts.shapeParams, RERANK_FETCH);
184
+ for (const row of fetched) {
185
+ const sprID = Number(row.spr_id);
186
+ if (present.has(sprID) || !contained(sprID))
187
+ continue;
188
+ present.add(sprID);
189
+ injected.push({ ...row, effectiveNegRank: row.neg_rank, demoted: false, containedByQualifier: true });
190
+ }
191
+ };
192
+ injectFrom(opts.nameKey, false);
193
+ // Also inject contained neighborhood-band namesakes (primary-keyed only).
194
+ const bandIDs = ["neighbourhood", "macrohood", "microhood"]
195
+ .map((placetype) => this.#placetypeToID.get(placetype))
196
+ .filter((id) => id !== undefined);
197
+ if (bandIDs.length) {
198
+ const bandSQL = "SELECT spr_id, name, country_id, placetype_id, latitude, longitude, min_lat, min_lon, max_lat, max_lon, neg_rank, is_primary, population" +
199
+ `${this.#importanceSelect} FROM candidate WHERE name_key = ? AND placetype_id IN (${bandIDs.map(() => "?").join(",")}) AND is_primary = 1 ` +
200
+ "ORDER BY neg_rank ASC LIMIT ?";
201
+ const fetched = allRows(this.database.prepare(bandSQL), opts.nameKey, ...bandIDs, RERANK_FETCH);
202
+ for (const row of fetched) {
203
+ const sprID = Number(row.spr_id);
204
+ if (present.has(sprID) || !contained(sprID))
205
+ continue;
206
+ present.add(sprID);
207
+ injected.push({ ...row, effectiveNegRank: row.neg_rank, demoted: false, containedByQualifier: true });
208
+ }
209
+ }
210
+ // Try stripped-key injection only when exact-key containment found no row.
211
+ if (!injected.length &&
212
+ !rows.some((row) => row.containedByQualifier) &&
213
+ opts.strippedKey &&
214
+ opts.strippedKey !== opts.nameKey) {
215
+ injectFrom(opts.strippedKey, true);
216
+ }
217
+ if (!injected.length && !rows.some((row) => row.containedByQualifier))
218
+ return rows;
219
+ return partitionByContainment([...rows, ...injected], (row) => row.containedByQualifier === true, (row) => !row.demoted && !row.fuzzy).slice(0, opts.limit);
220
+ }
221
+ #wantsLocality(placetype) {
222
+ if (!placetype)
223
+ return true;
224
+ const want = Array.isArray(placetype) ? placetype : [placetype];
225
+ return expandPlacetypeFilter(want).includes("locality");
226
+ }
227
+ #postcodeAnchor(postcode, country) {
228
+ const placetypeID = this.#placetypeToID.get("postalcode");
229
+ if (placetypeID === undefined)
230
+ return null;
231
+ const conds = ["name_key = ?", "placetype_id = ?"];
232
+ const params = [postcode.replaceAll(/\s+/g, ""), placetypeID];
233
+ if (country) {
234
+ const countryID = this.#countryToID.get(country.toUpperCase());
235
+ if (countryID === undefined)
236
+ return null; // Unknown country in this artifact.
237
+ conds.push("country_id = ?");
238
+ params.push(countryID);
239
+ }
240
+ const row = this.database
241
+ .prepare(`SELECT latitude, longitude FROM candidate WHERE ${conds.join(" AND ")} ORDER BY neg_rank ASC LIMIT 1`)
242
+ .get(...params);
243
+ if (!row || (Number(row.latitude) === 0 && Number(row.longitude) === 0))
244
+ return null;
245
+ return { lat: Number(row.latitude), lon: Number(row.longitude) };
246
+ }
247
+ async findPlace(query) {
248
+ let text = (query.text ?? "").trim();
249
+ if (!text)
250
+ return [];
251
+ // Postcode queries use whitespace-stripped keying.
252
+ const wantsPostcode = [query.placetype].flat().includes("postalcode");
253
+ if (wantsPostcode) {
254
+ text = text.replaceAll(/\s+/g, "");
255
+ }
256
+ const nameKey = normalizeLocalityForKey(text);
257
+ if (!nameKey)
258
+ return [];
259
+ if (query.postcode && this.#postalCityProbe && this.#wantsLocality(query.placetype)) {
260
+ const hit = this.#postalCityProbe.get(nameKey, query.postcode.trim());
261
+ if (hit) {
262
+ return [
263
+ {
264
+ id: Number(hit.spr_id),
265
+ name: String(hit.name ?? ""),
266
+ placetype: "locality",
267
+ country: query.country?.toUpperCase() ?? "",
268
+ lat: Number(hit.latitude),
269
+ lon: Number(hit.longitude),
270
+ score: 1,
271
+ exactMatch: true,
272
+ },
273
+ ];
274
+ }
275
+ }
276
+ const limit = Math.max(1, query.limit ?? 10);
277
+ // Shape filters are tracked separately from the shared country scope for exact and stripped probes.
278
+ const filters = [];
279
+ const filterParams = [];
280
+ const shapeFilters = [];
281
+ const shapeParams = [];
282
+ if (query.country) {
283
+ const cid = this.#countryToID.get(query.country.toUpperCase());
284
+ if (cid === undefined)
285
+ return []; // Unknown country in this artifact.
286
+ filters.push("country_id = ?");
287
+ filterParams.push(cid);
288
+ }
289
+ if (query.placetype) {
290
+ // Expand placetype equivalents (e.g. locality includes borough/localadmin).
291
+ const want = Array.isArray(query.placetype) ? query.placetype : [query.placetype];
292
+ const ids = expandPlacetypeFilter(want)
293
+ .map((t) => this.#placetypeToID.get(t))
294
+ .filter((v) => v !== undefined);
295
+ if (!ids.length)
296
+ return [];
297
+ shapeFilters.push(`placetype_id IN (${ids.map(() => "?").join(",")})`);
298
+ shapeParams.push(...ids);
299
+ }
300
+ if (query.bbox) {
301
+ const b = query.bbox;
302
+ shapeFilters.push("latitude BETWEEN ? AND ? AND longitude BETWEEN ? AND ?");
303
+ shapeParams.push(b.minLat, b.maxLat, b.minLon, b.maxLon);
304
+ }
305
+ // Optional guard: restrict to primary rows for token-extracted probes.
306
+ if (query.primaryOnly) {
307
+ shapeFilters.push("is_primary = 1");
308
+ }
309
+ // The role filter is skipped on an artifact lacking `name_role`.
310
+ if (query.excludeNameRoles?.length && this.#hasNameRole) {
311
+ shapeFilters.push(`(name_role IS NULL OR name_role NOT IN (${query.excludeNameRoles.map(() => "?").join(",")}))`);
312
+ shapeParams.push(...query.excludeNameRoles);
313
+ }
314
+ filters.push(...shapeFilters);
315
+ filterParams.push(...shapeParams);
316
+ // Region scope is optional (`region_id = parentID`); the fallback stays unscoped.
317
+ const regionParentID = query.parentID || undefined;
318
+ const probe = (nk, regionID, countryID) => {
319
+ const conds = ["name_key = ?", ...filters];
320
+ const params = [nk, ...filterParams];
321
+ if (regionID !== undefined) {
322
+ conds.push("region_id = ?");
323
+ params.push(regionID);
324
+ }
325
+ if (typeof countryID === "number") {
326
+ conds.push("country_id = ?");
327
+ params.push(countryID);
328
+ }
329
+ // Population-ordered fetch over-fetches for the bounded primary-preference rerank.
330
+ const sql = "SELECT spr_id, name, country_id, placetype_id, latitude, longitude, min_lat, min_lon, max_lat, max_lon, neg_rank, is_primary, population" +
331
+ `${this.#importanceSelect}${this.#roleSelect} FROM candidate WHERE ${conds.join(" AND ")} ORDER BY neg_rank ASC LIMIT ?`;
332
+ const fetched = allRows(this.database.prepare(sql), ...params, Math.max(limit, RERANK_FETCH));
333
+ return rankByPrimaryPreference(fetched, limit, undefined, this.#idToPlacetype, this.#variantAliasExemption);
334
+ };
335
+ const cascade = (regionID) => {
336
+ let rows = probe(nameKey, regionID);
337
+ if (!rows.length) {
338
+ const strippedKey = normalizeLocalityForKey(stripLocalityQualifier(text));
339
+ if (strippedKey && strippedKey !== nameKey) {
340
+ // Stripped probes only accept primary rows to avoid alias-scrape matches.
341
+ rows = probe(strippedKey, regionID).filter((r) => r.is_primary === 1);
342
+ }
343
+ }
344
+ // Typo-tolerant fallback for true name misses only, skipping postcodes and respecting the fuzzy-country scope.
345
+ const fuzzyCountryID = !query.country && query.fuzzyCountry ? this.#countryToID.get(query.fuzzyCountry.toUpperCase()) : undefined;
346
+ const fuzzyScopedOut = !query.country && !!query.fuzzyCountry && typeof fuzzyCountryID !== "number";
347
+ if (!rows.length &&
348
+ !wantsPostcode &&
349
+ !fuzzyScopedOut &&
350
+ this.#ftsProbe &&
351
+ this.#nameKeyExistsProbe &&
352
+ !this.#nameKeyExistsProbe.get(nameKey)) {
353
+ const match = ftsTrigramQuery(nameKey);
354
+ if (match) {
355
+ const hits = allRows(this.#ftsProbe, match, FUZZY_FETCH);
356
+ const ranked = hits
357
+ .map((h) => ({ nk: String(h.name_key), s: wordFuzzySimilarity(nameKey, String(h.name_key)) }))
358
+ .filter((h) => h.s >= WORD_FUZZY_MIN)
359
+ // oxlint-disable-next-line unicorn/no-array-sort -- sorts a freshly-built array. toSorted would double-allocate on a hot path
360
+ .sort((a, b) => b.s - a.s);
361
+ const seen = new Set();
362
+ for (const h of ranked) {
363
+ if (seen.has(h.nk))
364
+ continue;
365
+ seen.add(h.nk);
366
+ rows.push(...probe(h.nk, regionID, fuzzyCountryID).map((r) => ({ ...r, fuzzy: true })));
367
+ if (rows.length >= limit)
368
+ break;
369
+ }
370
+ rows = rows.slice(0, limit);
371
+ }
372
+ }
373
+ return rows;
374
+ };
375
+ let rows = cascade(regionParentID);
376
+ let regionScopeMiss = false;
377
+ if (!rows.length && regionParentID !== undefined) {
378
+ rows = cascade(undefined);
379
+ regionScopeMiss = rows.length > 0;
380
+ }
381
+ if (query.postcode &&
382
+ query.postcodeContainmentCoherence === true &&
383
+ this.#wantsLocality(query.placetype) &&
384
+ rows.length > 1) {
385
+ const anchor = this.#postcodeAnchor(query.postcode, query.country);
386
+ if (anchor) {
387
+ const insideThreshold = [];
388
+ const outsideThreshold = [];
389
+ for (const row of rows) {
390
+ const distanceKm = haversineKm(anchor.lat, anchor.lon, Number(row.latitude), Number(row.longitude));
391
+ if (distanceKm <= POSTCODE_CONTAINMENT_THRESHOLD_KM) {
392
+ insideThreshold.push({ row, distanceKm });
393
+ }
394
+ else {
395
+ outsideThreshold.push(row);
396
+ }
397
+ }
398
+ if (insideThreshold.length) {
399
+ // oxlint-disable-next-line unicorn/no-array-sort -- hot-path in-place sort
400
+ insideThreshold.sort((a, b) => a.distanceKm - b.distanceKm);
401
+ rows = [...insideThreshold.map(({ row }) => row), ...outsideThreshold];
402
+ }
403
+ }
404
+ }
405
+ // Admin-containment re-rank runs last.
406
+ if (query.regionQualifier?.trim() && this.#qualifierProbe && this.#wantsLocality(query.placetype)) {
407
+ rows = this.#applyAdminContainment(rows, query.regionQualifier.trim(), query.country, {
408
+ nameKey,
409
+ strippedKey: normalizeLocalityForKey(stripLocalityQualifier(text)),
410
+ shapeFilters,
411
+ shapeParams,
412
+ limit,
413
+ });
414
+ }
415
+ const candidates = rows.map((row) => {
416
+ const hasBbox = row.min_lat != null && row.max_lat != null && row.min_lon != null && row.max_lon != null;
417
+ const parent = this.#ancestorLineage(Number(row.spr_id))[0];
418
+ return {
419
+ id: Number(row.spr_id),
420
+ name: String(row.name ?? ""),
421
+ placetype: (this.#idToPlacetype.get(Number(row.placetype_id)) ?? ""),
422
+ country: this.#idToCountry.get(Number(row.country_id)) ?? "",
423
+ lat: Number(row.latitude),
424
+ lon: Number(row.longitude),
425
+ ...(parent ? { parent_id: Number(parent.id) } : {}),
426
+ score: -Number(row.neg_rank),
427
+ prominence: -Number(row.effectiveNegRank),
428
+ exactMatch: !row.demoted && !row.fuzzy,
429
+ ...(regionScopeMiss ? { regionScopeMiss: true } : {}),
430
+ ...(row.containedByQualifier === undefined ? {} : { containedByQualifier: row.containedByQualifier }),
431
+ ...(row.variantExempted ? { variantAliasExempted: true } : {}),
432
+ ...(row.population === null || row.population <= 0
433
+ ? {}
434
+ : { population: row.population, referential: referentialFromPopulation(row.population) }),
435
+ ...(typeof row.importance === "number" && Number.isFinite(row.importance)
436
+ ? { importance: row.importance }
437
+ : {}),
438
+ ...(hasBbox
439
+ ? {
440
+ bbox: {
441
+ minLat: Number(row.min_lat),
442
+ maxLat: Number(row.max_lat),
443
+ minLon: Number(row.min_lon),
444
+ maxLon: Number(row.max_lon),
445
+ },
446
+ }
447
+ : {}),
448
+ };
449
+ });
450
+ if (query.bias && query.bias.length) {
451
+ applyProximityRerank(candidates, query.bias);
452
+ }
453
+ return candidates;
454
+ }
455
+ }
456
+ //# sourceMappingURL=lookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../lib/candidate/lookup.ts"],"names":[],"mappings":"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"}
@@ -5,38 +5,26 @@
5
5
  * @file Pass 3c of the candidate build — the `name_role` detectors and the thresholds they are judged by.
6
6
  */
7
7
  import type { DatabaseClient } from "@mailwoman/sqlite/client";
8
- import type { CandidateDatabase } from "#candidate-schema";
9
8
  import type { PlaceAttrs } from "#candidate/place-attrs";
9
+ import type { CandidateDatabase } from "#candidate/schema";
10
10
  import type { WOFDatabase } from "#schema";
11
11
  /**
12
- * Key-count threshold for the gloss anomaly detector (#1730) — the sweep's own boundary: 4,000 places carried >= 50
13
- * keys, and a legitimate famous place at that count (New York, 176 keys) is separated by the PROMINENCE check, never by
14
- * this number alone.
12
+ * Key-count threshold for the gloss anomaly detector.
13
+ *
14
+ * A legitimate famous place is separated by the prominence check rather than this number by itself.
15
15
  */
16
16
  export declare const GLOSS_KEY_THRESHOLD = 50;
17
17
  /**
18
- * Placetypes the gloss detector never flags. A country or region legitimately carries a name in every language — that
19
- * is what an exonym set IS — so key volume discriminates nothing there. The detector's population is the non-admin
20
- * tail, where a place named by a common noun ("Poisson", "Sunday") accumulating 200+ translations is a
21
- * machine-translated gloss set, not fame.
18
+ * Placetypes the gloss detector never flags: a country or region legitimately has a
19
+ * name in every language, so key volume provides no signal there.
22
20
  */
23
21
  export declare const GLOSS_EXCLUDED_PLACETYPES: ReadonlySet<string>;
24
22
  /**
25
- * Pass 3c — the #1730 name-role prototype: two independent detectors over the staged rows, WRITE-ONLY in this
26
- * generation (no ranking consumer; the rank penalty is its own D-rule-conditional step with the `gloss_key` board as
27
- * regression check). Both stamp `is_primary = 0` rows only — a place's canonical name and the `place_abbr` region
28
- * abbreviations are never a gloss or a variant.
29
- *
30
- * - `gloss` is ANOMALY-based, and stamps only the certain core: key volume at/over the threshold + a non-admin placetype
31
- *
32
- * - NO measured prominence (population absent AND importance unmeasured). Provenance cannot separate a gloss from an
33
- * exonym — WOF imported both as `x_preferred` — and prominence is what rescues New York/Paris.
34
- * - `abbr` is PROVENANCE-based — the #936 signal: a WOF `variant` name in one of the country's official languages (or
35
- * English), measured there at a 13× key-collision rate. A source without a `names` table (fixture-scale admin DBs)
36
- * skips this detector loudly.
23
+ * Stamp `name_role` on non-primary rows: `abbr` by provenance, `variant` by
24
+ * own-name verdict, then `gloss` by key-volume anomaly.
37
25
  *
38
- * Returns the stamp counts plus the census the prototype exists to report: how much of the ≥-threshold key tail carries
39
- * any role.
26
+ * @returns The stamp counts plus the census the prototype exists to report:
27
+ * how much of the ≥-threshold key tail has any role.
40
28
  */
41
29
  export declare function stampNameRoles(ctx: {
42
30
  src: DatabaseClient<WOFDatabase>;
@@ -1 +1 @@
1
- {"version":3,"file":"name-roles.d.ts","sourceRoot":"","sources":["../../lib/candidate/name-roles.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAG9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAG1C;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAA;AAErC;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CASxD,CAAA;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE;IACnC,GAAG,EAAE,cAAc,CAAC,WAAW,CAAC,CAAA;IAChC,GAAG,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAA;IACtC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAC9B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAClD,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CA0K/G"}
1
+ {"version":3,"file":"name-roles.d.ts","sourceRoot":"","sources":["../../lib/candidate/name-roles.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAI9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAG1C;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAA;AAErC;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CASxD,CAAA;AAEF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE;IACnC,GAAG,EAAE,cAAc,CAAC,WAAW,CAAC,CAAA;IAChC,GAAG,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAA;IACtC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAC9B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAClD,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAoK/G"}
@@ -9,16 +9,14 @@ import { tableExists } from "@mailwoman/sqlite/introspection";
9
9
  import { isOwnNameVariant } from "#candidate/own-name";
10
10
  import { normalizeLocalityForKey } from "#street/normalize";
11
11
  /**
12
- * Key-count threshold for the gloss anomaly detector (#1730) — the sweep's own boundary: 4,000 places carried >= 50
13
- * keys, and a legitimate famous place at that count (New York, 176 keys) is separated by the PROMINENCE check, never by
14
- * this number alone.
12
+ * Key-count threshold for the gloss anomaly detector.
13
+ *
14
+ * A legitimate famous place is separated by the prominence check rather than this number by itself.
15
15
  */
16
16
  export const GLOSS_KEY_THRESHOLD = 50;
17
17
  /**
18
- * Placetypes the gloss detector never flags. A country or region legitimately carries a name in every language — that
19
- * is what an exonym set IS — so key volume discriminates nothing there. The detector's population is the non-admin
20
- * tail, where a place named by a common noun ("Poisson", "Sunday") accumulating 200+ translations is a
21
- * machine-translated gloss set, not fame.
18
+ * Placetypes the gloss detector never flags: a country or region legitimately has a
19
+ * name in every language, so key volume provides no signal there.
22
20
  */
23
21
  export const GLOSS_EXCLUDED_PLACETYPES = new Set([
24
22
  "country",
@@ -31,21 +29,11 @@ export const GLOSS_EXCLUDED_PLACETYPES = new Set([
31
29
  "county",
32
30
  ]);
33
31
  /**
34
- * Pass 3c — the #1730 name-role prototype: two independent detectors over the staged rows, WRITE-ONLY in this
35
- * generation (no ranking consumer; the rank penalty is its own D-rule-conditional step with the `gloss_key` board as
36
- * regression check). Both stamp `is_primary = 0` rows only — a place's canonical name and the `place_abbr` region
37
- * abbreviations are never a gloss or a variant.
38
- *
39
- * - `gloss` is ANOMALY-based, and stamps only the certain core: key volume at/over the threshold + a non-admin placetype
40
- *
41
- * - NO measured prominence (population absent AND importance unmeasured). Provenance cannot separate a gloss from an
42
- * exonym — WOF imported both as `x_preferred` — and prominence is what rescues New York/Paris.
43
- * - `abbr` is PROVENANCE-based — the #936 signal: a WOF `variant` name in one of the country's official languages (or
44
- * English), measured there at a 13× key-collision rate. A source without a `names` table (fixture-scale admin DBs)
45
- * skips this detector loudly.
32
+ * Stamp `name_role` on non-primary rows: `abbr` by provenance, `variant` by
33
+ * own-name verdict, then `gloss` by key-volume anomaly.
46
34
  *
47
- * Returns the stamp counts plus the census the prototype exists to report: how much of the ≥-threshold key tail carries
48
- * any role.
35
+ * @returns The stamp counts plus the census the prototype exists to report:
36
+ * how much of the ≥-threshold key tail has any role.
49
37
  */
50
38
  export function stampNameRoles(ctx) {
51
39
  const { src, out, attrs, keyCounts, glossThreshold, progress } = ctx;
@@ -63,7 +51,7 @@ export function stampNameRoles(ctx) {
63
51
  continue;
64
52
  if (GLOSS_EXCLUDED_PLACETYPES.has(ptNameByID.get(a.ptid) ?? ""))
65
53
  continue;
66
- if (a.pop > 0 || a.imp != null)
54
+ if ((a.pop ?? 0) > 0 || a.imp != null)
67
55
  continue;
68
56
  glossSids.push(sid);
69
57
  }
@@ -73,9 +61,8 @@ export function stampNameRoles(ctx) {
73
61
  const hasSourceNames = tableExists(src, "names");
74
62
  if (hasSourceNames) {
75
63
  out.exec("BEGIN");
76
- // Two provenance routes into the same stamp: WOF's abbreviation/short name KINDS arrive in the
77
- // LANGUAGE column ('abbr'/'short' — 280 rows, measured 2026-08-18, Toledo's 'TO' among them) and
78
- // qualify by kind alone; everything else qualifies as a variant in an official language.
64
+ // WOF's abbreviation/short name kinds qualify by kind only.
65
+ // Everything else qualifies as a variant in an official language.
79
66
  for (const r of src
80
67
  .prepare("SELECT id, name, language FROM names WHERE privateuse = 'variant' OR language IN ('abbr', 'short')")
81
68
  .iterate()) {
@@ -98,19 +85,14 @@ export function stampNameRoles(ctx) {
98
85
  else {
99
86
  progress("roles", "source carries no `names` table — abbr detector skipped (gloss still runs)");
100
87
  }
101
- // Stamp order is precedence: the provenance-based abbr first, then the own-name variant verdict,
102
- // then gloss fills what neither claimed.
88
+ // Stamp order is precedence: abbr first, then the own-name variant verdict, then gloss fills what neither claimed.
103
89
  const roleAbbr = Number(out
104
90
  .prepare(`UPDATE cand_stage SET name_role = 'abbr'
105
91
  WHERE is_primary = 0 AND EXISTS (
106
92
  SELECT 1 FROM role_key rk WHERE rk.spr_id = cand_stage.spr_id AND rk.name_key = cand_stage.name_key)`)
107
93
  .run().changes);
108
- // --- variant detector (#1882): the alias surface is the holder's OWN primary name in another
109
- // orthography — romanization, spacing/diacritic variant, or abbreviation expansion. The verdict
110
- // is per (alias key, primary key) pair, so it runs in JS over the still-unstamped alias rows;
111
- // an uncovered script answers no-verdict and stamps nothing (own-name.ts owns the predicate and
112
- // its measured threshold). Runs BEFORE gloss on purpose: a surface that IS the place's own name
113
- // is not a translation, whatever the key volume says.
94
+ // Runs before gloss so the place's own name remains its source name.
95
+ // An uncovered script answers no-verdict.
114
96
  out.exec("CREATE TEMP TABLE variant_key (spr_id INTEGER NOT NULL, name_key TEXT NOT NULL, PRIMARY KEY (spr_id, name_key)) WITHOUT ROWID");
115
97
  const insVariantKey = out.prepare("INSERT OR IGNORE INTO variant_key VALUES (?, ?)");
116
98
  let variantScanned = 0;