@mailwoman/resolver-wof-sqlite 9.2.0 → 9.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (488) hide show
  1. package/README.md +16 -19
  2. package/lib/address/index.ts +9 -0
  3. package/{address-point-interpolation.ts → lib/address/point-interpolation.ts} +24 -22
  4. package/{address-point-schema.ts → lib/address/point-schema.ts} +18 -4
  5. package/{address-point.ts → lib/address/point.ts} +89 -27
  6. package/{ancestry-backfill.ts → lib/ancestry/backfill.ts} +14 -19
  7. package/{ancestry.ts → lib/ancestry/index.ts} +5 -3
  8. package/{build-candidate.ts → lib/build-candidate.ts} +84 -77
  9. package/{build-slim.ts → lib/build-slim.ts} +150 -165
  10. package/{candidate → lib/candidate}/alias-bags.ts +8 -6
  11. package/{candidate → lib/candidate}/ancestors-sidecar.ts +13 -15
  12. package/{candidate → lib/candidate}/country-display-names.ts +2 -2
  13. package/{candidate/shard-fold.ts → lib/candidate/extract-fold.ts} +26 -25
  14. package/{candidate → lib/candidate}/name-roles.ts +17 -16
  15. package/{candidate → lib/candidate}/own-name.ts +1 -1
  16. package/{candidate → lib/candidate}/place-attrs.ts +3 -3
  17. package/{candidate-ancestors-schema.ts → lib/candidate-ancestors-schema.ts} +4 -4
  18. package/{candidate-fts.ts → lib/candidate-fts.ts} +3 -3
  19. package/{candidate-importance.ts → lib/candidate-importance.ts} +53 -57
  20. package/{candidate-lookup.ts → lib/candidate-lookup.ts} +76 -73
  21. package/{candidate-schema.ts → lib/candidate-schema.ts} +5 -5
  22. package/{candidate-scoring.ts → lib/candidate-scoring.ts} +15 -22
  23. package/{capital-schema.ts → lib/capital-schema.ts} +5 -6
  24. package/{capitals.ts → lib/capitals.ts} +2 -2
  25. package/{coincident-roles.ts → lib/coincident-roles.ts} +8 -11
  26. package/{convention.ts → lib/convention/index.ts} +3 -3
  27. package/{convention-schema.ts → lib/convention/schema.ts} +2 -2
  28. package/{coverage-manifest-schema.ts → lib/coverage-manifest-schema.ts} +9 -10
  29. package/{currency-backfill.ts → lib/currency-backfill.ts} +126 -41
  30. package/lib/env.ts +50 -0
  31. package/{exact-match.ts → lib/exact-match.ts} +23 -14
  32. package/{sharding.ts → lib/extracts.ts} +61 -58
  33. package/{fst-autocomplete.ts → lib/fst/autocomplete.ts} +4 -4
  34. package/{fst-builder.ts → lib/fst/builder.ts} +17 -16
  35. package/{fst-deserialize-web.ts → lib/fst/deserialize-web.ts} +27 -87
  36. package/lib/fst/format.ts +106 -0
  37. package/{fst-freshness.ts → lib/fst/freshness.ts} +41 -74
  38. package/lib/fst/index.ts +14 -0
  39. package/{fst-matcher.ts → lib/fst/matcher.ts} +1 -1
  40. package/{fst-serialize.ts → lib/fst/serialize.ts} +37 -115
  41. package/{fst-types.ts → lib/fst/types.ts} +4 -2
  42. package/{fts.ts → lib/fts/index.ts} +24 -19
  43. package/{fts-query.ts → lib/fts/query.ts} +1 -1
  44. package/{geonames-aliases.ts → lib/geonames/aliases.ts} +13 -13
  45. package/lib/geonames/index.ts +8 -0
  46. package/{geonames-postal.ts → lib/geonames/postal.ts} +14 -13
  47. package/{index.ts → lib/index.ts} +37 -37
  48. package/{interpolation.ts → lib/interpolation.ts} +27 -25
  49. package/{lookup.ts → lib/lookup.ts} +129 -141
  50. package/lib/nsul/index.ts +8 -0
  51. package/lib/nsul/lookup.ts +144 -0
  52. package/lib/nsul/schema.ts +130 -0
  53. package/{place-importance-schema.ts → lib/place-importance-schema.ts} +7 -8
  54. package/lib/poi/index.ts +8 -0
  55. package/{poi-lookup.ts → lib/poi/lookup.ts} +22 -28
  56. package/{poi-schema.ts → lib/poi/schema.ts} +3 -4
  57. package/{postal-city-alias-lookup.ts → lib/postal/city-alias-lookup.ts} +14 -20
  58. package/{postal-city-candidate-schema.ts → lib/postal/city-candidate-schema.ts} +2 -2
  59. package/lib/postal/index.ts +9 -0
  60. package/{postcode-point-lookup.ts → lib/postcode-point-lookup.ts} +17 -15
  61. package/{primary-preference.ts → lib/primary-preference.ts} +29 -10
  62. package/{proximity-rerank.ts → lib/proximity-rerank.ts} +2 -2
  63. package/{ranking-weights.ts → lib/ranking-weights.ts} +30 -4
  64. package/{region-keys.ts → lib/region-keys.ts} +9 -9
  65. package/{reverse.ts → lib/reverse.ts} +34 -46
  66. package/{schema.ts → lib/schema.ts} +10 -0
  67. package/{search-fetch.ts → lib/search-fetch.ts} +29 -28
  68. package/{sqlite-convention-source.ts → lib/sqlite-convention-source.ts} +9 -10
  69. package/{sqlite-utils.ts → lib/sqlite-utils.ts} +14 -18
  70. package/{street-centroid-schema.ts → lib/street/centroid-schema.ts} +5 -5
  71. package/{street-centroid.ts → lib/street/centroid.ts} +14 -21
  72. package/lib/street/index.ts +13 -0
  73. package/{street-morphology-fst-builder.ts → lib/street/morphology-fst-builder.ts} +24 -14
  74. package/{street-morphology-fst-loader.ts → lib/street/morphology-fst-loader.ts} +14 -12
  75. package/{street-name-lookup.ts → lib/street/name-lookup.ts} +14 -30
  76. package/{street-normalize.ts → lib/street/normalize.ts} +44 -19
  77. package/{street-segment-schema.ts → lib/street/segment-schema.ts} +7 -7
  78. package/{types.ts → lib/types.ts} +18 -12
  79. package/{unified-schema.ts → lib/unified-schema.ts} +20 -24
  80. package/lib/uprn/existence.ts +84 -0
  81. package/lib/uprn/index.ts +9 -0
  82. package/{uprn-lookup.ts → lib/uprn/lookup.ts} +14 -18
  83. package/{uprn-schema.ts → lib/uprn/schema.ts} +3 -3
  84. package/lib/weights-overlay-linker.ts +878 -0
  85. package/out/address/index.d.ts +9 -0
  86. package/out/address/index.d.ts.map +1 -0
  87. package/out/address/index.js +9 -0
  88. package/out/address/index.js.map +1 -0
  89. package/out/{address-point-interpolation.d.ts → address/point-interpolation.d.ts} +11 -10
  90. package/out/address/point-interpolation.d.ts.map +1 -0
  91. package/out/{address-point-interpolation.js → address/point-interpolation.js} +18 -18
  92. package/out/address/point-interpolation.js.map +1 -0
  93. package/out/{address-point-schema.d.ts → address/point-schema.d.ts} +16 -6
  94. package/out/address/point-schema.d.ts.map +1 -0
  95. package/out/{address-point-schema.js → address/point-schema.js} +7 -3
  96. package/out/address/point-schema.js.map +1 -0
  97. package/out/{address-point.d.ts → address/point.d.ts} +16 -8
  98. package/out/address/point.d.ts.map +1 -0
  99. package/out/{address-point.js → address/point.js} +71 -20
  100. package/out/address/point.js.map +1 -0
  101. package/out/{ancestry-backfill.d.ts → ancestry/backfill.d.ts} +7 -5
  102. package/out/ancestry/backfill.d.ts.map +1 -0
  103. package/out/{ancestry-backfill.js → ancestry/backfill.js} +12 -16
  104. package/out/ancestry/backfill.js.map +1 -0
  105. package/out/{ancestry.d.ts → ancestry/index.d.ts} +4 -3
  106. package/out/ancestry/index.d.ts.map +1 -0
  107. package/out/{ancestry.js → ancestry/index.js} +3 -2
  108. package/out/ancestry/index.js.map +1 -0
  109. package/out/build-candidate.d.ts +30 -24
  110. package/out/build-candidate.d.ts.map +1 -1
  111. package/out/build-candidate.js +50 -52
  112. package/out/build-candidate.js.map +1 -1
  113. package/out/build-slim.d.ts +4 -4
  114. package/out/build-slim.d.ts.map +1 -1
  115. package/out/build-slim.js +124 -139
  116. package/out/build-slim.js.map +1 -1
  117. package/out/candidate/alias-bags.d.ts +5 -3
  118. package/out/candidate/alias-bags.d.ts.map +1 -1
  119. package/out/candidate/alias-bags.js +2 -2
  120. package/out/candidate/alias-bags.js.map +1 -1
  121. package/out/candidate/ancestors-sidecar.d.ts +9 -10
  122. package/out/candidate/ancestors-sidecar.d.ts.map +1 -1
  123. package/out/candidate/ancestors-sidecar.js +7 -7
  124. package/out/candidate/ancestors-sidecar.js.map +1 -1
  125. package/out/candidate/country-display-names.d.ts +1 -1
  126. package/out/candidate/country-display-names.d.ts.map +1 -1
  127. package/out/candidate/country-display-names.js +1 -1
  128. package/out/candidate/country-display-names.js.map +1 -1
  129. package/out/candidate/extract-fold.d.ts +32 -0
  130. package/out/candidate/extract-fold.d.ts.map +1 -0
  131. package/out/candidate/{shard-fold.js → extract-fold.js} +20 -20
  132. package/out/candidate/extract-fold.js.map +1 -0
  133. package/out/candidate/name-roles.d.ts +13 -11
  134. package/out/candidate/name-roles.d.ts.map +1 -1
  135. package/out/candidate/name-roles.js +11 -10
  136. package/out/candidate/name-roles.js.map +1 -1
  137. package/out/candidate/own-name.d.ts +1 -1
  138. package/out/candidate/own-name.d.ts.map +1 -1
  139. package/out/candidate/own-name.js +1 -1
  140. package/out/candidate/own-name.js.map +1 -1
  141. package/out/candidate/place-attrs.d.ts +3 -3
  142. package/out/candidate/place-attrs.d.ts.map +1 -1
  143. package/out/candidate/place-attrs.js +1 -1
  144. package/out/candidate/place-attrs.js.map +1 -1
  145. package/out/candidate-ancestors-schema.d.ts +4 -4
  146. package/out/candidate-ancestors-schema.d.ts.map +1 -1
  147. package/out/candidate-ancestors-schema.js +2 -2
  148. package/out/candidate-ancestors-schema.js.map +1 -1
  149. package/out/candidate-fts.d.ts +3 -3
  150. package/out/candidate-fts.d.ts.map +1 -1
  151. package/out/candidate-fts.js +1 -1
  152. package/out/candidate-fts.js.map +1 -1
  153. package/out/candidate-importance.d.ts +16 -16
  154. package/out/candidate-importance.d.ts.map +1 -1
  155. package/out/candidate-importance.js +46 -51
  156. package/out/candidate-importance.js.map +1 -1
  157. package/out/candidate-lookup.d.ts +11 -9
  158. package/out/candidate-lookup.d.ts.map +1 -1
  159. package/out/candidate-lookup.js +61 -58
  160. package/out/candidate-lookup.js.map +1 -1
  161. package/out/candidate-schema.d.ts +5 -5
  162. package/out/candidate-schema.d.ts.map +1 -1
  163. package/out/candidate-schema.js.map +1 -1
  164. package/out/candidate-scoring.d.ts +7 -7
  165. package/out/candidate-scoring.d.ts.map +1 -1
  166. package/out/candidate-scoring.js +10 -14
  167. package/out/candidate-scoring.js.map +1 -1
  168. package/out/capital-schema.d.ts +3 -3
  169. package/out/capital-schema.d.ts.map +1 -1
  170. package/out/capital-schema.js +2 -2
  171. package/out/capital-schema.js.map +1 -1
  172. package/out/capitals.d.ts +1 -1
  173. package/out/capitals.d.ts.map +1 -1
  174. package/out/capitals.js +2 -2
  175. package/out/capitals.js.map +1 -1
  176. package/out/coincident-roles.d.ts +6 -5
  177. package/out/coincident-roles.d.ts.map +1 -1
  178. package/out/coincident-roles.js +2 -4
  179. package/out/coincident-roles.js.map +1 -1
  180. package/out/{convention.d.ts → convention/index.d.ts} +4 -4
  181. package/out/convention/index.d.ts.map +1 -0
  182. package/out/{convention.js → convention/index.js} +2 -2
  183. package/out/convention/index.js.map +1 -0
  184. package/out/{convention-schema.d.ts → convention/schema.d.ts} +2 -2
  185. package/out/convention/schema.d.ts.map +1 -0
  186. package/out/{convention-schema.js → convention/schema.js} +3 -3
  187. package/out/convention/schema.js.map +1 -0
  188. package/out/coverage-manifest-schema.d.ts +8 -8
  189. package/out/coverage-manifest-schema.d.ts.map +1 -1
  190. package/out/coverage-manifest-schema.js +4 -4
  191. package/out/coverage-manifest-schema.js.map +1 -1
  192. package/out/currency-backfill.d.ts +51 -7
  193. package/out/currency-backfill.d.ts.map +1 -1
  194. package/out/currency-backfill.js +65 -49
  195. package/out/currency-backfill.js.map +1 -1
  196. package/out/env.d.ts +43 -0
  197. package/out/env.d.ts.map +1 -0
  198. package/out/env.js +48 -0
  199. package/out/env.js.map +1 -0
  200. package/out/exact-match.d.ts +5 -5
  201. package/out/exact-match.d.ts.map +1 -1
  202. package/out/exact-match.js +10 -11
  203. package/out/exact-match.js.map +1 -1
  204. package/out/extracts.d.ts +114 -0
  205. package/out/extracts.d.ts.map +1 -0
  206. package/out/{sharding.js → extracts.js} +38 -38
  207. package/out/extracts.js.map +1 -0
  208. package/out/{fst-autocomplete.d.ts → fst/autocomplete.d.ts} +2 -2
  209. package/out/fst/autocomplete.d.ts.map +1 -0
  210. package/out/{fst-autocomplete.js → fst/autocomplete.js} +3 -3
  211. package/out/fst/autocomplete.js.map +1 -0
  212. package/out/{fst-builder.d.ts → fst/builder.d.ts} +5 -5
  213. package/out/fst/builder.d.ts.map +1 -0
  214. package/out/{fst-builder.js → fst/builder.js} +14 -13
  215. package/out/fst/builder.js.map +1 -0
  216. package/out/{fst-deserialize-web.d.ts → fst/deserialize-web.d.ts} +3 -3
  217. package/out/fst/deserialize-web.d.ts.map +1 -0
  218. package/out/{fst-deserialize-web.js → fst/deserialize-web.js} +10 -74
  219. package/out/fst/deserialize-web.js.map +1 -0
  220. package/out/fst/format.d.ts +80 -0
  221. package/out/fst/format.d.ts.map +1 -0
  222. package/out/fst/format.js +91 -0
  223. package/out/fst/format.js.map +1 -0
  224. package/out/{fst-freshness.d.ts → fst/freshness.d.ts} +10 -13
  225. package/out/fst/freshness.d.ts.map +1 -0
  226. package/out/{fst-freshness.js → fst/freshness.js} +41 -73
  227. package/out/fst/freshness.js.map +1 -0
  228. package/out/fst/index.d.ts +14 -0
  229. package/out/fst/index.d.ts.map +1 -0
  230. package/out/fst/index.js +14 -0
  231. package/out/fst/index.js.map +1 -0
  232. package/out/{fst-matcher.d.ts → fst/matcher.d.ts} +2 -2
  233. package/out/fst/matcher.d.ts.map +1 -0
  234. package/out/{fst-matcher.js → fst/matcher.js} +1 -1
  235. package/out/fst/matcher.js.map +1 -0
  236. package/out/{fst-serialize.d.ts → fst/serialize.d.ts} +5 -10
  237. package/out/fst/serialize.d.ts.map +1 -0
  238. package/out/{fst-serialize.js → fst/serialize.js} +18 -98
  239. package/out/fst/serialize.js.map +1 -0
  240. package/out/{fst-types.d.ts → fst/types.d.ts} +4 -3
  241. package/out/fst/types.d.ts.map +1 -0
  242. package/out/{fst-types.js → fst/types.js} +1 -1
  243. package/out/fst/types.js.map +1 -0
  244. package/out/{fts.d.ts → fts/index.d.ts} +16 -9
  245. package/out/fts/index.d.ts.map +1 -0
  246. package/out/{fts.js → fts/index.js} +16 -11
  247. package/out/fts/index.js.map +1 -0
  248. package/out/{fts-query.d.ts → fts/query.d.ts} +2 -2
  249. package/out/fts/query.d.ts.map +1 -0
  250. package/out/{fts-query.js → fts/query.js} +1 -1
  251. package/out/fts/query.js.map +1 -0
  252. package/out/{geonames-aliases.d.ts → geonames/aliases.d.ts} +8 -6
  253. package/out/geonames/aliases.d.ts.map +1 -0
  254. package/out/{geonames-aliases.js → geonames/aliases.js} +7 -7
  255. package/out/geonames/aliases.js.map +1 -0
  256. package/out/geonames/index.d.ts +8 -0
  257. package/out/geonames/index.d.ts.map +1 -0
  258. package/out/geonames/index.js +8 -0
  259. package/out/geonames/index.js.map +1 -0
  260. package/out/{geonames-postal.d.ts → geonames/postal.d.ts} +10 -8
  261. package/out/geonames/postal.d.ts.map +1 -0
  262. package/out/{geonames-postal.js → geonames/postal.js} +9 -9
  263. package/out/geonames/postal.js.map +1 -0
  264. package/out/index.d.ts +32 -32
  265. package/out/index.d.ts.map +1 -1
  266. package/out/index.js +24 -24
  267. package/out/index.js.map +1 -1
  268. package/out/interpolation.d.ts +10 -9
  269. package/out/interpolation.d.ts.map +1 -1
  270. package/out/interpolation.js +20 -20
  271. package/out/interpolation.js.map +1 -1
  272. package/out/lookup.d.ts +21 -20
  273. package/out/lookup.d.ts.map +1 -1
  274. package/out/lookup.js +102 -112
  275. package/out/lookup.js.map +1 -1
  276. package/out/name-score.d.ts.map +1 -1
  277. package/out/name-score.js.map +1 -1
  278. package/out/nsul/index.d.ts +8 -0
  279. package/out/nsul/index.d.ts.map +1 -0
  280. package/out/nsul/index.js +8 -0
  281. package/out/nsul/index.js.map +1 -0
  282. package/out/nsul/lookup.d.ts +83 -0
  283. package/out/nsul/lookup.d.ts.map +1 -0
  284. package/out/nsul/lookup.js +80 -0
  285. package/out/nsul/lookup.js.map +1 -0
  286. package/out/nsul/schema.d.ts +100 -0
  287. package/out/nsul/schema.d.ts.map +1 -0
  288. package/out/nsul/schema.js +78 -0
  289. package/out/nsul/schema.js.map +1 -0
  290. package/out/place-importance-schema.d.ts +5 -5
  291. package/out/place-importance-schema.d.ts.map +1 -1
  292. package/out/place-importance-schema.js +3 -3
  293. package/out/place-importance-schema.js.map +1 -1
  294. package/out/poi/index.d.ts +8 -0
  295. package/out/poi/index.d.ts.map +1 -0
  296. package/out/poi/index.js +8 -0
  297. package/out/poi/index.js.map +1 -0
  298. package/out/{poi-lookup.d.ts → poi/lookup.d.ts} +8 -10
  299. package/out/poi/lookup.d.ts.map +1 -0
  300. package/out/{poi-lookup.js → poi/lookup.js} +14 -18
  301. package/out/poi/lookup.js.map +1 -0
  302. package/out/{poi-schema.d.ts → poi/schema.d.ts} +4 -4
  303. package/out/poi/schema.d.ts.map +1 -0
  304. package/out/{poi-schema.js → poi/schema.js} +1 -1
  305. package/out/poi/schema.js.map +1 -0
  306. package/out/polygon-schema.d.ts.map +1 -1
  307. package/out/polygon-schema.js.map +1 -1
  308. package/out/{postal-city-alias-lookup.d.ts → postal/city-alias-lookup.d.ts} +6 -5
  309. package/out/postal/city-alias-lookup.d.ts.map +1 -0
  310. package/out/{postal-city-alias-lookup.js → postal/city-alias-lookup.js} +11 -15
  311. package/out/postal/city-alias-lookup.js.map +1 -0
  312. package/out/{postal-city-alias-schema.d.ts → postal/city-alias-schema.d.ts} +1 -1
  313. package/out/{postal-city-alias-schema.d.ts.map → postal/city-alias-schema.d.ts.map} +1 -1
  314. package/out/{postal-city-alias-schema.js → postal/city-alias-schema.js} +1 -1
  315. package/out/{postal-city-alias-schema.js.map → postal/city-alias-schema.js.map} +1 -1
  316. package/out/{postal-city-candidate-schema.d.ts → postal/city-candidate-schema.d.ts} +3 -3
  317. package/out/{postal-city-candidate-schema.d.ts.map → postal/city-candidate-schema.d.ts.map} +1 -1
  318. package/out/{postal-city-candidate-schema.js → postal/city-candidate-schema.js} +2 -2
  319. package/out/{postal-city-candidate-schema.js.map → postal/city-candidate-schema.js.map} +1 -1
  320. package/out/postal/index.d.ts +9 -0
  321. package/out/postal/index.d.ts.map +1 -0
  322. package/out/postal/index.js +9 -0
  323. package/out/postal/index.js.map +1 -0
  324. package/out/postcode-point-lookup.d.ts +10 -10
  325. package/out/postcode-point-lookup.d.ts.map +1 -1
  326. package/out/postcode-point-lookup.js +13 -13
  327. package/out/postcode-point-lookup.js.map +1 -1
  328. package/out/primary-preference.d.ts +13 -5
  329. package/out/primary-preference.d.ts.map +1 -1
  330. package/out/primary-preference.js +16 -8
  331. package/out/primary-preference.js.map +1 -1
  332. package/out/proximity-rerank.d.ts +2 -2
  333. package/out/proximity-rerank.d.ts.map +1 -1
  334. package/out/proximity-rerank.js +2 -2
  335. package/out/proximity-rerank.js.map +1 -1
  336. package/out/ranking-weights.d.ts +15 -3
  337. package/out/ranking-weights.d.ts.map +1 -1
  338. package/out/ranking-weights.js +21 -3
  339. package/out/ranking-weights.js.map +1 -1
  340. package/out/region-keys.d.ts +8 -8
  341. package/out/region-keys.d.ts.map +1 -1
  342. package/out/region-keys.js +9 -9
  343. package/out/region-keys.js.map +1 -1
  344. package/out/reverse.d.ts +6 -6
  345. package/out/reverse.d.ts.map +1 -1
  346. package/out/reverse.js +20 -29
  347. package/out/reverse.js.map +1 -1
  348. package/out/schema.d.ts +9 -0
  349. package/out/schema.d.ts.map +1 -1
  350. package/out/schema.js.map +1 -1
  351. package/out/search-fetch.d.ts +12 -10
  352. package/out/search-fetch.d.ts.map +1 -1
  353. package/out/search-fetch.js +21 -20
  354. package/out/search-fetch.js.map +1 -1
  355. package/out/sqlite-convention-source.d.ts +7 -7
  356. package/out/sqlite-convention-source.d.ts.map +1 -1
  357. package/out/sqlite-convention-source.js +5 -5
  358. package/out/sqlite-convention-source.js.map +1 -1
  359. package/out/sqlite-utils.d.ts +8 -8
  360. package/out/sqlite-utils.d.ts.map +1 -1
  361. package/out/sqlite-utils.js +7 -8
  362. package/out/sqlite-utils.js.map +1 -1
  363. package/out/{street-centroid-schema.d.ts → street/centroid-schema.d.ts} +6 -6
  364. package/out/{street-centroid-schema.d.ts.map → street/centroid-schema.d.ts.map} +1 -1
  365. package/out/{street-centroid-schema.js → street/centroid-schema.js} +5 -5
  366. package/out/{street-centroid-schema.js.map → street/centroid-schema.js.map} +1 -1
  367. package/out/{street-centroid.d.ts → street/centroid.d.ts} +6 -6
  368. package/out/street/centroid.d.ts.map +1 -0
  369. package/out/{street-centroid.js → street/centroid.js} +13 -19
  370. package/out/street/centroid.js.map +1 -0
  371. package/out/street/index.d.ts +13 -0
  372. package/out/street/index.d.ts.map +1 -0
  373. package/out/street/index.js +13 -0
  374. package/out/street/index.js.map +1 -0
  375. package/out/{street-morphology-fst-builder.d.ts → street/morphology-fst-builder.d.ts} +4 -4
  376. package/out/street/morphology-fst-builder.d.ts.map +1 -0
  377. package/out/{street-morphology-fst-builder.js → street/morphology-fst-builder.js} +18 -13
  378. package/out/street/morphology-fst-builder.js.map +1 -0
  379. package/out/{street-morphology-fst-loader.d.ts → street/morphology-fst-loader.d.ts} +5 -5
  380. package/out/street/morphology-fst-loader.d.ts.map +1 -0
  381. package/out/{street-morphology-fst-loader.js → street/morphology-fst-loader.js} +11 -10
  382. package/out/street/morphology-fst-loader.js.map +1 -0
  383. package/out/{street-name-lookup.d.ts → street/name-lookup.d.ts} +4 -7
  384. package/out/street/name-lookup.d.ts.map +1 -0
  385. package/out/{street-name-lookup.js → street/name-lookup.js} +9 -23
  386. package/out/street/name-lookup.js.map +1 -0
  387. package/out/{street-normalize.d.ts → street/normalize.d.ts} +25 -14
  388. package/out/street/normalize.d.ts.map +1 -0
  389. package/out/{street-normalize.js → street/normalize.js} +36 -17
  390. package/out/street/normalize.js.map +1 -0
  391. package/out/{street-segment-schema.d.ts → street/segment-schema.d.ts} +8 -8
  392. package/out/{street-segment-schema.d.ts.map → street/segment-schema.d.ts.map} +1 -1
  393. package/out/{street-segment-schema.js → street/segment-schema.js} +4 -4
  394. package/out/{street-segment-schema.js.map → street/segment-schema.js.map} +1 -1
  395. package/out/types.d.ts +18 -12
  396. package/out/types.d.ts.map +1 -1
  397. package/out/types.js.map +1 -1
  398. package/out/unified-schema.d.ts +5 -4
  399. package/out/unified-schema.d.ts.map +1 -1
  400. package/out/unified-schema.js +15 -18
  401. package/out/unified-schema.js.map +1 -1
  402. package/out/uprn/existence.d.ts +53 -0
  403. package/out/uprn/existence.d.ts.map +1 -0
  404. package/out/uprn/existence.js +61 -0
  405. package/out/uprn/existence.js.map +1 -0
  406. package/out/uprn/index.d.ts +9 -0
  407. package/out/uprn/index.d.ts.map +1 -0
  408. package/out/uprn/index.js +9 -0
  409. package/out/uprn/index.js.map +1 -0
  410. package/out/{uprn-lookup.d.ts → uprn/lookup.d.ts} +4 -4
  411. package/out/uprn/lookup.d.ts.map +1 -0
  412. package/out/{uprn-lookup.js → uprn/lookup.js} +11 -14
  413. package/out/uprn/lookup.js.map +1 -0
  414. package/out/{uprn-schema.d.ts → uprn/schema.d.ts} +4 -4
  415. package/out/uprn/schema.d.ts.map +1 -0
  416. package/out/{uprn-schema.js → uprn/schema.js} +4 -4
  417. package/out/uprn/schema.js.map +1 -0
  418. package/out/weights-overlay-linker.d.ts +184 -26
  419. package/out/weights-overlay-linker.d.ts.map +1 -1
  420. package/out/weights-overlay-linker.js +338 -86
  421. package/out/weights-overlay-linker.js.map +1 -1
  422. package/package.json +465 -269
  423. package/out/address-point-interpolation.d.ts.map +0 -1
  424. package/out/address-point-interpolation.js.map +0 -1
  425. package/out/address-point-schema.d.ts.map +0 -1
  426. package/out/address-point-schema.js.map +0 -1
  427. package/out/address-point.d.ts.map +0 -1
  428. package/out/address-point.js.map +0 -1
  429. package/out/ancestry-backfill.d.ts.map +0 -1
  430. package/out/ancestry-backfill.js.map +0 -1
  431. package/out/ancestry.d.ts.map +0 -1
  432. package/out/ancestry.js.map +0 -1
  433. package/out/candidate/shard-fold.d.ts +0 -31
  434. package/out/candidate/shard-fold.d.ts.map +0 -1
  435. package/out/candidate/shard-fold.js.map +0 -1
  436. package/out/convention-schema.d.ts.map +0 -1
  437. package/out/convention-schema.js.map +0 -1
  438. package/out/convention.d.ts.map +0 -1
  439. package/out/convention.js.map +0 -1
  440. package/out/fst-autocomplete.d.ts.map +0 -1
  441. package/out/fst-autocomplete.js.map +0 -1
  442. package/out/fst-builder.d.ts.map +0 -1
  443. package/out/fst-builder.js.map +0 -1
  444. package/out/fst-deserialize-web.d.ts.map +0 -1
  445. package/out/fst-deserialize-web.js.map +0 -1
  446. package/out/fst-freshness.d.ts.map +0 -1
  447. package/out/fst-freshness.js.map +0 -1
  448. package/out/fst-matcher.d.ts.map +0 -1
  449. package/out/fst-matcher.js.map +0 -1
  450. package/out/fst-serialize.d.ts.map +0 -1
  451. package/out/fst-serialize.js.map +0 -1
  452. package/out/fst-types.d.ts.map +0 -1
  453. package/out/fst-types.js.map +0 -1
  454. package/out/fts-query.d.ts.map +0 -1
  455. package/out/fts-query.js.map +0 -1
  456. package/out/fts.d.ts.map +0 -1
  457. package/out/fts.js.map +0 -1
  458. package/out/geonames-aliases.d.ts.map +0 -1
  459. package/out/geonames-aliases.js.map +0 -1
  460. package/out/geonames-postal.d.ts.map +0 -1
  461. package/out/geonames-postal.js.map +0 -1
  462. package/out/poi-lookup.d.ts.map +0 -1
  463. package/out/poi-lookup.js.map +0 -1
  464. package/out/poi-schema.d.ts.map +0 -1
  465. package/out/poi-schema.js.map +0 -1
  466. package/out/postal-city-alias-lookup.d.ts.map +0 -1
  467. package/out/postal-city-alias-lookup.js.map +0 -1
  468. package/out/sharding.d.ts +0 -114
  469. package/out/sharding.d.ts.map +0 -1
  470. package/out/sharding.js.map +0 -1
  471. package/out/street-centroid.d.ts.map +0 -1
  472. package/out/street-centroid.js.map +0 -1
  473. package/out/street-morphology-fst-builder.d.ts.map +0 -1
  474. package/out/street-morphology-fst-builder.js.map +0 -1
  475. package/out/street-morphology-fst-loader.d.ts.map +0 -1
  476. package/out/street-morphology-fst-loader.js.map +0 -1
  477. package/out/street-name-lookup.d.ts.map +0 -1
  478. package/out/street-name-lookup.js.map +0 -1
  479. package/out/street-normalize.d.ts.map +0 -1
  480. package/out/street-normalize.js.map +0 -1
  481. package/out/uprn-lookup.d.ts.map +0 -1
  482. package/out/uprn-lookup.js.map +0 -1
  483. package/out/uprn-schema.d.ts.map +0 -1
  484. package/out/uprn-schema.js.map +0 -1
  485. package/weights-overlay-linker.ts +0 -377
  486. /package/{name-score.ts → lib/name-score.ts} +0 -0
  487. /package/{polygon-schema.ts → lib/polygon-schema.ts} +0 -0
  488. /package/{postal-city-alias-schema.ts → lib/postal/city-alias-schema.ts} +0 -0
