@mailwoman/resolver-wof-sqlite 9.1.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 (501) hide show
  1. package/README.md +36 -20
  2. package/lib/address/index.ts +9 -0
  3. package/{address-point-interpolation.ts → lib/address/point-interpolation.ts} +40 -28
  4. package/{address-point-schema.ts → lib/address/point-schema.ts} +34 -8
  5. package/lib/address/point.ts +280 -0
  6. package/{ancestry-backfill.ts → lib/ancestry/backfill.ts} +14 -19
  7. package/{ancestry.ts → lib/ancestry/index.ts} +13 -8
  8. package/{build-candidate.ts → lib/build-candidate.ts} +243 -199
  9. package/{build-slim.ts → lib/build-slim.ts} +153 -168
  10. package/lib/candidate/alias-bags.ts +56 -0
  11. package/lib/candidate/ancestors-sidecar.ts +204 -0
  12. package/lib/candidate/country-display-names.ts +79 -0
  13. package/lib/candidate/extract-fold.ts +138 -0
  14. package/lib/candidate/name-roles.ts +238 -0
  15. package/lib/candidate/own-name.ts +146 -0
  16. package/lib/candidate/place-attrs.ts +44 -0
  17. package/lib/candidate-ancestors-schema.ts +195 -0
  18. package/{candidate-fts.ts → lib/candidate-fts.ts} +7 -5
  19. package/{candidate-importance.ts → lib/candidate-importance.ts} +54 -57
  20. package/lib/candidate-lookup.ts +976 -0
  21. package/{candidate-schema.ts → lib/candidate-schema.ts} +34 -6
  22. package/lib/candidate-scoring.ts +261 -0
  23. package/lib/capital-schema.ts +89 -0
  24. package/lib/capitals.ts +148 -0
  25. package/{coincident-roles.ts → lib/coincident-roles.ts} +75 -19
  26. package/{convention.ts → lib/convention/index.ts} +5 -5
  27. package/lib/convention/schema.ts +72 -0
  28. package/{coverage-manifest-schema.ts → lib/coverage-manifest-schema.ts} +15 -16
  29. package/lib/currency-backfill.ts +334 -0
  30. package/lib/env.ts +50 -0
  31. package/lib/exact-match.ts +113 -0
  32. package/{sharding.ts → lib/extracts.ts} +63 -60
  33. package/lib/fst/autocomplete.ts +176 -0
  34. package/{fst-builder.ts → lib/fst/builder.ts} +30 -27
  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} +42 -75
  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} +28 -23
  43. package/{fts-query.ts → lib/fts/query.ts} +2 -2
  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} +16 -15
  47. package/{index.ts → lib/index.ts} +52 -48
  48. package/{interpolation.ts → lib/interpolation.ts} +137 -41
  49. package/lib/lookup.ts +861 -0
  50. package/{name-score.ts → lib/name-score.ts} +6 -4
  51. package/lib/nsul/index.ts +8 -0
  52. package/lib/nsul/lookup.ts +144 -0
  53. package/lib/nsul/schema.ts +130 -0
  54. package/{place-importance-schema.ts → lib/place-importance-schema.ts} +70 -22
  55. package/lib/poi/index.ts +8 -0
  56. package/{poi-lookup.ts → lib/poi/lookup.ts} +32 -39
  57. package/{poi-schema.ts → lib/poi/schema.ts} +10 -6
  58. package/lib/polygon-schema.ts +47 -0
  59. package/{postal-city-alias-lookup.ts → lib/postal/city-alias-lookup.ts} +15 -21
  60. package/{postal-city-candidate-schema.ts → lib/postal/city-candidate-schema.ts} +4 -2
  61. package/lib/postal/index.ts +9 -0
  62. package/{postcode-point-lookup.ts → lib/postcode-point-lookup.ts} +17 -15
  63. package/lib/primary-preference.ts +226 -0
  64. package/lib/proximity-rerank.ts +120 -0
  65. package/{ranking-weights.ts → lib/ranking-weights.ts} +30 -4
  66. package/lib/region-keys.ts +144 -0
  67. package/{reverse.ts → lib/reverse.ts} +45 -56
  68. package/{schema.ts → lib/schema.ts} +11 -1
  69. package/lib/search-fetch.ts +257 -0
  70. package/{sqlite-convention-source.ts → lib/sqlite-convention-source.ts} +9 -10
  71. package/lib/sqlite-utils.ts +83 -0
  72. package/{street-centroid-schema.ts → lib/street/centroid-schema.ts} +12 -6
  73. package/{street-centroid.ts → lib/street/centroid.ts} +26 -28
  74. package/lib/street/index.ts +13 -0
  75. package/{street-morphology-fst-builder.ts → lib/street/morphology-fst-builder.ts} +24 -14
  76. package/{street-morphology-fst-loader.ts → lib/street/morphology-fst-loader.ts} +14 -12
  77. package/{street-name-lookup.ts → lib/street/name-lookup.ts} +14 -30
  78. package/lib/street/normalize.ts +572 -0
  79. package/{street-segment-schema.ts → lib/street/segment-schema.ts} +13 -8
  80. package/{types.ts → lib/types.ts} +49 -9
  81. package/{unified-schema.ts → lib/unified-schema.ts} +21 -25
  82. package/lib/uprn/existence.ts +84 -0
  83. package/lib/uprn/index.ts +9 -0
  84. package/lib/uprn/lookup.ts +206 -0
  85. package/lib/uprn/schema.ts +124 -0
  86. package/lib/weights-overlay-linker.ts +878 -0
  87. package/out/address/index.d.ts +9 -0
  88. package/out/address/index.d.ts.map +1 -0
  89. package/out/address/index.js +9 -0
  90. package/out/address/index.js.map +1 -0
  91. package/out/{address-point-interpolation.d.ts → address/point-interpolation.d.ts} +11 -10
  92. package/out/address/point-interpolation.d.ts.map +1 -0
  93. package/out/{address-point-interpolation.js → address/point-interpolation.js} +29 -23
  94. package/out/address/point-interpolation.js.map +1 -0
  95. package/out/{address-point-schema.d.ts → address/point-schema.d.ts} +30 -10
  96. package/out/address/point-schema.d.ts.map +1 -0
  97. package/out/{address-point-schema.js → address/point-schema.js} +7 -3
  98. package/out/address/point-schema.js.map +1 -0
  99. package/out/{address-point.d.ts → address/point.d.ts} +16 -8
  100. package/out/address/point.d.ts.map +1 -0
  101. package/out/address/point.js +191 -0
  102. package/out/address/point.js.map +1 -0
  103. package/out/{ancestry-backfill.d.ts → ancestry/backfill.d.ts} +7 -5
  104. package/out/ancestry/backfill.d.ts.map +1 -0
  105. package/out/{ancestry-backfill.js → ancestry/backfill.js} +12 -16
  106. package/out/ancestry/backfill.js.map +1 -0
  107. package/out/{ancestry.d.ts → ancestry/index.d.ts} +6 -5
  108. package/out/ancestry/index.d.ts.map +1 -0
  109. package/out/{ancestry.js → ancestry/index.js} +7 -7
  110. package/out/ancestry/index.js.map +1 -0
  111. package/out/build-candidate.d.ts +88 -7
  112. package/out/build-candidate.d.ts.map +1 -1
  113. package/out/build-candidate.js +145 -149
  114. package/out/build-candidate.js.map +1 -1
  115. package/out/build-slim.d.ts +5 -5
  116. package/out/build-slim.d.ts.map +1 -1
  117. package/out/build-slim.js +127 -142
  118. package/out/build-slim.js.map +1 -1
  119. package/out/candidate/alias-bags.d.ts +19 -0
  120. package/out/candidate/alias-bags.d.ts.map +1 -0
  121. package/out/candidate/alias-bags.js +39 -0
  122. package/out/candidate/alias-bags.js.map +1 -0
  123. package/out/candidate/ancestors-sidecar.d.ts +32 -0
  124. package/out/candidate/ancestors-sidecar.d.ts.map +1 -0
  125. package/out/candidate/ancestors-sidecar.js +140 -0
  126. package/out/candidate/ancestors-sidecar.js.map +1 -0
  127. package/out/candidate/country-display-names.d.ts +35 -0
  128. package/out/candidate/country-display-names.d.ts.map +1 -0
  129. package/out/candidate/country-display-names.js +59 -0
  130. package/out/candidate/country-display-names.js.map +1 -0
  131. package/out/candidate/extract-fold.d.ts +32 -0
  132. package/out/candidate/extract-fold.d.ts.map +1 -0
  133. package/out/candidate/extract-fold.js +104 -0
  134. package/out/candidate/extract-fold.js.map +1 -0
  135. package/out/candidate/name-roles.d.ts +57 -0
  136. package/out/candidate/name-roles.d.ts.map +1 -0
  137. package/out/candidate/name-roles.js +166 -0
  138. package/out/candidate/name-roles.js.map +1 -0
  139. package/out/candidate/own-name.d.ts +50 -0
  140. package/out/candidate/own-name.d.ts.map +1 -0
  141. package/out/candidate/own-name.js +132 -0
  142. package/out/candidate/own-name.js.map +1 -0
  143. package/out/candidate/place-attrs.d.ts +43 -0
  144. package/out/candidate/place-attrs.d.ts.map +1 -0
  145. package/out/candidate/place-attrs.js +15 -0
  146. package/out/candidate/place-attrs.js.map +1 -0
  147. package/out/candidate-ancestors-schema.d.ts +150 -0
  148. package/out/candidate-ancestors-schema.d.ts.map +1 -0
  149. package/out/candidate-ancestors-schema.js +123 -0
  150. package/out/candidate-ancestors-schema.js.map +1 -0
  151. package/out/candidate-fts.d.ts +7 -5
  152. package/out/candidate-fts.d.ts.map +1 -1
  153. package/out/candidate-fts.js +5 -3
  154. package/out/candidate-fts.js.map +1 -1
  155. package/out/candidate-importance.d.ts +16 -16
  156. package/out/candidate-importance.d.ts.map +1 -1
  157. package/out/candidate-importance.js +47 -52
  158. package/out/candidate-importance.js.map +1 -1
  159. package/out/candidate-lookup.d.ts +31 -52
  160. package/out/candidate-lookup.d.ts.map +1 -1
  161. package/out/candidate-lookup.js +380 -172
  162. package/out/candidate-lookup.js.map +1 -1
  163. package/out/candidate-schema.d.ts +31 -7
  164. package/out/candidate-schema.d.ts.map +1 -1
  165. package/out/candidate-schema.js +3 -0
  166. package/out/candidate-schema.js.map +1 -1
  167. package/out/candidate-scoring.d.ts +34 -0
  168. package/out/candidate-scoring.d.ts.map +1 -0
  169. package/out/candidate-scoring.js +196 -0
  170. package/out/candidate-scoring.js.map +1 -0
  171. package/out/capital-schema.d.ts +51 -0
  172. package/out/capital-schema.d.ts.map +1 -0
  173. package/out/capital-schema.js +63 -0
  174. package/out/capital-schema.js.map +1 -0
  175. package/out/capitals.d.ts +69 -0
  176. package/out/capitals.d.ts.map +1 -0
  177. package/out/capitals.js +98 -0
  178. package/out/capitals.js.map +1 -0
  179. package/out/coincident-roles.d.ts +12 -4
  180. package/out/coincident-roles.d.ts.map +1 -1
  181. package/out/coincident-roles.js +43 -11
  182. package/out/coincident-roles.js.map +1 -1
  183. package/out/{convention.d.ts → convention/index.d.ts} +5 -5
  184. package/out/convention/index.d.ts.map +1 -0
  185. package/out/{convention.js → convention/index.js} +4 -4
  186. package/out/convention/index.js.map +1 -0
  187. package/out/convention/schema.d.ts +51 -0
  188. package/out/convention/schema.d.ts.map +1 -0
  189. package/out/convention/schema.js +34 -0
  190. package/out/convention/schema.js.map +1 -0
  191. package/out/coverage-manifest-schema.d.ts +8 -8
  192. package/out/coverage-manifest-schema.d.ts.map +1 -1
  193. package/out/coverage-manifest-schema.js +6 -10
  194. package/out/coverage-manifest-schema.js.map +1 -1
  195. package/out/currency-backfill.d.ts +90 -0
  196. package/out/currency-backfill.d.ts.map +1 -0
  197. package/out/currency-backfill.js +196 -0
  198. package/out/currency-backfill.js.map +1 -0
  199. package/out/env.d.ts +43 -0
  200. package/out/env.d.ts.map +1 -0
  201. package/out/env.js +48 -0
  202. package/out/env.js.map +1 -0
  203. package/out/exact-match.d.ts +25 -0
  204. package/out/exact-match.d.ts.map +1 -0
  205. package/out/exact-match.js +88 -0
  206. package/out/exact-match.js.map +1 -0
  207. package/out/extracts.d.ts +114 -0
  208. package/out/extracts.d.ts.map +1 -0
  209. package/out/{sharding.js → extracts.js} +38 -38
  210. package/out/extracts.js.map +1 -0
  211. package/out/{fst-autocomplete.d.ts → fst/autocomplete.d.ts} +13 -13
  212. package/out/fst/autocomplete.d.ts.map +1 -0
  213. package/out/fst/autocomplete.js +113 -0
  214. package/out/fst/autocomplete.js.map +1 -0
  215. package/out/{fst-builder.d.ts → fst/builder.d.ts} +5 -5
  216. package/out/fst/builder.d.ts.map +1 -0
  217. package/out/{fst-builder.js → fst/builder.js} +24 -24
  218. package/out/fst/builder.js.map +1 -0
  219. package/out/{fst-deserialize-web.d.ts → fst/deserialize-web.d.ts} +3 -3
  220. package/out/fst/deserialize-web.d.ts.map +1 -0
  221. package/out/{fst-deserialize-web.js → fst/deserialize-web.js} +10 -74
  222. package/out/fst/deserialize-web.js.map +1 -0
  223. package/out/fst/format.d.ts +80 -0
  224. package/out/fst/format.d.ts.map +1 -0
  225. package/out/fst/format.js +91 -0
  226. package/out/fst/format.js.map +1 -0
  227. package/out/{fst-freshness.d.ts → fst/freshness.d.ts} +11 -14
  228. package/out/fst/freshness.d.ts.map +1 -0
  229. package/out/{fst-freshness.js → fst/freshness.js} +42 -74
  230. package/out/fst/freshness.js.map +1 -0
  231. package/out/fst/index.d.ts +14 -0
  232. package/out/fst/index.d.ts.map +1 -0
  233. package/out/fst/index.js +14 -0
  234. package/out/fst/index.js.map +1 -0
  235. package/out/{fst-matcher.d.ts → fst/matcher.d.ts} +2 -2
  236. package/out/fst/matcher.d.ts.map +1 -0
  237. package/out/{fst-matcher.js → fst/matcher.js} +1 -1
  238. package/out/fst/matcher.js.map +1 -0
  239. package/out/{fst-serialize.d.ts → fst/serialize.d.ts} +5 -10
  240. package/out/fst/serialize.d.ts.map +1 -0
  241. package/out/{fst-serialize.js → fst/serialize.js} +18 -98
  242. package/out/fst/serialize.js.map +1 -0
  243. package/out/{fst-types.d.ts → fst/types.d.ts} +4 -3
  244. package/out/fst/types.d.ts.map +1 -0
  245. package/out/{fst-types.js → fst/types.js} +1 -1
  246. package/out/fst/types.js.map +1 -0
  247. package/out/{fts.d.ts → fts/index.d.ts} +20 -13
  248. package/out/fts/index.d.ts.map +1 -0
  249. package/out/{fts.js → fts/index.js} +20 -15
  250. package/out/fts/index.js.map +1 -0
  251. package/out/{fts-query.d.ts → fts/query.d.ts} +2 -2
  252. package/out/fts/query.d.ts.map +1 -0
  253. package/out/{fts-query.js → fts/query.js} +2 -2
  254. package/out/fts/query.js.map +1 -0
  255. package/out/{geonames-aliases.d.ts → geonames/aliases.d.ts} +8 -6
  256. package/out/geonames/aliases.d.ts.map +1 -0
  257. package/out/{geonames-aliases.js → geonames/aliases.js} +7 -7
  258. package/out/geonames/aliases.js.map +1 -0
  259. package/out/geonames/index.d.ts +8 -0
  260. package/out/geonames/index.d.ts.map +1 -0
  261. package/out/geonames/index.js +8 -0
  262. package/out/geonames/index.js.map +1 -0
  263. package/out/{geonames-postal.d.ts → geonames/postal.d.ts} +12 -10
  264. package/out/geonames/postal.d.ts.map +1 -0
  265. package/out/{geonames-postal.js → geonames/postal.js} +11 -11
  266. package/out/geonames/postal.js.map +1 -0
  267. package/out/index.d.ts +32 -31
  268. package/out/index.d.ts.map +1 -1
  269. package/out/index.js +24 -24
  270. package/out/index.js.map +1 -1
  271. package/out/interpolation.d.ts +18 -9
  272. package/out/interpolation.d.ts.map +1 -1
  273. package/out/interpolation.js +108 -36
  274. package/out/interpolation.js.map +1 -1
  275. package/out/lookup.d.ts +25 -25
  276. package/out/lookup.d.ts.map +1 -1
  277. package/out/lookup.js +174 -558
  278. package/out/lookup.js.map +1 -1
  279. package/out/name-score.d.ts +0 -10
  280. package/out/name-score.d.ts.map +1 -1
  281. package/out/name-score.js +6 -4
  282. package/out/name-score.js.map +1 -1
  283. package/out/nsul/index.d.ts +8 -0
  284. package/out/nsul/index.d.ts.map +1 -0
  285. package/out/nsul/index.js +8 -0
  286. package/out/nsul/index.js.map +1 -0
  287. package/out/nsul/lookup.d.ts +83 -0
  288. package/out/nsul/lookup.d.ts.map +1 -0
  289. package/out/nsul/lookup.js +80 -0
  290. package/out/nsul/lookup.js.map +1 -0
  291. package/out/nsul/schema.d.ts +100 -0
  292. package/out/nsul/schema.d.ts.map +1 -0
  293. package/out/nsul/schema.js +78 -0
  294. package/out/nsul/schema.js.map +1 -0
  295. package/out/place-importance-schema.d.ts +47 -10
  296. package/out/place-importance-schema.d.ts.map +1 -1
  297. package/out/place-importance-schema.js +56 -10
  298. package/out/place-importance-schema.js.map +1 -1
  299. package/out/poi/index.d.ts +8 -0
  300. package/out/poi/index.d.ts.map +1 -0
  301. package/out/poi/index.js +8 -0
  302. package/out/poi/index.js.map +1 -0
  303. package/out/{poi-lookup.d.ts → poi/lookup.d.ts} +8 -10
  304. package/out/poi/lookup.d.ts.map +1 -0
  305. package/out/{poi-lookup.js → poi/lookup.js} +24 -29
  306. package/out/poi/lookup.js.map +1 -0
  307. package/out/{poi-schema.d.ts → poi/schema.d.ts} +10 -6
  308. package/out/poi/schema.d.ts.map +1 -0
  309. package/out/{poi-schema.js → poi/schema.js} +1 -1
  310. package/out/poi/schema.js.map +1 -0
  311. package/out/polygon-schema.d.ts +37 -0
  312. package/out/polygon-schema.d.ts.map +1 -0
  313. package/out/polygon-schema.js +23 -0
  314. package/out/polygon-schema.js.map +1 -0
  315. package/out/{postal-city-alias-lookup.d.ts → postal/city-alias-lookup.d.ts} +7 -6
  316. package/out/postal/city-alias-lookup.d.ts.map +1 -0
  317. package/out/{postal-city-alias-lookup.js → postal/city-alias-lookup.js} +12 -16
  318. package/out/postal/city-alias-lookup.js.map +1 -0
  319. package/out/{postal-city-alias-schema.d.ts → postal/city-alias-schema.d.ts} +1 -1
  320. package/out/{postal-city-alias-schema.d.ts.map → postal/city-alias-schema.d.ts.map} +1 -1
  321. package/out/{postal-city-alias-schema.js → postal/city-alias-schema.js} +1 -1
  322. package/out/{postal-city-alias-schema.js.map → postal/city-alias-schema.js.map} +1 -1
  323. package/out/{postal-city-candidate-schema.d.ts → postal/city-candidate-schema.d.ts} +4 -3
  324. package/out/postal/city-candidate-schema.d.ts.map +1 -0
  325. package/out/{postal-city-candidate-schema.js → postal/city-candidate-schema.js} +2 -2
  326. package/out/{postal-city-candidate-schema.js.map → postal/city-candidate-schema.js.map} +1 -1
  327. package/out/postal/index.d.ts +9 -0
  328. package/out/postal/index.d.ts.map +1 -0
  329. package/out/postal/index.js +9 -0
  330. package/out/postal/index.js.map +1 -0
  331. package/out/postcode-point-lookup.d.ts +10 -10
  332. package/out/postcode-point-lookup.d.ts.map +1 -1
  333. package/out/postcode-point-lookup.js +13 -13
  334. package/out/postcode-point-lookup.js.map +1 -1
  335. package/out/primary-preference.d.ts +133 -0
  336. package/out/primary-preference.d.ts.map +1 -0
  337. package/out/primary-preference.js +146 -0
  338. package/out/primary-preference.js.map +1 -0
  339. package/out/proximity-rerank.d.ts +77 -0
  340. package/out/proximity-rerank.d.ts.map +1 -0
  341. package/out/proximity-rerank.js +86 -0
  342. package/out/proximity-rerank.js.map +1 -0
  343. package/out/ranking-weights.d.ts +15 -3
  344. package/out/ranking-weights.d.ts.map +1 -1
  345. package/out/ranking-weights.js +21 -3
  346. package/out/ranking-weights.js.map +1 -1
  347. package/out/region-keys.d.ts +47 -0
  348. package/out/region-keys.d.ts.map +1 -0
  349. package/out/region-keys.js +121 -0
  350. package/out/region-keys.js.map +1 -0
  351. package/out/reverse.d.ts +6 -6
  352. package/out/reverse.d.ts.map +1 -1
  353. package/out/reverse.js +23 -35
  354. package/out/reverse.js.map +1 -1
  355. package/out/schema.d.ts +10 -1
  356. package/out/schema.d.ts.map +1 -1
  357. package/out/schema.js.map +1 -1
  358. package/out/search-fetch.d.ts +59 -0
  359. package/out/search-fetch.d.ts.map +1 -0
  360. package/out/search-fetch.js +184 -0
  361. package/out/search-fetch.js.map +1 -0
  362. package/out/sqlite-convention-source.d.ts +7 -7
  363. package/out/sqlite-convention-source.d.ts.map +1 -1
  364. package/out/sqlite-convention-source.js +5 -5
  365. package/out/sqlite-convention-source.js.map +1 -1
  366. package/out/sqlite-utils.d.ts +24 -6
  367. package/out/sqlite-utils.d.ts.map +1 -1
  368. package/out/sqlite-utils.js +24 -7
  369. package/out/sqlite-utils.js.map +1 -1
  370. package/out/{street-centroid-schema.d.ts → street/centroid-schema.d.ts} +12 -7
  371. package/out/street/centroid-schema.d.ts.map +1 -0
  372. package/out/{street-centroid-schema.js → street/centroid-schema.js} +5 -5
  373. package/out/{street-centroid-schema.js.map → street/centroid-schema.js.map} +1 -1
  374. package/out/{street-centroid.d.ts → street/centroid.d.ts} +6 -6
  375. package/out/street/centroid.d.ts.map +1 -0
  376. package/out/{street-centroid.js → street/centroid.js} +18 -24
  377. package/out/street/centroid.js.map +1 -0
  378. package/out/street/index.d.ts +13 -0
  379. package/out/street/index.d.ts.map +1 -0
  380. package/out/street/index.js +13 -0
  381. package/out/street/index.js.map +1 -0
  382. package/out/{street-morphology-fst-builder.d.ts → street/morphology-fst-builder.d.ts} +4 -4
  383. package/out/street/morphology-fst-builder.d.ts.map +1 -0
  384. package/out/{street-morphology-fst-builder.js → street/morphology-fst-builder.js} +18 -13
  385. package/out/street/morphology-fst-builder.js.map +1 -0
  386. package/out/{street-morphology-fst-loader.d.ts → street/morphology-fst-loader.d.ts} +5 -5
  387. package/out/street/morphology-fst-loader.d.ts.map +1 -0
  388. package/out/{street-morphology-fst-loader.js → street/morphology-fst-loader.js} +11 -10
  389. package/out/street/morphology-fst-loader.js.map +1 -0
  390. package/out/{street-name-lookup.d.ts → street/name-lookup.d.ts} +4 -7
  391. package/out/street/name-lookup.d.ts.map +1 -0
  392. package/out/{street-name-lookup.js → street/name-lookup.js} +9 -23
  393. package/out/street/name-lookup.js.map +1 -0
  394. package/out/street/normalize.d.ts +179 -0
  395. package/out/street/normalize.d.ts.map +1 -0
  396. package/out/street/normalize.js +457 -0
  397. package/out/street/normalize.js.map +1 -0
  398. package/out/{street-segment-schema.d.ts → street/segment-schema.d.ts} +13 -9
  399. package/out/street/segment-schema.d.ts.map +1 -0
  400. package/out/{street-segment-schema.js → street/segment-schema.js} +4 -4
  401. package/out/{street-segment-schema.js.map → street/segment-schema.js.map} +1 -1
  402. package/out/types.d.ts +49 -9
  403. package/out/types.d.ts.map +1 -1
  404. package/out/types.js.map +1 -1
  405. package/out/unified-schema.d.ts +6 -5
  406. package/out/unified-schema.d.ts.map +1 -1
  407. package/out/unified-schema.js +16 -19
  408. package/out/unified-schema.js.map +1 -1
  409. package/out/uprn/existence.d.ts +53 -0
  410. package/out/uprn/existence.d.ts.map +1 -0
  411. package/out/uprn/existence.js +61 -0
  412. package/out/uprn/existence.js.map +1 -0
  413. package/out/uprn/index.d.ts +9 -0
  414. package/out/uprn/index.d.ts.map +1 -0
  415. package/out/uprn/index.js +9 -0
  416. package/out/uprn/index.js.map +1 -0
  417. package/out/uprn/lookup.d.ts +85 -0
  418. package/out/uprn/lookup.d.ts.map +1 -0
  419. package/out/uprn/lookup.js +149 -0
  420. package/out/uprn/lookup.js.map +1 -0
  421. package/out/uprn/schema.d.ts +93 -0
  422. package/out/uprn/schema.d.ts.map +1 -0
  423. package/out/uprn/schema.js +78 -0
  424. package/out/uprn/schema.js.map +1 -0
  425. package/out/weights-overlay-linker.d.ts +299 -0
  426. package/out/weights-overlay-linker.d.ts.map +1 -0
  427. package/out/weights-overlay-linker.js +511 -0
  428. package/out/weights-overlay-linker.js.map +1 -0
  429. package/package.json +622 -154
  430. package/address-point.ts +0 -125
  431. package/candidate-lookup.ts +0 -720
  432. package/fst-autocomplete.ts +0 -204
  433. package/geo.ts +0 -121
  434. package/lookup.ts +0 -1354
  435. package/out/address-point-interpolation.d.ts.map +0 -1
  436. package/out/address-point-interpolation.js.map +0 -1
  437. package/out/address-point-schema.d.ts.map +0 -1
  438. package/out/address-point-schema.js.map +0 -1
  439. package/out/address-point.d.ts.map +0 -1
  440. package/out/address-point.js +0 -84
  441. package/out/address-point.js.map +0 -1
  442. package/out/ancestry-backfill.d.ts.map +0 -1
  443. package/out/ancestry-backfill.js.map +0 -1
  444. package/out/ancestry.d.ts.map +0 -1
  445. package/out/ancestry.js.map +0 -1
  446. package/out/convention.d.ts.map +0 -1
  447. package/out/convention.js.map +0 -1
  448. package/out/fst-autocomplete.d.ts.map +0 -1
  449. package/out/fst-autocomplete.js +0 -130
  450. package/out/fst-autocomplete.js.map +0 -1
  451. package/out/fst-builder.d.ts.map +0 -1
  452. package/out/fst-builder.js.map +0 -1
  453. package/out/fst-deserialize-web.d.ts.map +0 -1
  454. package/out/fst-deserialize-web.js.map +0 -1
  455. package/out/fst-freshness.d.ts.map +0 -1
  456. package/out/fst-freshness.js.map +0 -1
  457. package/out/fst-matcher.d.ts.map +0 -1
  458. package/out/fst-matcher.js.map +0 -1
  459. package/out/fst-serialize.d.ts.map +0 -1
  460. package/out/fst-serialize.js.map +0 -1
  461. package/out/fst-types.d.ts.map +0 -1
  462. package/out/fst-types.js.map +0 -1
  463. package/out/fts-query.d.ts.map +0 -1
  464. package/out/fts-query.js.map +0 -1
  465. package/out/fts.d.ts.map +0 -1
  466. package/out/fts.js.map +0 -1
  467. package/out/geo.d.ts +0 -74
  468. package/out/geo.d.ts.map +0 -1
  469. package/out/geo.js +0 -71
  470. package/out/geo.js.map +0 -1
  471. package/out/geonames-aliases.d.ts.map +0 -1
  472. package/out/geonames-aliases.js.map +0 -1
  473. package/out/geonames-postal.d.ts.map +0 -1
  474. package/out/geonames-postal.js.map +0 -1
  475. package/out/poi-lookup.d.ts.map +0 -1
  476. package/out/poi-lookup.js.map +0 -1
  477. package/out/poi-schema.d.ts.map +0 -1
  478. package/out/poi-schema.js.map +0 -1
  479. package/out/postal-city-alias-lookup.d.ts.map +0 -1
  480. package/out/postal-city-alias-lookup.js.map +0 -1
  481. package/out/postal-city-candidate-schema.d.ts.map +0 -1
  482. package/out/sharding.d.ts +0 -114
  483. package/out/sharding.d.ts.map +0 -1
  484. package/out/sharding.js.map +0 -1
  485. package/out/street-centroid-schema.d.ts.map +0 -1
  486. package/out/street-centroid.d.ts.map +0 -1
  487. package/out/street-centroid.js.map +0 -1
  488. package/out/street-morphology-fst-builder.d.ts.map +0 -1
  489. package/out/street-morphology-fst-builder.js.map +0 -1
  490. package/out/street-morphology-fst-loader.d.ts.map +0 -1
  491. package/out/street-morphology-fst-loader.js.map +0 -1
  492. package/out/street-name-lookup.d.ts.map +0 -1
  493. package/out/street-name-lookup.js.map +0 -1
  494. package/out/street-normalize.d.ts +0 -95
  495. package/out/street-normalize.d.ts.map +0 -1
  496. package/out/street-normalize.js +0 -272
  497. package/out/street-normalize.js.map +0 -1
  498. package/out/street-segment-schema.d.ts.map +0 -1
  499. package/sqlite-utils.ts +0 -46
  500. package/street-normalize.ts +0 -318
  501. /package/{postal-city-alias-schema.ts → lib/postal/city-alias-schema.ts} +0 -0
