@mailwoman/resolver-wof-sqlite 9.0.0 → 9.2.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 (297) hide show
  1. package/README.md +28 -9
  2. package/address-point-interpolation.ts +18 -8
  3. package/address-point-schema.ts +18 -6
  4. package/address-point.ts +111 -18
  5. package/ancestry.ts +9 -6
  6. package/build-candidate.ts +287 -157
  7. package/build-slim.ts +3 -3
  8. package/candidate/alias-bags.ts +54 -0
  9. package/candidate/ancestors-sidecar.ts +206 -0
  10. package/candidate/country-display-names.ts +79 -0
  11. package/candidate/name-roles.ts +237 -0
  12. package/candidate/own-name.ts +146 -0
  13. package/candidate/place-attrs.ts +44 -0
  14. package/candidate/shard-fold.ts +137 -0
  15. package/candidate-ancestors-schema.ts +195 -0
  16. package/candidate-fts.ts +4 -2
  17. package/candidate-importance.ts +228 -0
  18. package/candidate-lookup.ts +564 -174
  19. package/candidate-schema.ts +60 -3
  20. package/candidate-scoring.ts +268 -0
  21. package/capital-schema.ts +90 -0
  22. package/capitals.ts +148 -0
  23. package/coincident-roles.ts +69 -10
  24. package/convention-schema.ts +72 -0
  25. package/convention.ts +2 -2
  26. package/coverage-manifest-schema.ts +7 -7
  27. package/currency-backfill.ts +249 -0
  28. package/exact-match.ts +104 -0
  29. package/fst-autocomplete.ts +105 -122
  30. package/fst-builder.ts +39 -47
  31. package/fst-deserialize-web.ts +43 -7
  32. package/fst-freshness.ts +2 -2
  33. package/fst-serialize.ts +68 -12
  34. package/fst-types.ts +35 -1
  35. package/fts-query.ts +1 -1
  36. package/fts.ts +16 -4
  37. package/geonames-postal.ts +2 -2
  38. package/index.ts +26 -14
  39. package/interpolation.ts +113 -19
  40. package/lookup.ts +118 -560
  41. package/name-score.ts +6 -4
  42. package/out/address-point-interpolation.d.ts.map +1 -1
  43. package/out/address-point-interpolation.js +13 -7
  44. package/out/address-point-interpolation.js.map +1 -1
  45. package/out/address-point-schema.d.ts +16 -6
  46. package/out/address-point-schema.d.ts.map +1 -1
  47. package/out/address-point-schema.js.map +1 -1
  48. package/out/address-point.d.ts.map +1 -1
  49. package/out/address-point.js +70 -14
  50. package/out/address-point.js.map +1 -1
  51. package/out/ancestry.d.ts +2 -2
  52. package/out/ancestry.d.ts.map +1 -1
  53. package/out/ancestry.js +5 -6
  54. package/out/ancestry.js.map +1 -1
  55. package/out/build-candidate.d.ts +108 -0
  56. package/out/build-candidate.d.ts.map +1 -1
  57. package/out/build-candidate.js +151 -120
  58. package/out/build-candidate.js.map +1 -1
  59. package/out/build-slim.d.ts +1 -1
  60. package/out/build-slim.js +3 -3
  61. package/out/build-slim.js.map +1 -1
  62. package/out/candidate/alias-bags.d.ts +17 -0
  63. package/out/candidate/alias-bags.d.ts.map +1 -0
  64. package/out/candidate/alias-bags.js +39 -0
  65. package/out/candidate/alias-bags.js.map +1 -0
  66. package/out/candidate/ancestors-sidecar.d.ts +33 -0
  67. package/out/candidate/ancestors-sidecar.d.ts.map +1 -0
  68. package/out/candidate/ancestors-sidecar.js +140 -0
  69. package/out/candidate/ancestors-sidecar.js.map +1 -0
  70. package/out/candidate/country-display-names.d.ts +35 -0
  71. package/out/candidate/country-display-names.d.ts.map +1 -0
  72. package/out/candidate/country-display-names.js +59 -0
  73. package/out/candidate/country-display-names.js.map +1 -0
  74. package/out/candidate/name-roles.d.ts +55 -0
  75. package/out/candidate/name-roles.d.ts.map +1 -0
  76. package/out/candidate/name-roles.js +165 -0
  77. package/out/candidate/name-roles.js.map +1 -0
  78. package/out/candidate/own-name.d.ts +50 -0
  79. package/out/candidate/own-name.d.ts.map +1 -0
  80. package/out/candidate/own-name.js +132 -0
  81. package/out/candidate/own-name.js.map +1 -0
  82. package/out/candidate/place-attrs.d.ts +43 -0
  83. package/out/candidate/place-attrs.d.ts.map +1 -0
  84. package/out/candidate/place-attrs.js +15 -0
  85. package/out/candidate/place-attrs.js.map +1 -0
  86. package/out/candidate/shard-fold.d.ts +31 -0
  87. package/out/candidate/shard-fold.d.ts.map +1 -0
  88. package/out/candidate/shard-fold.js +104 -0
  89. package/out/candidate/shard-fold.js.map +1 -0
  90. package/out/candidate-ancestors-schema.d.ts +150 -0
  91. package/out/candidate-ancestors-schema.d.ts.map +1 -0
  92. package/out/candidate-ancestors-schema.js +123 -0
  93. package/out/candidate-ancestors-schema.js.map +1 -0
  94. package/out/candidate-fts.d.ts +4 -2
  95. package/out/candidate-fts.d.ts.map +1 -1
  96. package/out/candidate-fts.js +4 -2
  97. package/out/candidate-fts.js.map +1 -1
  98. package/out/candidate-importance.d.ts +132 -0
  99. package/out/candidate-importance.d.ts.map +1 -0
  100. package/out/candidate-importance.js +174 -0
  101. package/out/candidate-importance.js.map +1 -0
  102. package/out/candidate-lookup.d.ts +22 -37
  103. package/out/candidate-lookup.d.ts.map +1 -1
  104. package/out/candidate-lookup.js +446 -132
  105. package/out/candidate-lookup.js.map +1 -1
  106. package/out/candidate-schema.d.ts +52 -4
  107. package/out/candidate-schema.d.ts.map +1 -1
  108. package/out/candidate-schema.js +8 -0
  109. package/out/candidate-schema.js.map +1 -1
  110. package/out/candidate-scoring.d.ts +34 -0
  111. package/out/candidate-scoring.d.ts.map +1 -0
  112. package/out/candidate-scoring.js +200 -0
  113. package/out/candidate-scoring.js.map +1 -0
  114. package/out/capital-schema.d.ts +51 -0
  115. package/out/capital-schema.d.ts.map +1 -0
  116. package/out/capital-schema.js +63 -0
  117. package/out/capital-schema.js.map +1 -0
  118. package/out/capitals.d.ts +69 -0
  119. package/out/capitals.d.ts.map +1 -0
  120. package/out/capitals.js +98 -0
  121. package/out/capitals.js.map +1 -0
  122. package/out/coincident-roles.d.ts +7 -0
  123. package/out/coincident-roles.d.ts.map +1 -1
  124. package/out/coincident-roles.js +42 -8
  125. package/out/coincident-roles.js.map +1 -1
  126. package/out/convention-schema.d.ts +51 -0
  127. package/out/convention-schema.d.ts.map +1 -0
  128. package/out/convention-schema.js +34 -0
  129. package/out/convention-schema.js.map +1 -0
  130. package/out/convention.d.ts +1 -1
  131. package/out/convention.js +2 -2
  132. package/out/coverage-manifest-schema.js +3 -7
  133. package/out/coverage-manifest-schema.js.map +1 -1
  134. package/out/currency-backfill.d.ts +46 -0
  135. package/out/currency-backfill.d.ts.map +1 -0
  136. package/out/currency-backfill.js +180 -0
  137. package/out/currency-backfill.js.map +1 -0
  138. package/out/exact-match.d.ts +25 -0
  139. package/out/exact-match.d.ts.map +1 -0
  140. package/out/exact-match.js +89 -0
  141. package/out/exact-match.js.map +1 -0
  142. package/out/fst-autocomplete.d.ts +24 -14
  143. package/out/fst-autocomplete.d.ts.map +1 -1
  144. package/out/fst-autocomplete.js +84 -100
  145. package/out/fst-autocomplete.js.map +1 -1
  146. package/out/fst-builder.d.ts.map +1 -1
  147. package/out/fst-builder.js +32 -40
  148. package/out/fst-builder.js.map +1 -1
  149. package/out/fst-deserialize-web.d.ts.map +1 -1
  150. package/out/fst-deserialize-web.js +36 -7
  151. package/out/fst-deserialize-web.js.map +1 -1
  152. package/out/fst-freshness.d.ts +2 -2
  153. package/out/fst-freshness.js +2 -2
  154. package/out/fst-serialize.d.ts +14 -4
  155. package/out/fst-serialize.d.ts.map +1 -1
  156. package/out/fst-serialize.js +60 -12
  157. package/out/fst-serialize.js.map +1 -1
  158. package/out/fst-types.d.ts +35 -1
  159. package/out/fst-types.d.ts.map +1 -1
  160. package/out/fts-query.js +1 -1
  161. package/out/fts-query.js.map +1 -1
  162. package/out/fts.d.ts +15 -4
  163. package/out/fts.d.ts.map +1 -1
  164. package/out/fts.js +15 -4
  165. package/out/fts.js.map +1 -1
  166. package/out/geonames-postal.d.ts +2 -2
  167. package/out/geonames-postal.js +2 -2
  168. package/out/index.d.ts +4 -2
  169. package/out/index.d.ts.map +1 -1
  170. package/out/index.js +3 -2
  171. package/out/index.js.map +1 -1
  172. package/out/interpolation.d.ts +8 -0
  173. package/out/interpolation.d.ts.map +1 -1
  174. package/out/interpolation.js +91 -19
  175. package/out/interpolation.js.map +1 -1
  176. package/out/lookup.d.ts +4 -5
  177. package/out/lookup.d.ts.map +1 -1
  178. package/out/lookup.js +102 -444
  179. package/out/lookup.js.map +1 -1
  180. package/out/name-score.d.ts +0 -10
  181. package/out/name-score.d.ts.map +1 -1
  182. package/out/name-score.js +6 -4
  183. package/out/name-score.js.map +1 -1
  184. package/out/place-importance-schema.d.ts +226 -0
  185. package/out/place-importance-schema.d.ts.map +1 -0
  186. package/out/place-importance-schema.js +288 -0
  187. package/out/place-importance-schema.js.map +1 -0
  188. package/out/poi-lookup.d.ts +1 -1
  189. package/out/poi-lookup.d.ts.map +1 -1
  190. package/out/poi-lookup.js +12 -13
  191. package/out/poi-lookup.js.map +1 -1
  192. package/out/poi-schema.d.ts +7 -3
  193. package/out/poi-schema.d.ts.map +1 -1
  194. package/out/poi-schema.js.map +1 -1
  195. package/out/polygon-schema.d.ts +37 -0
  196. package/out/polygon-schema.d.ts.map +1 -0
  197. package/out/polygon-schema.js +23 -0
  198. package/out/polygon-schema.js.map +1 -0
  199. package/out/postal-city-alias-lookup.d.ts +1 -1
  200. package/out/postal-city-alias-lookup.js +1 -1
  201. package/out/postal-city-candidate-schema.d.ts +2 -1
  202. package/out/postal-city-candidate-schema.d.ts.map +1 -1
  203. package/out/postal-city-candidate-schema.js.map +1 -1
  204. package/out/postcode-point-lookup.d.ts +1 -1
  205. package/out/postcode-point-lookup.js +1 -1
  206. package/out/primary-preference.d.ts +125 -0
  207. package/out/primary-preference.d.ts.map +1 -0
  208. package/out/primary-preference.js +138 -0
  209. package/out/primary-preference.js.map +1 -0
  210. package/out/proximity-rerank.d.ts +77 -0
  211. package/out/proximity-rerank.d.ts.map +1 -0
  212. package/out/proximity-rerank.js +86 -0
  213. package/out/proximity-rerank.js.map +1 -0
  214. package/out/region-keys.d.ts +47 -0
  215. package/out/region-keys.d.ts.map +1 -0
  216. package/out/region-keys.js +121 -0
  217. package/out/region-keys.js.map +1 -0
  218. package/out/reverse.d.ts.map +1 -1
  219. package/out/reverse.js +6 -9
  220. package/out/reverse.js.map +1 -1
  221. package/out/schema.d.ts +1 -1
  222. package/out/search-fetch.d.ts +57 -0
  223. package/out/search-fetch.d.ts.map +1 -0
  224. package/out/search-fetch.js +183 -0
  225. package/out/search-fetch.js.map +1 -0
  226. package/out/sharding.d.ts +3 -3
  227. package/out/sharding.js +1 -1
  228. package/out/sqlite-convention-source.d.ts +1 -1
  229. package/out/sqlite-convention-source.js +1 -1
  230. package/out/sqlite-utils.d.ts +31 -1
  231. package/out/sqlite-utils.d.ts.map +1 -1
  232. package/out/sqlite-utils.js +38 -0
  233. package/out/sqlite-utils.js.map +1 -1
  234. package/out/street-centroid-schema.d.ts +7 -2
  235. package/out/street-centroid-schema.d.ts.map +1 -1
  236. package/out/street-centroid-schema.js.map +1 -1
  237. package/out/street-centroid.d.ts.map +1 -1
  238. package/out/street-centroid.js +7 -7
  239. package/out/street-centroid.js.map +1 -1
  240. package/out/street-morphology-fst-builder.d.ts.map +1 -1
  241. package/out/street-morphology-fst-builder.js +5 -4
  242. package/out/street-morphology-fst-builder.js.map +1 -1
  243. package/out/street-normalize.d.ts +83 -9
  244. package/out/street-normalize.d.ts.map +1 -1
  245. package/out/street-normalize.js +177 -10
  246. package/out/street-normalize.js.map +1 -1
  247. package/out/street-segment-schema.d.ts +6 -2
  248. package/out/street-segment-schema.d.ts.map +1 -1
  249. package/out/street-segment-schema.js.map +1 -1
  250. package/out/types.d.ts +74 -1
  251. package/out/types.d.ts.map +1 -1
  252. package/out/unified-schema.d.ts +1 -1
  253. package/out/unified-schema.js +1 -1
  254. package/out/uprn-lookup.d.ts +85 -0
  255. package/out/uprn-lookup.d.ts.map +1 -0
  256. package/out/uprn-lookup.js +152 -0
  257. package/out/uprn-lookup.js.map +1 -0
  258. package/out/uprn-schema.d.ts +93 -0
  259. package/out/uprn-schema.d.ts.map +1 -0
  260. package/out/uprn-schema.js +78 -0
  261. package/out/uprn-schema.js.map +1 -0
  262. package/out/weights-overlay-linker.d.ts +141 -0
  263. package/out/weights-overlay-linker.d.ts.map +1 -0
  264. package/out/weights-overlay-linker.js +259 -0
  265. package/out/weights-overlay-linker.js.map +1 -0
  266. package/package.json +296 -16
  267. package/place-importance-schema.ts +402 -0
  268. package/poi-lookup.ts +12 -13
  269. package/poi-schema.ts +8 -3
  270. package/polygon-schema.ts +47 -0
  271. package/postal-city-alias-lookup.ts +1 -1
  272. package/postal-city-candidate-schema.ts +3 -1
  273. package/postcode-point-lookup.ts +1 -1
  274. package/primary-preference.ts +207 -0
  275. package/proximity-rerank.ts +120 -0
  276. package/region-keys.ts +144 -0
  277. package/reverse.ts +17 -16
  278. package/schema.ts +1 -1
  279. package/search-fetch.ts +256 -0
  280. package/sharding.ts +3 -3
  281. package/sqlite-convention-source.ts +1 -1
  282. package/sqlite-utils.ts +63 -1
  283. package/street-centroid-schema.ts +8 -2
  284. package/street-centroid.ts +13 -8
  285. package/street-morphology-fst-builder.ts +5 -4
  286. package/street-normalize.ts +254 -24
  287. package/street-segment-schema.ts +7 -2
  288. package/types.ts +74 -1
  289. package/unified-schema.ts +1 -1
  290. package/uprn-lookup.ts +210 -0
  291. package/uprn-schema.ts +124 -0
  292. package/weights-overlay-linker.ts +377 -0
  293. package/geo.ts +0 -121
  294. package/out/geo.d.ts +0 -74
  295. package/out/geo.d.ts.map +0 -1
  296. package/out/geo.js +0 -71
  297. package/out/geo.js.map +0 -1