@@ -1,16 +1,18 @@
1
+ import { basename } from "path-ts"
2
+
1
3
  /**
2
4
  * @copyright Sister Software
3
5
  * @license AGPL-3.0
4
6
  * @author Teffen Ellis, et al.
5
7
  *
6
- * Multi-shard support for `WOFSQLitePlaceLookup` — opens multiple WOF SQLite distributions on one
7
- * connection via `ATTACH DATABASE`, and routes queries to the right shard based on placetype.
8
+ * Multi-extract support for `WOFSQLitePlaceLookup` — opens multiple WOF SQLite distributions on one
9
+ * connection via `ATTACH DATABASE`, and routes queries to the right extract based on placetype.
8
10
  *
9
11
  * ## The FTS5 syntax rule that drove this design
10
12
  *
11
13
  * The naive `SELECT … FROM pc.place_search WHERE pc.place_search MATCH ?` fails — SQLite parses the
12
14
  * schema-qualified table on the left of MATCH as "column place_search of table pc". Discovered in
13
- * the spike at PR review time; documented as `_SHARD_RULE.md` should it ever bite again.
15
+ * the spike at PR review time; documented as `_EXTRACT_RULE.md` should it ever bite again.
14
16
  *
15
17
  * The working form: schema-qualified in FROM, bare table name in MATCH:
16
18
  *
@@ -18,15 +20,13 @@
18
20
  * SELECT … FROM pc.place_search WHERE place_search MATCH ?
19
21
  * ```
20
22
  *
21
- * Identical table names across attached shards (which is what we have — every shard ships its own
23
+ * Identical table names across attached extracts (which is what we have — every extract ships its own
22
24
  * `place_search` + `place_bbox`) are fine because the bare-name MATCH resolves against FROM
23
25
  * scope.
24
26
  */
