@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
@@ -9,24 +9,22 @@ import { isOfficialLanguage } from "@mailwoman/codex/country"
9
9
  import type { DatabaseClient } from "@mailwoman/sqlite/client"
10
10
  import { tableExists } from "@mailwoman/sqlite/introspection"
11
11
 
12
- import type { CandidateDatabase } from "#candidate-schema"
13
12
  import { isOwnNameVariant } from "#candidate/own-name"
14
13
  import type { PlaceAttrs } from "#candidate/place-attrs"
14
+ import type { CandidateDatabase } from "#candidate/schema"
15
15
  import type { WOFDatabase } from "#schema"
16
16
  import { normalizeLocalityForKey } from "#street/normalize"
17
17
 
18
18
  /**
19
- * Key-count threshold for the gloss anomaly detector (#1730) — the sweep's own boundary: 4,000 places carried >= 50
20
- * keys, and a legitimate famous place at that count (New York, 176 keys) is separated by the PROMINENCE check, never by
21
- * this number alone.
19
+ * Key-count threshold for the gloss anomaly detector.
20
+ *
21
+ * A legitimate famous place is separated by the prominence check rather than this number by itself.
22
22
  */
23
23
  export const GLOSS_KEY_THRESHOLD = 50
24
24
 
25
25
  /**
26
- * Placetypes the gloss detector never flags. A country or region legitimately carries a name in every language — that
27
- * is what an exonym set IS — so key volume discriminates nothing there. The detector's population is the non-admin
28
- * tail, where a place named by a common noun ("Poisson", "Sunday") accumulating 200+ translations is a
29
- * machine-translated gloss set, not fame.
26
+ * Placetypes the gloss detector never flags: a country or region legitimately has a
27
+ * name in every language, so key volume provides no signal there.
30
28
  */