@@ -5,6 +5,24 @@
5
5
  *
6
6
  * Small shared helpers for the SQLite-backed lookups.
7
7
  */
8
+ import { allRows, getRow } from "@mailwoman/core/utils";
9
+ // The row-shape assertion itself lives in `core` so the readers that cannot depend on this package reach the same
10
+ // seam; re-exported here because this module is where this package's readers already look for it.
11
+ export { allRows, getRow } from "@mailwoman/core/utils";
12
+ /**
13
+ * Prepare a single-row query while preserving its exact parameter tuple at every call site.
14
+ */
15
+ export function prepareGet(db, sql) {
16
+ const statement = db.prepare(sql);
17
+ return (...parameters) => getRow(statement, ...parameters);
18
+ }
19
+ /**
20
+ * Prepare a multi-row query while preserving its exact parameter tuple at every call site.
21
+ */
22
+ export function prepareAll(db, sql) {
23
+ const statement = db.prepare(sql);
24
+ return (...parameters) => allRows(statement, ...parameters);
25
+ }
8
26
  /**
9
27
  * True when `name` is a table in the open database. The street-level lookups use this to degrade gracefully on an
10
28
  * empty/tableless shard — an interrupted `build-*-shard.ts`, or a stray 0-byte file (e.g. `sqlite3 <missing>.db "…"`
@@ -20,4 +38,24 @@ export function hasTable(db, name) {
20
38
  return false;
21
39
  }
22
40
  }
41
+ /**
42
+ * True when `table` exists in the open database AND carries `column`.
43
+ *
44
+ * The column-level sibling of {@link hasTable}, and it exists for the same reason one layer down: an artifact built
45
+ * before a column was added is still a VALID artifact, and a reader that unconditionally names the new column in its
46
+ * `SELECT` turns "this gazetteer is a build behind" into `no such column` at the first keystroke. Probe once at
47
+ * construction and shape the query — `table_info` is a PRAGMA, so it must not sit on a per-query path.
48
+ *
49
+ * Note the interpolation: PRAGMA does not take bound parameters, so `table` is spliced. Every caller passes a
50
+ * module-level constant; never pass user input.
51
+ */
52
+ export function hasColumn(db, table, column) {
53
+ try {
54
+ const rows = allRows(db.prepare(`PRAGMA table_info(${table})`));
55
+ return rows.some((r) => String(r.name) === column);
56
+ }
57
+ catch {
58
+ return false;
59
+ }
60
+ }
23
61
  //# sourceMappingURL=sqlite-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-utils.js","sourceRoot":"","sources":["../sqlite-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAgB,EAAE,IAAY;IACtD,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,uEAAuE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAEzG,OAAO,GAAG,KAAK,SAAS,CAAA;IACzB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAA;IACb,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"sqlite-utils.js","sourceRoot":"","sources":["../sqlite-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAEvD,kHAAkH;AAClH,kGAAkG;AAClG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAQvD;;GAEG;AACH,MAAM,UAAU,UAAU,CACzB,EAAgB,EAChB,GAAW;IAEX,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAEjC,OAAO,CAAC,GAAG,UAAU,EAAE,EAAE,CAAC,MAAM,CAAM,SAAS,EAAE,GAAG,UAAU,CAAC,CAAA;AAChE,CAAC;AAOD;;GAEG;AACH,MAAM,UAAU,UAAU,CACzB,EAAgB,EAChB,GAAW;IAEX,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAEjC,OAAO,CAAC,GAAG,UAAU,EAAE,EAAE,CAAC,OAAO,CAAM,SAAS,EAAE,GAAG,UAAU,CAAC,CAAA;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAgB,EAAE,IAAY;IACtD,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,uEAAuE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAEzG,OAAO,GAAG,KAAK,SAAS,CAAA;IACzB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAA;IACb,CAAC;AACF,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,SAAS,CAAC,EAAgB,EAAE,KAAa,EAAE,MAAc;IACxE,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,OAAO,CAAmB,EAAE,CAAC,OAAO,CAAC,qBAAqB,KAAK,GAAG,CAAC,CAAC,CAAA;QAEjF,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,CAAA;IACnD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAA;IACb,CAAC;AACF,CAAC"}