25
27
 
26
- import { basename } from "node:path"
27
-
28
28
  /**
29
- * Derive a SQL-safe schema name from a WOF distribution filename. Used by `ATTACH DATABASE … AS <name>` so each shard
29
+ * Derive a SQL-safe schema name from a WOF distribution filename. Used by `ATTACH DATABASE … AS <name>` so each extract
30
30
  * gets a stable, predictable handle.
31
31
  *
32
32
  * Convention strips the `whosonfirst-data-` prefix and the `-latest.db` (or just `.db`) suffix, then replaces `-` with
@@ -39,7 +39,7 @@ import { basename } from "node:path"
39
39
  * - `whosonfirst-data-admin-latest.db` → `admin`
40
40
  * - `my-custom.db` → `my_custom`
41
41
  *
42
- * Callers can override the derived name explicitly via `ShardConfig.schemaName` when the filename doesn't follow WOF
42
+ * Callers can override the derived name explicitly via `ExtractConfig.schemaName` when the filename doesn't follow WOF
43
43
  * convention.
44
44
  */
45
45
  export function deriveSchemaName(path: string): string {
@@ -57,11 +57,11 @@ export function deriveSchemaName(path: string): string {
57
57
  }
58
58
 
59
59
  /**
60
- * Per-shard configuration. The simple form is just a path string — the schema name is derived from it. The object form
61
- * lets callers override the derived schema name (useful when a filename doesn't follow WOF convention) or attach an
62
- * extra hint about which placetypes route here.
60
+ * Per-extract configuration. The simple form is just a path string — the schema name is derived from it. The object
61
+ * form lets callers override the derived schema name (useful when a filename doesn't follow WOF convention) or attach
62
+ * an extra hint about which placetypes route here.
63
63
  */
64
- export interface ShardConfig {
64
+ export interface ExtractConfig {
65
65
  path: string
66
66
  /**
67
67
  * Override the auto-derived schema name. Useful when the filename doesn't match WOF convention or when you want a
@@ -69,9 +69,9 @@ export interface ShardConfig {
69
69
  */
70
70
  schemaName?: string
71
71
  /**
72
- * Optional explicit list of placetypes this shard serves. When set, queries against any listed placetype are routed
73
- * to this shard. When omitted, routing falls back to a name-match heuristic: a shard whose `schemaName` contains the
74
- * placetype as a substring (e.g. `postalcode_us` for `postalcode` queries) is preferred for that placetype.
72
+ * Optional explicit list of placetypes this extract serves. When set, queries against any listed placetype are routed
73
+ * to this extract. When omitted, routing falls back to a name-match heuristic: a extract whose `schemaName` contains
74
+ * the placetype as a substring (e.g. `postalcode_us` for `postalcode` queries) is preferred for that placetype.
75
75
  */
76
76
  placetypes?: readonly string[]
77
77
  }
@@ -80,7 +80,7 @@ export interface ShardConfig {
80
80
  * Resolved post-derivation: paired path + chosen schema name + (possibly empty) placetypes hint. Used internally by
81
81
  * `WOFSQLitePlaceLookup` so the routing logic operates on uniform structures.
82
82
  */
83
- export interface ResolvedShard {
83
+ export interface ResolvedExtract {
84
84
  path: string
85
85
  schemaName: string
86
86
  placetypes: readonly string[]
@@ -93,40 +93,40 @@ const SQLITE_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_]*$/u
93
93
 
94
94
  /**
95
95
  * Normalize the user-provided `databasePath` opt (which may be a single string, an array of strings, or an array of
96
- * `ShardConfig` objects) into a uniform `ResolvedShard[]`.
96
+ * `ExtractConfig` objects) into a uniform `ResolvedExtract[]`.
97
97
  *
98
- * The first shard becomes `main` regardless of its derived schema name — that's the SQLite convention. Subsequent
99
- * shards keep their derived (or override) schema name.
98
+ * The first extract becomes `main` regardless of its derived schema name — that's the SQLite convention. Subsequent
99
+ * extracts keep their derived (or override) schema name.
100
100
  */
101
- export function resolveShards(input: string | ReadonlyArray<string | ShardConfig>): ResolvedShard[] {
101
+ export function resolveExtracts(input: string | ReadonlyArray<string | ExtractConfig>): ResolvedExtract[] {
102
102
  const list = typeof input === "string" ? [input] : input
103
103
 
104
- if (!list.length) throw new Error("resolveShards: at least one shard is required")
104
+ if (!list.length) throw new Error("resolveExtracts: at least one extract is required")
105
105
 
106
106
  const seen = new Set<string>()
107
- const out: ResolvedShard[] = []
107
+ const out: ResolvedExtract[] = []
108
108
 
109
109
  for (let i = 0; i < list.length; i++) {
110
110
  const entry = list[i]!
111
- const cfg: ShardConfig = typeof entry === "string" ? { path: entry } : entry
111
+ const cfg: ExtractConfig = typeof entry === "string" ? { path: entry } : entry
112
112
  const derived = cfg.schemaName ?? deriveSchemaName(cfg.path)
113
113
 
114
114
  if (!SQLITE_IDENT_RE.test(derived)) {
115
115
  throw new Error(
116
- `resolveShards: schema name ${JSON.stringify(derived)} is not a valid SQLite identifier ` +
116
+ `resolveExtracts: schema name ${JSON.stringify(derived)} is not a valid SQLite identifier ` +
117
117
  `(derived from path ${JSON.stringify(cfg.path)}). Pass an explicit ` +
118
118
  `{ path, schemaName } to override.`
119
119
  )
120
120
  }
121
121
 
122
- // The first shard is always main per SQLite semantics — its derived name is informational
123
- // only. Subsequent shards must have unique non-main names.
122
+ // The first extract is always main per SQLite semantics — its derived name is informational
123
+ // only. Subsequent extracts must have unique non-main names.
124
124
  const schemaName = i === 0 ? "main" : derived
125
125
 
126
126
  if (i > 0 && (schemaName === "main" || seen.has(schemaName))) {
127
127
  throw new Error(
128
- `resolveShards: schema name ${JSON.stringify(schemaName)} collides ` +
129
- `(either with "main" or another shard). Pass an explicit { path, schemaName }.`
128
+ `resolveExtracts: schema name ${JSON.stringify(schemaName)} collides ` +
129
+ `(either with "main" or another extract). Pass an explicit { path, schemaName }.`
130
130
  )
131
131
  }
132
132
 
@@ -143,36 +143,39 @@ export function resolveShards(input: string | ReadonlyArray<string | ShardConfig
143
143
  }
144
144
 
145
145
  /**
146
- * Pick the shard to route a query to given the requested placetype(s).
146
+ * Pick the extract to route a query to given the requested placetype(s).
147
147
  *
148
148
  * Routing rules, in order:
149
149
  *
150
- * 1. If any shard has explicit `placetypes` that includes the requested placetype, use it.
151
- * 2. Otherwise, if a non-main shard's `schemaName` matches the placetype (e.g. `postalcode_us` matches `postalcode`), use
152
- * it.
150
+ * 1. If any extract has explicit `placetypes` that includes the requested placetype, use it.
151
+ * 2. Otherwise, if a non-main extract's `schemaName` matches the placetype (e.g. `postalcode_us` matches `postalcode`),
152
+ * use it.
153
153
  * 3. Otherwise, fall back to `main`.
154
154
  *
155
- * This deliberately doesn't UNION across shards — BM25 scores aren't comparable across separately- indexed corpora, and
156
- * the typical mailwoman query has a single placetype anyway. If a caller needs cross-shard results they can issue two
157
- * `findPlace` calls.
155
+ * This deliberately doesn't UNION across extracts — BM25 scores aren't comparable across separately- indexed corpora,
156
+ * and the typical mailwoman query has a single placetype anyway. If a caller needs cross-extract results they can issue
157
+ * two `findPlace` calls.
158
158
  */
159
159
  /**
160
- * All placetype-matching shards, in routing order (the country-aware pick chooses among these). Used by the bias path:
161
- * a country-less postcode query with proximity hints fans out across every matching shard and merges, because
162
- * single-shard routing would hide the cross-country ambiguity the hints exist to resolve ("48026" lives in
160
+ * All placetype-matching extracts, in routing order (the country-aware pick chooses among these). Used by the bias
161
+ * path: a country-less postcode query with proximity hints fans out across every matching extract and merges, because
162
+ * single-extract routing would hide the cross-country ambiguity the hints exist to resolve ("48026" lives in
163
163
  * postalcode-us AND postalcode-intl).
164
164
  */
165
- export function pickShardsForPlacetype(shards: ResolvedShard[], placetype: string | undefined): ResolvedShard[] {
166
- if (!placetype) return [shards[0]!]
167
- const matches: ResolvedShard[] = []
168
-
169
- for (const s of shards) {
165
+ export function pickExtractsForPlacetype(
166
+ extracts: ResolvedExtract[],
167
+ placetype: string | undefined
168
+ ): ResolvedExtract[] {
169
+ if (!placetype) return [extracts[0]!]
170
+ const matches: ResolvedExtract[] = []
171
+
172
+ for (const s of extracts) {
170
173
  if (s.placetypes.includes(placetype)) {
171
174
  matches.push(s)
172
175
  }
173
176
  }
174
177
 
175
- for (const s of shards) {
178
+ for (const s of extracts) {
176
179
  if (s.schemaName === "main" || matches.includes(s)) continue
177
180
 
178
181
  if (
@@ -184,19 +187,19 @@ export function pickShardsForPlacetype(shards: ResolvedShard[], placetype: strin
184
187
  }
185
188
  }
186
189
 
187
- return matches.length ? matches : [shards[0]!]
190
+ return matches.length ? matches : [extracts[0]!]
188
191
  }
189
192
 
190
- export function pickShardForPlacetype(
191
- shards: ResolvedShard[],
193
+ export function pickExtractForPlacetype(
194
+ extracts: ResolvedExtract[],
192
195
  placetype: string | undefined,
193
196
  opts?: {
194
197
  /**
195
- * #920: the query's country constraint, when the caller has one. With MULTIPLE shards matching a placetype
196
- * (postalcode-us + postalcode-geonames-tail), first-match routing sent every postcode query to the first shard and
197
- * starved the rest — a FI postcode could never reach the tail shard. When `country` is given and a matching shard's
198
- * probed country set contains it, that shard wins; shards without the country are skipped; the placetype-match
199
- * order remains the tiebreak when no shard claims the country (or none was probed).
198
+ * #920: the query's country constraint, when the caller has one. With MULTIPLE extracts matching a placetype
199
+ * (postalcode-us + postalcode-geonames-tail), first-match routing sent every postcode query to the first extract
200
+ * and starved the rest — a FI postcode could never reach the tail extract. When `country` is given and a matching
201
+ * extract's probed country set contains it, that extract wins; extracts without the country are skipped; the
202
+ * placetype-match order remains the tiebreak when no extract claims the country (or none was probed).
200
203
  */
201
204
  country?: string
202
205
  /**
@@ -204,18 +207,18 @@ export function pickShardForPlacetype(
204
207
  */
205
208
  countriesBySchema?: ReadonlyMap<string, ReadonlySet<string>>
206
209
  }
207
- ): ResolvedShard {
208
- if (!placetype) return shards[0]!
210
+ ): ResolvedExtract {
211
+ if (!placetype) return extracts[0]!
209
212
 
210
- const matches: ResolvedShard[] = []
213
+ const matches: ResolvedExtract[] = []
211
214
 
212
- for (const s of shards) {
215
+ for (const s of extracts) {
213
216
  if (s.placetypes.includes(placetype)) {
214
217
  matches.push(s)
215
218
  }
216
219
  }
217
220
 
218
- for (const s of shards) {
221
+ for (const s of extracts) {
219
222
  if (s.schemaName === "main" || matches.includes(s)) continue
220
223
 
221
224
  // Substring match: `postalcode_us` matches `postalcode`. Conservative — requires the
@@ -230,7 +233,7 @@ export function pickShardForPlacetype(
230
233
  }
231
234
  }
232
235
 
233
- if (!matches.length) return shards[0]!
236
+ if (!matches.length) return extracts[0]!
234
237
 
235
238
  if (opts?.country && opts.countriesBySchema) {
236
239
  for (const s of matches) {
@@ -26,9 +26,9 @@ import type {
26
26
  } from "@mailwoman/ancestrie"
27
27
  import { autocomplete as ancestrieAutocomplete } from "@mailwoman/ancestrie"
28
28
 
29
- import type { FSTMatcher } from "./fst-matcher.ts"
30
- import { normalizeTokens } from "./fst-matcher.ts"
31
- import type { PlaceEntry } from "./fst-types.ts"
29
+ import type { FSTMatcher } from "#fst/matcher"
30
+ import { normalizeTokens } from "#fst/matcher"
31
+ import type { PlaceEntry } from "#fst/types"
32
32
 
33
33
  export interface AutocompleteResult {
34
34
  query: string
@@ -85,7 +85,7 @@ function topByReferential(entries: readonly PlaceEntry[], k: number): PlaceEntry
85
85
  }
86
86
 
87
87
  /**
88
- * {@link FSTMatcher} presented through ancestrie's storage seam. Records carry the {@link PlaceEntry} itself as the
88
+ * {@link FSTMatcher} presented through ancestrie's storage interface. Records carry the {@link PlaceEntry} itself as the
89
89
  * payload, so the entry that WINS the algorithm's shallowest-depth rule is the entry whose fields the suggestion
90
90
  * reports — a side lookup keyed on id could pick a different surface's row (`crossCountryBranches` differs per
91
91
  * surface).
@@ -11,14 +11,16 @@
11
11
  * PlaceEntry at terminals → return FSTMatcher.
12
12
  */
13
13
 
14
- import { DatabaseSync } from "node:sqlite"
14
+ import { DatabaseClient } from "@mailwoman/sqlite/client"
15
+ import { resolvePath } from "path-ts"
15
16
 
16
- import { readWOFSourceIdentity } from "./fst-freshness.ts"
17
- import type { FSTNode } from "./fst-matcher.ts"
18
- import { FSTMatcher, normalizeTokens } from "./fst-matcher.ts"
19
- import type { BuildFSTOpts, BuildFSTResult, FSTProvenance, PlaceEntry, PlacetypeID } from "./fst-types.ts"
20
- import { loadImportanceSplit } from "./place-importance-schema.ts"
21
- import { allRows, getRow } from "./sqlite-utils.ts"
17
+ import { readWOFSourceIdentity } from "#fst/freshness"
18
+ import type { FSTNode } from "#fst/matcher"
19
+ import { FSTMatcher, normalizeTokens } from "#fst/matcher"
20
+ import type { BuildFSTOpts, BuildFSTResult, FSTProvenance, PlaceEntry, PlacetypeID } from "#fst/types"
21
+ import { loadImportanceSplit } from "#place-importance-schema"
22
+ import type { WOFDatabase } from "#schema"
23
+ import { allRows, getRow } from "#sqlite-utils"
22
24
 
23
25
  const DEFAULT_PLACETYPES: PlacetypeID[] = [
24
26
  "country",
@@ -54,18 +56,19 @@ interface NameRow {
54
56
  privateuse: string
55
57
  }
56
58
 
57
- export function buildFSTFromWOF(opts: BuildFSTOpts): {
59
+ export async function buildFSTFromWOF(opts: BuildFSTOpts): Promise<{
58
60
  matcher: FSTMatcher
59
61
  provenance: FSTProvenance
60
62
  result: BuildFSTResult
61
- } {
63
+ }> {
62
64
  const countries = opts.countries ?? DEFAULT_COUNTRIES
63
65
  const placetypes = opts.placetypes ?? DEFAULT_PLACETYPES
64
66
  const languages = opts.languages ?? DEFAULT_LANGUAGES
65
67
  const progress = opts.onProgress ?? (() => {})
68
+ const dbPath = resolvePath(opts.dbPath)
66
69
 
67
- progress("open", opts.dbPath)
68
- const db = new DatabaseSync(opts.dbPath, { open: true })
70
+ progress("open", dbPath)
71
+ using db = new DatabaseClient<WOFDatabase>(dbPath, { open: true })
69
72
 
70
73
  // Phase 1: Load all matching SPR rows.
71
74
  progress("spr", `Loading places for countries=[${countries}], placetypes=[${placetypes}]`)
@@ -324,8 +327,6 @@ export function buildFSTFromWOF(opts: BuildFSTOpts): {
324
327
  }
325
328
  }
326
329
 
327
- db.close()
328
-
329
330
  progress(
330
331
  "done",
331
332
  `Built trie: ${nodes.length} states, ${insertCount} name insertions` +
@@ -341,8 +342,8 @@ export function buildFSTFromWOF(opts: BuildFSTOpts): {
341
342
  // and is free whenever the `.md5` sidecar is current, which the admin build already writes.
342
343
  // `sourceIdentity` lets a caller that already knows the digest (or is building from something that
343
344
  // is not a file at all) supply it instead.
344
- progress("stamp", `Reading source identity for ${opts.dbPath}`)
345
- const source = opts.sourceIdentity ?? readWOFSourceIdentity(opts.dbPath)
345
+ progress("stamp", `Reading source identity for ${dbPath}`)
346
+ const source = opts.sourceIdentity ?? (await readWOFSourceIdentity(dbPath))
346
347
 
347
348
  const provenance: FSTProvenance = {
348
349
  builtAt: new Date().toISOString(),
@@ -354,7 +355,7 @@ export function buildFSTFromWOF(opts: BuildFSTOpts): {
354
355
  importanceMatches: split.referential.size,
355
356
  encyclopedicMatches: split.encyclopedic.size,
356
357
  importanceSource: split.source,
357
- sourceDB: opts.dbPath,
358
+ sourceDB: dbPath,
358
359
  sourceDBMD5: source.md5,
359
360
  sourceDBBytes: source.bytes,
360
361
  ...(excludeSurfaces !== undefined || excludeAllTokensOf !== undefined
@@ -10,87 +10,27 @@
10
10
  * build-time operation).
11
11
  */
12
12
 
13
- import { tryParsingJSON } from "@mailwoman/core/objects"
14
-
15
- import type { FSTNode } from "./fst-matcher.ts"
16
- import { FSTMatcher } from "./fst-matcher.ts"
17
- import type { FSTProvenance, PlaceEntry, PlacetypeID } from "./fst-types.ts"
18
-
19
- /**
20
- * Format version that widened the per-state edge and place counters from 16 to 32 bits, growing the state entry from 12
21
- * to 16 bytes. Readers branch on it to stay backward-compatible with v2/v3 files.
22
- */
23
- const VERSION_WIDE_STATE_COUNTERS = 4
24
-
25
- /**
26
- * State-table entry size in bytes at or above {@link VERSION_WIDE_STATE_COUNTERS}.
27
- */
28
- const WIDE_STATE_ENTRY_SIZE = 16
29
-
30
- /**
31
- * State-table entry size in bytes below {@link VERSION_WIDE_STATE_COUNTERS}.
32
- */
33
- const NARROW_STATE_ENTRY_SIZE = 12
34
-
35
- /**
36
- * First format version carrying the trailing metadata block; older files simply have none.
37
- */
38
- const VERSION_WITH_METADATA = 3
39
-
40
- const HEADER_SIZE = 32
41
- const EDGE_ENTRY_SIZE = 8
42
-
43
- /**
44
- * Format version that split the single `importance` float into `referential` + `encyclopedic` (ROAD_TO_V9 §2 R1),
45
- * growing the place entry from 56 to 60 bytes. Mirrors `fst-serialize.ts`'s constant of the same name.
46
- */
47
- const VERSION_TWO_SCORE_SPLIT = 5
48
-
49
- /**
50
- * Place-entry size in bytes at or above {@link VERSION_TWO_SCORE_SPLIT}.
51
- */
52
- const SPLIT_PLACE_ENTRY_SIZE = 60
53
-
54
- /**
55
- * Place-entry size in bytes below {@link VERSION_TWO_SCORE_SPLIT}.
56
- */
57
- const LEGACY_PLACE_ENTRY_SIZE = 56
58
-
59
- /**
60
- * Byte offset of the encyclopedic float inside a v5 place entry — immediately after the 8-slot parent chain.
61
- */
62
- const ENCYCLOPEDIC_OFFSET = 56
63
-
64
- /**
65
- * `placeFlags` bit 0 (byte `pp+7`, v5+): this place carries an encyclopedic score. Per-place because absence is the
66
- * common case; see `fst-serialize.ts`.
67
- */
68
- const PLACE_FLAG_HAS_ENCYCLOPEDIC = 1
69
- /**
70
- * "FST\0".
71
- */
72
- const MAGIC_BYTES = [0x46, 0x53, 0x54, 0x00]
73
- /**
74
- * Must track the serializer's VERSION (fst-serialize.ts, currently 5). The v3 provenance + v4 16-byte-state/u32-count
75
- * layout logic below already matches the Node deserializer; only this gate was left stale at 2, so the browser FST
76
- * loader rejected every real (v4) artifact. It was left stale again at 4 by the v5 two-score split until this line
77
- * moved with it — the gate is a SEPARATE number from the layout branches, which is exactly why it keeps drifting.
78
- */
79
- const MAX_VERSION = 5
80
-
81
- const PLACETYPE_ORDER: readonly PlacetypeID[] = [
82
- "country",
83
- "region",
84
- "county",
85
- "locality",
86
- "localadmin",
87
- "borough",
88
- "neighbourhood",
89
- "postalcode",
90
- "campus",
91
- "dependency",
92
- "street_affix",
93
- ]
13
+ import { tryParsingJSON } from "@mailwoman/core/json"
14
+
15
+ import {
16
+ EDGE_ENTRY_SIZE,
17
+ ENCYCLOPEDIC_OFFSET,
18
+ FST_FORMAT_VERSION,
19
+ FST_MAGIC_BYTES,
20
+ HEADER_SIZE,
21
+ LEGACY_PLACE_ENTRY_SIZE,
22
+ NARROW_STATE_ENTRY_SIZE,
23
+ PLACE_FLAG_HAS_ENCYCLOPEDIC,
24
+ PLACETYPE_ORDER,
25
+ SPLIT_PLACE_ENTRY_SIZE,
26
+ VERSION_TWO_SCORE_SPLIT,
27
+ VERSION_WIDE_STATE_COUNTERS,
28
+ VERSION_WITH_METADATA,
29
+ WIDE_STATE_ENTRY_SIZE,
30
+ } from "#fst/format"
31
+ import type { FSTNode } from "#fst/matcher"
32
+ import { FSTMatcher } from "#fst/matcher"
33
+ import type { FSTProvenance, PlaceEntry } from "#fst/types"
94
34
 
95
35
  export function deserializeFSTWeb(input: ArrayBuffer | Uint8Array): FSTMatcher {
96
36
  const bytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input
@@ -100,18 +40,18 @@ export function deserializeFSTWeb(input: ArrayBuffer | Uint8Array): FSTMatcher {
100
40
  if (bytes.byteLength < HEADER_SIZE) throw new Error("FST buffer too small for header")
101
41
 
102
42
  if (
103
- bytes[0] !== MAGIC_BYTES[0] ||
104
- bytes[1] !== MAGIC_BYTES[1] ||
105
- bytes[2] !== MAGIC_BYTES[2] ||
106
- bytes[3] !== MAGIC_BYTES[3]
43
+ bytes[0] !== FST_MAGIC_BYTES[0] ||
44
+ bytes[1] !== FST_MAGIC_BYTES[1] ||
45
+ bytes[2] !== FST_MAGIC_BYTES[2] ||
46
+ bytes[3] !== FST_MAGIC_BYTES[3]
107
47
  ) {
108
48
  throw new Error("FST magic mismatch")
109
49
  }
110
50
 
111
51
  const version = view.getUint16(4, true)
112
52
 
113
- if (version < 1 || version > MAX_VERSION) {
114
- throw new Error(`FST version ${version} unsupported (expected 1..${MAX_VERSION})`)
53
+ if (version < 1 || version > FST_FORMAT_VERSION) {
54
+ throw new Error(`FST version ${version} unsupported (expected 1..${FST_FORMAT_VERSION})`)
115
55
  }
116
56
 
117
57
  const isV2 = version >= 2
@@ -0,0 +1,106 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * The FST binary-format constants, shared by the Node serializer/deserializer (`fst-serialize.ts`)
7
+ * and the browser deserializer (`fst-deserialize-web.ts`). Platform-free by design — no Buffer at
8
+ * module scope; both runtimes convert {@link FST_MAGIC_BYTES} themselves.
9
+ */
10
+
11
+ import type { PlacetypeID } from "#fst/types"
12
+
13
+ /**
14
+ * Format version this tree WRITES and the maximum either deserializer accepts, published so a freshness guard can call
15
+ * an older artifact format-stale without re-typing the number (mirrors `REQUIRED_PAIR_INDEX_SCHEMA`'s role for PIX1 —
16
+ * see `fst-freshness.ts`).
17
+ *
18
+ * ONE constant for the writer and both readers, deliberately. The browser reader's acceptance criterion was a SEPARATE
19
+ * `MAX_VERSION` number from the layout branches, and it drifted twice: left stale at 2 when the v4 wide-state layout
20
+ * shipped (rejecting every real artifact), and stale again at 4 through the v5 two-score split until the line moved by
21
+ * hand. A check that is the writer's version cannot drift from it.
22
+ */
23
+ export const FST_FORMAT_VERSION = 5
24
+
25
+ /**
26
+ * Fixed header size in bytes: magic, version, and the section offsets that follow it.
27
+ */
28
+ export const HEADER_SIZE = 32
29
+
30
+ /**
31
+ * Edge-table entry: the transition label and the target state index.
32
+ */
33
+ export const EDGE_ENTRY_SIZE = 8
34
+
35
+ /**
36
+ * Format version that widened the per-state edge and place counters from 16 to 32 bits, growing the state entry from 12
37
+ * to 16 bytes. Readers branch on it to stay backward-compatible with v2/v3 files.
38
+ */
39
+ export const VERSION_WIDE_STATE_COUNTERS = 4
40
+
41
+ /**
42
+ * State-table entry size in bytes at or above {@link VERSION_WIDE_STATE_COUNTERS}.
43
+ */
44
+ export const WIDE_STATE_ENTRY_SIZE = 16
45
+
46
+ /**
47
+ * State-table entry size in bytes below {@link VERSION_WIDE_STATE_COUNTERS}.
48
+ */
49
+ export const NARROW_STATE_ENTRY_SIZE = 12
50
+
51
+ /**
52
+ * First format version carrying the trailing metadata block; older files simply have none.
53
+ */
54
+ export const VERSION_WITH_METADATA = 3
55
+
56
+ /**
57
+ * Format version that split the single `importance` float into `referential` + `encyclopedic` (ROAD_TO_V9 §2 R1),
58
+ * growing the place entry from 56 to 60 bytes and claiming the previously-reserved `pp+7` byte as
59
+ * {@link PLACE_FLAG_HAS_ENCYCLOPEDIC}.
60
+ */
61
+ export const VERSION_TWO_SCORE_SPLIT = 5
62
+
63
+ /**
64
+ * Place-entry size in bytes at or above {@link VERSION_TWO_SCORE_SPLIT}.
65
+ */
66
+ export const SPLIT_PLACE_ENTRY_SIZE = 60
67
+
68
+ /**
69
+ * Place-entry size in bytes below {@link VERSION_TWO_SCORE_SPLIT}.
70
+ */
71
+ export const LEGACY_PLACE_ENTRY_SIZE = 56
72
+
73
+ /**
74
+ * Byte offset of the encyclopedic float inside a v5 place entry — immediately after the 8-slot parent chain.
75
+ */
76
+ export const ENCYCLOPEDIC_OFFSET = 56
77
+
78
+ /**
79
+ * `placeFlags` bit 0 (byte `pp+7`, v5+): this place carries an encyclopedic score. Per-PLACE rather than per-file
80
+ * because absence is the common case — roughly 89% of the 2026-08-05 gazetteer has no Wikipedia article — and a
81
+ * file-level flag would force every one of those rows to claim a 0 it never had.
82
+ */
83
+ export const PLACE_FLAG_HAS_ENCYCLOPEDIC = 1
84
+
85
+ /**
86
+ * File magic, "FST\0" as bytes. A reader rejects anything not starting with these four bytes before parsing further.
87
+ */
88
+ export const FST_MAGIC_BYTES: readonly number[] = [0x46, 0x53, 0x54, 0x00]
89
+
90
+ /**
91
+ * Placetypes in hierarchy order, largest first. The index into this array is what gets written into a place entry, so
92
+ * REORDERING IT BREAKS EVERY EXISTING FILE — append instead, and bump the version.
93
+ */
94
+ export const PLACETYPE_ORDER: readonly PlacetypeID[] = [
95
+ "country",
96
+ "region",
97
+ "county",
98
+ "locality",
99
+ "localadmin",
100
+ "borough",
101
+ "neighbourhood",
102
+ "postalcode",
103
+ "campus",
104
+ "dependency",
105
+ "street_affix",
106
+ ]