31
29
  export const GLOSS_EXCLUDED_PLACETYPES: ReadonlySet<string> = new Set([
32
30
  "country",
@@ -40,21 +38,11 @@ export const GLOSS_EXCLUDED_PLACETYPES: ReadonlySet<string> = new Set([
40
38
  ])
41
39
 
42
40
  /**
43
- * Pass 3c — the #1730 name-role prototype: two independent detectors over the staged rows, WRITE-ONLY in this
44
- * generation (no ranking consumer; the rank penalty is its own D-rule-conditional step with the `gloss_key` board as
45
- * regression check). Both stamp `is_primary = 0` rows only — a place's canonical name and the `place_abbr` region
46
- * abbreviations are never a gloss or a variant.
47
- *
48
- * - `gloss` is ANOMALY-based, and stamps only the certain core: key volume at/over the threshold + a non-admin placetype
49
- *
50
- * - NO measured prominence (population absent AND importance unmeasured). Provenance cannot separate a gloss from an
51
- * exonym — WOF imported both as `x_preferred` — and prominence is what rescues New York/Paris.
52
- * - `abbr` is PROVENANCE-based — the #936 signal: a WOF `variant` name in one of the country's official languages (or
53
- * English), measured there at a 13× key-collision rate. A source without a `names` table (fixture-scale admin DBs)
54
- * skips this detector loudly.
41
+ * Stamp `name_role` on non-primary rows: `abbr` by provenance, `variant` by
42
+ * own-name verdict, then `gloss` by key-volume anomaly.
55
43
  *
56
- * Returns the stamp counts plus the census the prototype exists to report: how much of the ≥-threshold key tail carries
57
- * any role.
44
+ * @returns The stamp counts plus the census the prototype exists to report:
45
+ * how much of the ≥-threshold key tail has any role.
58
46
  */
59
47
  export function stampNameRoles(ctx: {
60
48
  src: DatabaseClient<WOFDatabase>
@@ -85,7 +73,7 @@ export function stampNameRoles(ctx: {
85
73
 
86
74
  if (GLOSS_EXCLUDED_PLACETYPES.has(ptNameByID.get(a.ptid) ?? "")) continue
87
75
 
88
- if (a.pop > 0 || a.imp != null) continue
76
+ if ((a.pop ?? 0) > 0 || a.imp != null) continue
89
77
  glossSids.push(sid)
90
78
  }
91
79
 
@@ -101,9 +89,8 @@ export function stampNameRoles(ctx: {
101
89
  if (hasSourceNames) {
102
90
  out.exec("BEGIN")
103
91
 
104
- // Two provenance routes into the same stamp: WOF's abbreviation/short name KINDS arrive in the
105
- // LANGUAGE column ('abbr'/'short' — 280 rows, measured 2026-08-18, Toledo's 'TO' among them) and
106
- // qualify by kind alone; everything else qualifies as a variant in an official language.
92
+ // WOF's abbreviation/short name kinds qualify by kind only.
93
+ // Everything else qualifies as a variant in an official language.
107
94
  for (const r of src
108
95
  .prepare("SELECT id, name, language FROM names WHERE privateuse = 'variant' OR language IN ('abbr', 'short')")
109
96
  .iterate()) {
@@ -129,8 +116,7 @@ export function stampNameRoles(ctx: {
129
116
  progress("roles", "source carries no `names` table — abbr detector skipped (gloss still runs)")
130
117
  }
131
118
 
132
- // Stamp order is precedence: the provenance-based abbr first, then the own-name variant verdict,
133
- // then gloss fills what neither claimed.
119
+ // Stamp order is precedence: abbr first, then the own-name variant verdict, then gloss fills what neither claimed.
134
120
  const roleAbbr = Number(
135
121
  out
136
122
  .prepare(
@@ -141,12 +127,8 @@ export function stampNameRoles(ctx: {
141
127
  .run().changes
142
128
  )
143
129
 
144
- // --- variant detector (#1882): the alias surface is the holder's OWN primary name in another
145
- // orthography — romanization, spacing/diacritic variant, or abbreviation expansion. The verdict
146
- // is per (alias key, primary key) pair, so it runs in JS over the still-unstamped alias rows;
147
- // an uncovered script answers no-verdict and stamps nothing (own-name.ts owns the predicate and
148
- // its measured threshold). Runs BEFORE gloss on purpose: a surface that IS the place's own name
149
- // is not a translation, whatever the key volume says.
130
+ // Runs before gloss so the place's own name remains its source name.
131
+ // An uncovered script answers no-verdict.
150
132
  out.exec(
151
133
  "CREATE TEMP TABLE variant_key (spr_id INTEGER NOT NULL, name_key TEXT NOT NULL, PRIMARY KEY (spr_id, name_key)) WITHOUT ROWID"
152
134
  )
@@ -3,40 +3,36 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
- * The OWN-NAME VARIANT predicate (#1882): is an alias surface the holder's own primary name in
7
- * another orthography — a romanization (`Брэст` → `brest`), a spacing/diacritic variant
8
- * (`George Town` → `georgetown`), an abbreviation expansion (`St. George's` → `Saint George's`)
9
- * — rather than a different name that merely shares the folded key?
6
+ * The own-name variant predicate: is an alias surface the holder's own primary name in another
7
+ * orthography, whether a romanization (`Брэст` → `brest`), a spacing or diacritic variant
8
+ * (`George Town` → `georgetown`), or an abbreviation expansion (`St. George's` → `Saint George's`)?
9
+ * The alternative is a different name that merely shares the folded key.
10
10
  *
11
- * The comparator is `levenshteinSimilarity`, NOT Jaro-Winkler: JW's common-prefix bonus scores
12
- * the required NEGATIVE case (`chanchun` vs `cancun`, 0.925) above real positives
13
- * (`saint george s` vs `st georges` expanded, 0.914), so no JW threshold separates them.
14
- * Measured on the #1882 census contests, edit similarity separates every case with margin:
11
+ * The comparator is `levenshteinSimilarity`. Jaro-Winkler's common-prefix bonus scores the required
12
+ * negative case (`chanchun` against `cancun`, 0.925) above real positives (`saint george s` against
13
+ * `st georges` expanded, 0.914), so no JW threshold separates them. Edit similarity separates every
14
+ * measured case with margin.
15
15
  *
16
- * - IN: `brest`/`brest` 1.0 · `george town`/`georgetown` 0.909 · `saint george s`/`saint georges`
17
- * 0.929 · `adamovka`/`adamowka` 0.875
18
- * - OUT: `lievin`/`levin` 0.833 (Liévin FR vs Levin NZ — different places with near-identical
19
- * names; the panel's `41 Weraroa Road, Levin` row needs this side) · `chanchun`/`cancun` 0.75 ·
20
- * `augsburg`/`augusta` 0.375 · `west bay`/`west end` 0.625 · `derry`/`londonderry` 0.455
21
- * (Derry/Londonderry is a DUAL NAME, not a variant — its own follow-up on #1882)
22
- *
23
- * An unhandled script (Arabic, Hebrew, CJK — the romanizer covers Cyrillic only) answers NULL,
24
- * never "different name": absence of a verdict must not stamp anything (the meaning-of-zero rule).
25
- * The #1882 census counted 396 demoted Arabic/Hebrew-primary aliases left unclassified by this.
16
+ * An unhandled script (Arabic, Hebrew, CJK, since the romanizer covers Cyrillic only) answers NULL,
17
+ * never "different name". Absence of a verdict must not stamp anything.
26
18
  */
27
19
 
28
20
  import { levenshteinSimilarity } from "@mailwoman/match/comparators"
29
21
 
30
22
  /**
31
- * Edit-similarity floor for the variant verdict. The measured band: nearest admitted pair 0.875
32
- * (`adamovka`/`adamowka`), nearest refused pair 0.833 (`lievin`/`levin`).
23
+ * Edit-similarity floor for the variant verdict.
24
+ *
25
+ * The measured band: nearest admitted pair 0.875 (`adamovka`/`adamowka`),
26
+ * nearest refused pair 0.833 (`lievin`/`levin`).
33
27
  */
34
28
  export const VARIANT_SIMILARITY_MIN = 0.85
35
29
 
36
30
  /**
37
- * BGN/PCGN-flavored Cyrillic romanization, folded to the name-key alphabet. Digraph outputs (zh, kh, ts, ch, sh, shch,
38
- * yu, ya) match the dominant transliteration conventions the gazetteer's Latin aliases actually use; the `w`/`v` and
39
- * `kh`/`h` style variance between systems is what the edit-similarity threshold absorbs.
31
+ * BGN/pcgn-flavored Cyrillic romanization, folded to the name-key alphabet.
32
+ *
33
+ * Digraph outputs (zh, kh, ts, ch, sh, shch, yu, ya) match the dominant transliteration
34
+ * conventions the gazetteer's Latin aliases actually use.
35
+ * The `w`/`v` and `kh`/`h` style variance between systems is what the edit-similarity threshold absorbs.
40
36
  */
41
37
  const CYRILLIC_TO_LATIN: Record<string, string> = {
42
38
  а: "a",
@@ -80,8 +76,10 @@ const CYRILLIC_TO_LATIN: Record<string, string> = {
80
76
  }
81
77
 
82
78
  /**
83
- * Leading-word abbreviations expanded BEFORE comparison, so `st georges` meets `saint george s` inside the edit
84
- * threshold. Whole-word only — `st` inside `stanley` never expands.
79
+ * Leading-word abbreviations expanded before comparison, so `st georges` meets
80
+ * `saint george s` inside the edit threshold.
81
+ *
82
+ * Whole-word only, so `st` inside `stanley` never expands.
85
83
  */
86
84
  const NAME_ABBREVIATIONS: ReadonlyArray<[RegExp, string]> = [
87
85
  [/\bst\b/g, "saint"],
@@ -91,7 +89,7 @@ const NAME_ABBREVIATIONS: ReadonlyArray<[RegExp, string]> = [
91
89
  ]
92
90
 
93
91
  /**
94
- * Expand the whole-word abbreviations above.
92
+ * Expand the whole-word abbreviations above in a name key.
95
93
  */
96
94
  export function expandNameAbbreviations(key: string): string {
97
95
  let out = key
@@ -104,8 +102,10 @@ export function expandNameAbbreviations(key: string): string {
104
102
  }
105
103
 
106
104
  /**
107
- * Romanize a folded name key to the a–z0–9/space alphabet. `null` when characters outside the covered scripts remain —
108
- * an unhandled script is NO VERDICT, not a mismatch.
105
+ * Romanize a folded name key to the a–z0–9/space alphabet.
106
+ *
107
+ * `null` when characters outside the covered scripts remain.
108
+ * An unhandled script is no verdict.
109
109
  */
110
110
  export function romanizeNameKey(key: string): string | null {
111
111
  let out = ""
@@ -124,10 +124,13 @@ export function romanizeNameKey(key: string): string | null {
124
124
  }
125
125
 
126
126
  /**
127
- * Edit similarity between a holder's primary name key and one of its alias keys, both romanized and
128
- * abbreviation-expanded. `null` when either side's script is uncovered.
127
+ * Edit similarity between a holder's primary name key and one of its alias keys,
128
+ * both romanized and abbreviation-expanded.
129
+ *
130
+ * `null` when either side's script is uncovered.
129
131
  */
130
- // repo-health-ignore export-name-affix -- romanizes and expands abbreviations first; `nameSimilarity` compares as given.
132
+ // repo-health-ignore export-name-affix -- romanizes and expands abbreviations first;
133
+ // `nameSimilarity` compares as given.
131
134
  export function ownNameSimilarity(primaryKey: string, aliasKey: string): number | null {
132
135
  const primary = romanizeNameKey(primaryKey)
133
136
  const alias = romanizeNameKey(aliasKey)
@@ -4,12 +4,11 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  * @file The per-place record every candidate-staging pass writes its rows from.
6
6
  *
7
- * Pass 1 reduces each current `spr` row to one {@link PlaceAttrs}; every later pass (alias bags,
7
+ * Pass 1 reduces each current `spr` row to one {@link PlaceAttrs}. Every later pass (alias bags,
8
8
  * region abbreviations, country display names, the currency backfill, the extract folds) discovers
9
- * ADDITIONAL name keys for a place already in that map and stages a row against the same record.
10
- * That is what keeps each candidate row denormalized without re-reading the source, and it is why
11
- * a pass needs exactly four things to stage: the key it found, the place, the id the row hangs on,
12
- * and whether the key is the place's canonical name.
9
+ * additional name keys for a place already in that map and stages a row against the same record.
10
+ * That keeps each candidate row denormalized without re-reading the source. A pass therefore needs
11
+ * exactly four values: the key, place, row ID, plus a flag for the place's canonical name.
13
12
  */
14
13
 
15
14
  export interface PlaceAttrs {
@@ -23,22 +22,30 @@ export interface PlaceAttrs {
23
22
  mnLon: number
24
23
  mxLat: number
25
24
  mxLon: number
26
- pop: number
25
+ /**
26
+ * The place's recorded population, or null when the gazetteer never measured one.
27
+ *
28
+ * NULL rather than zero.
29
+ * `place_population` holds no zero, so an absent row is the only way a place has no number.
30
+ * A zero written for those would be an unmeasured count.
31
+ */
32
+ pop: number | null
27
33
  neg: number
28
34
  pkey: string
29
35
  /**
30
- * The place's toponym-fame score, or null when the score source has no measurement for it (#28). A property of the
31
- * PLACE, so it rides {@link StageRow} onto the alias and abbrev rows too — that is how a bare `Moscow` reaches
32
- * Москва's score through the alias row that carries the key.
36
+ * The place's toponym-fame score, or null when the score source has no measurement for it.
37
+ *
38
+ * A property of the place, so it appears on {@link StageRow} and on alias and abbrev rows too.
39
+ * That is how a bare `Moscow` reaches Москва's score through the alias row that includes the key.
33
40
  */
34
41
  imp: number | null
35
42
  }
36
43
 
37
44
  /**
38
- * Stage one candidate row: a normalized name key, the place it belongs to, the source id the row hangs on, and whether
39
- * the key is that place's canonical name (`is_primary`).
45
+ * Stages one candidate row with a normalized name key, place, source ID,
46
+ * plus a canonical-name flag (`is_primary`).
40
47
  *
41
- * `sid` is passed separately rather than read off the place because a extract fold and the alias pass stage rows for
42
- * ids the admin `attrs` map never held.
48
+ * `sid` is passed separately rather than read off the place because an extract fold
49
+ * and the alias pass stage rows for ids the admin `attrs` map never held.
43
50
  */
44
51
  export type StageRow = (k: string, a: PlaceAttrs, sid: number, isPrimary: number) => void
@@ -0,0 +1,211 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+
7
+ import { sql, type Kysely } from "kysely"
8
+
9
+ import type { CandidateAncestorsDatabase } from "#candidate/ancestors/schema"
10
+ import type { CapitalTable } from "#capital-schema"
11
+ import type { NameKey } from "#street/normalize"
12
+
13
+ /**
14
+ * One candidate row.
15
+ *
16
+ * `name_key`, four small integer keys, `neg_rank`, and `spr_id` form the clustered primary key.
17
+ * The remaining fields are denormalized so a resolve needs one probe.
18
+ */
19
+ export interface CandidateTable {
20
+ /**
21
+ * The shared {@link normalizeLocalityForKey} of the name/alias — the probe key.
22
+ */
23
+ name_key: NameKey
24
+ /**
25
+ * Small int from {@link CountryCodeTable} (shrinks the clustered key).
26
+ */
27
+ country_id: number
28
+ /**
29
+ * The place's region-tier ancestor id, or 0.
30
+ */
31
+ region_id: number
32
+ /**
33
+ * Small int from {@link PlacetypeCodeTable}.
34
+ */
35
+ placetype_id: number
36
+ /**
37
+ * `-log10(population + 1)`.
38
+ *
39
+ * The sort uses ascending order to put the highest population first.
40
+ * Postcodes use `0`.
41
+ */
42
+ neg_rank: number
43
+ /**
44
+ * WOF id of the place this row resolves to.
45
+ */
46
+ spr_id: number
47
+ name: string | null
48
+ latitude: number | null
49
+ longitude: number | null
50
+ min_lat: number | null
51
+ min_lon: number | null
52
+ max_lat: number | null
53
+ max_lon: number | null
54
+ population: number | null
55
+ /**
56
+ * 1 when the row is the place's canonical name (vs an alias/abbrev).
57
+ */
58
+ is_primary: number | null
59
+ /**
60
+ * Blended place importance in [0, 1], NULL when unmeasured (never zero) and copied
61
+ * verbatim from the pre-split score source rather than the split `encyclopedic` channel.
62
+ */
63
+ importance: number | null
64
+ /**
65
+ * The name's detected role on this row (`'abbr'`, `'gloss'` or `'variant'`),
66
+ * or NULL when no role was detected.
67
+ * The column is write-only in this build generation.
68
+ */
69
+ name_role: string | null
70
+ }
71
+
72
+ /**
73
+ * `(id → ISO country code)` dictionary.
74
+ */
75
+ export interface CountryCodeTable {
76
+ id: number
77
+ code: string
78
+ }
79
+
80
+ /**
81
+ * `(id → placetype)` dictionary.
82
+ */
83
+ export interface PlacetypeCodeTable {
84
+ id: number
85
+ placetype: string
86
+ }
87
+
88
+ /**
89
+ * The candidate database schema, extending the ancestors sidecar so one typed
90
+ * client covers every table in the artifact.
91
+ */
92
+ export interface CandidateDatabase extends CandidateAncestorsDatabase {
93
+ /**
94
+ * The clustered `without rowid` lookup table the reader probes.
95
+ */
96
+ candidate: CandidateTable
97
+ /**
98
+ * Transient staging table (same columns); dropped once `candidate` is materialized.
99
+ */
100
+ cand_stage: CandidateTable
101
+ country_codes: CountryCodeTable
102
+ placetype_codes: PlacetypeCodeTable
103
+ /**
104
+ * The capital-status reference stored in the artifact.
105
+ * See capital-schema.ts.
106
+ */
107
+ capital: CapitalTable
108
+ }
109
+
110
+ /**
111
+ * The `candidate`/`cand_stage` columns in clustered-key order, from which the
112
+ * materialization derives its column list.
113
+ * Keep in sync with {@link CandidateTable}.
114
+ */
115
+ export const CANDIDATE_COLUMNS = [
116
+ "name_key",
117
+ "country_id",
118
+ "region_id",
119
+ "placetype_id",
120
+ "neg_rank",
121
+ "spr_id",
122
+ "name",
123
+ "latitude",
124
+ "longitude",
125
+ "min_lat",
126
+ "min_lon",
127
+ "max_lat",
128
+ "max_lon",
129
+ "population",
130
+ "is_primary",
131
+ // Appended, never inserted mid-list: the positional `insert into cand_stage values (…)` binds by position.
132
+ "importance",
133
+ "name_role",
134
+ ] as const
135
+
136
+ /**
137
+ * Create the code dictionaries and the transient staging table; `cand_stage` mirrors
138
+ * {@link CandidateTable} with every column nullable because the loader fills them positionally.
139
+ */
140
+ export async function createCandidateStagingTables(db: Kysely<CandidateDatabase>): Promise<void> {
141
+ await db.schema
142
+ .createTable("country_codes")
143
+ .addColumn("id", "integer", (c) => c.primaryKey())
144
+ .addColumn("code", "text", (c) => c.unique())
145
+ .execute()
146
+
147
+ await db.schema
148
+ .createTable("placetype_codes")
149
+ .addColumn("id", "integer", (c) => c.primaryKey())
150
+ .addColumn("placetype", "text", (c) => c.unique())
151
+ .execute()
152
+
153
+ await db.schema
154
+ .createTable("cand_stage")
155
+ .addColumn("name_key", "text")
156
+ .addColumn("country_id", "integer")
157
+ .addColumn("region_id", "integer")
158
+ .addColumn("placetype_id", "integer")
159
+ .addColumn("neg_rank", "real")
160
+ .addColumn("spr_id", "integer")
161
+ .addColumn("name", "text")
162
+ .addColumn("latitude", "real")
163
+ .addColumn("longitude", "real")
164
+ .addColumn("min_lat", "real")
165
+ .addColumn("min_lon", "real")
166
+ .addColumn("max_lat", "real")
167
+ .addColumn("max_lon", "real")
168
+ .addColumn("population", "integer")
169
+ .addColumn("is_primary", "integer")
170
+ .addColumn("importance", "real")
171
+ .addColumn("name_role", "text")
172
+ .execute()
173
+ }
174
+
175
+ /**
176
+ * Create the clustered `without rowid` lookup table.
177
+ *
178
+ * Its first six columns form the primary key, ranked by population through `neg_rank`.
179
+ */
180
+ export async function createCandidateTable(db: Kysely<CandidateDatabase>): Promise<void> {
181
+ await db.schema
182
+ .createTable("candidate")
183
+ .addColumn("name_key", "text", (c) => c.notNull())
184
+ .addColumn("country_id", "integer", (c) => c.notNull())
185
+ .addColumn("region_id", "integer", (c) => c.notNull())
186
+ .addColumn("placetype_id", "integer", (c) => c.notNull())
187
+ .addColumn("neg_rank", "real", (c) => c.notNull())
188
+ .addColumn("spr_id", "integer", (c) => c.notNull())
189
+ .addColumn("name", "text")
190
+ .addColumn("latitude", "real")
191
+ .addColumn("longitude", "real")
192
+ .addColumn("min_lat", "real")
193
+ .addColumn("min_lon", "real")
194
+ .addColumn("max_lat", "real")
195
+ .addColumn("max_lon", "real")
196
+ .addColumn("population", "integer")
197
+ .addColumn("is_primary", "integer")
198
+ .addColumn("importance", "real")
199
+ .addColumn("name_role", "text")
200
+ .addPrimaryKeyConstraint("candidate_pk", [
201
+ "name_key",
202
+ "country_id",
203
+ "region_id",
204
+ "placetype_id",
205
+ "neg_rank",
206
+ "spr_id",
207
+ ])
208
+ // `without rowid` has no first-class builder. The raw modifier is the idiomatic fallback.
209
+ .modifyEnd(sql`without rowid`)
210
+ .execute()
211
+ }