@mailwoman/resolver-wof-sqlite 9.3.0 → 10.0.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 (286) hide show
  1. package/lib/address/index.ts +3 -3
  2. package/lib/address/{point.ts → point/index.ts} +55 -7
  3. package/lib/address/{point-interpolation.ts → point/interpolation.ts} +2 -3
  4. package/lib/ancestry/backfill.ts +4 -2
  5. package/lib/ancestry/index.ts +1 -2
  6. package/lib/{build-candidate.ts → build/candidate.ts} +62 -31
  7. package/lib/candidate/alias-bags.ts +68 -7
  8. package/lib/{candidate-ancestors-schema.ts → candidate/ancestors/schema.ts} +1 -1
  9. package/lib/candidate/{ancestors-sidecar.ts → ancestors/sidecar.ts} +2 -2
  10. package/lib/candidate/extract-fold.ts +91 -10
  11. package/lib/{candidate-importance.ts → candidate/importance.ts} +1 -1
  12. package/lib/{candidate-lookup.ts → candidate/lookup.ts} +13 -16
  13. package/lib/candidate/name-roles.ts +2 -2
  14. package/lib/candidate/own-name.ts +1 -0
  15. package/lib/{candidate-schema.ts → candidate/schema.ts} +2 -2
  16. package/lib/{candidate-scoring.ts → candidate/scoring.ts} +1 -1
  17. package/lib/coincident-roles.ts +2 -3
  18. package/lib/coverage-manifest-schema.ts +2 -1
  19. package/lib/currency-backfill.ts +2 -2
  20. package/lib/fst/builder.ts +1 -1
  21. package/lib/fst/deserialize-web.ts +2 -2
  22. package/lib/fst/freshness.ts +0 -1
  23. package/lib/fst/serialize.ts +9 -9
  24. package/lib/geonames/aliases.ts +1 -7
  25. package/lib/geonames/postal.ts +1 -7
  26. package/lib/index.ts +18 -25
  27. package/lib/interpolation.ts +1 -1
  28. package/lib/lookup.ts +6 -5
  29. package/lib/place-importance-schema.ts +1 -9
  30. package/lib/poi/lookup.ts +1 -2
  31. package/lib/postal/{city-alias-lookup.ts → city/alias/lookup.ts} +1 -1
  32. package/lib/postal/index.ts +3 -3
  33. package/lib/primary-preference.ts +15 -5
  34. package/lib/reverse.ts +1 -2
  35. package/lib/search-fetch.ts +1 -2
  36. package/lib/{sqlite-utils.ts → sqlite/utils.ts} +0 -1
  37. package/lib/street/{centroid.ts → centroid/index.ts} +2 -2
  38. package/lib/street/index.ts +4 -4
  39. package/lib/street/{morphology-fst-builder.ts → morphology/fst/builder.ts} +8 -2
  40. package/lib/street/{morphology-fst-loader.ts → morphology/fst/loader.ts} +1 -1
  41. package/lib/street/normalize.ts +42 -1
  42. package/lib/uprn/lookup.ts +1 -2
  43. package/lib/weights-overlay-linker.ts +5 -4
  44. package/out/address/index.d.ts +3 -3
  45. package/out/address/index.d.ts.map +1 -1
  46. package/out/address/index.js +3 -3
  47. package/out/address/index.js.map +1 -1
  48. package/out/address/{point.d.ts → point/index.d.ts} +5 -3
  49. package/out/address/point/index.d.ts.map +1 -0
  50. package/out/address/{point.js → point/index.js} +38 -7
  51. package/out/address/point/index.js.map +1 -0
  52. package/out/address/{point-interpolation.d.ts → point/interpolation.d.ts} +3 -3
  53. package/out/address/point/interpolation.d.ts.map +1 -0
  54. package/out/address/{point-interpolation.js → point/interpolation.js} +1 -1
  55. package/out/address/point/interpolation.js.map +1 -0
  56. package/out/address/{point-schema.d.ts → point/schema.d.ts} +1 -1
  57. package/out/address/point/schema.d.ts.map +1 -0
  58. package/out/address/{point-schema.js → point/schema.js} +1 -1
  59. package/out/address/point/schema.js.map +1 -0
  60. package/out/ancestry/backfill.d.ts.map +1 -1
  61. package/out/ancestry/backfill.js +4 -2
  62. package/out/ancestry/backfill.js.map +1 -1
  63. package/out/ancestry/index.d.ts.map +1 -1
  64. package/out/ancestry/index.js +1 -1
  65. package/out/ancestry/index.js.map +1 -1
  66. package/out/{build-candidate.d.ts → build/candidate.d.ts} +12 -4
  67. package/out/build/candidate.d.ts.map +1 -0
  68. package/out/{build-candidate.js → build/candidate.js} +39 -24
  69. package/out/build/candidate.js.map +1 -0
  70. package/out/{build-slim.d.ts → build/slim.d.ts} +1 -1
  71. package/out/build/slim.d.ts.map +1 -0
  72. package/out/{build-slim.js → build/slim.js} +1 -1
  73. package/out/build/slim.js.map +1 -0
  74. package/out/candidate/alias-bags.d.ts +10 -2
  75. package/out/candidate/alias-bags.d.ts.map +1 -1
  76. package/out/candidate/alias-bags.js +49 -5
  77. package/out/candidate/alias-bags.js.map +1 -1
  78. package/out/{candidate-ancestors-schema.d.ts → candidate/ancestors/schema.d.ts} +2 -2
  79. package/out/candidate/ancestors/schema.d.ts.map +1 -0
  80. package/out/{candidate-ancestors-schema.js → candidate/ancestors/schema.js} +1 -1
  81. package/out/candidate/ancestors/schema.js.map +1 -0
  82. package/out/candidate/{ancestors-sidecar.d.ts → ancestors/sidecar.d.ts} +2 -2
  83. package/out/candidate/ancestors/sidecar.d.ts.map +1 -0
  84. package/out/candidate/{ancestors-sidecar.js → ancestors/sidecar.js} +2 -2
  85. package/out/candidate/ancestors/sidecar.js.map +1 -0
  86. package/out/candidate/extract-fold.d.ts +12 -3
  87. package/out/candidate/extract-fold.d.ts.map +1 -1
  88. package/out/candidate/extract-fold.js +57 -8
  89. package/out/candidate/extract-fold.js.map +1 -1
  90. package/out/{candidate-fts.d.ts → candidate/fts.d.ts} +1 -1
  91. package/out/candidate/fts.d.ts.map +1 -0
  92. package/out/{candidate-fts.js → candidate/fts.js} +1 -1
  93. package/out/candidate/fts.js.map +1 -0
  94. package/out/{candidate-importance.d.ts → candidate/importance.d.ts} +1 -1
  95. package/out/candidate/importance.d.ts.map +1 -0
  96. package/out/{candidate-importance.js → candidate/importance.js} +1 -1
  97. package/out/candidate/importance.js.map +1 -0
  98. package/out/{candidate-lookup.d.ts → candidate/lookup.d.ts} +7 -7
  99. package/out/candidate/lookup.d.ts.map +1 -0
  100. package/out/{candidate-lookup.js → candidate/lookup.js} +13 -11
  101. package/out/candidate/lookup.js.map +1 -0
  102. package/out/candidate/name-roles.d.ts +1 -1
  103. package/out/candidate/name-roles.d.ts.map +1 -1
  104. package/out/candidate/name-roles.js +1 -1
  105. package/out/candidate/name-roles.js.map +1 -1
  106. package/out/candidate/own-name.d.ts.map +1 -1
  107. package/out/candidate/own-name.js +1 -0
  108. package/out/candidate/own-name.js.map +1 -1
  109. package/out/{candidate-schema.d.ts → candidate/schema.d.ts} +3 -3
  110. package/out/candidate/schema.d.ts.map +1 -0
  111. package/out/{candidate-schema.js → candidate/schema.js} +2 -2
  112. package/out/candidate/schema.js.map +1 -0
  113. package/out/{candidate-scoring.d.ts → candidate/scoring.d.ts} +1 -1
  114. package/out/candidate/scoring.d.ts.map +1 -0
  115. package/out/{candidate-scoring.js → candidate/scoring.js} +2 -2
  116. package/out/candidate/scoring.js.map +1 -0
  117. package/out/capitals.d.ts.map +1 -1
  118. package/out/coincident-roles.d.ts +1 -1
  119. package/out/coincident-roles.d.ts.map +1 -1
  120. package/out/coincident-roles.js +1 -1
  121. package/out/coincident-roles.js.map +1 -1
  122. package/out/convention/index.d.ts.map +1 -1
  123. package/out/convention/index.js.map +1 -1
  124. package/out/coverage-manifest-schema.d.ts.map +1 -1
  125. package/out/coverage-manifest-schema.js +2 -1
  126. package/out/coverage-manifest-schema.js.map +1 -1
  127. package/out/currency-backfill.d.ts +2 -2
  128. package/out/currency-backfill.d.ts.map +1 -1
  129. package/out/env.d.ts +1 -1
  130. package/out/fst/autocomplete.js.map +1 -1
  131. package/out/fst/builder.d.ts.map +1 -1
  132. package/out/fst/builder.js +1 -1
  133. package/out/fst/builder.js.map +1 -1
  134. package/out/fst/deserialize-web.js +2 -2
  135. package/out/fst/deserialize-web.js.map +1 -1
  136. package/out/fst/freshness.d.ts +0 -1
  137. package/out/fst/freshness.d.ts.map +1 -1
  138. package/out/fst/freshness.js +0 -1
  139. package/out/fst/freshness.js.map +1 -1
  140. package/out/fst/matcher.d.ts.map +1 -1
  141. package/out/fst/serialize.js +9 -9
  142. package/out/fst/serialize.js.map +1 -1
  143. package/out/fts/index.js.map +1 -1
  144. package/out/geonames/aliases.d.ts +0 -5
  145. package/out/geonames/aliases.d.ts.map +1 -1
  146. package/out/geonames/aliases.js +1 -6
  147. package/out/geonames/aliases.js.map +1 -1
  148. package/out/geonames/postal.d.ts +0 -6
  149. package/out/geonames/postal.d.ts.map +1 -1
  150. package/out/geonames/postal.js +1 -6
  151. package/out/geonames/postal.js.map +1 -1
  152. package/out/index.d.ts +18 -19
  153. package/out/index.d.ts.map +1 -1
  154. package/out/index.js +13 -14
  155. package/out/index.js.map +1 -1
  156. package/out/interpolation.d.ts +1 -1
  157. package/out/interpolation.d.ts.map +1 -1
  158. package/out/lookup.d.ts +2 -2
  159. package/out/lookup.d.ts.map +1 -1
  160. package/out/lookup.js +4 -4
  161. package/out/lookup.js.map +1 -1
  162. package/out/nsul/lookup.d.ts.map +1 -1
  163. package/out/place-importance-schema.d.ts +0 -1
  164. package/out/place-importance-schema.d.ts.map +1 -1
  165. package/out/place-importance-schema.js +1 -2
  166. package/out/place-importance-schema.js.map +1 -1
  167. package/out/poi/lookup.d.ts.map +1 -1
  168. package/out/poi/lookup.js +1 -1
  169. package/out/poi/lookup.js.map +1 -1
  170. package/out/poi/schema.d.ts.map +1 -1
  171. package/out/postal/{city-alias-lookup.d.ts → city/alias/lookup.d.ts} +2 -2
  172. package/out/postal/city/alias/lookup.d.ts.map +1 -0
  173. package/out/postal/{city-alias-lookup.js → city/alias/lookup.js} +1 -1
  174. package/out/postal/city/alias/lookup.js.map +1 -0
  175. package/out/postal/{city-alias-schema.d.ts → city/alias/schema.d.ts} +1 -1
  176. package/out/postal/city/alias/schema.d.ts.map +1 -0
  177. package/out/postal/{city-alias-schema.js → city/alias/schema.js} +1 -1
  178. package/out/postal/city/alias/schema.js.map +1 -0
  179. package/out/postal/{city-candidate-schema.d.ts → city/candidate-schema.d.ts} +1 -1
  180. package/out/postal/city/candidate-schema.d.ts.map +1 -0
  181. package/out/postal/{city-candidate-schema.js → city/candidate-schema.js} +1 -1
  182. package/out/postal/city/candidate-schema.js.map +1 -0
  183. package/out/postal/index.d.ts +3 -3
  184. package/out/postal/index.js +3 -3
  185. package/out/postcode-point-lookup.d.ts.map +1 -1
  186. package/out/primary-preference.d.ts +3 -3
  187. package/out/primary-preference.d.ts.map +1 -1
  188. package/out/primary-preference.js +12 -4
  189. package/out/primary-preference.js.map +1 -1
  190. package/out/reverse.d.ts.map +1 -1
  191. package/out/reverse.js +1 -1
  192. package/out/reverse.js.map +1 -1
  193. package/out/search-fetch.d.ts.map +1 -1
  194. package/out/search-fetch.js +1 -1
  195. package/out/search-fetch.js.map +1 -1
  196. package/out/{sqlite-convention-source.d.ts → sqlite/convention-source.d.ts} +1 -1
  197. package/out/sqlite/convention-source.d.ts.map +1 -0
  198. package/out/{sqlite-convention-source.js → sqlite/convention-source.js} +1 -1
  199. package/out/sqlite/convention-source.js.map +1 -0
  200. package/out/{sqlite-utils.d.ts → sqlite/utils.d.ts} +1 -2
  201. package/out/sqlite/utils.d.ts.map +1 -0
  202. package/out/{sqlite-utils.js → sqlite/utils.js} +1 -4
  203. package/out/sqlite/utils.js.map +1 -0
  204. package/out/street/{centroid.d.ts → centroid/index.d.ts} +2 -2
  205. package/out/street/centroid/index.d.ts.map +1 -0
  206. package/out/street/{centroid.js → centroid/index.js} +1 -1
  207. package/out/street/centroid/index.js.map +1 -0
  208. package/out/street/{centroid-schema.d.ts → centroid/schema.d.ts} +1 -1
  209. package/out/street/centroid/schema.d.ts.map +1 -0
  210. package/out/street/{centroid-schema.js → centroid/schema.js} +1 -1
  211. package/out/street/centroid/schema.js.map +1 -0
  212. package/out/street/index.d.ts +4 -4
  213. package/out/street/index.d.ts.map +1 -1
  214. package/out/street/index.js +4 -4
  215. package/out/street/index.js.map +1 -1
  216. package/out/street/{morphology-fst-builder.d.ts → morphology/fst/builder.d.ts} +1 -1
  217. package/out/street/morphology/fst/builder.d.ts.map +1 -0
  218. package/out/street/{morphology-fst-builder.js → morphology/fst/builder.js} +8 -3
  219. package/out/street/morphology/fst/builder.js.map +1 -0
  220. package/out/street/{morphology-fst-loader.d.ts → morphology/fst/loader.d.ts} +1 -1
  221. package/out/street/morphology/fst/loader.d.ts.map +1 -0
  222. package/out/street/{morphology-fst-loader.js → morphology/fst/loader.js} +2 -2
  223. package/out/street/morphology/fst/loader.js.map +1 -0
  224. package/out/street/name-lookup.d.ts.map +1 -1
  225. package/out/street/name-lookup.js.map +1 -1
  226. package/out/street/normalize.d.ts +13 -1
  227. package/out/street/normalize.d.ts.map +1 -1
  228. package/out/street/normalize.js +37 -0
  229. package/out/street/normalize.js.map +1 -1
  230. package/out/street/segment-schema.d.ts.map +1 -1
  231. package/out/uprn/lookup.d.ts.map +1 -1
  232. package/out/uprn/lookup.js +1 -1
  233. package/out/uprn/lookup.js.map +1 -1
  234. package/out/weights-overlay-linker.d.ts.map +1 -1
  235. package/out/weights-overlay-linker.js +4 -3
  236. package/out/weights-overlay-linker.js.map +1 -1
  237. package/package.json +64 -64
  238. package/out/address/point-interpolation.d.ts.map +0 -1
  239. package/out/address/point-interpolation.js.map +0 -1
  240. package/out/address/point-schema.d.ts.map +0 -1
  241. package/out/address/point-schema.js.map +0 -1
  242. package/out/address/point.d.ts.map +0 -1
  243. package/out/address/point.js.map +0 -1
  244. package/out/build-candidate.d.ts.map +0 -1
  245. package/out/build-candidate.js.map +0 -1
  246. package/out/build-slim.d.ts.map +0 -1
  247. package/out/build-slim.js.map +0 -1
  248. package/out/candidate/ancestors-sidecar.d.ts.map +0 -1
  249. package/out/candidate/ancestors-sidecar.js.map +0 -1
  250. package/out/candidate-ancestors-schema.d.ts.map +0 -1
  251. package/out/candidate-ancestors-schema.js.map +0 -1
  252. package/out/candidate-fts.d.ts.map +0 -1
  253. package/out/candidate-fts.js.map +0 -1
  254. package/out/candidate-importance.d.ts.map +0 -1
  255. package/out/candidate-importance.js.map +0 -1
  256. package/out/candidate-lookup.d.ts.map +0 -1
  257. package/out/candidate-lookup.js.map +0 -1
  258. package/out/candidate-schema.d.ts.map +0 -1
  259. package/out/candidate-schema.js.map +0 -1
  260. package/out/candidate-scoring.d.ts.map +0 -1
  261. package/out/candidate-scoring.js.map +0 -1
  262. package/out/postal/city-alias-lookup.d.ts.map +0 -1
  263. package/out/postal/city-alias-lookup.js.map +0 -1
  264. package/out/postal/city-alias-schema.d.ts.map +0 -1
  265. package/out/postal/city-alias-schema.js.map +0 -1
  266. package/out/postal/city-candidate-schema.d.ts.map +0 -1
  267. package/out/postal/city-candidate-schema.js.map +0 -1
  268. package/out/sqlite-convention-source.d.ts.map +0 -1
  269. package/out/sqlite-convention-source.js.map +0 -1
  270. package/out/sqlite-utils.d.ts.map +0 -1
  271. package/out/sqlite-utils.js.map +0 -1
  272. package/out/street/centroid-schema.d.ts.map +0 -1
  273. package/out/street/centroid-schema.js.map +0 -1
  274. package/out/street/centroid.d.ts.map +0 -1
  275. package/out/street/centroid.js.map +0 -1
  276. package/out/street/morphology-fst-builder.d.ts.map +0 -1
  277. package/out/street/morphology-fst-builder.js.map +0 -1
  278. package/out/street/morphology-fst-loader.d.ts.map +0 -1
  279. package/out/street/morphology-fst-loader.js.map +0 -1
  280. /package/lib/address/{point-schema.ts → point/schema.ts} +0 -0
  281. /package/lib/{build-slim.ts → build/slim.ts} +0 -0
  282. /package/lib/{candidate-fts.ts → candidate/fts.ts} +0 -0
  283. /package/lib/postal/{city-alias-schema.ts → city/alias/schema.ts} +0 -0
  284. /package/lib/postal/{city-candidate-schema.ts → city/candidate-schema.ts} +0 -0
  285. /package/lib/{sqlite-convention-source.ts → sqlite/convention-source.ts} +0 -0
  286. /package/lib/street/{centroid-schema.ts → centroid/schema.ts} +0 -0