@@ -0,0 +1,114 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Multi-extract support for `WOFSQLitePlaceLookup` — opens multiple WOF SQLite distributions on one
7
+ * connection via `ATTACH DATABASE`, and routes queries to the right extract based on placetype.
8
+ *
9
+ * ## The FTS5 syntax rule that drove this design
10
+ *
11
+ * The naive `SELECT … FROM pc.place_search WHERE pc.place_search MATCH ?` fails — SQLite parses the
12
+ * 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 `_EXTRACT_RULE.md` should it ever bite again.
14
+ *
15
+ * The working form: schema-qualified in FROM, bare table name in MATCH:
16
+ *
17
+ * ```sql
18
+ * SELECT … FROM pc.place_search WHERE place_search MATCH ?
19
+ * ```
20
+ *
21
+ * Identical table names across attached extracts (which is what we have — every extract ships its own
22
+ * `place_search` + `place_bbox`) are fine because the bare-name MATCH resolves against FROM
23
+ * scope.
24
+ */
25
+ /**
26
+ * Derive a SQL-safe schema name from a WOF distribution filename. Used by `ATTACH DATABASE … AS <name>` so each extract
27
+ * gets a stable, predictable handle.
28
+ *
29
+ * Convention strips the `whosonfirst-data-` prefix and the `-latest.db` (or just `.db`) suffix, then replaces `-` with
30
+ * `_` for SQL identifier safety.
31
+ *
32
+ * Examples:
33
+ *
34
+ * - `whosonfirst-data-admin-us-latest.db` → `admin_us`
35
+ * - `whosonfirst-data-postalcode-us-latest.db` → `postalcode_us`
36
+ * - `whosonfirst-data-admin-latest.db` → `admin`
37
+ * - `my-custom.db` → `my_custom`
38
+ *
39
+ * Callers can override the derived name explicitly via `ExtractConfig.schemaName` when the filename doesn't follow WOF
40
+ * convention.
41
+ */
42
+ export declare function deriveSchemaName(path: string): string;
43
+ /**
44
+ * Per-extract configuration. The simple form is just a path string — the schema name is derived from it. The object
45
+ * form lets callers override the derived schema name (useful when a filename doesn't follow WOF convention) or attach
46
+ * an extra hint about which placetypes route here.
47
+ */
48
+ export interface ExtractConfig {
49
+ path: string;
50
+ /**
51
+ * Override the auto-derived schema name. Useful when the filename doesn't match WOF convention or when you want a
52
+ * memorable handle. Must be a valid SQLite identifier — `[a-zA-Z_][a-zA-Z0-9_]*`.
53
+ */
54
+ schemaName?: string;
55
+ /**
56
+ * Optional explicit list of placetypes this extract serves. When set, queries against any listed placetype are routed
57
+ * to this extract. When omitted, routing falls back to a name-match heuristic: a extract whose `schemaName` contains
58
+ * the placetype as a substring (e.g. `postalcode_us` for `postalcode` queries) is preferred for that placetype.
59
+ */
60
+ placetypes?: readonly string[];
61
+ }
62
+ /**
63
+ * Resolved post-derivation: paired path + chosen schema name + (possibly empty) placetypes hint. Used internally by
64
+ * `WOFSQLitePlaceLookup` so the routing logic operates on uniform structures.
65
+ */
66
+ export interface ResolvedExtract {
67
+ path: string;
68
+ schemaName: string;
69
+ placetypes: readonly string[];
70
+ }
71
+ /**
72
+ * Normalize the user-provided `databasePath` opt (which may be a single string, an array of strings, or an array of
73
+ * `ExtractConfig` objects) into a uniform `ResolvedExtract[]`.
74
+ *
75
+ * The first extract becomes `main` regardless of its derived schema name — that's the SQLite convention. Subsequent
76
+ * extracts keep their derived (or override) schema name.
77
+ */
78
+ export declare function resolveExtracts(input: string | ReadonlyArray<string | ExtractConfig>): ResolvedExtract[];
79
+ /**
80
+ * Pick the extract to route a query to given the requested placetype(s).
81
+ *
82
+ * Routing rules, in order:
83
+ *
84
+ * 1. If any extract has explicit `placetypes` that includes the requested placetype, use it.
85
+ * 2. Otherwise, if a non-main extract's `schemaName` matches the placetype (e.g. `postalcode_us` matches `postalcode`),
86
+ * use it.
87
+ * 3. Otherwise, fall back to `main`.
88
+ *
89
+ * This deliberately doesn't UNION across extracts — BM25 scores aren't comparable across separately- indexed corpora,
90
+ * and the typical mailwoman query has a single placetype anyway. If a caller needs cross-extract results they can issue
91
+ * two `findPlace` calls.
92
+ */
93
+ /**
94
+ * All placetype-matching extracts, in routing order (the country-aware pick chooses among these). Used by the bias
95
+ * path: a country-less postcode query with proximity hints fans out across every matching extract and merges, because
96
+ * single-extract routing would hide the cross-country ambiguity the hints exist to resolve ("48026" lives in
97
+ * postalcode-us AND postalcode-intl).
98
+ */
99
+ export declare function pickExtractsForPlacetype(extracts: ResolvedExtract[], placetype: string | undefined): ResolvedExtract[];
100
+ export declare function pickExtractForPlacetype(extracts: ResolvedExtract[], placetype: string | undefined, opts?: {
101
+ /**
102
+ * #920: the query's country constraint, when the caller has one. With MULTIPLE extracts matching a placetype
103
+ * (postalcode-us + postalcode-geonames-tail), first-match routing sent every postcode query to the first extract
104
+ * and starved the rest — a FI postcode could never reach the tail extract. When `country` is given and a matching
105
+ * extract's probed country set contains it, that extract wins; extracts without the country are skipped; the
106
+ * placetype-match order remains the tiebreak when no extract claims the country (or none was probed).
107
+ */
108
+ country?: string;
109
+ /**
110
+ * Per-schema probed country sets (see `WOFSQLitePlaceLookup`'s construction probe).
111
+ */
112
+ countriesBySchema?: ReadonlyMap<string, ReadonlySet<string>>;
113
+ }): ResolvedExtract;
114
+ //# sourceMappingURL=extracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extracts.d.ts","sourceRoot":"","sources":["../lib/extracts.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYrD;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;CAC7B;AAOD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,GAAG,eAAe,EAAE,CA0CxG;AAED;;;;;;;;;;;;;GAaG;AACH;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACvC,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC3B,eAAe,EAAE,CAuBnB;AAED,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,IAAI,CAAC,EAAE;IACN;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,iBAAiB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;CAC5D,GACC,eAAe,CAmCjB"}
@@ -1,16 +1,17 @@
1
+ import { basename } from "path-ts";
1
2
  /**
2
3
  * @copyright Sister Software
3
4
  * @license AGPL-3.0
4
5
  * @author Teffen Ellis, et al.
5
6
  *
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.
7
+ * Multi-extract support for `WOFSQLitePlaceLookup` — opens multiple WOF SQLite distributions on one
8
+ * connection via `ATTACH DATABASE`, and routes queries to the right extract based on placetype.
8
9
  *
9
10
  * ## The FTS5 syntax rule that drove this design
10
11
  *
11
12
  * The naive `SELECT … FROM pc.place_search WHERE pc.place_search MATCH ?` fails — SQLite parses the
12
13
  * 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.
14
+ * the spike at PR review time; documented as `_EXTRACT_RULE.md` should it ever bite again.
14
15
  *
15
16
  * The working form: schema-qualified in FROM, bare table name in MATCH:
16
17
  *
@@ -18,13 +19,12 @@
18
19
  * SELECT … FROM pc.place_search WHERE place_search MATCH ?
19
20
  * ```
20
21
  *
21
- * Identical table names across attached shards (which is what we have — every shard ships its own
22
+ * Identical table names across attached extracts (which is what we have — every extract ships its own
22
23
  * `place_search` + `place_bbox`) are fine because the bare-name MATCH resolves against FROM
23
24
  * scope.
24
25
  */
