@mailwoman/resolver-wof-sqlite 9.2.0 → 9.4.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 (493) hide show
  1. package/README.md +16 -19
  2. package/lib/address/index.ts +9 -0
  3. package/{address-point-interpolation.ts → lib/address/point-interpolation.ts} +25 -24
  4. package/{address-point-schema.ts → lib/address/point-schema.ts} +18 -4
  5. package/lib/address/point.ts +328 -0
  6. package/{ancestry-backfill.ts → lib/ancestry/backfill.ts} +14 -19
  7. package/{ancestry.ts → lib/ancestry/index.ts} +5 -4
  8. package/{build-candidate.ts → lib/build-candidate.ts} +99 -79
  9. package/{build-slim.ts → lib/build-slim.ts} +150 -165
  10. package/{candidate → lib/candidate}/alias-bags.ts +8 -6
  11. package/{candidate → lib/candidate}/ancestors-sidecar.ts +13 -15
  12. package/{candidate → lib/candidate}/country-display-names.ts +2 -2
  13. package/lib/candidate/extract-fold.ts +219 -0
  14. package/{candidate → lib/candidate}/name-roles.ts +17 -16
  15. package/{candidate → lib/candidate}/own-name.ts +2 -1
  16. package/{candidate → lib/candidate}/place-attrs.ts +3 -3
  17. package/{candidate-ancestors-schema.ts → lib/candidate-ancestors-schema.ts} +4 -4
  18. package/{candidate-fts.ts → lib/candidate-fts.ts} +3 -3
  19. package/{candidate-importance.ts → lib/candidate-importance.ts} +53 -57
  20. package/{candidate-lookup.ts → lib/candidate-lookup.ts} +84 -80
  21. package/{candidate-schema.ts → lib/candidate-schema.ts} +6 -6
  22. package/{candidate-scoring.ts → lib/candidate-scoring.ts} +15 -22
  23. package/{capital-schema.ts → lib/capital-schema.ts} +5 -6
  24. package/{capitals.ts → lib/capitals.ts} +2 -2
  25. package/{coincident-roles.ts → lib/coincident-roles.ts} +9 -13
  26. package/{convention.ts → lib/convention/index.ts} +3 -3
  27. package/{convention-schema.ts → lib/convention/schema.ts} +2 -2
  28. package/{coverage-manifest-schema.ts → lib/coverage-manifest-schema.ts} +10 -10
  29. package/{currency-backfill.ts → lib/currency-backfill.ts} +126 -41
  30. package/lib/env.ts +50 -0
  31. package/{exact-match.ts → lib/exact-match.ts} +23 -14
  32. package/{sharding.ts → lib/extracts.ts} +61 -58
  33. package/{fst-autocomplete.ts → lib/fst/autocomplete.ts} +4 -4
  34. package/{fst-builder.ts → lib/fst/builder.ts} +17 -16
  35. package/{fst-deserialize-web.ts → lib/fst/deserialize-web.ts} +27 -87
  36. package/lib/fst/format.ts +106 -0
  37. package/{fst-freshness.ts → lib/fst/freshness.ts} +40 -74
  38. package/lib/fst/index.ts +14 -0
  39. package/{fst-matcher.ts → lib/fst/matcher.ts} +1 -1
  40. package/{fst-serialize.ts → lib/fst/serialize.ts} +37 -115
  41. package/{fst-types.ts → lib/fst/types.ts} +4 -2
  42. package/{fts.ts → lib/fts/index.ts} +24 -19
  43. package/{fts-query.ts → lib/fts/query.ts} +1 -1
  44. package/{geonames-aliases.ts → lib/geonames/aliases.ts} +13 -13
  45. package/lib/geonames/index.ts +8 -0
  46. package/{geonames-postal.ts → lib/geonames/postal.ts} +14 -13
  47. package/{index.ts → lib/index.ts} +37 -37
  48. package/{interpolation.ts → lib/interpolation.ts} +28 -26
  49. package/{lookup.ts → lib/lookup.ts} +130 -142
  50. package/lib/nsul/index.ts +8 -0
  51. package/lib/nsul/lookup.ts +144 -0
  52. package/lib/nsul/schema.ts +130 -0
  53. package/{place-importance-schema.ts → lib/place-importance-schema.ts} +7 -16
  54. package/lib/poi/index.ts +8 -0
  55. package/{poi-lookup.ts → lib/poi/lookup.ts} +22 -29
  56. package/{poi-schema.ts → lib/poi/schema.ts} +3 -4
  57. package/{postal-city-alias-lookup.ts → lib/postal/city-alias-lookup.ts} +14 -20
  58. package/{postal-city-candidate-schema.ts → lib/postal/city-candidate-schema.ts} +2 -2
  59. package/lib/postal/index.ts +9 -0
  60. package/{postcode-point-lookup.ts → lib/postcode-point-lookup.ts} +17 -15
  61. package/{primary-preference.ts → lib/primary-preference.ts} +43 -14
  62. package/{proximity-rerank.ts → lib/proximity-rerank.ts} +2 -2
  63. package/{ranking-weights.ts → lib/ranking-weights.ts} +30 -4
  64. package/{region-keys.ts → lib/region-keys.ts} +9 -9
  65. package/{reverse.ts → lib/reverse.ts} +34 -47
  66. package/{schema.ts → lib/schema.ts} +10 -0
  67. package/{search-fetch.ts → lib/search-fetch.ts} +29 -29
  68. package/{sqlite-convention-source.ts → lib/sqlite-convention-source.ts} +9 -10
  69. package/{sqlite-utils.ts → lib/sqlite-utils.ts} +14 -19
  70. package/{street-centroid-schema.ts → lib/street/centroid-schema.ts} +5 -5
  71. package/{street-centroid.ts → lib/street/centroid.ts} +15 -22
  72. package/lib/street/index.ts +13 -0
  73. package/{street-morphology-fst-builder.ts → lib/street/morphology-fst-builder.ts} +24 -14
  74. package/{street-morphology-fst-loader.ts → lib/street/morphology-fst-loader.ts} +14 -12
  75. package/{street-name-lookup.ts → lib/street/name-lookup.ts} +14 -30
  76. package/{street-normalize.ts → lib/street/normalize.ts} +86 -20
  77. package/{street-segment-schema.ts → lib/street/segment-schema.ts} +7 -7
  78. package/{types.ts → lib/types.ts} +18 -12
  79. package/{unified-schema.ts → lib/unified-schema.ts} +20 -24
  80. package/lib/uprn/existence.ts +84 -0
  81. package/lib/uprn/index.ts +9 -0
  82. package/{uprn-lookup.ts → lib/uprn/lookup.ts} +14 -19
  83. package/{uprn-schema.ts → lib/uprn/schema.ts} +3 -3
  84. package/lib/weights-overlay-linker.ts +879 -0
  85. package/out/address/index.d.ts +9 -0
  86. package/out/address/index.d.ts.map +1 -0
  87. package/out/address/index.js +9 -0
  88. package/out/address/index.js.map +1 -0
  89. package/out/{address-point-interpolation.d.ts → address/point-interpolation.d.ts} +12 -11
  90. package/out/address/point-interpolation.d.ts.map +1 -0
  91. package/out/{address-point-interpolation.js → address/point-interpolation.js} +18 -18
  92. package/out/address/point-interpolation.js.map +1 -0
  93. package/out/{address-point-schema.d.ts → address/point-schema.d.ts} +16 -6
  94. package/out/address/point-schema.d.ts.map +1 -0
  95. package/out/{address-point-schema.js → address/point-schema.js} +7 -3
  96. package/out/address/point-schema.js.map +1 -0
  97. package/out/{address-point.d.ts → address/point.d.ts} +19 -9
  98. package/out/address/point.d.ts.map +1 -0
  99. package/out/address/point.js +222 -0
  100. package/out/address/point.js.map +1 -0
  101. package/out/{ancestry-backfill.d.ts → ancestry/backfill.d.ts} +7 -5
  102. package/out/ancestry/backfill.d.ts.map +1 -0
  103. package/out/{ancestry-backfill.js → ancestry/backfill.js} +12 -16
  104. package/out/ancestry/backfill.js.map +1 -0
  105. package/out/{ancestry.d.ts → ancestry/index.d.ts} +4 -3
  106. package/out/ancestry/index.d.ts.map +1 -0
  107. package/out/{ancestry.js → ancestry/index.js} +3 -2
  108. package/out/ancestry/index.js.map +1 -0
  109. package/out/build-candidate.d.ts +32 -24
  110. package/out/build-candidate.d.ts.map +1 -1
  111. package/out/build-candidate.js +60 -54
  112. package/out/build-candidate.js.map +1 -1
  113. package/out/build-slim.d.ts +4 -4
  114. package/out/build-slim.d.ts.map +1 -1
  115. package/out/build-slim.js +124 -139
  116. package/out/build-slim.js.map +1 -1
  117. package/out/candidate/alias-bags.d.ts +5 -3
  118. package/out/candidate/alias-bags.d.ts.map +1 -1
  119. package/out/candidate/alias-bags.js +2 -2
  120. package/out/candidate/alias-bags.js.map +1 -1
  121. package/out/candidate/ancestors-sidecar.d.ts +9 -10
  122. package/out/candidate/ancestors-sidecar.d.ts.map +1 -1
  123. package/out/candidate/ancestors-sidecar.js +7 -7
  124. package/out/candidate/ancestors-sidecar.js.map +1 -1
  125. package/out/candidate/country-display-names.d.ts +1 -1
  126. package/out/candidate/country-display-names.d.ts.map +1 -1
  127. package/out/candidate/country-display-names.js +1 -1
  128. package/out/candidate/country-display-names.js.map +1 -1
  129. package/out/candidate/extract-fold.d.ts +41 -0
  130. package/out/candidate/extract-fold.d.ts.map +1 -0
  131. package/out/candidate/extract-fold.js +153 -0
  132. package/out/candidate/extract-fold.js.map +1 -0
  133. package/out/candidate/name-roles.d.ts +13 -11
  134. package/out/candidate/name-roles.d.ts.map +1 -1
  135. package/out/candidate/name-roles.js +11 -10
  136. package/out/candidate/name-roles.js.map +1 -1
  137. package/out/candidate/own-name.d.ts +1 -1
  138. package/out/candidate/own-name.d.ts.map +1 -1
  139. package/out/candidate/own-name.js +2 -1
  140. package/out/candidate/own-name.js.map +1 -1
  141. package/out/candidate/place-attrs.d.ts +3 -3
  142. package/out/candidate/place-attrs.d.ts.map +1 -1
  143. package/out/candidate/place-attrs.js +1 -1
  144. package/out/candidate/place-attrs.js.map +1 -1
  145. package/out/candidate-ancestors-schema.d.ts +4 -4
  146. package/out/candidate-ancestors-schema.d.ts.map +1 -1
  147. package/out/candidate-ancestors-schema.js +2 -2
  148. package/out/candidate-ancestors-schema.js.map +1 -1
  149. package/out/candidate-fts.d.ts +3 -3
  150. package/out/candidate-fts.d.ts.map +1 -1
  151. package/out/candidate-fts.js +1 -1
  152. package/out/candidate-fts.js.map +1 -1
  153. package/out/candidate-importance.d.ts +16 -16
  154. package/out/candidate-importance.d.ts.map +1 -1
  155. package/out/candidate-importance.js +46 -51
  156. package/out/candidate-importance.js.map +1 -1
  157. package/out/candidate-lookup.d.ts +16 -14
  158. package/out/candidate-lookup.d.ts.map +1 -1
  159. package/out/candidate-lookup.js +67 -63
  160. package/out/candidate-lookup.js.map +1 -1
  161. package/out/candidate-schema.d.ts +6 -6
  162. package/out/candidate-schema.d.ts.map +1 -1
  163. package/out/candidate-schema.js +1 -1
  164. package/out/candidate-schema.js.map +1 -1
  165. package/out/candidate-scoring.d.ts +7 -7
  166. package/out/candidate-scoring.d.ts.map +1 -1
  167. package/out/candidate-scoring.js +10 -14
  168. package/out/candidate-scoring.js.map +1 -1
  169. package/out/capital-schema.d.ts +3 -3
  170. package/out/capital-schema.d.ts.map +1 -1
  171. package/out/capital-schema.js +2 -2
  172. package/out/capital-schema.js.map +1 -1
  173. package/out/capitals.d.ts +1 -1
  174. package/out/capitals.d.ts.map +1 -1
  175. package/out/capitals.js +2 -2
  176. package/out/capitals.js.map +1 -1
  177. package/out/coincident-roles.d.ts +7 -6
  178. package/out/coincident-roles.d.ts.map +1 -1
  179. package/out/coincident-roles.js +2 -4
  180. package/out/coincident-roles.js.map +1 -1
  181. package/out/{convention.d.ts → convention/index.d.ts} +4 -4
  182. package/out/convention/index.d.ts.map +1 -0
  183. package/out/{convention.js → convention/index.js} +2 -2
  184. package/out/convention/index.js.map +1 -0
  185. package/out/{convention-schema.d.ts → convention/schema.d.ts} +2 -2
  186. package/out/convention/schema.d.ts.map +1 -0
  187. package/out/{convention-schema.js → convention/schema.js} +3 -3
  188. package/out/convention/schema.js.map +1 -0
  189. package/out/coverage-manifest-schema.d.ts +8 -8
  190. package/out/coverage-manifest-schema.d.ts.map +1 -1
  191. package/out/coverage-manifest-schema.js +5 -4
  192. package/out/coverage-manifest-schema.js.map +1 -1
  193. package/out/currency-backfill.d.ts +51 -7
  194. package/out/currency-backfill.d.ts.map +1 -1
  195. package/out/currency-backfill.js +65 -49
  196. package/out/currency-backfill.js.map +1 -1
  197. package/out/env.d.ts +43 -0
  198. package/out/env.d.ts.map +1 -0
  199. package/out/env.js +48 -0
  200. package/out/env.js.map +1 -0
  201. package/out/exact-match.d.ts +5 -5
  202. package/out/exact-match.d.ts.map +1 -1
  203. package/out/exact-match.js +10 -11
  204. package/out/exact-match.js.map +1 -1
  205. package/out/extracts.d.ts +114 -0
  206. package/out/extracts.d.ts.map +1 -0
  207. package/out/{sharding.js → extracts.js} +38 -38
  208. package/out/extracts.js.map +1 -0
  209. package/out/{fst-autocomplete.d.ts → fst/autocomplete.d.ts} +2 -2
  210. package/out/fst/autocomplete.d.ts.map +1 -0
  211. package/out/{fst-autocomplete.js → fst/autocomplete.js} +3 -3
  212. package/out/fst/autocomplete.js.map +1 -0
  213. package/out/{fst-builder.d.ts → fst/builder.d.ts} +5 -5
  214. package/out/fst/builder.d.ts.map +1 -0
  215. package/out/{fst-builder.js → fst/builder.js} +14 -13
  216. package/out/fst/builder.js.map +1 -0
  217. package/out/{fst-deserialize-web.d.ts → fst/deserialize-web.d.ts} +3 -3
  218. package/out/fst/deserialize-web.d.ts.map +1 -0
  219. package/out/{fst-deserialize-web.js → fst/deserialize-web.js} +10 -74
  220. package/out/fst/deserialize-web.js.map +1 -0
  221. package/out/fst/format.d.ts +80 -0
  222. package/out/fst/format.d.ts.map +1 -0
  223. package/out/fst/format.js +91 -0
  224. package/out/fst/format.js.map +1 -0
  225. package/out/{fst-freshness.d.ts → fst/freshness.d.ts} +9 -13
  226. package/out/fst/freshness.d.ts.map +1 -0
  227. package/out/{fst-freshness.js → fst/freshness.js} +40 -73
  228. package/out/fst/freshness.js.map +1 -0
  229. package/out/fst/index.d.ts +14 -0
  230. package/out/fst/index.d.ts.map +1 -0
  231. package/out/fst/index.js +14 -0
  232. package/out/fst/index.js.map +1 -0
  233. package/out/{fst-matcher.d.ts → fst/matcher.d.ts} +2 -2
  234. package/out/fst/matcher.d.ts.map +1 -0
  235. package/out/{fst-matcher.js → fst/matcher.js} +1 -1
  236. package/out/fst/matcher.js.map +1 -0
  237. package/out/{fst-serialize.d.ts → fst/serialize.d.ts} +5 -10
  238. package/out/fst/serialize.d.ts.map +1 -0
  239. package/out/{fst-serialize.js → fst/serialize.js} +18 -98
  240. package/out/fst/serialize.js.map +1 -0
  241. package/out/{fst-types.d.ts → fst/types.d.ts} +4 -3
  242. package/out/fst/types.d.ts.map +1 -0
  243. package/out/{fst-types.js → fst/types.js} +1 -1
  244. package/out/fst/types.js.map +1 -0
  245. package/out/{fts.d.ts → fts/index.d.ts} +16 -9
  246. package/out/fts/index.d.ts.map +1 -0
  247. package/out/{fts.js → fts/index.js} +16 -11
  248. package/out/fts/index.js.map +1 -0
  249. package/out/{fts-query.d.ts → fts/query.d.ts} +2 -2
  250. package/out/fts/query.d.ts.map +1 -0
  251. package/out/{fts-query.js → fts/query.js} +1 -1
  252. package/out/fts/query.js.map +1 -0
  253. package/out/{geonames-aliases.d.ts → geonames/aliases.d.ts} +8 -6
  254. package/out/geonames/aliases.d.ts.map +1 -0
  255. package/out/{geonames-aliases.js → geonames/aliases.js} +7 -7
  256. package/out/geonames/aliases.js.map +1 -0
  257. package/out/geonames/index.d.ts +8 -0
  258. package/out/geonames/index.d.ts.map +1 -0
  259. package/out/geonames/index.js +8 -0
  260. package/out/geonames/index.js.map +1 -0
  261. package/out/{geonames-postal.d.ts → geonames/postal.d.ts} +10 -8
  262. package/out/geonames/postal.d.ts.map +1 -0
  263. package/out/{geonames-postal.js → geonames/postal.js} +9 -9
  264. package/out/geonames/postal.js.map +1 -0
  265. package/out/index.d.ts +32 -32
  266. package/out/index.d.ts.map +1 -1
  267. package/out/index.js +24 -24
  268. package/out/index.js.map +1 -1
  269. package/out/interpolation.d.ts +11 -10
  270. package/out/interpolation.d.ts.map +1 -1
  271. package/out/interpolation.js +20 -20
  272. package/out/interpolation.js.map +1 -1
  273. package/out/lookup.d.ts +22 -21
  274. package/out/lookup.d.ts.map +1 -1
  275. package/out/lookup.js +103 -113
  276. package/out/lookup.js.map +1 -1
  277. package/out/name-score.d.ts.map +1 -1
  278. package/out/name-score.js.map +1 -1
  279. package/out/nsul/index.d.ts +8 -0
  280. package/out/nsul/index.d.ts.map +1 -0
  281. package/out/nsul/index.js +8 -0
  282. package/out/nsul/index.js.map +1 -0
  283. package/out/nsul/lookup.d.ts +83 -0
  284. package/out/nsul/lookup.d.ts.map +1 -0
  285. package/out/nsul/lookup.js +80 -0
  286. package/out/nsul/lookup.js.map +1 -0
  287. package/out/nsul/schema.d.ts +100 -0
  288. package/out/nsul/schema.d.ts.map +1 -0
  289. package/out/nsul/schema.js +78 -0
  290. package/out/nsul/schema.js.map +1 -0
  291. package/out/place-importance-schema.d.ts +5 -6
  292. package/out/place-importance-schema.d.ts.map +1 -1
  293. package/out/place-importance-schema.js +3 -4
  294. package/out/place-importance-schema.js.map +1 -1
  295. package/out/poi/index.d.ts +8 -0
  296. package/out/poi/index.d.ts.map +1 -0
  297. package/out/poi/index.js +8 -0
  298. package/out/poi/index.js.map +1 -0
  299. package/out/{poi-lookup.d.ts → poi/lookup.d.ts} +8 -10
  300. package/out/poi/lookup.d.ts.map +1 -0
  301. package/out/{poi-lookup.js → poi/lookup.js} +14 -18
  302. package/out/poi/lookup.js.map +1 -0
  303. package/out/{poi-schema.d.ts → poi/schema.d.ts} +4 -4
  304. package/out/poi/schema.d.ts.map +1 -0
  305. package/out/{poi-schema.js → poi/schema.js} +1 -1
  306. package/out/poi/schema.js.map +1 -0
  307. package/out/polygon-schema.d.ts.map +1 -1
  308. package/out/polygon-schema.js.map +1 -1
  309. package/out/{postal-city-alias-lookup.d.ts → postal/city-alias-lookup.d.ts} +6 -5
  310. package/out/postal/city-alias-lookup.d.ts.map +1 -0
  311. package/out/{postal-city-alias-lookup.js → postal/city-alias-lookup.js} +11 -15
  312. package/out/postal/city-alias-lookup.js.map +1 -0
  313. package/out/{postal-city-alias-schema.d.ts → postal/city-alias-schema.d.ts} +1 -1
  314. package/out/{postal-city-alias-schema.d.ts.map → postal/city-alias-schema.d.ts.map} +1 -1
  315. package/out/{postal-city-alias-schema.js → postal/city-alias-schema.js} +1 -1
  316. package/out/{postal-city-alias-schema.js.map → postal/city-alias-schema.js.map} +1 -1
  317. package/out/{postal-city-candidate-schema.d.ts → postal/city-candidate-schema.d.ts} +3 -3
  318. package/out/{postal-city-candidate-schema.d.ts.map → postal/city-candidate-schema.d.ts.map} +1 -1
  319. package/out/{postal-city-candidate-schema.js → postal/city-candidate-schema.js} +2 -2
  320. package/out/{postal-city-candidate-schema.js.map → postal/city-candidate-schema.js.map} +1 -1
  321. package/out/postal/index.d.ts +9 -0
  322. package/out/postal/index.d.ts.map +1 -0
  323. package/out/postal/index.js +9 -0
  324. package/out/postal/index.js.map +1 -0
  325. package/out/postcode-point-lookup.d.ts +10 -10
  326. package/out/postcode-point-lookup.d.ts.map +1 -1
  327. package/out/postcode-point-lookup.js +13 -13
  328. package/out/postcode-point-lookup.js.map +1 -1
  329. package/out/primary-preference.d.ts +15 -7
  330. package/out/primary-preference.d.ts.map +1 -1
  331. package/out/primary-preference.js +28 -12
  332. package/out/primary-preference.js.map +1 -1
  333. package/out/proximity-rerank.d.ts +2 -2
  334. package/out/proximity-rerank.d.ts.map +1 -1
  335. package/out/proximity-rerank.js +2 -2
  336. package/out/proximity-rerank.js.map +1 -1
  337. package/out/ranking-weights.d.ts +15 -3
  338. package/out/ranking-weights.d.ts.map +1 -1
  339. package/out/ranking-weights.js +21 -3
  340. package/out/ranking-weights.js.map +1 -1
  341. package/out/region-keys.d.ts +8 -8
  342. package/out/region-keys.d.ts.map +1 -1
  343. package/out/region-keys.js +9 -9
  344. package/out/region-keys.js.map +1 -1
  345. package/out/reverse.d.ts +6 -6
  346. package/out/reverse.d.ts.map +1 -1
  347. package/out/reverse.js +20 -29
  348. package/out/reverse.js.map +1 -1
  349. package/out/schema.d.ts +9 -0
  350. package/out/schema.d.ts.map +1 -1
  351. package/out/schema.js.map +1 -1
  352. package/out/search-fetch.d.ts +12 -10
  353. package/out/search-fetch.d.ts.map +1 -1
  354. package/out/search-fetch.js +21 -20
  355. package/out/search-fetch.js.map +1 -1
  356. package/out/sqlite-convention-source.d.ts +7 -7
  357. package/out/sqlite-convention-source.d.ts.map +1 -1
  358. package/out/sqlite-convention-source.js +5 -5
  359. package/out/sqlite-convention-source.js.map +1 -1
  360. package/out/sqlite-utils.d.ts +8 -9
  361. package/out/sqlite-utils.d.ts.map +1 -1
  362. package/out/sqlite-utils.js +6 -10
  363. package/out/sqlite-utils.js.map +1 -1
  364. package/out/{street-centroid-schema.d.ts → street/centroid-schema.d.ts} +6 -6
  365. package/out/{street-centroid-schema.d.ts.map → street/centroid-schema.d.ts.map} +1 -1
  366. package/out/{street-centroid-schema.js → street/centroid-schema.js} +5 -5
  367. package/out/{street-centroid-schema.js.map → street/centroid-schema.js.map} +1 -1
  368. package/out/{street-centroid.d.ts → street/centroid.d.ts} +7 -7
  369. package/out/street/centroid.d.ts.map +1 -0
  370. package/out/{street-centroid.js → street/centroid.js} +13 -19
  371. package/out/street/centroid.js.map +1 -0
  372. package/out/street/index.d.ts +13 -0
  373. package/out/street/index.d.ts.map +1 -0
  374. package/out/street/index.js +13 -0
  375. package/out/street/index.js.map +1 -0
  376. package/out/{street-morphology-fst-builder.d.ts → street/morphology-fst-builder.d.ts} +4 -4
  377. package/out/street/morphology-fst-builder.d.ts.map +1 -0
  378. package/out/{street-morphology-fst-builder.js → street/morphology-fst-builder.js} +18 -13
  379. package/out/street/morphology-fst-builder.js.map +1 -0
  380. package/out/{street-morphology-fst-loader.d.ts → street/morphology-fst-loader.d.ts} +5 -5
  381. package/out/street/morphology-fst-loader.d.ts.map +1 -0
  382. package/out/{street-morphology-fst-loader.js → street/morphology-fst-loader.js} +11 -10
  383. package/out/street/morphology-fst-loader.js.map +1 -0
  384. package/out/{street-name-lookup.d.ts → street/name-lookup.d.ts} +4 -7
  385. package/out/street/name-lookup.d.ts.map +1 -0
  386. package/out/{street-name-lookup.js → street/name-lookup.js} +9 -23
  387. package/out/street/name-lookup.js.map +1 -0
  388. package/out/{street-normalize.d.ts → street/normalize.d.ts} +38 -15
  389. package/out/street/normalize.d.ts.map +1 -0
  390. package/out/{street-normalize.js → street/normalize.js} +73 -17
  391. package/out/street/normalize.js.map +1 -0
  392. package/out/{street-segment-schema.d.ts → street/segment-schema.d.ts} +8 -8
  393. package/out/{street-segment-schema.d.ts.map → street/segment-schema.d.ts.map} +1 -1
  394. package/out/{street-segment-schema.js → street/segment-schema.js} +4 -4
  395. package/out/{street-segment-schema.js.map → street/segment-schema.js.map} +1 -1
  396. package/out/types.d.ts +18 -12
  397. package/out/types.d.ts.map +1 -1
  398. package/out/types.js.map +1 -1
  399. package/out/unified-schema.d.ts +5 -4
  400. package/out/unified-schema.d.ts.map +1 -1
  401. package/out/unified-schema.js +15 -18
  402. package/out/unified-schema.js.map +1 -1
  403. package/out/uprn/existence.d.ts +53 -0
  404. package/out/uprn/existence.d.ts.map +1 -0
  405. package/out/uprn/existence.js +61 -0
  406. package/out/uprn/existence.js.map +1 -0
  407. package/out/uprn/index.d.ts +9 -0
  408. package/out/uprn/index.d.ts.map +1 -0
  409. package/out/uprn/index.js +9 -0
  410. package/out/uprn/index.js.map +1 -0
  411. package/out/{uprn-lookup.d.ts → uprn/lookup.d.ts} +4 -4
  412. package/out/uprn/lookup.d.ts.map +1 -0
  413. package/out/{uprn-lookup.js → uprn/lookup.js} +11 -14
  414. package/out/uprn/lookup.js.map +1 -0
  415. package/out/{uprn-schema.d.ts → uprn/schema.d.ts} +4 -4
  416. package/out/uprn/schema.d.ts.map +1 -0
  417. package/out/{uprn-schema.js → uprn/schema.js} +4 -4
  418. package/out/uprn/schema.js.map +1 -0
  419. package/out/weights-overlay-linker.d.ts +184 -26
  420. package/out/weights-overlay-linker.d.ts.map +1 -1
  421. package/out/weights-overlay-linker.js +339 -86
  422. package/out/weights-overlay-linker.js.map +1 -1
  423. package/package.json +465 -269
  424. package/address-point.ts +0 -218
  425. package/candidate/shard-fold.ts +0 -137
  426. package/out/address-point-interpolation.d.ts.map +0 -1
  427. package/out/address-point-interpolation.js.map +0 -1
  428. package/out/address-point-schema.d.ts.map +0 -1
  429. package/out/address-point-schema.js.map +0 -1
  430. package/out/address-point.d.ts.map +0 -1
  431. package/out/address-point.js +0 -140
  432. package/out/address-point.js.map +0 -1
  433. package/out/ancestry-backfill.d.ts.map +0 -1
  434. package/out/ancestry-backfill.js.map +0 -1
  435. package/out/ancestry.d.ts.map +0 -1
  436. package/out/ancestry.js.map +0 -1
  437. package/out/candidate/shard-fold.d.ts +0 -31
  438. package/out/candidate/shard-fold.d.ts.map +0 -1
  439. package/out/candidate/shard-fold.js +0 -104
  440. package/out/candidate/shard-fold.js.map +0 -1
  441. package/out/convention-schema.d.ts.map +0 -1
  442. package/out/convention-schema.js.map +0 -1
  443. package/out/convention.d.ts.map +0 -1
  444. package/out/convention.js.map +0 -1
  445. package/out/fst-autocomplete.d.ts.map +0 -1
  446. package/out/fst-autocomplete.js.map +0 -1
  447. package/out/fst-builder.d.ts.map +0 -1
  448. package/out/fst-builder.js.map +0 -1
  449. package/out/fst-deserialize-web.d.ts.map +0 -1
  450. package/out/fst-deserialize-web.js.map +0 -1
  451. package/out/fst-freshness.d.ts.map +0 -1
  452. package/out/fst-freshness.js.map +0 -1
  453. package/out/fst-matcher.d.ts.map +0 -1
  454. package/out/fst-matcher.js.map +0 -1
  455. package/out/fst-serialize.d.ts.map +0 -1
  456. package/out/fst-serialize.js.map +0 -1
  457. package/out/fst-types.d.ts.map +0 -1
  458. package/out/fst-types.js.map +0 -1
  459. package/out/fts-query.d.ts.map +0 -1
  460. package/out/fts-query.js.map +0 -1
  461. package/out/fts.d.ts.map +0 -1
  462. package/out/fts.js.map +0 -1
  463. package/out/geonames-aliases.d.ts.map +0 -1
  464. package/out/geonames-aliases.js.map +0 -1
  465. package/out/geonames-postal.d.ts.map +0 -1
  466. package/out/geonames-postal.js.map +0 -1
  467. package/out/poi-lookup.d.ts.map +0 -1
  468. package/out/poi-lookup.js.map +0 -1
  469. package/out/poi-schema.d.ts.map +0 -1
  470. package/out/poi-schema.js.map +0 -1
  471. package/out/postal-city-alias-lookup.d.ts.map +0 -1
  472. package/out/postal-city-alias-lookup.js.map +0 -1
  473. package/out/sharding.d.ts +0 -114
  474. package/out/sharding.d.ts.map +0 -1
  475. package/out/sharding.js.map +0 -1
  476. package/out/street-centroid.d.ts.map +0 -1
  477. package/out/street-centroid.js.map +0 -1
  478. package/out/street-morphology-fst-builder.d.ts.map +0 -1
  479. package/out/street-morphology-fst-builder.js.map +0 -1
  480. package/out/street-morphology-fst-loader.d.ts.map +0 -1
  481. package/out/street-morphology-fst-loader.js.map +0 -1
  482. package/out/street-name-lookup.d.ts.map +0 -1
  483. package/out/street-name-lookup.js.map +0 -1
  484. package/out/street-normalize.d.ts.map +0 -1
  485. package/out/street-normalize.js.map +0 -1
  486. package/out/uprn-lookup.d.ts.map +0 -1
  487. package/out/uprn-lookup.js.map +0 -1
  488. package/out/uprn-schema.d.ts.map +0 -1
  489. package/out/uprn-schema.js.map +0 -1
  490. package/weights-overlay-linker.ts +0 -377
  491. /package/{name-score.ts → lib/name-score.ts} +0 -0
  492. /package/{polygon-schema.ts → lib/polygon-schema.ts} +0 -0
  493. /package/{postal-city-alias-schema.ts → lib/postal/city-alias-schema.ts} +0 -0