@@ -32,11 +32,10 @@
32
32
  */
33
33
 
34
34
  import { referentialFromPopulation } from "@mailwoman/core/resolver"
35
+ import { allRows } from "@mailwoman/core/utils"
35
36
  import type { DatabaseClient } from "@mailwoman/sqlite/client"
36
37
  import type { Kysely } from "kysely"
37
38
 
38
- import { allRows } from "#sqlite-utils"
39
-
40
39
  //#region Schema
41
40
 
42
41
  /**
@@ -106,13 +105,6 @@ export async function createPlaceImportanceTable(db: Kysely<PlaceImportanceDatab
106
105
  * (backend-agnostic — it cannot import this package) reads the same number. Re-exported HERE so the schema module stays
107
106
  * the one-stop read for the table: the column and the function that fills it are one hop apart.
108
107
  */
109
- export {
110
- compareReferential,
111
- REFERENTIAL_LOG2_SCALE,
112
- REFERENTIAL_POPULATION_DIVISOR,
113
- REFERENTIAL_SATURATION_POPULATION,
114
- referentialFromPopulation,
115
- } from "@mailwoman/core/resolver"
116
108
 
117
109
  //#endregion
118
110
 
package/lib/poi/lookup.ts CHANGED
@@ -25,13 +25,12 @@
25
25
  * it).