@@ -20,6 +20,7 @@
20
20
  * every postcode/arrondissement it spans.
21
21
  */
22
22
  import type { Kysely } from "kysely";
23
+ import type { NameKey, StreetKey } from "./street-normalize.ts";
23
24
  /**
24
25
  * One street roll-up. `(street_norm, postcode, locality_base)` is unique. `lat`/`lon` are the UNWEIGHTED mean of the
25
26
  * group's member address points (each source row = one point), so a cross-group weighted mean (`SUM(lat*point_count) /
@@ -30,7 +31,7 @@ export interface StreetCentroidTable {
30
31
  /**
31
32
  * Shared `normalizeStreetForKeyLocale` of the street — the build/query-consistent probe key.
32
33
  */
33
- street_norm: string;
34
+ street_norm: StreetKey;
34
35
  /**
35
36
  * The 5-digit postcode of this group, or null when the source row carried none.
36
37
  */
@@ -38,7 +39,7 @@ export interface StreetCentroidTable {
38
39
  /**
39
40
  * Arrondissement-stripped commune (`stripArrondissement(normalizeLocalityForKey(commune))`) — the fallback scope.
40
41
  */
41
- locality_base: string;
42
+ locality_base: NameKey;
42
43
  /**
43
44
  * Weighted-mean centroid latitude of the street's member points.
44
45
  */
@@ -73,6 +74,10 @@ export interface StreetCentroidTable {
73
74
  * name-evidence rerank folds the model's street surface with the SAME `foldStreetSurface` used to build this column
74
75
  * (the fold-parity contract), so it must not drift from `street_norm`'s richer normalizer. Indexed (`idx_sc_name`)
75
76
  * for a direct seek.
77
+ *
78
+ * Deliberately UNBRANDED despite the `name_key` column name: `foldStreetSurface` is a different fold from the
79
+ * {@link NameKey} one every other `name_key` column carries, and giving it that brand would invite exactly the
80
+ * cross-fold probe the brands exist to stop.
76
81
  */
77
82
  name_key: string;
78
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"street-centroid-schema.d.ts","sourceRoot":"","sources":["../street-centroid-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IACnC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IACX;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACtC,eAAe,EAAE,mBAAmB,CAAA;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,+KAe1B,CAAA;AAEV;;GAEG;AACH,wBAAsB,yBAAyB,CAAC,EAAE,EAAE,MAAM,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBjG;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,EAAE,EAAE,MAAM,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAUnG"}
1
+ {"version":3,"file":"street-centroid-schema.d.ts","sourceRoot":"","sources":["../street-centroid-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IACnC;;OAEG;IACH,WAAW,EAAE,SAAS,CAAA;IACtB;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB;;OAEG;IACH,aAAa,EAAE,OAAO,CAAA;IACtB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IACX;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;;;;OAUG;IACH,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACtC,eAAe,EAAE,mBAAmB,CAAA;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,+KAe1B,CAAA;AAEV;;GAEG;AACH,wBAAsB,yBAAyB,CAAC,EAAE,EAAE,MAAM,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBjG;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,EAAE,EAAE,MAAM,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAUnG"}
@@ -1 +1 @@
1
- {"version":3,"file":"street-centroid-schema.js","sourceRoot":"","sources":["../street-centroid-schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"street-centroid-schema.js","sourceRoot":"","sources":["../street-centroid-schema.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"street-centroid.d.ts","sourceRoot":"","sources":["../street-centroid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAGlF,OAAO,EAGN,KAAK,YAAY,EAEjB,MAAM,uBAAuB,CAAA;AAwC9B,qBAAa,0BAA2B,YAAW,oBAAoB;;IAMtE;;;;OAIG;gBACS,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,YAAY,CAAC,EAAE,YAAY,CAAA;KAAO;IAiBtE,IAAI,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,iBAAiB,GAAG,IAAI;IA4B/F,KAAK,IAAI,IAAI;CAGb"}
1
+ {"version":3,"file":"street-centroid.d.ts","sourceRoot":"","sources":["../street-centroid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAGlF,OAAO,EAMN,KAAK,YAAY,EAEjB,MAAM,uBAAuB,CAAA;AAwC9B,qBAAa,0BAA2B,YAAW,oBAAoB;;IAMtE;;;;OAIG;gBACS,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,YAAY,CAAC,EAAE,YAAY,CAAA;KAAO;IAmBtE,IAAI,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,iBAAiB,GAAG,IAAI;IA4B/F,KAAK,IAAI,IAAI;CAGb"}
@@ -19,8 +19,8 @@
19
19
  * exact-after-normalization only (no fuzzy street matching in this tier).
20
20
  */
21
21
  import { DatabaseSync } from "node:sqlite";
22
- import { hasTable } from "./sqlite-utils.js";
23
- import { normalizeLocalityForKey, normalizeStreetForKeyLocale, stripArrondissement, } from "./street-normalize.js";
22
+ import { hasTable, prepareGet } from "./sqlite-utils.js";
23
+ import { normalizeLocalityForKey, normalizeStreetForKeyLocale, streetLocaleForSurface, stripArrondissement, } from "./street-normalize.js";
24
24
  /**
25
25
  * Weighted-centroid aggregate over a WHERE-filtered set. `SUM(coord*n)/SUM(n)` reconstructs the grand centroid.
26
26
  */
@@ -57,23 +57,23 @@ export class StreetCentroidSqliteLookup {
57
57
  // Degrade gracefully on an empty/tableless shard (interrupted build, stray 0-byte file): with no
58
58
  // `street_centroid` table this lookup is a no-op miss, not a crash (mirrors the address-point reader).
59
59
  if (hasTable(this.#db, "street_centroid")) {
60
- this.#byPostcode = this.#db.prepare(`SELECT ${AGG_SELECT} FROM street_centroid WHERE postcode = ? AND street_norm = ?`);
61
- this.#byLocality = this.#db.prepare(`SELECT ${AGG_SELECT} FROM street_centroid WHERE locality_base = ? AND street_norm = ?`);
60
+ this.#byPostcode = prepareGet(this.#db, `SELECT ${AGG_SELECT} FROM street_centroid WHERE postcode = ? AND street_norm = ?`);
61
+ this.#byLocality = prepareGet(this.#db, `SELECT ${AGG_SELECT} FROM street_centroid WHERE locality_base = ? AND street_norm = ?`);
62
62
  }
63
63
  }
64
64
  find(query) {
65
65
  if (!this.#byPostcode || !this.#byLocality)
66
66
  return null;
67
- const streetNorm = normalizeStreetForKeyLocale(query.street, this.#locale);
67
+ const streetNorm = normalizeStreetForKeyLocale(query.street, streetLocaleForSurface(query.street, this.#locale));
68
68
  if (!streetNorm)
69
69
  return null;
70
70
  let row;
71
71
  if (query.postcode?.trim()) {
72
- row = this.#byPostcode.get(query.postcode.trim(), streetNorm);
72
+ row = this.#byPostcode(query.postcode.trim(), streetNorm);
73
73
  }
74
74
  if ((!row || row.lat == null) && query.locality?.trim()) {
75
75
  const base = stripArrondissement(normalizeLocalityForKey(query.locality));
76
- row = this.#byLocality.get(base, streetNorm);
76
+ row = this.#byLocality(base, streetNorm);
77
77
  }
78
78
  if (!row || row.lat == null || row.lon == null)
79
79
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"street-centroid.js","sourceRoot":"","sources":["../street-centroid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"street-centroid.js","sourceRoot":"","sources":["../street-centroid.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"street-morphology-fst-builder.d.ts","sourceRoot":"","sources":["../street-morphology-fst-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAQH,OAAO,EAAE,UAAU,EAAmB,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,gBAAgB,CAAA;AAW/D,MAAM,WAAW,4BAA4B;IAC5C;;OAEG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CACrD;AAED,MAAM,WAAW,8BAA8B;IAC9C,OAAO,EAAE,UAAU,CAAA;IACnB,UAAU,EAAE,aAAa,CAAA;IACzB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,EAAE,CAAA;CACjB;AAuBD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,4BAA4B,GAAG,8BAA8B,CAqJ3G"}
1
+ {"version":3,"file":"street-morphology-fst-builder.d.ts","sourceRoot":"","sources":["../street-morphology-fst-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAQH,OAAO,EAAE,UAAU,EAAmB,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,gBAAgB,CAAA;AAW/D,MAAM,WAAW,4BAA4B;IAC5C;;OAEG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CACrD;AAED,MAAM,WAAW,8BAA8B;IAC9C,OAAO,EAAE,UAAU,CAAA;IACnB,UAAU,EAAE,aAAa,CAAA;IACzB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,EAAE,CAAA;CACjB;AAuBD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,4BAA4B,GAAG,8BAA8B,CAsJ3G"}
@@ -131,10 +131,11 @@ export function buildStreetMorphologyFST(opts) {
131
131
  placetype: "street_affix",
132
132
  name: canonical,
133
133
  parentChain: [],
134
- // Fixed importance: street affixes are structurally unambiguous (Avenue is almost never
135
- // anything but street-typing). The morphology prior caps bias separately; this value
136
- // just feeds the cap formula `importance * cap`.
137
- importance: 1,
134
+ // Fixed referential score: street affixes are structurally unambiguous (Avenue is almost
135
+ // never anything but street-typing). The morphology prior caps bias separately; this value
136
+ // just feeds the cap formula `referential * cap`. No encyclopedic field — a street affix is
137
+ // not a place and has no article; absence here is the correct statement.
138
+ referential: 1,
138
139
  lat: 0,
139
140
  lon: 0,
140
141
  };
@@ -1 +1 @@
1
- {"version":3,"file":"street-morphology-fst-builder.js","sourceRoot":"","sources":["../street-morphology-fst-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"street-morphology-fst-builder.js","sourceRoot":"","sources":["../street-morphology-fst-builder.ts"],"names":[],"mappings":"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"}
@@ -21,11 +21,39 @@
21
21
  * folds to its digit form (`tenth street` → `10th street`, #723) so the grid-city ordinal
22
22
  * cross-streets the source data spells with digits become reachable.
23
23
  */
24
+ import type { Tagged } from "type-fest";
25
+ /**
26
+ * A place name folded by {@link normalizeLocalityForKey} — the value stored in, and required to probe, every
27
+ * `name_key`-style column: the candidate gazetteer, the postal-city side-index, the street-centroid shard, an ancestor
28
+ * chain's `parent_name_key`, and the address-point locality scope.
29
+ *
30
+ * The brand is here because the fold is applied at BUILD time and is therefore mandatory at QUERY time, while a
31
+ * near-miss approximation of it (`toLowerCase()`, `trim()`) is still a `string`: it binds to the parameter, returns
32
+ * fewer rows, and the shortfall reads as a coverage gap in the data rather than a defect in the probe. Requiring the
33
+ * brand at the seam turns that silent under-match into a compile error. Mint one only by calling the fold.
34
+ */
35
+ export type NameKey = Tagged<string, "NameKey">;
36
+ /**
37
+ * A street name folded by {@link normalizeStreetForKey} / {@link normalizeStreetForKeyLocale} — the value stored in a
38
+ * `street_norm` address-point column and required to probe it.
39
+ *
40
+ * Distinct from {@link RouteKey}: the route fold is a FURTHER canonicalization applied to some columns and not others,
41
+ * so the two are not interchangeable even though both are folded streets.
42
+ */
43
+ export type StreetKey = Tagged<string, "StreetKey">;
44
+ /**
45
+ * A street key that has additionally passed {@link canonicalizeRouteKey} — the numbered-route canonical form.
46
+ *
47
+ * A separate brand from {@link StreetKey} because it identifies a DIFFERENT set of columns, and the two folds disagree
48
+ * exactly on the rows that motivate the route fold: binding a plain street key to a route-folded column silently misses
49
+ * every row whose source spelled the route differently, which is the miss class the fold exists to close.
50
+ */
51
+ export type RouteKey = Tagged<string, "RouteKey">;
24
52
  /**
25
53
  * Normalize a street name for address-point keying. Same function at build time and lookup time — see module docstring
26
54
  * for the contract.
27
55
  */
28
- export declare function normalizeStreetForKey(street: string): string;
56
+ export declare function normalizeStreetForKey(street: string): StreetKey;
29
57
  /**
30
58
  * Street-name locale for the address-point key. The US path is the full USPS pipeline ({@link normalizeStreetForKey});
31
59
  * the international paths fold + apply a SMALL, consistent per-locale type-token canonicalization. Same discipline as
@@ -34,32 +62,60 @@ export declare function normalizeStreetForKey(street: string): string;
34
62
  * article, so no salient-token / multi-key index is built yet (deferred until probing shows the normalizer can't absorb
35
63
  * the false-negatives).
36
64
  */
37
- export type StreetLocale = "us" | "fr" | "de" | "nl";
65
+ export type StreetLocale = "us" | "en" | "fr" | "de" | "nl" | "pl" | "vn" | "id";
38
66
  /**
39
67
  * Normalize a street name for the address-point key in a non-US locale. Same function build-side and probe-side (the
40
68
  * one-function discipline). US delegates to {@link normalizeStreetForKey}.
41
69
  *
70
+ * - **en** — the shared English address-key pipeline (directionals + suffix aliases), currently identical to US.
42
71
  * - **fr** — fold + expand leading type abbreviations and Saint/Sainte (token map).
43
72
  * - **de** — fold + ß→ss + canonicalize the GLUED `-str(.)` suffix to `-strasse` ("Lindenstr." → "lindenstrasse",
44
73
  * "Lindenstraße" → "lindenstrasse"); an already-full "-strasse" is left intact.
45
74
  * - **nl** — fold + canonicalize the glued `-str` suffix to `-straat` ("Kerkstr." → "kerkstraat").
75
+ * - **pl** — fold + ł→l (Ł does not NFKD-decompose, so the generic fold keeps it and an undiacritized query would miss;
76
+ * every other Polish diacritic is a combining form the fold already strips) + STRIP the leading type token — see
77
+ * {@link PL_LEADING_TYPE} for the measured reason expansion was wrong for this source.
78
+ * - **vn** — fold + đ→d AND ð→d (both non-decomposing, and OSM mixes the two codepoints inside single values — see the
79
+ * branch comment). Deliberately NO type-abbreviation map yet: the common abbreviation is the single letter "Đ." for
80
+ * Đường, and expanding a bare folded "d" token would rewrite initials — measure the miss rate on the built shard
81
+ * before adding anything.
82
+ * - **id** — fold + expand leading type abbreviations (jl/jln→jalan, gg→gang); Indonesian street surfaces are otherwise
83
+ * ASCII-clean.
46
84
  */
47
- export declare function normalizeStreetForKeyLocale(street: string, locale: StreetLocale): string;
85
+ export declare function normalizeStreetForKeyLocale(street: string, locale: StreetLocale): StreetKey;
48
86
  /**
49
87
  * Normalize a locality name for address-point keying (fold only — no street semantics).
50
88
  */
51
- export declare function normalizeLocalityForKey(locality: string): string;
89
+ export declare function normalizeLocalityForKey(locality: string): NameKey;
90
+ /**
91
+ * Surface-driven street-locale ROUTER for bilingual shards — the Québec finishing move on the CA rooftop shard.
92
+ *
93
+ * A country registers ONE street locale, but Canada's street surfaces are two languages: under the `en` rules a French
94
+ * surface passes through mostly unchanged (both sides fold identically, so those rows stay reachable), and what breaks
95
+ * is abbreviation variance — the `en` rules cannot fold "boul"/"Ste-" to the full French word, so an abbreviated query
96
+ * misses a full-word row and vice versa. Routing on the SURFACE (not the province) also carries bilingual NB and the
97
+ * French street names outside Québec for free.
98
+ *
99
+ * ONE function, called by the shard BUILDER and the query PROBE alike — the #861 discipline: routing is part of the
100
+ * fold contract, and two transcriptions of this predicate would diverge exactly where it matters. Only an `en` base
101
+ * re-routes: a `fr`/`de`/`nl` shard already speaks its own rules, and the US pipeline stays untouched.
102
+ *
103
+ * Measured basis (CA shard, 2026-08-19): 183,963 distinct surfaces, 43,762 French-lead; 29,682 fold differently under
104
+ * fr-vs-en (888,265 rows), and the non-French half of those are English surfaces this router keeps on `en` unchanged.
105
+ */
106
+ export declare function streetLocaleForSurface(street: string, base: StreetLocale): StreetLocale;
52
107
  /**
53
108
  * Strip a trailing French arrondissement designator from a FOLDED commune key ("paris 8e arrondissement" → "paris",
54
109
  * "lyon 1er arrondissement" → "lyon", "marseille 10e arrondissement" → "marseille"). Paris, Lyon and Marseille are the
55
110
  * only French communes subdivided into _arrondissements municipaux_; a national register (BAN) names each row per
56
111
  * arrondissement, but a query names the base commune ("Place Bellecour, Lyon", never "…, Lyon 2e"). Applied on BOTH
57
112
  * sides of the #1042 street-centroid key — build-side (deriving the `locality_base` column) and query-side (folding the
58
- * probe commune) — so the two agree by construction (the one-function discipline). Input must already be folded
59
- * (lower-case, diacritic-stripped); a no-op for every other commune. Returns the input unchanged if the strip would
60
- * empty it.
113
+ * probe commune) — so the two agree by construction (the one-function discipline). The {@link NameKey} parameter is the
114
+ * enforcement of "must already be folded": stripping an arrondissement off an unfolded surface yields a key neither
115
+ * side stores. A no-op for every other commune, and the strip leaves a fold fixed point, so the result is still a
116
+ * {@link NameKey}. Returns the input unchanged if the strip would empty it.
61
117
  */
62
- export declare function stripArrondissement(localityNorm: string): string;
118
+ export declare function stripArrondissement(localityNorm: NameKey): NameKey;
63
119
  /**
64
120
  * Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized name misses the
65
121
  * gazetteer's canonical name, retry with the qualifier removed. OA address data carries disambiguating qualifiers the
@@ -90,5 +146,23 @@ export declare function stripLocalityQualifier(locality: string): string;
90
146
  * is ambiguous (designator unknown) and it stays unfolded — a bare-route query therefore misses rather than guessing a
91
147
  * designator.
92
148
  */
93
- export declare function canonicalizeRouteKey(streetNorm: string): string;
149
+ export declare function canonicalizeRouteKey(streetNorm: StreetKey): RouteKey;
150
+ /**
151
+ * Ordered lookup-key variants for a US/EN street span — the primary normalized key first, then the null-only recovery
152
+ * forms a reader may probe when the primary misses. Two register mismatches motivate them, both measured on live
153
+ * queries (2026-08-14):
154
+ *
155
+ * - **Doubled type** — a user types the type twice ("Saint Pauls PL St"), and the normalizer canonicalizes only the LAST
156
+ * type token, leaving `saint pauls pl street`, which matches nothing anywhere. The signature is visible in the key
157
+ * itself: a canonical type word in last position DIRECTLY after an uncanonicalized type abbreviation. The variant
158
+ * drops the trailing word and canonicalizes what remains (`saint pauls place`). A street genuinely named with two
159
+ * types keys identically on both sides and is caught by the primary probe first.
160
+ * - **Saint↔St register split** — the artifacts preserve each SOURCE's spelling (NYC situs keys `st pauls place`, Nassau
161
+ * keys `saint pauls place`), and a query arrives in whichever register the user typed. A leading `saint` or `st`
162
+ * token is swapped for its sibling; leading position only — a leading `st` is always the hagionym in US street names,
163
+ * and interior tokens ("Mount Saint Helens Dr") are out of scope until measured.
164
+ *
165
+ * Deduplicated and ordered most-literal-first, so probing the list in order preserves the primary key's precedence.
166
+ */
167
+ export declare function streetKeyVariants(street: string, locale?: StreetLocale): StreetKey[];
94
168
  //# sourceMappingURL=street-normalize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"street-normalize.d.ts","sourceRoot":"","sources":["../street-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AA8DH;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAkE5D;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AA6BpD;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAsCxF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAIhE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAc/D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAM/D"}
1
+ {"version":3,"file":"street-normalize.d.ts","sourceRoot":"","sources":["../street-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAEvC;;;;;;;;;GASG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AAE/C;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;AAEnD;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AA4DjD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAkE/D;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAgDhF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,SAAS,CAoE3F;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEjE;AAWD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,YAAY,CAEvF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAIlE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA+C/D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,SAAS,GAAG,QAAQ,CASpE;AAWD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,YAAmB,GAAG,SAAS,EAAE,CA8C1F"}
@@ -157,23 +157,56 @@ const FR_STREET_ABBREV = new Map([
157
157
  ["ste", "sainte"],
158
158
  ["sts", "saints"],
159
159
  ]);
160
+ /**
161
+ * Polish leading street-type tokens, STRIPPED rather than expanded. Measured on the 5.56M-row PL OSM shard
162
+ * (2026-08-19): OSM Poland tags `addr:street` BARE — `ulica%` covers 22 rows and `ul.%` eight, so an EXPANSION rule
163
+ * makes a typed query ("ul. Świętokrzyska" → "ulica swietokrzyska") miss the 3,846 bare "swietokrzyska" rows. Stripping
164
+ * the leading type on BOTH sides keys typed and bare surfaces identically. The full words are stripped too: the
165
+ * aleja/plac/osiedle populations (48,597 / 26,815 / 39,552 rows) spell the word out, and "Plac Zamkowy" must key the
166
+ * same as a query's "plac zamkowy" or bare "Zamkowy". Never stripped when it is the only token.
167
+ */
168
+ const PL_LEADING_TYPE = new Set(["ul", "ulica", "al", "aleja", "aleje", "pl", "plac", "os", "osiedle"]);
169
+ /**
170
+ * Indonesian street-type abbreviations → canonical full form, leading position ("Jl. Thamrin", "Gg. Waru").
171
+ */
172
+ const ID_STREET_ABBREV = new Map([
173
+ ["jl", "jalan"],
174
+ ["jln", "jalan"],
175
+ ["gg", "gang"],
176
+ ]);
160
177
  /**
161
178
  * Normalize a street name for the address-point key in a non-US locale. Same function build-side and probe-side (the
162
179
  * one-function discipline). US delegates to {@link normalizeStreetForKey}.
163
180
  *
181
+ * - **en** — the shared English address-key pipeline (directionals + suffix aliases), currently identical to US.
164
182
  * - **fr** — fold + expand leading type abbreviations and Saint/Sainte (token map).
165
183
  * - **de** — fold + ß→ss + canonicalize the GLUED `-str(.)` suffix to `-strasse` ("Lindenstr." → "lindenstrasse",
166
184
  * "Lindenstraße" → "lindenstrasse"); an already-full "-strasse" is left intact.
167
185
  * - **nl** — fold + canonicalize the glued `-str` suffix to `-straat` ("Kerkstr." → "kerkstraat").
186
+ * - **pl** — fold + ł→l (Ł does not NFKD-decompose, so the generic fold keeps it and an undiacritized query would miss;
187
+ * every other Polish diacritic is a combining form the fold already strips) + STRIP the leading type token — see
188
+ * {@link PL_LEADING_TYPE} for the measured reason expansion was wrong for this source.
189
+ * - **vn** — fold + đ→d AND ð→d (both non-decomposing, and OSM mixes the two codepoints inside single values — see the
190
+ * branch comment). Deliberately NO type-abbreviation map yet: the common abbreviation is the single letter "Đ." for
191
+ * Đường, and expanding a bare folded "d" token would rewrite initials — measure the miss rate on the built shard
192
+ * before adding anything.
193
+ * - **id** — fold + expand leading type abbreviations (jl/jln→jalan, gg→gang); Indonesian street surfaces are otherwise
194
+ * ASCII-clean.
168
195
  */
169
196
  export function normalizeStreetForKeyLocale(street, locale) {
170
- if (locale === "us")
197
+ if (locale === "us" || locale === "en")
171
198
  return normalizeStreetForKey(street);
172
199
  // Hyphen → space so a compound name keys the same whether the source or the query writes the
173
200
  // hyphen ("Champs-Élysées", "St-Honoré") or a space — both sides fold identically, so this is pure
174
201
  // robustness. It also splits a hyphenated abbreviation ("St-Honoré" → "st honore") into tokens the
175
- // per-locale type/Saint map can see.
176
- const tokens = fold(street).replaceAll("ß", "ss").replaceAll("-", " ").split(/\s+/).filter(Boolean);
202
+ // per-locale type/Saint map can see. Letter maps for non-decomposing letters (ß, ł, đ) live in the
203
+ // per-locale branches, NEVER here: widening the shared pipeline would silently change keys under
204
+ // every already-built shard of the other locales.
205
+ const tokens = fold(street)
206
+ .replaceAll("ß", "ss")
207
+ .replaceAll("-", " ")
208
+ .split(/\s+/)
209
+ .filter((value) => value.length > 0);
177
210
  if (!tokens.length)
178
211
  return "";
179
212
  switch (locale) {
@@ -198,6 +231,29 @@ export function normalizeStreetForKeyLocale(street, locale) {
198
231
  }
199
232
  }
200
233
  break;
234
+ case "pl":
235
+ for (let i = 0; i < tokens.length; i++) {
236
+ tokens[i] = tokens[i].replaceAll("ł", "l");
237
+ }
238
+ if (tokens.length > 1 && PL_LEADING_TYPE.has(tokens[0])) {
239
+ tokens.shift();
240
+ }
241
+ break;
242
+ case "id":
243
+ for (let i = 0; i < tokens.length; i++) {
244
+ tokens[i] = ID_STREET_ABBREV.get(tokens[i]) ?? tokens[i];
245
+ }
246
+ break;
247
+ case "vn":
248
+ // đ (U+0111, d-with-stroke) AND ð (U+00F0, eth): OSM Vietnamese data mixes the two visually
249
+ // identical codepoints inside single values — the 2026-08-19 shard measured `Đường Trần Hưng
250
+ // Đạo` carrying d-with-stroke at the front and ETH in `Đạo`, splitting the country's most
251
+ // common street into two keys with the MAJORITY variant (630 vs 421 rows) unreachable by a
252
+ // correctly-typed query. No abbreviation map — see the locale table.
253
+ for (let i = 0; i < tokens.length; i++) {
254
+ tokens[i] = tokens[i].replaceAll("đ", "d").replaceAll("ð", "d");
255
+ }
256
+ break;
201
257
  }
202
258
  return tokens.join(" ");
203
259
  }
@@ -207,15 +263,42 @@ export function normalizeStreetForKeyLocale(street, locale) {
207
263
  export function normalizeLocalityForKey(locality) {
208
264
  return fold(locality);
209
265
  }
266
+ /**
267
+ * Leading French street-type token. French types LEAD the name ("avenue du Parc", "boul Saint-Laurent") while English
268
+ * types TRAIL ("Fifth Avenue", "Grosvenor Place"), so a leading type-token is the discriminating signal — "1 Avenue NE"
269
+ * starts with a digit and never matches. The separator lookahead is explicit rather than `\b` because a word boundary
270
+ * after an accented final letter ("carré") is not one to an ASCII-word `\b`.
271
+ */
272
+ const FRENCH_LEAD_TYPE = /^(?:rue|ruelle|av|ave|avenue|boul|bd|boulevard|ch|che|chemin|all[ée]e|imp|impasse|mont[ée]e|c[ôo]te|pl|place|prom|promenade|rang|rte|route|autoroute|carr[eé]|croissant|terrasse|sentier)(?=[\s.-]|$)/i;
273
+ /**
274
+ * Surface-driven street-locale ROUTER for bilingual shards — the Québec finishing move on the CA rooftop shard.
275
+ *
276
+ * A country registers ONE street locale, but Canada's street surfaces are two languages: under the `en` rules a French
277
+ * surface passes through mostly unchanged (both sides fold identically, so those rows stay reachable), and what breaks
278
+ * is abbreviation variance — the `en` rules cannot fold "boul"/"Ste-" to the full French word, so an abbreviated query
279
+ * misses a full-word row and vice versa. Routing on the SURFACE (not the province) also carries bilingual NB and the
280
+ * French street names outside Québec for free.
281
+ *
282
+ * ONE function, called by the shard BUILDER and the query PROBE alike — the #861 discipline: routing is part of the
283
+ * fold contract, and two transcriptions of this predicate would diverge exactly where it matters. Only an `en` base
284
+ * re-routes: a `fr`/`de`/`nl` shard already speaks its own rules, and the US pipeline stays untouched.
285
+ *
286
+ * Measured basis (CA shard, 2026-08-19): 183,963 distinct surfaces, 43,762 French-lead; 29,682 fold differently under
287
+ * fr-vs-en (888,265 rows), and the non-French half of those are English surfaces this router keeps on `en` unchanged.
288
+ */
289
+ export function streetLocaleForSurface(street, base) {
290
+ return base === "en" && FRENCH_LEAD_TYPE.test(street.trimStart()) ? "fr" : base;
291
+ }
210
292
  /**
211
293
  * Strip a trailing French arrondissement designator from a FOLDED commune key ("paris 8e arrondissement" → "paris",
212
294
  * "lyon 1er arrondissement" → "lyon", "marseille 10e arrondissement" → "marseille"). Paris, Lyon and Marseille are the
213
295
  * only French communes subdivided into _arrondissements municipaux_; a national register (BAN) names each row per
214
296
  * arrondissement, but a query names the base commune ("Place Bellecour, Lyon", never "…, Lyon 2e"). Applied on BOTH
215
297
  * sides of the #1042 street-centroid key — build-side (deriving the `locality_base` column) and query-side (folding the
216
- * probe commune) — so the two agree by construction (the one-function discipline). Input must already be folded
217
- * (lower-case, diacritic-stripped); a no-op for every other commune. Returns the input unchanged if the strip would
218
- * empty it.
298
+ * probe commune) — so the two agree by construction (the one-function discipline). The {@link NameKey} parameter is the
299
+ * enforcement of "must already be folded": stripping an arrondissement off an unfolded surface yields a key neither
300
+ * side stores. A no-op for every other commune, and the strip leaves a fold fixed point, so the result is still a
301
+ * {@link NameKey}. Returns the input unchanged if the strip would empty it.
219
302
  */
220
303
  export function stripArrondissement(localityNorm) {
221
304
  const stripped = localityNorm.replace(/\s+\d+(?:er|e)\s+arrondissement$/, "").trim();
@@ -239,10 +322,31 @@ export function stripLocalityQualifier(locality) {
239
322
  if (s.includes("/")) {
240
323
  s = s.split("/")[0].trim();
241
324
  }
242
- // "Kraubath/Mur", "St.Kanzian/Klopeiner See"
243
- s = s.replace(/\s+[a-zà-ÿ]\.\s*\S.*$/iu, ""); // abbreviated " b.Graz" / " o.Bleiburg" / " a.d. …"
244
- s = s.replace(/\s+(im|an der|ob|bei|in der|unter|vor)\s+\S.*$/iu, ""); // " im Simmental", " bei Graz"
245
- s = s.replace(/\s+(S|N|E|W|V|Ø|Sø|Fyn|Thy|Sjælland|Jylland|[A-ZÅÄÖ]{2})$/u, ""); // " S", " VD", " Thy"
325
+ const words = [...s.matchAll(/\S+/gu)].map((match) => ({ value: match[0], index: match.index }));
326
+ let qualifierStart;
327
+ for (let index = 1; index < words.length; index++) {
328
+ const word = words[index];
329
+ const first = word.value[0] ?? "";
330
+ const abbreviated = /[a-zà-ÿ]/iu.test(first) && word.value[1] === "." && word.value.length > 2;
331
+ const oneWordQualifier = ["im", "ob", "bei", "unter", "vor"].includes(word.value.toLowerCase());
332
+ const twoWordQualifier = ["an", "in"].includes(word.value.toLowerCase()) && words[index + 1]?.value.toLowerCase() === "der";
333
+ const hasQualifierValue = oneWordQualifier ? index + 1 < words.length : index + 2 < words.length;
334
+ if (abbreviated || ((oneWordQualifier || twoWordQualifier) && hasQualifierValue)) {
335
+ qualifierStart = word.index;
336
+ break;
337
+ }
338
+ }
339
+ const suffix = words.at(-1);
340
+ if (qualifierStart === undefined &&
341
+ suffix &&
342
+ words.length > 1 &&
343
+ (["S", "N", "E", "W", "V", "Ø", "Sø", "Fyn", "Thy", "Sjælland", "Jylland"].includes(suffix.value) ||
344
+ /^[A-ZÅÄÖ]{2}$/u.test(suffix.value))) {
345
+ qualifierStart = suffix.index;
346
+ }
347
+ if (qualifierStart !== undefined) {
348
+ s = s.slice(0, qualifierStart).trimEnd();
349
+ }
246
350
  s = s.trim();
247
351
  return s === locality.trim() ? "" : s;
248
352
  }
@@ -264,8 +368,71 @@ export function stripLocalityQualifier(locality) {
264
368
  */
265
369
  export function canonicalizeRouteKey(streetNorm) {
266
370
  const match = /^(us|state|[a-z]{2}) (?:route|rte|rt|highway|hwy) (\d.*)$/.exec(streetNorm);
371
+ // A street naming no route is already its own route key. {@link StreetKey} and {@link RouteKey} are
372
+ // SIBLING brands rather than nested ones — precisely so neither column accepts the other's key — so
373
+ // re-minting here is an explicit hop through the unbranded string.
267
374
  if (!match)
268
375
  return streetNorm;
269
376
  return `${match[1] === "us" ? "us" : "state"} route ${match[2]}`;
270
377
  }
378
+ /**
379
+ * The canonical street-type words (lowercase) — the VALUE side of the codex suffix table. Membership means "this
380
+ * normalized token is a fully-spelled street type" ("place", "street", "road" …), which is how the doubled-type
381
+ * collapse below recognizes its shape without any parse-tree knowledge.
382
+ */
383
+ const CANONICAL_TYPE_WORDS = new Set([...US_STREET_SUFFIX_LOOKUP.values()].map((v) => v.toLowerCase()));
384
+ /**
385
+ * Ordered lookup-key variants for a US/EN street span — the primary normalized key first, then the null-only recovery
386
+ * forms a reader may probe when the primary misses. Two register mismatches motivate them, both measured on live
387
+ * queries (2026-08-14):
388
+ *
389
+ * - **Doubled type** — a user types the type twice ("Saint Pauls PL St"), and the normalizer canonicalizes only the LAST
390
+ * type token, leaving `saint pauls pl street`, which matches nothing anywhere. The signature is visible in the key
391
+ * itself: a canonical type word in last position DIRECTLY after an uncanonicalized type abbreviation. The variant
392
+ * drops the trailing word and canonicalizes what remains (`saint pauls place`). A street genuinely named with two
393
+ * types keys identically on both sides and is caught by the primary probe first.
394
+ * - **Saint↔St register split** — the artifacts preserve each SOURCE's spelling (NYC situs keys `st pauls place`, Nassau
395
+ * keys `saint pauls place`), and a query arrives in whichever register the user typed. A leading `saint` or `st`
396
+ * token is swapped for its sibling; leading position only — a leading `st` is always the hagionym in US street names,
397
+ * and interior tokens ("Mount Saint Helens Dr") are out of scope until measured.
398
+ *
399
+ * Deduplicated and ordered most-literal-first, so probing the list in order preserves the primary key's precedence.
400
+ */
401
+ export function streetKeyVariants(street, locale = "us") {
402
+ const primary = locale === "us" ? normalizeStreetForKey(street) : normalizeStreetForKeyLocale(street, locale);
403
+ const variants = primary ? [primary] : [];
404
+ if (!primary || (locale !== "us" && locale !== "en"))
405
+ return variants;
406
+ const tokens = primary.split(" ");
407
+ const last = tokens.at(-1);
408
+ const secondLast = tokens.at(-2);
409
+ if (tokens.length > 2 &&
410
+ last &&
411
+ secondLast &&
412
+ CANONICAL_TYPE_WORDS.has(last) &&
413
+ !CANONICAL_TYPE_WORDS.has(secondLast) &&
414
+ US_STREET_SUFFIX_LOOKUP.has(secondLast)) {
415
+ const collapsed = normalizeStreetForKey(tokens.slice(0, -1).join(" "));
416
+ if (collapsed && !variants.includes(collapsed)) {
417
+ variants.push(collapsed);
418
+ }
419
+ }
420
+ // Snapshot before the swap pass — it appends while reading, and iterating the live array would
421
+ // re-visit its own additions.
422
+ const preSwap = variants.slice();
423
+ for (const variant of preSwap) {
424
+ const [head, ...rest] = variant.split(" ");
425
+ const swapped = head === "saint" ? "st" : head === "st" ? "saint" : null;
426
+ if (swapped && rest.length) {
427
+ // Substituting a leading hagionym token in an already-normalized key leaves a fold fixed point —
428
+ // the suffix pass never rewrites position 0 — so the swap yields a {@link StreetKey} without
429
+ // re-folding.
430
+ const candidate = [swapped, ...rest].join(" ");
431
+ if (!variants.includes(candidate)) {
432
+ variants.push(candidate);
433
+ }
434
+ }
435
+ }
436
+ return variants;
437
+ }
271
438
  //# sourceMappingURL=street-normalize.js.map