@@ -29,23 +29,23 @@
29
29
  * (both derive purely from `spr` + `names` — see `fts.ts`). That means `WOFSQLitePlaceLookup`
30
30
  * opens the slim DB without any code change — it sees a smaller universe, nothing more.
31
31
  *
32
- * Multi-shard inputs (e.g. admin + postcode) are processed in sequence; selected rows accumulate
33
- * into the single output DB. The postcode shard contributes only postcodes; admin contributes
34
- * everything else. Empty / missing input paths are skipped (callers pass `""` when a shard, such
32
+ * Multi-extract inputs (e.g. admin + postcode) are processed in sequence; selected rows accumulate
33
+ * into the single output DB. The postcode extract contributes only postcodes; admin contributes
34
+ * everything else. Empty / missing input paths are skipped (callers pass `""` when a extract, such
35
35
  * as a custom postcode DB, isn't built yet).
36
36
  */
37
37
 
38
- import { copyFileSync, existsSync, mkdtempSync, rmSync, statSync } from "node:fs"
39
- import { tmpdir } from "node:os"
40
- import { join } from "node:path"
41
- import { DatabaseSync } from "node:sqlite"
38
+ import { statPath, pathExists } from "@mailwoman/core/fs/readers"
39
+ import { temporaryDirectory } from "@mailwoman/core/fs/temporary"
40
+ import { copyFileTo, removePath } from "@mailwoman/core/fs/writers"
41
+ import { countRows } from "@mailwoman/sqlite"
42
+ import { DatabaseClient } from "@mailwoman/sqlite/client"
43
+ import { sealDatabase } from "@mailwoman/sqlite/sealed-db"
44
+ import { sql } from "kysely"
45
+ import type { Kysely } from "kysely"
42
46
 
43
- import { SqliteDialect } from "@mailwoman/core/kysley/dialect"
44
- import { sealDatabase } from "@mailwoman/core/utils"
45
- import { Kysely, sql } from "kysely"
46
-
47
- import { buildPlaceSearchFTS, PLACE_BBOX_TABLE, PLACE_POPULATION_TABLE, PLACE_SEARCH_TABLE } from "./fts.ts"
48
- import type { NamesTable, SprTable } from "./schema.ts"
47
+ import { buildPlaceSearchFTS, PLACE_BBOX_TABLE, PLACE_POPULATION_TABLE, PLACE_SEARCH_TABLE } from "#fts/index"
48
+ import type { NamesTable, SprTable, WOFDatabase } from "#schema"
49
49
 
50
50
  export interface BuildSlimOptions {
51
51
  /**
@@ -69,7 +69,7 @@ export interface BuildSlimOptions {
69
69
  * external `content=`), so once it's built `names` is only the build-time source — the resolver queries
70
70
  * `place_search` + `spr` + `place_population` + `coincident_roles` and never reads `names` at runtime. Dropping it is
71
71
  * the single biggest size win (~2/3 of the file for a multi-locale build; see #359). A future consumer that needs raw
72
- * alt-names at runtime should ship a SEPARATE shard rather than re-bloat the hot DB.
72
+ * alt-names at runtime should ship a SEPARATE extract rather than re-bloat the hot DB.
73
73
  */
74
74
  dropNames?: boolean
75
75
  /**
@@ -149,65 +149,59 @@ export async function buildSlimWOFDatabase(opts: BuildSlimOptions): Promise<Buil
149
149
  const topLocalities = opts.topLocalitiesPerCountry ?? 1000
150
150
  const progress = opts.onProgress ?? (() => {})
151
151
 
152
- // Callers pass `""` for shards that don't exist yet (e.g. a not-yet-built custom postcode DB).
152
+ // Callers pass `""` for extracts that don't exist yet (e.g. a not-yet-built custom postcode DB).
153
153
  // Skip empties up front; require every remaining path to exist.
154
154
  const inputs = opts.inputs.filter((p) => p.length > 0)
155
155
 
156
156
  if (!inputs.length) throw new Error("no input WOF dbs provided")
157
157
 
158
158
  for (const input of inputs) {
159
- if (!existsSync(input)) throw new Error(`input WOF db not found: ${input}`)
159
+ if (!(await pathExists(input))) throw new Error(`input WOF db not found: ${input}`)
160
160
  }
161
161
 
162
162
  progress("init", `${inputs.length} input(s) → ${opts.output}`)
163
163
 
164
- if (existsSync(opts.output)) {
165
- rmSync(opts.output)
164
+ if (await pathExists(opts.output)) {
165
+ await removePath(opts.output)
166
166
  }
167
167
 
168
168
  // Open the output DB and create the empty schema. We discover the schema from the FIRST input
169
169
  // (raw sqlite_master read — Kysely doesn't model that) so the output mirrors source column
170
170
  // ordering / types. `CREATE TABLE AS SELECT` flattens types to dynamic, which would break
171
171
  // callers that rely on column-affinity behavior.
172
- const out = new DatabaseSync(opts.output)
172
+ const out = new DatabaseClient<BuildSchema>(opts.output)
173
173
  let result: BuildSlimResult
174
174
 
175
175
  try {
176
- const firstSource = new DatabaseSync(inputs[0]!, { readOnly: true })
177
-
178
- try {
179
- progress("schema", "copying spr / names / place_population schemas from first input")
180
-
181
- for (const table of COPIED_TABLES) {
182
- const createSQL = firstSource
183
- .prepare(`SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?`)
184
- .get(table) as { sql?: string } | undefined
185
-
186
- if (createSQL?.sql) {
187
- // Raw DDL by design (introspect-and-replay): we exec the SOURCE DB's own CREATE TABLE
188
- // string read from sqlite_master, so a static Kysely builder can't express it. See AGENTS.md.
189
- out.exec(createSQL.sql)
190
- } else if (table === PLACE_POPULATION_TABLE) {
191
- // Older source builds may predate the aux table — create it empty so the per-source
192
- // copy + ranking have somewhere to land. Sparse-by-design; missing rows are fine.
193
- out.exec(PLACE_POPULATION_DDL)
194
- } else {
195
- throw new Error(`source DB ${inputs[0]} is missing required table '${table}'`)
196
- }
176
+ using firstSource = new DatabaseClient<WOFDatabase>(inputs[0]!, { readOnly: true })
177
+
178
+ progress("schema", "copying spr / names / place_population schemas from first input")
179
+
180
+ for (const table of COPIED_TABLES) {
181
+ const createSQL = firstSource
182
+ .prepare(`SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?`)
183
+ .get(table) as { sql?: string } | undefined
184
+
185
+ if (createSQL?.sql) {
186
+ // Raw DDL by design (introspect-and-replay): we exec the SOURCE DB's own CREATE TABLE
187
+ // string read from sqlite_master, so a static Kysely builder can't express it. See AGENTS.md.
188
+ out.exec(createSQL.sql)
189
+ } else if (table === PLACE_POPULATION_TABLE) {
190
+ // Older source builds may predate the aux table — create it empty so the per-source
191
+ // copy + ranking have somewhere to land. Sparse-by-design; missing rows are fine.
192
+ out.exec(PLACE_POPULATION_DDL)
193
+ } else {
194
+ throw new Error(`source DB ${inputs[0]} is missing required table '${table}'`)
197
195
  }
198
-
199
- // PRIMARY KEY on spr.id + place_population.id come from the schemas we copied; an explicit
200
- // index on names.id helps the per-id INSERT SELECT later.
201
- out.exec(`CREATE INDEX IF NOT EXISTS names_id_idx ON names(id);`)
202
- } finally {
203
- firstSource.close()
204
196
  }
205
197
 
206
- const kysely = new Kysely<BuildSchema>({ dialect: new SqliteDialect({ database: out }) })
198
+ // PRIMARY KEY on spr.id + place_population.id come from the schemas we copied; an explicit
199
+ // index on names.id helps the per-id INSERT SELECT later.
200
+ out.exec(`CREATE INDEX IF NOT EXISTS names_id_idx ON names(id);`)
207
201
 
208
202
  // Pull rows from each input.
209
203
  for (const inputPath of inputs) {
210
- await copyFromSource(out, kysely, inputPath, countries, topLocalities, progress)
204
+ await copyFromSource(out, out, inputPath, countries, topLocalities, progress)
211
205
  }
212
206
 
213
207
  // Build the resolver virtual tables on the trimmed row set. Both place_search (FTS5) and
@@ -264,21 +258,21 @@ export async function buildSlimWOFDatabase(opts: BuildSlimOptions): Promise<Buil
264
258
 
265
259
  result = {
266
260
  outputPath: opts.output,
267
- outputBytes: statSync(opts.output).size,
261
+ outputBytes: (await statPath(opts.output)).size,
268
262
  rowCounts,
269
263
  }
270
264
  } finally {
271
- out.close()
265
+ await out.destroy()
272
266
  }
273
267
 
274
268
  // The sealed-artifact invariant: a built DB is a read-only asset from the moment it exists.
275
- sealDatabase(opts.output)
269
+ await sealDatabase(opts.output)
276
270
 
277
271
  return result
278
272
  }
279
273
 
280
274
  async function copyFromSource(
281
- out: DatabaseSync,
275
+ out: DatabaseClient<BuildSchema>,
282
276
  kysely: Kysely<BuildSchema>,
283
277
  inputPath: string,
284
278
  countries: string[],
@@ -290,134 +284,125 @@ async function copyFromSource(
290
284
  // ATTACH will still want a writable journal on the side; copying to /tmp dodges that without
291
285
  // mutating the canonical files in /mnt/playpen/mailwoman-data/wof/. ATTACH / DETACH stay raw
292
286
  // — Kysely doesn't model them.
293
- const tmpScratch = mkdtempSync(join(tmpdir(), "mailwoman-slim-src-"))
294
- const scratchPath = join(tmpScratch, "src.db")
295
- copyFileSync(inputPath, scratchPath)
287
+ await using tmpScratch = await temporaryDirectory("mailwoman-slim-src-")
288
+ const scratchPath = tmpScratch.resolve("src.db")
296
289
 
297
- try {
298
- out.exec(`ATTACH DATABASE '${scratchPath.replaceAll("'", "''")}' AS src;`)
299
-
300
- try {
301
- // Does this shard carry the pre-built population aux table? The admin source does; a bare
302
- // postcode shard might not. The locality ranking + population copy below adapt accordingly.
303
- const srcHasPopulation = Boolean(
304
- out.prepare(`SELECT 1 FROM src.sqlite_master WHERE type = 'table' AND name = '${PLACE_POPULATION_TABLE}'`).get()
305
- )
290
+ await copyFileTo(inputPath, scratchPath)
306
291
 
307
- // The SELECT-INSERT queries below go through Kysely. The cross-schema FROM is the only
308
- // "interesting" bit: by declaring `src.spr` / `src.names` / `src.place_population` in
309
- // `BuildSchema`, Kysely lets us write `selectFrom("src.spr")` with the same column-type
310
- // checking as the regular schema. SQLite parses the dotted identifier as a schema-name
311
- // qualifier, so this works directly without any aliasing trick.
292
+ out.exec(`ATTACH DATABASE '${scratchPath.replaceAll("'", "''")}' AS src;`)
312
293
 
313
- // 1. Ancestor placetypes (country / region / county / etc.) — always-kept.
314
- progress("country", `${inputPath}: ancestor placetypes in (${countries.join(",")})`)
315
-
316
- await kysely
317
- .insertInto("spr")
318
- .expression((eb) =>
319
- eb
320
- .selectFrom("src.spr")
321
- .selectAll()
322
- .where("is_current", "!=", 0)
323
- .where("is_deprecated", "=", 0)
324
- .where("country", "in", countries)
325
- .where("placetype", "in", [...ANCESTOR_PLACETYPES])
326
- )
327
- .onConflict((oc) => oc.doNothing())
328
- .execute()
294
+ try {
295
+ // Does this extract carry the pre-built population aux table? The admin source does; a bare
296
+ // postcode extract might not. The locality ranking + population copy below adapt accordingly.
297
+ const srcHasPopulation = Boolean(
298
+ out.prepare(`SELECT 1 FROM src.sqlite_master WHERE type = 'table' AND name = '${PLACE_POPULATION_TABLE}'`).get()
299
+ )
300
+
301
+ // The SELECT-INSERT queries below go through Kysely. The cross-schema FROM is the only
302
+ // "interesting" bit: by declaring `src.spr` / `src.names` / `src.place_population` in
303
+ // `BuildSchema`, Kysely lets us write `selectFrom("src.spr")` with the same column-type
304
+ // checking as the regular schema. SQLite parses the dotted identifier as a schema-name
305
+ // qualifier, so this works directly without any aliasing trick.
306
+
307
+ // 1. Ancestor placetypes (country / region / county / etc.) — always-kept.
308
+ progress("country", `${inputPath}: ancestor placetypes in (${countries.join(",")})`)
309
+
310
+ await kysely
311
+ .insertInto("spr")
312
+ .expression((eb) =>
313
+ eb
314
+ .selectFrom("src.spr")
315
+ .selectAll()
316
+ .where("is_current", "!=", 0)
317
+ .where("is_deprecated", "=", 0)
318
+ .where("country", "in", countries)
319
+ .where("placetype", "in", [...ANCESTOR_PLACETYPES])
320
+ )
321
+ .onConflict((oc) => oc.doNothing())
322
+ .execute()
323
+
324
+ // 2. Top-K localities by population. Population lives in the pre-built `place_population`
325
+ // aux table — left-join it so localities without a population row still qualify (sorted
326
+ // last). If the extract has no population table, fall back to a deterministic id ordering.
327
+ progress("locality", `${inputPath}: top-${topLocalities} localities by population`)
328
+
329
+ await kysely
330
+ .insertInto("spr")
331
+ .expression((eb) =>
332
+ eb
333
+ .selectFrom("src.spr as s")
334
+ .$if(srcHasPopulation, (qb) => qb.leftJoin("src.place_population as p", "p.id", "s.id"))
335
+ .selectAll("s")
336
+ .where("s.is_current", "!=", 0)
337
+ .where("s.is_deprecated", "=", 0)
338
+ .where("s.country", "in", countries)
339
+ .where("s.placetype", "=", "locality")
340
+ .orderBy(srcHasPopulation ? sql<number>`COALESCE(p.population, 0)` : sql<number>`s.id`, "desc")
341
+ .limit(topLocalities)
342
+ )
343
+ .onConflict((oc) => oc.doNothing())
344
+ .execute()
345
+
346
+ // 3. All postcodes in scope.
347
+ progress("postcode", `${inputPath}: all postcodes`)
348
+
349
+ await kysely
350
+ .insertInto("spr")
351
+ .expression((eb) =>
352
+ eb
353
+ .selectFrom("src.spr")
354
+ .selectAll()
355
+ .where("is_current", "!=", 0)
356
+ .where("is_deprecated", "=", 0)
357
+ .where("country", "in", countries)
358
+ .where("placetype", "=", "postalcode")
359
+ )
360
+ .onConflict((oc) => oc.doNothing())
361
+ .execute()
329
362
 
330
- // 2. Top-K localities by population. Population lives in the pre-built `place_population`
331
- // aux table — left-join it so localities without a population row still qualify (sorted
332
- // last). If the shard has no population table, fall back to a deterministic id ordering.
333
- progress("locality", `${inputPath}: top-${topLocalities} localities by population`)
363
+ // 4. Pull names for the IDs we just selected.
364
+ progress("names", `${inputPath}: names rows for selected IDs`)
334
365
 
335
- await kysely
336
- .insertInto("spr")
337
- .expression((eb) =>
338
- eb
339
- .selectFrom("src.spr as s")
340
- .$if(srcHasPopulation, (qb) => qb.leftJoin("src.place_population as p", "p.id", "s.id"))
341
- .selectAll("s")
342
- .where("s.is_current", "!=", 0)
343
- .where("s.is_deprecated", "=", 0)
344
- .where("s.country", "in", countries)
345
- .where("s.placetype", "=", "locality")
346
- .orderBy(srcHasPopulation ? sql<number>`COALESCE(p.population, 0)` : sql<number>`s.id`, "desc")
347
- .limit(topLocalities)
348
- )
349
- .onConflict((oc) => oc.doNothing())
350
- .execute()
366
+ await kysely
367
+ .insertInto("names")
368
+ .expression((eb) => eb.selectFrom("src.names").selectAll().where("id", "in", eb.selectFrom("spr").select("id")))
369
+ .onConflict((oc) => oc.doNothing())
370
+ .execute()
351
371
 
352
- // 3. All postcodes in scope.
353
- progress("postcode", `${inputPath}: all postcodes`)
372
+ // 5. Pull population rows for the selected IDs (sparse — only the places WOF has a count for).
373
+ if (srcHasPopulation) {
374
+ progress("place_population", `${inputPath}: population rows for selected IDs`)
354
375
 
355
376
  await kysely
356
- .insertInto("spr")
377
+ .insertInto("place_population")
357
378
  .expression((eb) =>
358
- eb
359
- .selectFrom("src.spr")
360
- .selectAll()
361
- .where("is_current", "!=", 0)
362
- .where("is_deprecated", "=", 0)
363
- .where("country", "in", countries)
364
- .where("placetype", "=", "postalcode")
379
+ eb.selectFrom("src.place_population").selectAll().where("id", "in", eb.selectFrom("spr").select("id"))
365
380
  )
366
381
  .onConflict((oc) => oc.doNothing())
367
382
  .execute()
383
+ }
368
384
 
369
- // 4. Pull names for the IDs we just selected.
370
- progress("names", `${inputPath}: names rows for selected IDs`)
371
-
372
- await kysely
373
- .insertInto("names")
374
- .expression((eb) => eb.selectFrom("src.names").selectAll().where("id", "in", eb.selectFrom("spr").select("id")))
375
- .onConflict((oc) => oc.doNothing())
376
- .execute()
377
-
378
- // 5. Pull population rows for the selected IDs (sparse — only the places WOF has a count for).
379
- if (srcHasPopulation) {
380
- progress("place_population", `${inputPath}: population rows for selected IDs`)
381
-
382
- await kysely
383
- .insertInto("place_population")
384
- .expression((eb) =>
385
- eb.selectFrom("src.place_population").selectAll().where("id", "in", eb.selectFrom("spr").select("id"))
386
- )
387
- .onConflict((oc) => oc.doNothing())
388
- .execute()
389
- }
390
-
391
- // 6. Carry the coincident_roles relation (#402) when this source has it (the admin DB), so the
392
- // slim/demo DB supports dual-role hierarchy completion (on by default). Filtered to surviving
393
- // spr ids → no orphans. Tiny (~hundreds of rows). `ancestors` is intentionally NOT copied (huge
394
- // + build-only), so we copy the derived table rather than rebuild it. Raw SQL — conditional +
395
- // not in the Kysely build schema.
396
- const relationSchema = out
397
- .prepare(`SELECT sql FROM src.sqlite_master WHERE type = 'table' AND name = 'coincident_roles'`)
398
- .get() as { sql?: string } | undefined
399
-
400
- if (relationSchema?.sql) {
401
- progress("coincident_roles", `${inputPath}: copying dual-role relation`)
402
- out.exec(relationSchema.sql.replace(/CREATE TABLE/i, "CREATE TABLE IF NOT EXISTS"))
403
-
404
- out.exec(
405
- `INSERT OR IGNORE INTO coincident_roles SELECT * FROM src.coincident_roles
406
- WHERE admin_id IN (SELECT id FROM spr) AND locality_id IN (SELECT id FROM spr)`
407
- )
385
+ // 6. Carry the coincident_roles relation (#402) when this source has it (the admin DB), so the
386
+ // slim/demo DB supports dual-role hierarchy completion (on by default). Filtered to surviving
387
+ // spr ids → no orphans. Tiny (~hundreds of rows). `ancestors` is intentionally NOT copied (huge
388
+ // + build-only), so we copy the derived table rather than rebuild it. Raw SQL — conditional +
389
+ // not in the Kysely build schema.
390
+ const relationSchema = out
391
+ .prepare(`SELECT sql FROM src.sqlite_master WHERE type = 'table' AND name = 'coincident_roles'`)
392
+ .get() as { sql?: string } | undefined
393
+
394
+ if (relationSchema?.sql) {
395
+ progress("coincident_roles", `${inputPath}: copying dual-role relation`)
396
+ out.exec(relationSchema.sql.replace(/CREATE TABLE/i, "CREATE TABLE IF NOT EXISTS"))
397
+
398
+ out.exec(
399
+ `INSERT OR IGNORE INTO coincident_roles SELECT * FROM src.coincident_roles
400
+ WHERE admin_id IN (SELECT id FROM spr) AND locality_id IN (SELECT id FROM spr)`
401
+ )
408
402
 
409
- out.exec(`CREATE INDEX IF NOT EXISTS coincident_roles_by_admin ON coincident_roles (admin_id)`)
410
- }
411
- } finally {
412
- out.exec(`DETACH DATABASE src;`)
403
+ out.exec(`CREATE INDEX IF NOT EXISTS coincident_roles_by_admin ON coincident_roles (admin_id)`)
413
404
  }
414
405
  } finally {
415
- rmSync(tmpScratch, { recursive: true, force: true })
406
+ out.exec(`DETACH DATABASE src;`)
416
407
  }
417
408
  }
418
-
419
- function countRows(db: DatabaseSync, table: string): number {
420
- const row = db.prepare(`SELECT COUNT(*) AS n FROM ${table}`).get() as { n?: number } | undefined
421
-
422
- return Number(row?.n ?? 0)
423
- }
@@ -5,19 +5,21 @@
5
5
  * @file Pass 2 of the candidate build — explode `place_search.alt_names` into distinct alias rows.
6
6
  */
7
7
 
8
- import type { DatabaseSync } from "node:sqlite"
8
+ import type { DatabaseClient } from "@mailwoman/sqlite/client"
9
9
 
10
- import { ALIAS_SEPARATOR } from "../fts.ts"
11
- import { normalizeLocalityForKey } from "../street-normalize.ts"
12
- import type { PlaceAttrs, StageRow } from "./place-attrs.ts"
10
+ import type { CandidateDatabase } from "#candidate-schema"
11
+ import type { PlaceAttrs, StageRow } from "#candidate/place-attrs"
12
+ import { ALIAS_SEPARATOR } from "#fts/index"
13
+ import type { WOFDatabase } from "#schema"
14
+ import { normalizeLocalityForKey } from "#street/normalize"
13
15
 
14
16
  /**
15
17
  * Pass 2 — explode each place's `place_search.alt_names` bag into distinct-key alias rows (`is_primary = 0`), and count
16
18
  * each place's distinct staged keys (primary included) — the gloss detector's key-count signal (#1730).
17
19
  */
18
20
  export function explodeAliasBags(
19
- src: DatabaseSync,
20
- out: DatabaseSync,
21
+ src: DatabaseClient<WOFDatabase>,
22
+ out: DatabaseClient<CandidateDatabase>,
21
23
  attrs: Map<number, PlaceAttrs>,
22
24
  stageRow: StageRow
23
25
  ): { nAlias: number; keyCounts: Map<number, number> } {
@@ -5,11 +5,9 @@
5
5
  * @file Pass 3b of the candidate build — the containment sidecar (closure rows + interval labels).
6
6
  */
7
7
 
8
- import type { DatabaseSync } from "node:sqlite"
8
+ import type { DatabaseClient } from "@mailwoman/sqlite/client"
9
9
 
10
- import type { DatabaseClient } from "@mailwoman/core/kysley/client"
11
-
12
- import { placetypeDepth } from "../ancestry.ts"
10
+ import { placetypeDepth } from "#ancestry/index"
13
11
  import {
14
12
  CANDIDATE_ANCESTOR_COLUMNS,
15
13
  CANDIDATE_ANCESTOR_TABLE,
@@ -17,9 +15,10 @@ import {
17
15
  createCandidateAncestorTable,
18
16
  createCandidateIntervalTable,
19
17
  MAX_ANCESTOR_DEPTH,
20
- } from "../candidate-ancestors-schema.ts"
21
- import type { CandidateDatabase } from "../candidate-schema.ts"
22
- import type { PlaceAttrs } from "./place-attrs.ts"
18
+ } from "#candidate-ancestors-schema"
19
+ import type { CandidateDatabase } from "#candidate-schema"
20
+ import type { PlaceAttrs } from "#candidate/place-attrs"
21
+ import type { WOFDatabase } from "#schema"
23
22
 
24
23
  /**
25
24
  * Pass 3b — the ancestors sidecar: closure rows + interval labels (candidate-ancestors-schema.ts owns the encoding
@@ -27,14 +26,13 @@ import type { PlaceAttrs } from "./place-attrs.ts"
27
26
  * denormalizing each edge with the parent's name/key from `attrs`, streamed `ORDER BY id` so the clustered `(spr_id,
28
27
  * depth)` insert is sorted — the contiguous-leaves discipline of the candidate table itself.
29
28
  *
30
- * Excluded by policy: self rows, and placetypes outside the containment ladder (continent, empire, …: `placetypeDepth`
31
- * 0) — they discriminate nothing a consumer of this sidecar checks. An edge to a parent with no current `spr` row has
32
- * no name to denormalize; it is dropped and counted rather than stored blind.
29
+ * Excluded by policy: self rows, and placetypes outside the containment ladder (continent, empire, …: `placetypeDepth` 0)
30
+ * — they discriminate nothing a consumer of this sidecar checks. An edge to a parent with no current `spr` row has no
31
+ * name to denormalize; it is dropped and counted rather than stored blind.
33
32
  */
34
33
  export async function buildAncestorsSidecar(ctx: {
35
- src: DatabaseSync
36
- out: DatabaseSync
37
- kdb: DatabaseClient<CandidateDatabase>
34
+ src: DatabaseClient<WOFDatabase>
35
+ out: DatabaseClient<CandidateDatabase>
38
36
  attrs: Map<number, PlaceAttrs>
39
37
  ptID: (pt: string | null) => number
40
38
  progress: (phase: string, message: string) => void
@@ -42,8 +40,8 @@ export async function buildAncestorsSidecar(ctx: {
42
40
  const { src, out, attrs, ptID, progress } = ctx
43
41
 
44
42
  progress("ancestors", "building containment sidecar (closure rows + interval labels)")
45
- await createCandidateAncestorTable(ctx.kdb)
46
- await createCandidateIntervalTable(ctx.kdb)
43
+ await createCandidateAncestorTable(ctx.out)
44
+ await createCandidateIntervalTable(ctx.out)
47
45
 
48
46
  const insAncestor = out.prepare(
49
47
  `INSERT INTO ${CANDIDATE_ANCESTOR_TABLE} VALUES (${CANDIDATE_ANCESTOR_COLUMNS.map(() => "?").join(", ")})`
@@ -7,8 +7,8 @@
7
7
 
8
8
  import { enumerateCountryDisplayNames } from "@mailwoman/codex/country"
9
9
 
10
- import { normalizeLocalityForKey } from "../street-normalize.ts"
11
- import type { PlaceAttrs, StageRow } from "./place-attrs.ts"
10
+ import type { PlaceAttrs, StageRow } from "#candidate/place-attrs"
11
+ import { normalizeLocalityForKey } from "#street/normalize"
12
12
 
13
13
  /**
14
14
  * Fold every country surface ICU knows onto that country's candidate row (#1678 thread 1).