25
- import { basename } from "node:path";
26
26
  /**
27
- * Derive a SQL-safe schema name from a WOF distribution filename. Used by `ATTACH DATABASE … AS <name>` so each shard
27
+ * Derive a SQL-safe schema name from a WOF distribution filename. Used by `ATTACH DATABASE … AS <name>` so each extract
28
28
  * gets a stable, predictable handle.
29
29
  *
30
30
  * Convention strips the `whosonfirst-data-` prefix and the `-latest.db` (or just `.db`) suffix, then replaces `-` with
@@ -37,7 +37,7 @@ import { basename } from "node:path";
37
37
  * - `whosonfirst-data-admin-latest.db` → `admin`
38
38
  * - `my-custom.db` → `my_custom`
39
39
  *
40
- * Callers can override the derived name explicitly via `ShardConfig.schemaName` when the filename doesn't follow WOF
40
+ * Callers can override the derived name explicitly via `ExtractConfig.schemaName` when the filename doesn't follow WOF
41
41
  * convention.
42
42
  */
43
43
  export function deriveSchemaName(path) {
@@ -57,15 +57,15 @@ export function deriveSchemaName(path) {
57
57
  const SQLITE_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_]*$/u;
58
58
  /**
59
59
  * Normalize the user-provided `databasePath` opt (which may be a single string, an array of strings, or an array of
60
- * `ShardConfig` objects) into a uniform `ResolvedShard[]`.
60
+ * `ExtractConfig` objects) into a uniform `ResolvedExtract[]`.
61
61
  *
62
- * The first shard becomes `main` regardless of its derived schema name — that's the SQLite convention. Subsequent
63
- * shards keep their derived (or override) schema name.
62
+ * The first extract becomes `main` regardless of its derived schema name — that's the SQLite convention. Subsequent
63
+ * extracts keep their derived (or override) schema name.
64
64
  */
65
- export function resolveShards(input) {
65
+ export function resolveExtracts(input) {
66
66
  const list = typeof input === "string" ? [input] : input;
67
67
  if (!list.length)
68
- throw new Error("resolveShards: at least one shard is required");
68
+ throw new Error("resolveExtracts: at least one extract is required");
69
69
  const seen = new Set();
70
70
  const out = [];
71
71
  for (let i = 0; i < list.length; i++) {
@@ -73,16 +73,16 @@ export function resolveShards(input) {
73
73
  const cfg = typeof entry === "string" ? { path: entry } : entry;
74
74
  const derived = cfg.schemaName ?? deriveSchemaName(cfg.path);
75
75
  if (!SQLITE_IDENT_RE.test(derived)) {
76
- throw new Error(`resolveShards: schema name ${JSON.stringify(derived)} is not a valid SQLite identifier ` +
76
+ throw new Error(`resolveExtracts: schema name ${JSON.stringify(derived)} is not a valid SQLite identifier ` +
77
77
  `(derived from path ${JSON.stringify(cfg.path)}). Pass an explicit ` +
78
78
  `{ path, schemaName } to override.`);
79
79
  }
80
- // The first shard is always main per SQLite semantics — its derived name is informational
81
- // only. Subsequent shards must have unique non-main names.
80
+ // The first extract is always main per SQLite semantics — its derived name is informational
81
+ // only. Subsequent extracts must have unique non-main names.
82
82
  const schemaName = i === 0 ? "main" : derived;
83
83
  if (i > 0 && (schemaName === "main" || seen.has(schemaName))) {
84
- throw new Error(`resolveShards: schema name ${JSON.stringify(schemaName)} collides ` +
85
- `(either with "main" or another shard). Pass an explicit { path, schemaName }.`);
84
+ throw new Error(`resolveExtracts: schema name ${JSON.stringify(schemaName)} collides ` +
85
+ `(either with "main" or another extract). Pass an explicit { path, schemaName }.`);
86
86
  }
87
87
  seen.add(schemaName);
88
88
  out.push({
@@ -94,35 +94,35 @@ export function resolveShards(input) {
94
94
  return out;
95
95
  }
96
96
  /**
97
- * Pick the shard to route a query to given the requested placetype(s).
97
+ * Pick the extract to route a query to given the requested placetype(s).
98
98
  *
99
99
  * Routing rules, in order:
100
100
  *
101
- * 1. If any shard has explicit `placetypes` that includes the requested placetype, use it.
102
- * 2. Otherwise, if a non-main shard's `schemaName` matches the placetype (e.g. `postalcode_us` matches `postalcode`), use
103
- * it.
101
+ * 1. If any extract has explicit `placetypes` that includes the requested placetype, use it.
102
+ * 2. Otherwise, if a non-main extract's `schemaName` matches the placetype (e.g. `postalcode_us` matches `postalcode`),
103
+ * use it.
104
104
  * 3. Otherwise, fall back to `main`.
105
105
  *
106
- * This deliberately doesn't UNION across shards — BM25 scores aren't comparable across separately- indexed corpora, and
107
- * the typical mailwoman query has a single placetype anyway. If a caller needs cross-shard results they can issue two
108
- * `findPlace` calls.
106
+ * This deliberately doesn't UNION across extracts — BM25 scores aren't comparable across separately- indexed corpora,
107
+ * and the typical mailwoman query has a single placetype anyway. If a caller needs cross-extract results they can issue
108
+ * two `findPlace` calls.
109
109
  */
110
110
  /**
111
- * All placetype-matching shards, in routing order (the country-aware pick chooses among these). Used by the bias path:
112
- * a country-less postcode query with proximity hints fans out across every matching shard and merges, because
113
- * single-shard routing would hide the cross-country ambiguity the hints exist to resolve ("48026" lives in
111
+ * All placetype-matching extracts, in routing order (the country-aware pick chooses among these). Used by the bias
112
+ * path: a country-less postcode query with proximity hints fans out across every matching extract and merges, because
113
+ * single-extract routing would hide the cross-country ambiguity the hints exist to resolve ("48026" lives in
114
114
  * postalcode-us AND postalcode-intl).
115
115
  */
116
- export function pickShardsForPlacetype(shards, placetype) {
116
+ export function pickExtractsForPlacetype(extracts, placetype) {
117
117
  if (!placetype)
118
- return [shards[0]];
118
+ return [extracts[0]];
119
119
  const matches = [];
120
- for (const s of shards) {
120
+ for (const s of extracts) {
121
121
  if (s.placetypes.includes(placetype)) {
122
122
  matches.push(s);
123
123
  }
124
124
  }
125
- for (const s of shards) {
125
+ for (const s of extracts) {
126
126
  if (s.schemaName === "main" || matches.includes(s))
127
127
  continue;
128
128
  if (s.schemaName === placetype ||
@@ -131,18 +131,18 @@ export function pickShardsForPlacetype(shards, placetype) {
131
131
  matches.push(s);
132
132
  }
133
133
  }
134
- return matches.length ? matches : [shards[0]];
134
+ return matches.length ? matches : [extracts[0]];
135
135
  }
136
- export function pickShardForPlacetype(shards, placetype, opts) {
136
+ export function pickExtractForPlacetype(extracts, placetype, opts) {
137
137
  if (!placetype)
138
- return shards[0];
138
+ return extracts[0];
139
139
  const matches = [];
140
- for (const s of shards) {
140
+ for (const s of extracts) {
141
141
  if (s.placetypes.includes(placetype)) {
142
142
  matches.push(s);
143
143
  }
144
144
  }
145
- for (const s of shards) {
145
+ for (const s of extracts) {
146
146
  if (s.schemaName === "main" || matches.includes(s))
147
147
  continue;
148
148
  // Substring match: `postalcode_us` matches `postalcode`. Conservative — requires the
@@ -155,7 +155,7 @@ export function pickShardForPlacetype(shards, placetype, opts) {
155
155
  }
156
156
  }
157
157
  if (!matches.length)
158
- return shards[0];
158
+ return extracts[0];
159
159
  if (opts?.country && opts.countriesBySchema) {
160
160
  for (const s of matches) {
161
161
  if (opts.countriesBySchema.get(s.schemaName)?.has(opts.country))
@@ -164,4 +164,4 @@ export function pickShardForPlacetype(shards, placetype, opts) {
164
164
  }
165
165
  return matches[0];
166
166
  }
167
- //# sourceMappingURL=sharding.js.map
167
+ //# sourceMappingURL=extracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extracts.js","sourceRoot":"","sources":["../lib/extracts.ts"],"names":[],"mappings":"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"}
@@ -3,20 +3,20 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
- * FST-based autocomplete. Prefix walk + BFS expansion to collect ranked place suggestions. O(depth
7
- * × branching) — the FST IS the autocomplete index.
6
+ * FST-based autocomplete — mailwoman vocabulary over `@mailwoman/ancestrie`'s generic algorithm
7
+ * (#1728 phase 2). The #587 behavior — prefix walk + BFS expansion, partial-last-token completion,
8
+ * per-branch capping, dedupe — lives in ancestrie's `autocomplete`; this module contributes only
9
+ * the storage adapter ({@link FSTMatcher} → `AncestrieReaderLike`) and the mapping back to
10
+ * mailwoman's suggestion shape (name, placetype, referential/encyclopedic, WOF ids).
8
11
  *
9
- * Two query shapes are handled (the FST is a trie over normalized WORD tokens):
10
- *
11
- * - COMPLETE tokens ("new york") — `walk` lands on a state; collect its accepting entries + BFS a
12
- * couple tokens past it for nearby completions. This is the CLI's "complete a place word"
13
- * path.
14
- * - A PARTIAL last token ("new yor", "chic") — `walk` fails (there is no "yor" edge, only "york"). So
15
- * walk the complete prefix, then complete the partial token by prefix-filtering the
16
- * continuation edges (`token.startsWith(partial)`). This is what a char-level typeahead
17
- * needs; without it "new yor" returns nothing useful. (#587)
12
+ * THE BYTES DO NOT MIGRATE. The shipped artifacts are `FST\0` v1–v5 (`fst-serialize.ts`), not
13
+ * ancestrie's `ANCT`: ancestrie entries are id-keyed with one record per id, while an FST place row
14
+ * is per-(surface, place) — `crossCountryBranches` is a property of the SURFACE, so the same wofID
15
+ * legitimately carries different values under different aliases and cannot be represented id-keyed.
16
+ * The matcher, both deserializers, and the serializer therefore stay here; what migrated is the
17
+ * ALGORITHM, which is the half that drifts (the #861 share-the-function rule).
18
18
  */
19
- import type { FSTMatcher } from "./fst-matcher.ts";
19
+ import type { FSTMatcher } from "#fst/matcher";
20
20
  export interface AutocompleteResult {
21
21
  query: string;
22
22
  normalizedTokens: string[];
@@ -56,4 +56,4 @@ export interface AutocompleteOpts {
56
56
  * Autocomplete from the current prefix. Returns suggestions ranked referential-descending.
57
57
  */
58
58
  export declare function autocomplete(fst: FSTMatcher, query: string, opts?: AutocompleteOpts): AutocompleteResult;
59
- //# sourceMappingURL=fst-autocomplete.d.ts.map
59
+ //# sourceMappingURL=autocomplete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autocomplete.d.ts","sourceRoot":"","sources":["../../lib/fst/autocomplete.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAWH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAI9C,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,sBAAsB,EAAE,CAAA;CACrC;AAED,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAChC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACtB;AAyED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,kBAAkB,CA+B5G"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * FST-based autocomplete — mailwoman vocabulary over `@mailwoman/ancestrie`'s generic algorithm
7
+ * (#1728 phase 2). The #587 behavior — prefix walk + BFS expansion, partial-last-token completion,
8
+ * per-branch capping, dedupe — lives in ancestrie's `autocomplete`; this module contributes only
9
+ * the storage adapter ({@link FSTMatcher} → `AncestrieReaderLike`) and the mapping back to
10
+ * mailwoman's suggestion shape (name, placetype, referential/encyclopedic, WOF ids).
11
+ *
12
+ * THE BYTES DO NOT MIGRATE. The shipped artifacts are `FST\0` v1–v5 (`fst-serialize.ts`), not
13
+ * ancestrie's `ANCT`: ancestrie entries are id-keyed with one record per id, while an FST place row
14
+ * is per-(surface, place) — `crossCountryBranches` is a property of the SURFACE, so the same wofID
15
+ * legitimately carries different values under different aliases and cannot be represented id-keyed.
16
+ * The matcher, both deserializers, and the serializer therefore stay here; what migrated is the
17
+ * ALGORITHM, which is the half that drifts (the #861 share-the-function rule).
18
+ */
19
+ import { autocomplete as ancestrieAutocomplete } from "@mailwoman/ancestrie";
20
+ import { normalizeTokens } from "#fst/matcher";
21
+ /**
22
+ * Max accepting entries collected per BFS branch — keeps one dense branch from starving the search.
23
+ */
24
+ const PER_BRANCH = 4;
25
+ /**
26
+ * The top-`k` entries by REFERENTIAL likelihood (descending). Avoids sorting/allocating when `entries` is small — and
27
+ * that shortcut is part of the observable contract: at or under `k` the INSERTION order is served, which decides
28
+ * suggestion order among referential ties.
29
+ */
30
+ function topByReferential(entries, k) {
31
+ if (entries.length <= k)
32
+ return [...entries];
33
+ return [...entries].toSorted((a, b) => b.referential - a.referential).slice(0, k);
34
+ }
35
+ /**
36
+ * {@link FSTMatcher} presented through ancestrie's storage interface. Records carry the {@link PlaceEntry} itself as the
37
+ * payload, so the entry that WINS the algorithm's shallowest-depth rule is the entry whose fields the suggestion
38
+ * reports — a side lookup keyed on id could pick a different surface's row (`crossCountryBranches` differs per
39
+ * surface).
40
+ */
41
+ class FSTReader {
42
+ #fst;
43
+ /**
44
+ * Parent chains of the entries this reader has served, id-keyed. A place's chain is identical across its surfaces (it
45
+ * is place-row data), so last-write-wins is safe. The algorithm asks {@link FSTReader.ancestorsOf} only for ids it
46
+ * just received from {@link FSTReader.entriesAt}, so serving from this memo answers every real call without an
47
+ * artifact-wide id index.
48
+ */
49
+ #chains = new Map();
50
+ constructor(fst) {
51
+ this.#fst = fst;
52
+ }
53
+ walk(tokens) {
54
+ return this.#fst.walk([...tokens]);
55
+ }
56
+ continuations(stateID) {
57
+ // Insertion order, verbatim — BFS visit order under the suggestion budget depends on it.
58
+ return this.#fst.continuations(stateID).map((c) => ({
59
+ token: c.token,
60
+ targetState: c.targetState,
61
+ entryCount: c.acceptingCount,
62
+ }));
63
+ }
64
+ entriesAt(stateID, limit) {
65
+ const places = this.#fst.accepting(stateID);
66
+ const selected = limit === undefined ? places : topByReferential(places, limit);
67
+ return selected.map((entry) => {
68
+ this.#chains.set(entry.wofID, entry.parentChain);
69
+ return {
70
+ id: entry.wofID,
71
+ rank: entry.referential,
72
+ parentIDs: entry.parentChain,
73
+ payload: entry,
74
+ };
75
+ });
76
+ }
77
+ ancestorsOf(id) {
78
+ return this.#chains.get(id) ?? [];
79
+ }
80
+ }
81
+ /**
82
+ * Autocomplete from the current prefix. Returns suggestions ranked referential-descending.
83
+ */
84
+ export function autocomplete(fst, query, opts = {}) {
85
+ const normalizedTokens = normalizeTokens(query);
86
+ const result = ancestrieAutocomplete(new FSTReader(fst), normalizedTokens, {
87
+ ...(opts.maxSuggestions === undefined ? {} : { maxSuggestions: opts.maxSuggestions }),
88
+ ...(opts.maxExpansionDepth === undefined ? {} : { maxExpansionDepth: opts.maxExpansionDepth }),
89
+ perBranchLimit: PER_BRANCH,
90
+ // The dedupe key is the DISPLAY name, not the token path: two surfaces of one name must still collapse. (#587)
91
+ ...(opts.dedupeByName ? { dedupe: (s) => s.payload.name.toLowerCase() } : {}),
92
+ });
93
+ return {
94
+ query,
95
+ normalizedTokens,
96
+ depth: result.depth,
97
+ suggestions: result.suggestions.map((s) => {
98
+ // Every record this adapter serves carries its entry; the assertion documents the invariant.
99
+ const entry = s.payload;
100
+ return {
101
+ name: entry.name,
102
+ placetype: entry.placetype,
103
+ referential: entry.referential,
104
+ ...(entry.encyclopedic === undefined ? {} : { encyclopedic: entry.encyclopedic }),
105
+ wofID: s.id,
106
+ parentChain: s.parentIDs,
107
+ matchDepth: s.matchDepth,
108
+ completionTokens: s.completionTokens,
109
+ };
110
+ }),
111
+ };
112
+ }
113
+ //# sourceMappingURL=autocomplete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autocomplete.js","sourceRoot":"","sources":["../../lib/fst/autocomplete.ts"],"names":[],"mappings":"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"}
@@ -10,11 +10,11 @@
10
10
  * Build pipeline: open WOF DB → query spr + names → normalize names → insert into trie → attach
11
11
  * PlaceEntry at terminals → return FSTMatcher.
12
12
  */
13
- import { FSTMatcher } from "./fst-matcher.ts";
14
- import type { BuildFSTOpts, BuildFSTResult, FSTProvenance } from "./fst-types.ts";
15
- export declare function buildFSTFromWOF(opts: BuildFSTOpts): {
13
+ import { FSTMatcher } from "#fst/matcher";
14
+ import type { BuildFSTOpts, BuildFSTResult, FSTProvenance } from "#fst/types";
15
+ export declare function buildFSTFromWOF(opts: BuildFSTOpts): Promise<{
16
16
  matcher: FSTMatcher;
17
17
  provenance: FSTProvenance;
18
18
  result: BuildFSTResult;
19
- };
20
- //# sourceMappingURL=fst-builder.d.ts.map
19
+ }>;
20
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../lib/fst/builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAA;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAA2B,MAAM,YAAY,CAAA;AAuCtG,wBAAsB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC;IAClE,OAAO,EAAE,UAAU,CAAA;IACnB,UAAU,EAAE,aAAa,CAAA;IACzB,MAAM,EAAE,cAAc,CAAA;CACtB,CAAC,CAyTD"}
@@ -10,10 +10,12 @@
10
10
  * Build pipeline: open WOF DB → query spr + names → normalize names → insert into trie → attach
11
11
  * PlaceEntry at terminals → return FSTMatcher.
12
12
  */
13
- import { DatabaseSync } from "node:sqlite";
14
- import { readWOFSourceIdentity } from "./fst-freshness.js";
15
- import { FSTMatcher, normalizeTokens } from "./fst-matcher.js";
16
- import { loadImportanceSplit } from "./place-importance-schema.js";
13
+ import { DatabaseClient } from "@mailwoman/sqlite/client";
14
+ import { resolvePath } from "path-ts";
15
+ import { readWOFSourceIdentity } from "#fst/freshness";
16
+ import { FSTMatcher, normalizeTokens } from "#fst/matcher";
17
+ import { loadImportanceSplit } from "#place-importance-schema";
18
+ import { allRows, getRow } from "#sqlite-utils";
17
19
  const DEFAULT_PLACETYPES = [
18
20
  "country",
19
21
  "region",
@@ -30,13 +32,14 @@ const DEFAULT_LANGUAGES = ["eng", ""];
30
32
  * down, so both read paths bind the same shape.
31
33
  */
32
34
  const ANCESTOR_CHUNK = 500;
33
- export function buildFSTFromWOF(opts) {
35
+ export async function buildFSTFromWOF(opts) {
34
36
  const countries = opts.countries ?? DEFAULT_COUNTRIES;
35
37
  const placetypes = opts.placetypes ?? DEFAULT_PLACETYPES;
36
38
  const languages = opts.languages ?? DEFAULT_LANGUAGES;
37
39
  const progress = opts.onProgress ?? (() => { });
38
- progress("open", opts.dbPath);
39
- const db = new DatabaseSync(opts.dbPath, { open: true });
40
+ const dbPath = resolvePath(opts.dbPath);
41
+ progress("open", dbPath);
42
+ using db = new DatabaseClient(dbPath, { open: true });
40
43
  // Phase 1: Load all matching SPR rows.
41
44
  progress("spr", `Loading places for countries=[${countries}], placetypes=[${placetypes}]`);
42
45
  const placeholders = (arr) => arr.map(() => "?").join(",");
@@ -45,7 +48,7 @@ export function buildFSTFromWOF(opts) {
45
48
  WHERE is_current = 1
46
49
  AND country IN (${placeholders(countries)})
47
50
  AND placetype IN (${placeholders(placetypes)})`);
48
- const sprRows = sprStmt.all(...countries, ...placetypes);
51
+ const sprRows = allRows(sprStmt, ...countries, ...placetypes);
49
52
  progress("spr", `Loaded ${sprRows.length} places`);
50
53
  // Phase 2: Build a lookup for parent chain resolution.
51
54
  const sprByID = new Map();
@@ -63,15 +66,13 @@ export function buildFSTFromWOF(opts) {
63
66
  const orphanIDs = sprRows.filter((row) => row.parent_id <= 0).map((row) => row.id);
64
67
  for (let i = 0; i < orphanIDs.length; i += ANCESTOR_CHUNK) {
65
68
  const chunk = orphanIDs.slice(i, i + ANCESTOR_CHUNK);
66
- const rows = db
67
- .prepare(`SELECT DISTINCT id, ancestor_id FROM ancestors
69
+ const rows = allRows(db.prepare(`SELECT DISTINCT id, ancestor_id FROM ancestors
68
70
  WHERE id IN (${chunk.map(() => "?").join(",")}) AND ancestor_placetype IN ('country', 'region', 'county')
69
71
  ORDER BY id, CASE ancestor_placetype
70
72
  WHEN 'county' THEN 1
71
73
  WHEN 'region' THEN 2
72
74
  WHEN 'country' THEN 3
73
- END`)
74
- .all(...chunk);
75
+ END`), ...chunk);
75
76
  for (const row of rows) {
76
77
  let chain = ancestorsByID.get(row.id);
77
78
  if (!chain) {
@@ -101,7 +102,7 @@ export function buildFSTFromWOF(opts) {
101
102
  chain.push(current);
102
103
  let parentRow = sprByID.get(current);
103
104
  if (!parentRow) {
104
- const fetched = parentStmt.get(current);
105
+ const fetched = getRow(parentStmt, current);
105
106
  if (!fetched)
106
107
  break;
107
108
  parentRow = fetched;
@@ -130,18 +131,18 @@ export function buildFSTFromWOF(opts) {
130
131
  ")");
131
132
  // Phase 4: Load names for matching places.
132
133
  progress("names", "Loading name variants");
133
- const placeIds = sprRows.map((r) => r.id);
134
+ const placeIDs = sprRows.map((r) => r.id);
134
135
  const namesByPlace = new Map();
135
136
  const allLanguages = languages.includes("*");
136
- for (let i = 0; i < placeIds.length; i += 500) {
137
- const chunk = placeIds.slice(i, i + 500);
137
+ for (let i = 0; i < placeIDs.length; i += 500) {
138
+ const chunk = placeIDs.slice(i, i + 500);
138
139
  const idPlaceholders = chunk.map(() => "?").join(",");
139
140
  const nameStmt = allLanguages
140
141
  ? db.prepare(`SELECT id, name, language, privateuse FROM names WHERE id IN (${idPlaceholders})`)
141
142
  : db.prepare(`SELECT id, name, language, privateuse FROM names WHERE id IN (${idPlaceholders}) AND language IN (${languages.map(() => "?").join(",")})`);
142
- const nameRows = (allLanguages
143
- ? nameStmt.all(...chunk)
144
- : nameStmt.all(...chunk, ...languages));
143
+ const nameRows = allLanguages
144
+ ? allRows(nameStmt, ...chunk)
145
+ : allRows(nameStmt, ...chunk, ...languages);
145
146
  for (const row of nameRows) {
146
147
  const existing = namesByPlace.get(row.id) ?? [];
147
148
  if (!existing.includes(row.name)) {
@@ -235,7 +236,6 @@ export function buildFSTFromWOF(opts) {
235
236
  }
236
237
  }
237
238
  }
238
- db.close();
239
239
  progress("done", `Built trie: ${nodes.length} states, ${insertCount} name insertions` +
240
240
  (excludedCount > 0 ? ` (${excludedCount} degenerate surfaces excluded)` : ""));
241
241
  const edgeCount = nodes.reduce((sum, n) => sum + n.edges.size, 0);
@@ -246,8 +246,8 @@ export function buildFSTFromWOF(opts) {
246
246
  // and is free whenever the `.md5` sidecar is current, which the admin build already writes.
247
247
  // `sourceIdentity` lets a caller that already knows the digest (or is building from something that
248
248
  // is not a file at all) supply it instead.
249
- progress("stamp", `Reading source identity for ${opts.dbPath}`);
250
- const source = opts.sourceIdentity ?? readWOFSourceIdentity(opts.dbPath);
249
+ progress("stamp", `Reading source identity for ${dbPath}`);
250
+ const source = opts.sourceIdentity ?? (await readWOFSourceIdentity(dbPath));
251
251
  const provenance = {
252
252
  builtAt: new Date().toISOString(),
253
253
  countries,
@@ -258,7 +258,7 @@ export function buildFSTFromWOF(opts) {
258
258
  importanceMatches: split.referential.size,
259
259
  encyclopedicMatches: split.encyclopedic.size,
260
260
  importanceSource: split.source,
261
- sourceDB: opts.dbPath,
261
+ sourceDB: dbPath,
262
262
  sourceDBMD5: source.md5,
263
263
  sourceDBBytes: source.bytes,
264
264
  ...(excludeSurfaces !== undefined || excludeAllTokensOf !== undefined
@@ -276,4 +276,4 @@ export function buildFSTFromWOF(opts) {
276
276
  },
277
277
  };
278
278
  }
279
- //# sourceMappingURL=fst-builder.js.map
279
+ //# sourceMappingURL=builder.js.map