26
26
  */
27
27
 
28
+ import { allRows } from "@mailwoman/core/utils"
28
29
  import { haversineKm, shortCellToInt, type H3Cell } from "@mailwoman/spatial"
29
30
  import { DatabaseClient } from "@mailwoman/sqlite/client"
30
31
  import { gridDisk, latLngToCell } from "h3-js"
31
32
 
32
33
  import type { POICategoryCodeTable, POIDatabase, POITable } from "#poi/schema"
33
- import { allRows } from "#sqlite-utils"
34
-
35
34
  /**
36
35
  * Resolution the `poi` table's `h3_cell` column is keyed at — matches the builder (spec §3.4).
37
36
  */
@@ -18,7 +18,7 @@
18
18
 
19
19
  import { DatabaseClient } from "@mailwoman/sqlite/client"
20
20
 
21
- import type { PostalCityAliasDatabase } from "#postal/city-alias-schema"
21
+ import type { PostalCityAliasDatabase } from "#postal/city/alias/schema"
22
22
 
23
23
  export interface WOFPostalCityAliasLookupOpts {
24
24
  /**
@@ -4,6 +4,6 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
 
7
- export * from "#postal/city-alias-lookup"
8
- export * from "#postal/city-alias-schema"
9
- export * from "#postal/city-candidate-schema"
7
+ export * from "#postal/city/alias/lookup"
8
+ export * from "#postal/city/alias/schema"
9
+ export * from "#postal/city/candidate-schema"
@@ -5,13 +5,13 @@
5
5
  *
6
6
  * Bounded cross-country PRIMARY-NAME preference over a population-ordered candidate row set — the
7
7
  * `is_primary` ranking signal, PURE and platform-free so the Node candidate lookup
8
- * (`candidate-lookup.ts`) and the browser twin (`docs/src/shared/httpvfs-resolver.ts`) rank with the
9
- * SAME function rather than two copies that drift (the #861 server↔demo parity contract).
8
+ * (`candidate-lookup.ts`) and the browser twin (`packages/resolver-wof-wasm/lib/httpvfs/resolver.ts`) rank with
9
+ * the SAME function rather than two copies that drift (the #861 server↔browser parity contract).
10
10
  *
11
11
  * Only type imports and arithmetic live here: anything with a `node:` import stays out.
12
12
  */
13
13
 
14
- import type { CandidateTable } from "#candidate-schema"
14
+ import type { CandidateTable } from "#candidate/schema"
15
15
 
16
16
  /**
17
17
  * The row shape the re-rank needs. `is_primary` is optional: a reader over an artifact vintage that predates the column
@@ -207,17 +207,27 @@ export function rankByPrimaryPreference<R extends PrimaryPreferenceRow>(
207
207
  ? 1
208
208
  : 0
209
209
 
210
+ // 1 for a PRIMARY-name row whose prominence is unmeasured (population 0), 0 for everything else. Two unmeasured
211
+ // rows tie on `neg_rank`, and that tie used to fall through to scan order — the B-tree's `spr_id`, which is no
212
+ // evidence about either place. A row that IS named X ranks ahead of one merely also-known-as X when nothing else
213
+ // separates them: Taiwan's 溪州鄉 township row (its own name, unmeasured) over the village 溪洲 30 km away that
214
+ // carries `溪州鄉` as an alias (unmeasured), which the lower WOF id had been winning. Populated ties are untouched —
215
+ // a populated alias ("NYC") never reaches this term, and two populated rows keep the order they had.
216
+ const unmeasuredPrimary = (r: R): number =>
217
+ r.is_primary === 1 && typeof r.population === "number" && r.population === 0 ? 1 : 0
218
+
210
219
  return (
211
220
  rows
212
221
  .map((r, i) => ({ row: annotate(r), i }))
213
- // Effective rank ASC; ties keep population order, then the seat preference DESC, then original
214
- // index (stable).
222
+ // Effective rank ASC; ties keep population order, then the seat preference DESC, then the primary name
223
+ // among unmeasured rows, then original index (stable).
215
224
  // oxlint-disable-next-line unicorn/no-array-sort -- sorts a freshly-built array; toSorted would double-allocate on a hot path
216
225
  .sort(
217
226
  (a, b) =>
218
227
  a.row.effectiveNegRank - b.row.effectiveNegRank ||
219
228
  a.row.neg_rank - b.row.neg_rank ||
220
229
  seatPreference(b.row) - seatPreference(a.row) ||
230
+ unmeasuredPrimary(b.row) - unmeasuredPrimary(a.row) ||
221
231
  a.i - b.i
222
232
  )
223
233
  .slice(0, limit)
package/lib/reverse.ts CHANGED
@@ -29,6 +29,7 @@
29
29
  */
30
30
 
31
31
  import { tryParsingJSON } from "@mailwoman/core/json"
32
+ import { allRows } from "@mailwoman/core/utils"
32
33
  import { bboxAround, geometryContains, haversineKm, type ParsedGeometry } from "@mailwoman/spatial"
33
34
  import { DatabaseClient } from "@mailwoman/sqlite/client"
34
35
  import { tableExists } from "@mailwoman/sqlite/introspection"
@@ -36,9 +37,7 @@ import { tableExists } from "@mailwoman/sqlite/introspection"
36
37
  import { ancestorLineage, placetypeDepth } from "#ancestry/index"
37
38
  import { PLACE_BBOX_TABLE } from "#fts/index"
38
39
  import type { WOFDatabase } from "#schema"
39
- import { allRows } from "#sqlite-utils"
40
40
  import type { PlaceCandidate, WOFPlacetype } from "#types"
41
-
42
41
  /**
43
42
  * Largest absolute latitude in WGS-84 degrees.
44
43
  */
@@ -12,14 +12,13 @@
12
12
  * whole corpus, so an exact haversine over the survivors is cheap.
13
13
  */
14
14
 
15
+ import { allRows } from "@mailwoman/core/utils"
15
16
  import { bboxAround } from "@mailwoman/spatial"
16
17
  import type { DatabaseClient, SQLInputValue } from "@mailwoman/sqlite/client"
17
18
 
18
19
  import { PLACE_BBOX_TABLE, PLACE_POPULATION_TABLE } from "#fts/index"
19
20
  import type { RankingWeights } from "#ranking-weights"
20
- import { allRows } from "#sqlite-utils"
21
21
  import type { FindPlaceQuery, WOFPlacetype } from "#types"
22
-
23
22
  /**
24
23
  * Query length at or below which the FTS window is widened. A two- or three-character query is almost always a region
25
24
  * abbreviation, where the exact match can otherwise fall outside the window behind higher-bm25 partial hits — "NY"
@@ -12,7 +12,6 @@ import { hasColumn as columnExists, tableExists } from "@mailwoman/sqlite/intros
12
12
 
13
13
  // The row-shape assertion itself lives in `core` so the readers that cannot depend on this package reach the same
14
14
  // helper; re-exported here because this module is where this package's readers already look for it.
15
- export { allRows, getRow } from "@mailwoman/core/utils"
16
15
 
17
16
  /**
18
17
  * A prepared single-row query whose parameter tuple remains visible to TypeScript. `StatementSync` accepts only the
@@ -19,12 +19,12 @@
19
19
  * exact-after-normalization only (no fuzzy street matching in this tier).
20
20
  */
21
21
 
22
- import type { StreetCentroidHit, StreetCentroidLookup } from "@mailwoman/resolver"
22
+ import type { StreetCentroidHit, StreetCentroidLookup } from "@mailwoman/core/resolver"
23
23
  import { haversineKm } from "@mailwoman/spatial"
24
24
  import { DatabaseClient } from "@mailwoman/sqlite/client"
25
25
 
26
26
  import { hasTable, prepareGet, type PreparedGet } from "#sqlite-utils"
27
- import type { StreetCentroidDatabase } from "#street/centroid-schema"
27
+ import type { StreetCentroidDatabase } from "#street/centroid/schema"
28
28
  import {
29
29
  normalizeLocalityForKey,
30
30
  normalizeStreetForKeyLocale,
@@ -4,10 +4,10 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
 
7
- export * from "#street/centroid"
8
- export * from "#street/centroid-schema"
9
- export * from "#street/morphology-fst-builder"
10
- export * from "#street/morphology-fst-loader"
7
+ export * from "#street/centroid/index"
8
+ export * from "#street/centroid/schema"
9
+ export * from "#street/morphology/fst/builder"
10
+ export * from "#street/morphology/fst/loader"
11
11
  export * from "#street/name-lookup"
12
12
  export * from "#street/normalize"
13
13
  export * from "#street/segment-schema"
@@ -23,9 +23,10 @@
23
23
  * `fst-street-morphology.bin`.
24
24
  */
25
25
 
26
- import { isDirectory, readDirectory, readLocalTextFile, statPath } from "@mailwoman/core/fs/readers"
26
+ import { isDirectory, readLocalTextFile, statPath } from "@mailwoman/core/fs/readers"
27
27
  import { join } from "path-ts"
28
28
  import { TextSpliterator } from "spliterator"
29
+ import { Globerator } from "spliterator/node/fs"
29
30
 
30
31
  import type { FSTNode } from "#fst/matcher"
31
32
  import { FSTMatcher, normalizeTokens } from "#fst/matcher"
@@ -108,7 +109,12 @@ export async function buildStreetMorphologyFST(
108
109
  if (opts.locales && opts.locales.length) {
109
110
  locales = opts.locales
110
111
  } else {
111
- const entries = await readDirectory(opts.dictionariesDir)
112
+ const entries = await Globerator.from("*", {
113
+ cwd: opts.dictionariesDir,
114
+ absolute: false,
115
+ onlyFiles: false,
116
+ }).toArray()
117
+
112
118
  const localeProbes: Array<[string, boolean]> = []
113
119
 
114
120
  for (const entry of entries) {
@@ -28,7 +28,7 @@ import { resourceDictionaryPath } from "@mailwoman/core/paths"
28
28
  import type { FSTMatcher } from "#fst/matcher"
29
29
  import { deserializeFST, readFSTProvenance } from "#fst/serialize"
30
30
  import type { FSTProvenance } from "#fst/types"
31
- import { buildStreetMorphologyFST } from "#street/morphology-fst-builder"
31
+ import { buildStreetMorphologyFST } from "#street/morphology/fst/builder"
32
32
 
33
33
  /**
34
34
  * The sealed artifact's canonical filename — identical in the data-root staging dir and as a weights-package sibling.
@@ -193,7 +193,17 @@ export function normalizeStreetForKey(street: string): StreetKey {
193
193
  * article, so no salient-token / multi-key index is built yet (deferred until probing shows the normalizer can't absorb
194
194
  * the false-negatives).
195
195
  */
196
- export type StreetLocale = "us" | "en" | "fr" | "de" | "nl" | "pl" | "vn" | "id"
196
+ export type StreetLocale = "us" | "en" | "fr" | "de" | "nl" | "pl" | "vn" | "id" | "zh"
197
+
198
+ /**
199
+ * The Han fold shared by every `zh` key: NFKC so a full-width digit or letter keys as its ASCII form (the Taiwanese
200
+ * civil-affairs registers write `122`, a person types `122`), 臺 → 台 (the register writes 臺北市, the common hand writes
201
+ * 台北市), and no whitespace at all, because a Han surface carries none and a stray space would split one key into two.
202
+ * Kanji numerals stay as written: the register spells a road section `一段`, and so does a query.
203
+ */
204
+ function foldHan(input: string): string {
205
+ return input.normalize("NFKC").replaceAll("臺", "台").replaceAll(/\s+/g, "").toLowerCase()
206
+ }
197
207
 
198
208
  /**
199
209
  * Country → street-locale registry surface for the acquisition SDKs (BAN, OSM). Each SDK keeps its own map — membership
@@ -288,6 +298,10 @@ const ID_STREET_ABBREV = new Map<string, string>([
288
298
  export function normalizeStreetForKeyLocale(street: string, locale: StreetLocale): StreetKey {
289
299
  if (locale === "us" || locale === "en") return normalizeStreetForKey(street)
290
300
 
301
+ // A Han street name has no tokens, no type abbreviation and no diacritics; the Latin pipeline below would only
302
+ // split it on whitespace it never carries. `zh` keys are the Han fold and nothing else.
303
+ if (locale === "zh") return foldHan(street) as StreetKey
304
+
291
305
  // Hyphen → space so a compound name keys the same whether the source or the query writes the
292
306
  // hyphen ("Champs-Élysées", "St-Honoré") or a space — both sides fold identically, so this is pure
293
307
  // robustness. It also splits a hyphenated abbreviation ("St-Honoré" → "st honore") into tokens the
@@ -362,6 +376,33 @@ export function normalizeLocalityForKey(locality: string): NameKey {
362
376
  return fold(locality) as NameKey
363
377
  }
364
378
 
379
+ /**
380
+ * The locality key under a street locale: the Han fold for `zh`, {@link normalizeLocalityForKey} for every other.
381
+ * Separate from the shared fold on purpose — the candidate gazetteer's `name_key` column is the shared fold, and a Han
382
+ * rule inside it would re-key every 臺 name under an extract built without the rule.
383
+ */
384
+ export function normalizeLocalityForKeyLocale(locality: string, locale: StreetLocale): NameKey {
385
+ return locale === "zh" ? (foldHan(locality) as NameKey) : normalizeLocalityForKey(locality)
386
+ }
387
+
388
+ /**
389
+ * The house-number key under a street locale. Every Latin register stores a lower-cased, trimmed number and the reader
390
+ * probes the same; `zh` additionally folds width and drops the trailing 號 the Taiwanese registers write on the number
391
+ * itself (`122號`), which a parse also carries on the `house_number` span (`122號`). Both sides key `122`.
392
+ */
393
+ export function normalizeHouseNumberForKey(number: string, locale: StreetLocale): string {
394
+ // The sub-number is written two ways — `30之19號` and `30號之19` — and an attached number a third (`30附40號`,
395
+ // `55之23附1號`); the register stores the base `30` with the rest in `unit`. Every form keys with the 號 dropped and
396
+ // the base number first, which the reader's sub-number rung then falls from.
397
+ if (locale === "zh") {
398
+ return foldHan(number)
399
+ .replace(/^(\d+)號([之附]\d+)$/u, "$1$2")
400
+ .replace(/號$/u, "")
401
+ }
402
+
403
+ return number.trim().toLowerCase()
404
+ }
405
+
365
406
  /**
366
407
  * Leading French street-type token. French types LEAD the name ("avenue du Parc", "boul Saint-Laurent") while English
367
408
  * types TRAIL ("Fifth Avenue", "Grosvenor Place"), so a leading type-token is the discriminating signal — "1 Avenue NE"
@@ -25,14 +25,13 @@
25
25
  * `@mailwoman/spatial`'s `shortCellToInt` via `uprnFullCell` — never reimplemented here.
26
26
  */
27
27
 
28
+ import { allRows } from "@mailwoman/core/utils"
28
29
  import { haversineKm, shortCellToInt, type H3Cell } from "@mailwoman/spatial"
29
30
  import { DatabaseClient } from "@mailwoman/sqlite/client"
30
31
  import { gridDisk } from "h3-js"
31
32
 
32
- import { allRows } from "#sqlite-utils"
33
33
  import type { UPRNDatabase } from "#uprn/schema"
34
34
  import { uprnFullCell } from "#uprn/schema"
35
-
36
35
  /**
37
36
  * Conservative FLOOR on how much CENTRE distance one unit of res-9 GRID distance buys, metres. Adjacent centres sit √3
38
37
  * × edge apart (avg edge 174.4 m → ≈302 m); the worst bearing across a ring costs a further ×0.866, and H3's projection
@@ -222,6 +222,7 @@ const MD5_HEX_LENGTH = 32
222
222
  *
223
223
  * The shared home for the copies the base linkers (`en-us`, `en-gb`, `en-nz`) each carry — new callers import this one.
224
224
  */
225
+ // repo-health-ignore export-name-affix -- the sidecar cache IS the added behaviour; `md5File` hashes every time.
225
226
  export async function md5FileWithSidecar(path: string): Promise<string> {
226
227
  const sidecarPath = `${path}.md5`
227
228
  const sourceStats = await statPath(path)
@@ -318,7 +319,7 @@ export async function warnIfFSTStale(fstPath: string, locale: string): Promise<v
318
319
  const warning = await fstFreshnessWarning({
319
320
  fstPath,
320
321
  sourceDBPath: String(dataRootPath("wof", "admin-global-priority.db")),
321
- rebuildCommand: `node packages/mailwoman/out/cli.js gazetteer build fst --locales ${locale} (writes to a staging dir; swap is operator-conditional)`,
322
+ rebuildCommand: `node packages/mailwoman/out/cli/index.js gazetteer build fst --locales ${locale} (writes to a staging dir; swap is operator-conditional)`,
322
323
  })
323
324
 
324
325
  if (warning) {
@@ -456,7 +457,7 @@ async function pairIndexIsFresh(
456
457
  */
457
458
  export async function buildPairIndexOverlay(overlay: PairIndexOverlay): Promise<void> {
458
459
  const { packageDir, country, delta, transitionBeta, parentDelta } = overlay
459
- const CLI = String(workspacePath("mailwoman", "out", "cli.js"))
460
+ const CLI = String(workspacePath("mailwoman", "out", "cli", "index.js"))
460
461
  const ARTIFACT = `pair-index-${country}.bin`
461
462
  // Built into the data-root OVERLAY, not into the tracked package. The locale is recovered from the
462
463
  // workspace name (`neural-weights-en-gb` → `en-gb`) so callers keep passing the one identifier they
@@ -531,7 +532,7 @@ export async function buildPairIndexOverlay(overlay: PairIndexOverlay): Promise<
531
532
  console.log(`built ${ARTIFACT}`)
532
533
  }
533
534
 
534
- // --- the manifest form ----------------------------------------------------------------------------------------------
535
+ // The manifest form records the overlay's source and artifact identity.
535
536
 
536
537
  /**
537
538
  * A soft-feed sibling an overlay links: where it comes from, the name it takes in the overlay, and the consequence line
@@ -822,7 +823,7 @@ async function buildPostcodeBinary(
822
823
  */
823
824
  export async function materializeDevOverlay(manifest: DevOverlayManifest): Promise<DevOverlay> {
824
825
  const destDir = String(weightsOverlayPath(manifest.locale))
825
- const cli = String(workspacePath("mailwoman", "out", "cli.js"))
826
+ const cli = String(workspacePath("mailwoman", "out", "cli", "index.js"))
826
827
  const card = await readWeightsCard(`neural-weights-${manifest.locale}`)
827
828
 
828
829
  await makeDirectories(destDir)
@@ -3,7 +3,7 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
- export * from "#address/point";
7
- export * from "#address/point-interpolation";
8
- export * from "#address/point-schema";
6
+ export * from "#address/point/index";
7
+ export * from "#address/point/interpolation";
8
+ export * from "#address/point/schema";
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/address/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/address/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA"}
@@ -3,7 +3,7 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
- export * from "#address/point";
7
- export * from "#address/point-interpolation";
8
- export * from "#address/point-schema";
6
+ export * from "#address/point/index";
7
+ export * from "#address/point/interpolation";
8
+ export * from "#address/point/schema";
9
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/address/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/address/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA"}
@@ -14,8 +14,8 @@
14
14
  * postcode, then locality, then the bbox fall-through (only when a bbox is supplied AND the prior
15
15
  * scopes missed). Multiple hits return the first by rowid — unit siblings share the building coord.
16
16
  */
17
- import type { AddressPointHit, AddressPointLookup } from "@mailwoman/resolver";
18
- import type { AddressPointDatabase } from "#address/point-schema";
17
+ import type { AddressPointHit, AddressPointLookup } from "@mailwoman/core/resolver";
18
+ import type { AddressPointDatabase } from "#address/point/schema";
19
19
  import { type StreetLocale } from "#street/normalize";
20
20
  export declare class AddressPointSqliteLookup<DB extends AddressPointDatabase = AddressPointDatabase> implements AddressPointLookup, Disposable {
21
21
  #private;
@@ -39,6 +39,8 @@ export declare class AddressPointSqliteLookup<DB extends AddressPointDatabase =
39
39
  number: string;
40
40
  postcode?: string;
41
41
  locality?: string;
42
+ region?: string;
43
+ subregion?: string;
42
44
  bbox?: {
43
45
  minLat: number;
44
46
  maxLat: number;
@@ -48,4 +50,4 @@ export declare class AddressPointSqliteLookup<DB extends AddressPointDatabase =
48
50
  }): AddressPointHit | null;
49
51
  [Symbol.dispose](): void;
50
52
  }
51
- //# sourceMappingURL=point.d.ts.map
53
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/address/point/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAGnF,OAAO,KAAK,EAAE,oBAAoB,EAAqB,MAAM,uBAAuB,CAAA;AAEpF,OAAO,EASN,KAAK,YAAY,EACjB,MAAM,mBAAmB,CAAA;AAc1B,qBAAa,wBAAwB,CAAC,EAAE,SAAS,oBAAoB,GAAG,oBAAoB,CAC3F,YAAW,kBAAkB,EAAE,UAAU;;IAwBzC;;;;;;;;;;OAUG;IACH,YAAY,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,YAAY,CAAC,EAAE,YAAY,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,CAAA;KAAO,EAsC5G;IAED,IAAI,CAAC,KAAK,EAAE;QACX,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,IAAI,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;KACzE,GAAG,eAAe,GAAG,IAAI,CAsCzB;IA4JD,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAEvB;CACD"}
@@ -16,7 +16,7 @@
16
16
  */
17
17
  import { DatabaseClient } from "@mailwoman/sqlite/client";
18
18
  import { hasTable, prepareGet } from "#sqlite-utils";
19
- import { normalizeLocalityForKey, streetKeyVariants, streetLocaleForSurface, stripArrondissement, } from "#street/normalize";
19
+ import { normalizeHouseNumberForKey, normalizeLocalityForKey, normalizeLocalityForKeyLocale, streetKeyVariants, streetLocaleForSurface, stripArrondissement, } from "#street/normalize";
20
20
  /**
21
21
  * The 4 columns the reader SELECTs, in the schema's order — referenced by the prepared SELECTs so the projected
22
22
  * `AddressPointRow` stays in lockstep with the shared schema.
@@ -29,6 +29,11 @@ export class AddressPointSqliteLookup {
29
29
  #byPostcode;
30
30
  #byPostcodeLocality;
31
31
  #byLocality;
32
+ /**
33
+ * The scope key matched by its TAIL — a `zh` query that names the 鄉鎮市區 without its 縣市. Narrowed by the (street,
34
+ * number) index first, so the LIKE walks the handful of rows that share the pair.
35
+ */
36
+ #byLocalityTail;
32
37
  #byBbox;
33
38
  /**
34
39
  * @param dbPath Extract path.
@@ -56,20 +61,31 @@ export class AddressPointSqliteLookup {
56
61
  WHERE locality_norm = ? AND street_norm = ? AND number = ? LIMIT 1`);
57
62
  this.#byBbox = prepareGet(this.#db, `SELECT ${SELECT_COLS} FROM address_point
58
63
  WHERE street_norm = ? AND number = ? AND lat BETWEEN ? AND ? AND lon BETWEEN ? AND ? LIMIT 1`);
64
+ this.#byLocalityTail = prepareGet(this.#db, `SELECT ${SELECT_COLS} FROM address_point
65
+ WHERE street_norm = ? AND number = ? AND locality_norm LIKE ? LIMIT 1`);
59
66
  }
60
67
  }
61
68
  find(query) {
62
69
  if (!this.#byPostcode || !this.#byLocality || !this.#byBbox)
63
70
  return null;
64
- const number = query.number.trim().toLowerCase();
71
+ const number = normalizeHouseNumberForKey(query.number, this.#locale);
65
72
  if (!number)
66
73
  return null;
74
+ // A `zh` extract scopes a point by 縣市 + 鄉鎮市區, the pair the parse tags `region` + `subregion`; the Taiwanese
75
+ // register carries no postcode and the parse no `locality`. The pair becomes the locality key here, on the
76
+ // reader that was built with the same fold, and a Latin extract never sees the two fields. A line that names
77
+ // only the 鄉鎮市區 (`中和區中興街281號`, 14.7% of the TW board) matches the stored pair by its tail instead.
78
+ const scoped = this.#locale === "zh" && !query.locality && query.subregion
79
+ ? query.region
80
+ ? { ...query, locality: `${query.region}${query.subregion}` }
81
+ : { ...query, localityTail: normalizeLocalityForKeyLocale(query.subregion, "zh") }
82
+ : query;
67
83
  // Key-variant ladder (see `streetKeyVariants`): the literal key first, then the doubled-type
68
84
  // collapse and the saint↔st register swap — each variant runs the FULL number ladder below, and
69
85
  // the first variant to answer wins, so an attested literal key is never second-guessed.
70
86
  let row;
71
87
  for (const streetNorm of streetKeyVariants(query.street, streetLocaleForSurface(query.street, this.#locale))) {
72
- row = this.#findForKey(streetNorm, number, query);
88
+ row = this.#findForKey(streetNorm, number, scoped);
73
89
  if (row)
74
90
  break;
75
91
  }
@@ -116,6 +132,17 @@ export class AddressPointSqliteLookup {
116
132
  row = this.#probe(streetNorm, `${spaced[1]} ${spaced[2]}`, query) ?? this.#probe(streetNorm, spaced[1], query);
117
133
  }
118
134
  }
135
+ // Sub-number fallback for the Taiwanese register: `14之12` is building 12 off number 14, `30附40` an attached
136
+ // number, stored as number `14` / `30` with the rest in `unit`. A query that kept the pair on the number span
137
+ // falls to the base number — the same adjacent-parcel approximation the letter-suffix rung makes, priced the
138
+ // same: on the 2,000-row served read the rows answered this way sit a median 256 m and at most 1.0 km from the
139
+ // building.
140
+ if (!row && this.#locale === "zh") {
141
+ const base = /^(\d+)(?:[之附]\d+)+$/u.exec(number)?.[1];
142
+ if (base) {
143
+ row = this.#probe(streetNorm, base, query);
144
+ }
145
+ }
119
146
  return row;
120
147
  }
121
148
  /**
@@ -142,6 +169,10 @@ export class AddressPointSqliteLookup {
142
169
  // "Paris" both hit. No-op for "us" extracts and every non-arrondissement commune.
143
170
  row = this.#byLocality(this.#localityKey(query.locality), streetNorm, number);
144
171
  }
172
+ if (!row && query.localityTail && this.#byLocalityTail) {
173
+ // A Han key carries no `%` or `_`, so the tail is a literal suffix pattern.
174
+ row = this.#byLocalityTail(streetNorm, number, `%${query.localityTail}`);
175
+ }
145
176
  // Bbox fall-through (#247): the point carries no postcode/locality of its own, but its coordinate falls
146
177
  // inside the resolved locality's box. Only reached when the scoped probes missed AND a bbox was supplied.
147
178
  if (!row && query.bbox) {
@@ -161,9 +192,9 @@ export class AddressPointSqliteLookup {
161
192
  * 13e Arrondissement" and "Paris" both hit; a no-op for every other locale.
162
193
  */
163
194
  #localityKey(locality) {
164
- return this.#locale === "fr"
165
- ? stripArrondissement(normalizeLocalityForKey(locality))
166
- : normalizeLocalityForKey(locality);
195
+ if (this.#locale === "fr")
196
+ return stripArrondissement(normalizeLocalityForKey(locality));
197
+ return normalizeLocalityForKeyLocale(locality, this.#locale);
167
198
  }
168
199
  /**
169
200
  * Whether a row's OWN postcode or locality names a different place than the query did. Absent scope on the row is not
@@ -188,4 +219,4 @@ export class AddressPointSqliteLookup {
188
219
  this.#db[Symbol.dispose]();
189
220
  }
190
221
  }
191
- //# sourceMappingURL=point.js.map
222
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/address/point/index.ts"],"names":[],"mappings":"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"}
@@ -32,9 +32,9 @@
32
32
  *
33
33
  * Standalone like the segment tier — core wiring rides the Phase 2 ordered `spatialTiers` list.
34
34
  */
35
- import type { InterpolationLookup } from "@mailwoman/resolver";
35
+ import type { InterpolationLookup } from "@mailwoman/core/resolver";
36
36
  import { DatabaseClient } from "@mailwoman/sqlite/client";
37
- import type { AddressPointDatabase } from "#address/point-schema";
37
+ import type { AddressPointDatabase } from "#address/point/schema";
38
38
  import type { InterpolatedHit, InterpolationQuery, StreetInterpolator } from "#interpolation";
39
39
  export declare class AddressPointInterpolator<DB extends AddressPointDatabase = AddressPointDatabase> implements InterpolationLookup {
40
40
  #private;
@@ -46,4 +46,4 @@ export declare class AddressPointInterpolator<DB extends AddressPointDatabase =
46
46
  find(query: InterpolationQuery): InterpolatedHit | null;
47
47
  [Symbol.dispose](): void;
48
48
  }
49
- //# sourceMappingURL=point-interpolation.d.ts.map
49
+ //# sourceMappingURL=interpolation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpolation.d.ts","sourceRoot":"","sources":["../../../lib/address/point/interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AA4B7F,qBAAa,wBAAwB,CACpC,EAAE,SAAS,oBAAoB,GAAG,oBAAoB,CACrD,YAAW,mBAAmB;;IAU/B,YAAY,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;QAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;KAAE,EAyBlG;IAED,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,GAAG,IAAI,CAuBtD;IAED,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAEvB;CACD"}
@@ -173,4 +173,4 @@ function interpolateFromNeighbors(rows, n) {
173
173
  release: near.release,
174
174
  };
175
175
  }
176
- //# sourceMappingURL=point-interpolation.js.map
176
+ //# sourceMappingURL=interpolation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpolation.js","sourceRoot":"","sources":["../../../lib/address/point/interpolation.ts"],"names":[],"mappings":"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"}
@@ -94,4 +94,4 @@ export declare function createAddressPointTable(db: AddressPointSchemaHandle): P
94
94
  * Create the three probe indexes the reader relies on (postcode-scope, locality-scope, route-key).
95
95
  */
96
96
  export declare function createAddressPointIndexes(db: AddressPointSchemaHandle): Promise<void>;
97
- //# sourceMappingURL=point-schema.d.ts.map
97
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../lib/address/point/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAErE;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC;;OAEG;IACH,WAAW,EAAE,SAAS,CAAA;IACtB;;;OAGG;IACH,UAAU,EAAE,QAAQ,CAAA;IACpB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB;;OAEG;IACH,aAAa,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB;;;OAGG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,aAAa,EAAE,iBAAiB,CAAA;CAChC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAE,QAAQ,CAAC,CAAA;AAEnF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,YACjC,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,UAAU,EACV,eAAe,EACf,YAAY,EACZ,KAAK,EACL,KAAK,EACL,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,CACF,CAAA;AAEV;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBzF;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAAC,EAAE,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB3F"}
@@ -77,4 +77,4 @@ export async function createAddressPointIndexes(db) {
77
77
  // bbox so it simply carries one extra (cheap) index on a future rebuild.
78
78
  await db.schema.createIndex("idx_ap_street").on("address_point").columns(["street_norm", "number"]).execute();
79
79
  }
80
- //# sourceMappingURL=point-schema.js.map
80
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../lib/address/point/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAyEH;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACpC,aAAa;IACb,YAAY;IACZ,QAAQ;IACR,MAAM;IACN,UAAU;IACV,eAAe;IACf,YAAY;IACZ,KAAK;IACL,KAAK;IACL,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,WAAW;CACF,CAAA;AAEV;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,EAA4B;IACzE,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,eAAe,CAAC;SAC5B,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACrD,wFAAwF;SACvF,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACnD,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;SACzB,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC;SAC7B,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC;SAClC,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACnD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC5C,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC5C,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/C,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAChD,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC;SAC/B,SAAS,CAAC,WAAW,EAAE,SAAS,CAAC;SACjC,OAAO,EAAE,CAAA;AACZ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,EAA4B;IAC3E,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,iBAAiB,CAAC;SAC9B,EAAE,CAAC,eAAe,CAAC;SACnB,OAAO,CAAC,CAAC,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;SAC9C,OAAO,EAAE,CAAA;IAEX,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,iBAAiB,CAAC;SAC9B,EAAE,CAAC,eAAe,CAAC;SACnB,OAAO,CAAC,CAAC,eAAe,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;SACnD,OAAO,EAAE,CAAA;IAEX,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;IACjH,oGAAoG;IACpG,uGAAuG;IACvG,wGAAwG;IACxG,yEAAyE;IACzE,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;AAC9G,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"backfill.d.ts","sourceRoot":"","sources":["../../lib/ancestry/backfill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,SAAS,CAAA;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAO1C,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA4B1F;AAYD;;;;;;;;;;;GAWG;AACH,wBAAsB,8BAA8B,CACnD,EAAE,EAAE,cAAc,CAAC,WAAW,CAAC,EAC/B,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3B,OAAO,CAAC,sBAAsB,CAAC,CAkHjC"}
1
+ {"version":3,"file":"backfill.d.ts","sourceRoot":"","sources":["../../lib/ancestry/backfill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,SAAS,CAAA;AAGjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAO1C,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA8B1F;AAYD;;;;;;;;;;;GAWG;AACH,wBAAsB,8BAA8B,CACnD,EAAE,EAAE,cAAc,CAAC,WAAW,CAAC,EAC/B,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3B,OAAO,CAAC,sBAAsB,CAAC,CAkHjC"}