@mailwoman/resolver-wof-sqlite 4.16.2 → 5.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 (154) hide show
  1. package/out/address-point-interpolation.d.ts.map +1 -1
  2. package/out/address-point-interpolation.js +6 -6
  3. package/out/address-point-interpolation.js.map +1 -1
  4. package/out/address-point-schema.d.ts +5 -6
  5. package/out/address-point-schema.d.ts.map +1 -1
  6. package/out/address-point-schema.js +7 -2
  7. package/out/address-point-schema.js.map +1 -1
  8. package/out/address-point.d.ts +22 -8
  9. package/out/address-point.d.ts.map +1 -1
  10. package/out/address-point.js +29 -13
  11. package/out/address-point.js.map +1 -1
  12. package/out/ancestry-backfill.d.ts +53 -0
  13. package/out/ancestry-backfill.d.ts.map +1 -0
  14. package/out/ancestry-backfill.js +150 -0
  15. package/out/ancestry-backfill.js.map +1 -0
  16. package/out/ancestry.d.ts +6 -6
  17. package/out/ancestry.d.ts.map +1 -1
  18. package/out/ancestry.js +6 -6
  19. package/out/ancestry.js.map +1 -1
  20. package/out/build-candidate-cli.d.ts.map +1 -1
  21. package/out/build-candidate-cli.js.map +1 -1
  22. package/out/build-candidate.d.ts +4 -5
  23. package/out/build-candidate.d.ts.map +1 -1
  24. package/out/build-candidate.js +15 -14
  25. package/out/build-candidate.js.map +1 -1
  26. package/out/build-coincident-roles-cli.d.ts.map +1 -1
  27. package/out/build-coincident-roles-cli.js.map +1 -1
  28. package/out/build-fts-cli.d.ts +1 -1
  29. package/out/build-fts-cli.d.ts.map +1 -1
  30. package/out/build-fts-cli.js +6 -6
  31. package/out/build-fts-cli.js.map +1 -1
  32. package/out/build-slim-cli.d.ts +1 -1
  33. package/out/build-slim-cli.d.ts.map +1 -1
  34. package/out/build-slim-cli.js +3 -3
  35. package/out/build-slim-cli.js.map +1 -1
  36. package/out/build-slim.d.ts +7 -8
  37. package/out/build-slim.d.ts.map +1 -1
  38. package/out/build-slim.js +9 -9
  39. package/out/build-slim.js.map +1 -1
  40. package/out/candidate-fts.d.ts +5 -7
  41. package/out/candidate-fts.d.ts.map +1 -1
  42. package/out/candidate-fts.js +5 -7
  43. package/out/candidate-fts.js.map +1 -1
  44. package/out/candidate-lookup.d.ts +7 -7
  45. package/out/candidate-lookup.d.ts.map +1 -1
  46. package/out/candidate-lookup.js +31 -35
  47. package/out/candidate-lookup.js.map +1 -1
  48. package/out/candidate-schema.d.ts +13 -14
  49. package/out/candidate-schema.d.ts.map +1 -1
  50. package/out/candidate-schema.js +9 -9
  51. package/out/candidate-schema.js.map +1 -1
  52. package/out/coincident-roles.d.ts +9 -11
  53. package/out/coincident-roles.d.ts.map +1 -1
  54. package/out/coincident-roles.js +7 -7
  55. package/out/coincident-roles.js.map +1 -1
  56. package/out/convention.d.ts +30 -35
  57. package/out/convention.d.ts.map +1 -1
  58. package/out/convention.js +19 -21
  59. package/out/convention.js.map +1 -1
  60. package/out/fst-autocomplete.d.ts +5 -5
  61. package/out/fst-autocomplete.d.ts.map +1 -1
  62. package/out/fst-autocomplete.js +12 -13
  63. package/out/fst-autocomplete.js.map +1 -1
  64. package/out/fst-builder.d.ts +7 -7
  65. package/out/fst-builder.d.ts.map +1 -1
  66. package/out/fst-builder.js +9 -9
  67. package/out/fst-builder.js.map +1 -1
  68. package/out/fst-deserialize-web.d.ts +4 -4
  69. package/out/fst-deserialize-web.d.ts.map +1 -1
  70. package/out/fst-deserialize-web.js +4 -4
  71. package/out/fst-deserialize-web.js.map +1 -1
  72. package/out/fst-matcher.d.ts +12 -12
  73. package/out/fst-matcher.d.ts.map +1 -1
  74. package/out/fst-matcher.js +25 -25
  75. package/out/fst-matcher.js.map +1 -1
  76. package/out/fst-serialize.d.ts +5 -5
  77. package/out/fst-serialize.d.ts.map +1 -1
  78. package/out/fst-serialize.js +7 -6
  79. package/out/fst-serialize.js.map +1 -1
  80. package/out/fst-types.d.ts +13 -13
  81. package/out/fts.d.ts +74 -80
  82. package/out/fts.d.ts.map +1 -1
  83. package/out/fts.js +65 -71
  84. package/out/fts.js.map +1 -1
  85. package/out/geo.d.ts +14 -15
  86. package/out/geo.d.ts.map +1 -1
  87. package/out/geo.js +8 -8
  88. package/out/geo.js.map +1 -1
  89. package/out/geonames-aliases.d.ts +18 -9
  90. package/out/geonames-aliases.d.ts.map +1 -1
  91. package/out/geonames-aliases.js +70 -12
  92. package/out/geonames-aliases.js.map +1 -1
  93. package/out/index.d.ts +9 -9
  94. package/out/index.js +7 -7
  95. package/out/interpolation.d.ts +8 -10
  96. package/out/interpolation.d.ts.map +1 -1
  97. package/out/interpolation.js +6 -6
  98. package/out/interpolation.js.map +1 -1
  99. package/out/lookup.d.ts +74 -81
  100. package/out/lookup.d.ts.map +1 -1
  101. package/out/lookup.js +114 -128
  102. package/out/lookup.js.map +1 -1
  103. package/out/postal-city-alias-lookup.d.ts +9 -10
  104. package/out/postal-city-alias-lookup.d.ts.map +1 -1
  105. package/out/postal-city-alias-lookup.js +13 -14
  106. package/out/postal-city-alias-lookup.js.map +1 -1
  107. package/out/postal-city-alias-schema.d.ts +5 -6
  108. package/out/postal-city-alias-schema.d.ts.map +1 -1
  109. package/out/postal-city-alias-schema.js +3 -4
  110. package/out/postal-city-alias-schema.js.map +1 -1
  111. package/out/postal-city-candidate-schema.d.ts +7 -10
  112. package/out/postal-city-candidate-schema.d.ts.map +1 -1
  113. package/out/postal-city-candidate-schema.js +4 -6
  114. package/out/postal-city-candidate-schema.js.map +1 -1
  115. package/out/postcode-point-lookup.d.ts +3 -4
  116. package/out/postcode-point-lookup.d.ts.map +1 -1
  117. package/out/postcode-point-lookup.js +2 -2
  118. package/out/postcode-point-lookup.js.map +1 -1
  119. package/out/reverse.d.ts +26 -29
  120. package/out/reverse.d.ts.map +1 -1
  121. package/out/reverse.js +36 -38
  122. package/out/reverse.js.map +1 -1
  123. package/out/schema.d.ts +32 -33
  124. package/out/schema.d.ts.map +1 -1
  125. package/out/sharding.d.ts +26 -28
  126. package/out/sharding.d.ts.map +1 -1
  127. package/out/sharding.js +16 -16
  128. package/out/sharding.js.map +1 -1
  129. package/out/sqlite-convention-source.d.ts +3 -3
  130. package/out/sqlite-convention-source.d.ts.map +1 -1
  131. package/out/sqlite-convention-source.js +6 -6
  132. package/out/sqlite-convention-source.js.map +1 -1
  133. package/out/sqlite-utils.d.ts +4 -5
  134. package/out/sqlite-utils.d.ts.map +1 -1
  135. package/out/sqlite-utils.js +4 -5
  136. package/out/sqlite-utils.js.map +1 -1
  137. package/out/street-morphology-fst-builder.d.ts +15 -18
  138. package/out/street-morphology-fst-builder.d.ts.map +1 -1
  139. package/out/street-morphology-fst-builder.js +17 -17
  140. package/out/street-morphology-fst-builder.js.map +1 -1
  141. package/out/street-normalize.d.ts +43 -28
  142. package/out/street-normalize.d.ts.map +1 -1
  143. package/out/street-normalize.js +96 -34
  144. package/out/street-normalize.js.map +1 -1
  145. package/out/street-segment-schema.d.ts +5 -5
  146. package/out/street-segment-schema.js +2 -2
  147. package/out/types.d.ts +42 -47
  148. package/out/types.d.ts.map +1 -1
  149. package/out/types.js +1 -1
  150. package/out/unified-schema.d.ts +6 -6
  151. package/out/unified-schema.d.ts.map +1 -1
  152. package/out/unified-schema.js +10 -10
  153. package/out/unified-schema.js.map +1 -1
  154. package/package.json +26 -22
@@ -19,22 +19,22 @@
19
19
  * Source: `core/data/libpostal/dictionaries/{locale}/street_types.txt`. Each line is pipe-delimited
20
20
  * surface forms with the canonical form first: avenue|av|ave|aven|avenu|avn|avnu|avnue
21
21
  *
22
- * Output: an `FstMatcher` ready to serialize via `serializeFst` to e.g.
22
+ * Output: an `FSTMatcher` ready to serialize via `serializeFST` to e.g.
23
23
  * `fst-street-morphology.bin`.
24
24
  */
25
25
  import { readdirSync, readFileSync, statSync } from "node:fs";
26
26
  import { join } from "node:path";
27
- import { FstMatcher, normalizeTokens } from "./fst-matcher.js";
27
+ import { FSTMatcher, normalizeTokens } from "./fst-matcher.js";
28
28
  /**
29
- * Reserved synthetic wofID base for street-morphology entries. 32-bit unsigned, well above any
30
- * realistic WOF allocation. Reusing the same base across rebuilds keeps IDs stable for any consumer
31
- * that caches them. See [[project-schema-storage-decision]] for the reserved range policy.
29
+ * Reserved synthetic wofID base for street-morphology entries. 32-bit unsigned, well above any realistic WOF
30
+ * allocation. Reusing the same base across rebuilds keeps IDs stable for any consumer that caches them. See
31
+ * [[project-schema-storage-decision]] for the reserved range policy.
32
32
  */
33
33
  const STREET_AFFIX_WOFID_BASE = 1_900_000_000;
34
34
  const STREET_TYPES_FILENAME = "street_types.txt";
35
35
  /**
36
- * Parse one `street_types.txt` line into `{ canonical, variants }`. Canonical is the first token
37
- * (pre-`|`); variants are all whitespace-stripped non-empty tokens including the canonical.
36
+ * Parse one `street_types.txt` line into `{ canonical, variants }`. Canonical is the first token (pre-`|`); variants
37
+ * are all whitespace-stripped non-empty tokens including the canonical.
38
38
  *
39
39
  * Lines with no `|` are treated as a single-form entry where canonical == variant.
40
40
  */
@@ -50,7 +50,7 @@ function parseLine(line) {
50
50
  return null;
51
51
  return { canonical: parts[0], variants: parts };
52
52
  }
53
- export function buildStreetMorphologyFst(opts) {
53
+ export function buildStreetMorphologyFST(opts) {
54
54
  const progress = opts.onProgress ?? (() => { });
55
55
  const minVariantLength = opts.minVariantLength ?? 3;
56
56
  // Discover locales — either provided explicitly, or all directories containing street_types.txt.
@@ -92,9 +92,9 @@ export function buildStreetMorphologyFst(opts) {
92
92
  progress("collect", `Collected ${canonicalToVariants.size} canonical affixes`);
93
93
  // Assign stable synthetic wofIDs. Sort canonicals for determinism.
94
94
  const sortedCanonicals = [...canonicalToVariants.keys()].sort();
95
- const canonicalToWofID = new Map();
95
+ const canonicalToWOFID = new Map();
96
96
  for (let i = 0; i < sortedCanonicals.length; i++) {
97
- canonicalToWofID.set(sortedCanonicals[i], STREET_AFFIX_WOFID_BASE + i);
97
+ canonicalToWOFID.set(sortedCanonicals[i], STREET_AFFIX_WOFID_BASE + i);
98
98
  }
99
99
  // Build the trie. Each variant is inserted as a token sequence pointing to its canonical's
100
100
  // PlaceEntry — so all variants of "avenue" (av/ave/aven/...) lead to the same terminal entry.
@@ -102,18 +102,18 @@ export function buildStreetMorphologyFst(opts) {
102
102
  function insertName(tokens, entry) {
103
103
  if (tokens.length === 0)
104
104
  return;
105
- let stateId = 0;
105
+ let stateID = 0;
106
106
  for (const t of tokens) {
107
- const node = nodes[stateId];
107
+ const node = nodes[stateID];
108
108
  let next = node.edges.get(t);
109
109
  if (next === undefined) {
110
110
  next = nodes.length;
111
111
  nodes.push({ edges: new Map(), places: [] });
112
112
  node.edges.set(t, next);
113
113
  }
114
- stateId = next;
114
+ stateID = next;
115
115
  }
116
- const existing = nodes[stateId].places;
116
+ const existing = nodes[stateID].places;
117
117
  if (!existing.some((p) => p.wofID === entry.wofID && p.placetype === entry.placetype)) {
118
118
  existing.push(entry);
119
119
  }
@@ -122,7 +122,7 @@ export function buildStreetMorphologyFst(opts) {
122
122
  let variantCount = 0;
123
123
  for (const canonical of sortedCanonicals) {
124
124
  const variants = canonicalToVariants.get(canonical);
125
- const wofID = canonicalToWofID.get(canonical);
125
+ const wofID = canonicalToWOFID.get(canonical);
126
126
  const entry = {
127
127
  wofID,
128
128
  placetype: "street_affix",
@@ -151,7 +151,7 @@ export function buildStreetMorphologyFst(opts) {
151
151
  }
152
152
  progress("trie", `Built trie: ${nodes.length} states, ${insertCount} variant insertions`);
153
153
  const edgeCount = nodes.reduce((sum, n) => sum + n.edges.size, 0);
154
- const matcher = FstMatcher.fromNodes(nodes);
154
+ const matcher = FSTMatcher.fromNodes(nodes);
155
155
  const provenance = {
156
156
  builtAt: new Date().toISOString(),
157
157
  countries: locales, // Reuse `countries` slot for locale provenance — semantics differ from admin FST.
@@ -160,7 +160,7 @@ export function buildStreetMorphologyFst(opts) {
160
160
  edgeCount,
161
161
  nameInsertions: insertCount,
162
162
  importanceMatches: 0, // No importance scoring for morphology — fixed at 1.0.
163
- sourceDb: opts.dictionariesDir,
163
+ sourceDB: opts.dictionariesDir,
164
164
  };
165
165
  return {
166
166
  matcher,
@@ -1 +1 @@
1
- {"version":3,"file":"street-morphology-fst-builder.js","sourceRoot":"","sources":["../street-morphology-fst-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAG9D;;;;GAIG;AACH,MAAM,uBAAuB,GAAG,aAAa,CAAA;AAE7C,MAAM,qBAAqB,GAAG,kBAAkB,CAAA;AAmChD;;;;;GAKG;AACH,SAAS,SAAS,CAAC,IAAY;IAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAChE,MAAM,KAAK,GAAG,OAAO;SACnB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACnC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAAkC;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAC9C,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAA;IAEnD,iGAAiG;IACjG,IAAI,OAAiB,CAAA;IACrB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;IACvB,CAAC;SAAM,CAAC;QACP,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;YACpD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE;gBAAE,OAAO,KAAK,CAAA;YACrD,IAAI,CAAC;gBACJ,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC,CAAA;gBACjD,OAAO,IAAI,CAAA;YACZ,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,KAAK,CAAA;YACb,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC;IACD,QAAQ,CAAC,UAAU,EAAE,SAAS,OAAO,CAAC,MAAM,iBAAiB,qBAAqB,EAAE,CAAC,CAAA;IAErF,4FAA4F;IAC5F,wEAAwE;IACxE,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC1D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAA;QAC1E,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QAC9C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;YAC9B,IAAI,CAAC,MAAM;gBAAE,SAAQ;YACrB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,GAAG,EAAU,CAAA;YAC/E,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ;gBAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAC5D,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;QACpD,CAAC;IACF,CAAC;IACD,QAAQ,CAAC,SAAS,EAAE,aAAa,mBAAmB,CAAC,IAAI,oBAAoB,CAAC,CAAA;IAE9E,mEAAmE;IACnE,MAAM,gBAAgB,GAAG,CAAC,GAAG,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC/D,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAA;IAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClD,gBAAgB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAE,EAAE,uBAAuB,GAAG,CAAC,CAAC,CAAA;IACxE,CAAC;IAED,2FAA2F;IAC3F,8FAA8F;IAC9F,MAAM,KAAK,GAAc,CAAC,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;IAE3D,SAAS,UAAU,CAAC,MAAgB,EAAE,KAAiB;QACtD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC/B,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAE,CAAA;YAC5B,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YAC5B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACxB,IAAI,GAAG,KAAK,CAAC,MAAM,CAAA;gBACnB,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;gBAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;YACxB,CAAC;YACD,OAAO,GAAG,IAAI,CAAA;QACf,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAE,CAAC,MAAM,CAAA;QACvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACvF,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;IACF,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,IAAI,YAAY,GAAG,CAAC,CAAA;IACpB,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAE,CAAA;QACpD,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAE,CAAA;QAC9C,MAAM,KAAK,GAAe;YACzB,KAAK;YACL,SAAS,EAAE,cAAc;YACzB,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,EAAE;YACf,wFAAwF;YACxF,qFAAqF;YACrF,iDAAiD;YACjD,UAAU,EAAE,GAAG;YACf,GAAG,EAAE,CAAC;YACN,GAAG,EAAE,CAAC;SACN,CAAA;QACD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;YACvC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAQ;YACjC,qFAAqF;YACrF,2FAA2F;YAC3F,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAC9B,IAAI,MAAM,CAAC,MAAM,GAAG,gBAAgB;gBAAE,SAAQ;YAC9C,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YACzB,WAAW,EAAE,CAAA;YACb,YAAY,EAAE,CAAA;QACf,CAAC;IACF,CAAC;IACD,QAAQ,CAAC,MAAM,EAAE,eAAe,KAAK,CAAC,MAAM,YAAY,WAAW,qBAAqB,CAAC,CAAA;IAEzF,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IACjE,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,UAAU,GAAkB;QACjC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACjC,SAAS,EAAE,OAAO,EAAE,kFAAkF;QACtG,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,UAAU,EAAE,gBAAgB,CAAC,MAAM;QACnC,SAAS;QACT,cAAc,EAAE,WAAW;QAC3B,iBAAiB,EAAE,CAAC,EAAE,uDAAuD;QAC7E,QAAQ,EAAE,IAAI,CAAC,eAAe;KAC9B,CAAA;IAED,OAAO;QACN,OAAO;QACP,UAAU;QACV,cAAc,EAAE,gBAAgB,CAAC,MAAM;QACvC,YAAY;QACZ,WAAW;QACX,OAAO;KACP,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"street-morphology-fst-builder.js","sourceRoot":"","sources":["../street-morphology-fst-builder.ts"],"names":[],"mappings":"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"}
@@ -22,45 +22,60 @@
22
22
  * cross-streets the source data spells with digits become reachable.
23
23
  */
24
24
  /**
25
- * Normalize a street name for address-point keying. Same function at build time and lookup time —
26
- * see module docstring for the contract.
25
+ * Normalize a street name for address-point keying. Same function at build time and lookup time — see module docstring
26
+ * for the contract.
27
27
  */
28
28
  export declare function normalizeStreetForKey(street: string): string;
29
+ /**
30
+ * Street-name locale for the address-point key. The US path is the full USPS pipeline ({@link normalizeStreetForKey});
31
+ * the international paths fold + apply a SMALL, consistent per-locale type-token canonicalization. Same discipline as
32
+ * the US normalizer: build side and probe side call the identical function, so the key only needs to be CONSISTENT, not
33
+ * linguistically perfect — a folded "rue du chevaleret" keys the same on both sides whether or not we reorder the
34
+ * article, so no salient-token / multi-key index is built yet (deferred until probing shows the normalizer can't absorb
35
+ * the false-negatives).
36
+ */
37
+ export type StreetLocale = "us" | "fr" | "de" | "nl";
38
+ /**
39
+ * Normalize a street name for the address-point key in a non-US locale. Same function build-side and probe-side (the
40
+ * one-function discipline). US delegates to {@link normalizeStreetForKey}.
41
+ *
42
+ * - **fr** — fold + expand leading type abbreviations and Saint/Sainte (token map).
43
+ * - **de** — fold + ß→ss + canonicalize the GLUED `-str(.)` suffix to `-strasse` ("Lindenstr." → "lindenstrasse",
44
+ * "Lindenstraße" → "lindenstrasse"); an already-full "-strasse" is left intact.
45
+ * - **nl** — fold + canonicalize the glued `-str` suffix to `-straat` ("Kerkstr." → "kerkstraat").
46
+ */
47
+ export declare function normalizeStreetForKeyLocale(street: string, locale: StreetLocale): string;
29
48
  /** Normalize a locality name for address-point keying (fold only — no street semantics). */
30
49
  export declare function normalizeLocalityForKey(locality: string): string;
31
50
  /**
32
- * Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized
33
- * name misses the gazetteer's canonical name, retry with the qualifier removed. OA address data
34
- * carries disambiguating qualifiers the gazetteer's canonical name omits: Austrian `Kraubath/Mur`
35
- * and `Hart b.Graz` → `Hart`; Swiss `Lenk im Simmental` → `Lenk`, `Roche VD` → `Roche`; Danish
36
- * `Odense S`, `Hurup Thy`. A FALLBACK ONLY — the exact name is tried first, and the region-bbox
37
- * disambiguation resolves any base-name ambiguity downstream. The candidate table is unchanged
38
- * (this is purely query-side); feed the result back through {@link normalizeLocalityForKey}. Returns
39
- * "" when nothing was stripped (no point re-probing the identical key).
51
+ * Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized name misses the
52
+ * gazetteer's canonical name, retry with the qualifier removed. OA address data carries disambiguating qualifiers the
53
+ * gazetteer's canonical name omits: Austrian `Kraubath/Mur` and `Hart b.Graz` → `Hart`; Swiss `Lenk im Simmental` →
54
+ * `Lenk`, `Roche VD` → `Roche`; Danish `Odense S`, `Hurup Thy`. A FALLBACK ONLY — the exact name is tried first, and
55
+ * the region-bbox disambiguation resolves any base-name ambiguity downstream. The candidate table is unchanged (this is
56
+ * purely query-side); feed the result back through {@link normalizeLocalityForKey}. Returns "" when nothing was stripped
57
+ * (no point re-probing the identical key).
40
58
  *
41
- * Measured (`scripts/eval/candidate-recall.ts --strip-fallback`, EU OA holdouts): recovers AT
42
- * 74.1→88.2% (+14.1pp), DK 91.5→96.2%, CH 90.4→92.6%; +1.3pp overall (diluted by the already-100%
43
- * locales). Conservative by design — only the qualifier forms above; FI/PT/SI misses are
44
- * untouched.
59
+ * Measured (`scripts/eval/candidate-recall.ts --strip-fallback`, EU OA holdouts): recovers AT 74.1→88.2% (+14.1pp), DK
60
+ * 91.5→96.2%, CH 90.4→92.6%; +1.3pp overall (diluted by the already-100% locales). Conservative by design — only the
61
+ * qualifier forms above; FI/PT/SI misses are untouched.
45
62
  */
46
63
  export declare function stripLocalityQualifier(locality: string): string;
47
64
  /**
48
- * Fold numbered-route designators to a canonical key, applied AFTER {@link normalizeStreetForKey}.
49
- * Sources disagree systematically on how they spell a route: TIGER says `State Rte 100` / `US Hwy
50
- * 5` where E911/Overture say `VT ROUTE 100` / `US ROUTE 5` — the dominant street-name miss class in
51
- * the #483 interpolation eval (rural addresses live on routes). `us <designator> N…` folds to `us
52
- * route N…`; `state <designator> N…` and `<2-letter-prefix> <designator> N…` (the state
53
- * abbreviation form) fold to `state route N…`. Only digit-leading route numbers fold — `State
54
- * Street` and friends never match.
65
+ * Fold numbered-route designators to a canonical key, applied AFTER {@link normalizeStreetForKey}. Sources disagree
66
+ * systematically on how they spell a route: TIGER says `State Rte 100` / `US Hwy 5` where E911/Overture say `VT ROUTE
67
+ * 100` / `US ROUTE 5` — the dominant street-name miss class in the #483 interpolation eval (rural addresses live on
68
+ * routes). `us <designator> N…` folds to `us route N…`; `state <designator> N…` and `<2-letter-prefix> <designator> N…`
69
+ * (the state abbreviation form) fold to `state route N…`. Only digit-leading route numbers fold — `State Street` and
70
+ * friends never match.
55
71
  *
56
- * Used by BOTH the segment-shard builder (`scripts/build-interpolation-shard.ts`) and the
57
- * interpolation lookup — same one-function discipline as {@link normalizeStreetForKey}. The
58
- * address-point tier (#476) does NOT apply it yet: adopting it there requires a shard rebuild
59
- * (noted on #483).
72
+ * Used by BOTH the segment-shard builder (`scripts/build-interpolation-shard.ts`) and the interpolation lookup — same
73
+ * one-function discipline as {@link normalizeStreetForKey}. The address-point tier (#476) does NOT apply it yet:
74
+ * adopting it there requires a shard rebuild (noted on #483).
60
75
  *
61
- * A same-numbered US and state route stay DISTINCT keys (`us route 5` vs `state route 5`); only the
62
- * BARE `route N` form is ambiguous (designator unknown) and it stays unfolded — a bare-route query
63
- * therefore misses rather than guessing a designator.
76
+ * A same-numbered US and state route stay DISTINCT keys (`us route 5` vs `state route 5`); only the BARE `route N` form
77
+ * is ambiguous (designator unknown) and it stays unfolded — a bare-route query therefore misses rather than guessing a
78
+ * designator.
64
79
  */
65
80
  export declare function canonicalizeRouteKey(streetNorm: string): string;
66
81
  //# 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;AAuDH;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA6C5D;AAED,4FAA4F;AAC5F,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ/D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAI/D"}
1
+ {"version":3,"file":"street-normalize.d.ts","sourceRoot":"","sources":["../street-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAsDH;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqD5D;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,CAgCxF;AAED,4FAA4F;AAC5F,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU/D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAM/D"}
@@ -23,12 +23,11 @@
23
23
  */
24
24
  import { AbbreviationToDirectional, US_STREET_SUFFIX_LOOKUP } from "@mailwoman/codex/us";
25
25
  /**
26
- * Spelled ordinal street names → their digit-ordinal form ("tenth" → "10th"), applied ONLY when a
27
- * street-type suffix follows (#723 admin-tail) — so the ordinal cross-streets common in grid cities
28
- * ("Tenth Street", "Fifth Avenue") match the shards' digit keys, WITHOUT rewriting ordinal-WORD
29
- * names where the next token is not a suffix ("First National Bank Rd" stays "first national …").
30
- * Digit-source shards are unaffected (a digit token isn't in this map), so the existing keys need
31
- * no rebuild; a future rebuild folds any spelled-source key the same way (the one-function
26
+ * Spelled ordinal street names → their digit-ordinal form ("tenth" → "10th"), applied ONLY when a street-type suffix
27
+ * follows (#723 admin-tail) — so the ordinal cross-streets common in grid cities ("Tenth Street", "Fifth Avenue") match
28
+ * the shards' digit keys, WITHOUT rewriting ordinal-WORD names where the next token is not a suffix ("First National
29
+ * Bank Rd" stays "first national …"). Digit-source shards are unaffected (a digit token isn't in this map), so the
30
+ * existing keys need no rebuild; a future rebuild folds any spelled-source key the same way (the one-function
32
31
  * discipline).
33
32
  */
34
33
  const SPELLED_ORDINAL_TO_DIGIT = new Map([
@@ -72,8 +71,8 @@ function fold(input) {
72
71
  .trim();
73
72
  }
74
73
  /**
75
- * Normalize a street name for address-point keying. Same function at build time and lookup time —
76
- * see module docstring for the contract.
74
+ * Normalize a street name for address-point keying. Same function at build time and lookup time — see module docstring
75
+ * for the contract.
77
76
  */
78
77
  export function normalizeStreetForKey(street) {
79
78
  const tokens = fold(street).split(" ");
@@ -120,24 +119,89 @@ export function normalizeStreetForKey(street) {
120
119
  }
121
120
  return tokens.join(" ");
122
121
  }
122
+ /**
123
+ * French street-type abbreviations → canonical full form, applied per token after {@link fold}. French address types
124
+ * LEAD the name ("Av. de…", "Bd …", "Pl. …") and "St"/"Ste" abbreviate Saint/Sainte inside names ("Rue St-Honoré" →
125
+ * "rue saint honore"). fold() has already stripped the trailing period, so the keys are point-free ("av", "bd").
126
+ */
127
+ const FR_STREET_ABBREV = new Map([
128
+ ["av", "avenue"],
129
+ ["ave", "avenue"],
130
+ ["bd", "boulevard"],
131
+ ["bld", "boulevard"],
132
+ ["bvd", "boulevard"],
133
+ ["boul", "boulevard"],
134
+ ["pl", "place"],
135
+ ["imp", "impasse"],
136
+ ["all", "allee"],
137
+ ["ch", "chemin"],
138
+ ["che", "chemin"],
139
+ ["sq", "square"],
140
+ ["pas", "passage"],
141
+ ["fg", "faubourg"],
142
+ ["fbg", "faubourg"],
143
+ ["rte", "route"],
144
+ ["st", "saint"],
145
+ ["ste", "sainte"],
146
+ ["sts", "saints"],
147
+ ]);
148
+ /**
149
+ * Normalize a street name for the address-point key in a non-US locale. Same function build-side and probe-side (the
150
+ * one-function discipline). US delegates to {@link normalizeStreetForKey}.
151
+ *
152
+ * - **fr** — fold + expand leading type abbreviations and Saint/Sainte (token map).
153
+ * - **de** — fold + ß→ss + canonicalize the GLUED `-str(.)` suffix to `-strasse` ("Lindenstr." → "lindenstrasse",
154
+ * "Lindenstraße" → "lindenstrasse"); an already-full "-strasse" is left intact.
155
+ * - **nl** — fold + canonicalize the glued `-str` suffix to `-straat` ("Kerkstr." → "kerkstraat").
156
+ */
157
+ export function normalizeStreetForKeyLocale(street, locale) {
158
+ if (locale === "us")
159
+ return normalizeStreetForKey(street);
160
+ // Hyphen → space so a compound name keys the same whether the source or the query writes the
161
+ // hyphen ("Champs-Élysées", "St-Honoré") or a space — both sides fold identically, so this is pure
162
+ // robustness. It also splits a hyphenated abbreviation ("St-Honoré" → "st honore") into tokens the
163
+ // per-locale type/Saint map can see.
164
+ const tokens = fold(street).replace(/ß/g, "ss").replace(/-/g, " ").split(/\s+/).filter(Boolean);
165
+ if (tokens.length === 0)
166
+ return "";
167
+ switch (locale) {
168
+ case "fr":
169
+ for (let i = 0; i < tokens.length; i++)
170
+ tokens[i] = FR_STREET_ABBREV.get(tokens[i]) ?? tokens[i];
171
+ break;
172
+ case "de":
173
+ for (let i = 0; i < tokens.length; i++) {
174
+ const t = tokens[i];
175
+ if (t.endsWith("str") && !t.endsWith("strasse"))
176
+ tokens[i] = t.replace(/str$/, "strasse");
177
+ }
178
+ break;
179
+ case "nl":
180
+ for (let i = 0; i < tokens.length; i++) {
181
+ const t = tokens[i];
182
+ if (t.endsWith("str") && !t.endsWith("straat"))
183
+ tokens[i] = t.replace(/str$/, "straat");
184
+ }
185
+ break;
186
+ }
187
+ return tokens.join(" ");
188
+ }
123
189
  /** Normalize a locality name for address-point keying (fold only — no street semantics). */
124
190
  export function normalizeLocalityForKey(locality) {
125
191
  return fold(locality);
126
192
  }
127
193
  /**
128
- * Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized
129
- * name misses the gazetteer's canonical name, retry with the qualifier removed. OA address data
130
- * carries disambiguating qualifiers the gazetteer's canonical name omits: Austrian `Kraubath/Mur`
131
- * and `Hart b.Graz` → `Hart`; Swiss `Lenk im Simmental` → `Lenk`, `Roche VD` → `Roche`; Danish
132
- * `Odense S`, `Hurup Thy`. A FALLBACK ONLY — the exact name is tried first, and the region-bbox
133
- * disambiguation resolves any base-name ambiguity downstream. The candidate table is unchanged
134
- * (this is purely query-side); feed the result back through {@link normalizeLocalityForKey}. Returns
135
- * "" when nothing was stripped (no point re-probing the identical key).
194
+ * Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized name misses the
195
+ * gazetteer's canonical name, retry with the qualifier removed. OA address data carries disambiguating qualifiers the
196
+ * gazetteer's canonical name omits: Austrian `Kraubath/Mur` and `Hart b.Graz` → `Hart`; Swiss `Lenk im Simmental` →
197
+ * `Lenk`, `Roche VD` → `Roche`; Danish `Odense S`, `Hurup Thy`. A FALLBACK ONLY — the exact name is tried first, and
198
+ * the region-bbox disambiguation resolves any base-name ambiguity downstream. The candidate table is unchanged (this is
199
+ * purely query-side); feed the result back through {@link normalizeLocalityForKey}. Returns "" when nothing was stripped
200
+ * (no point re-probing the identical key).
136
201
  *
137
- * Measured (`scripts/eval/candidate-recall.ts --strip-fallback`, EU OA holdouts): recovers AT
138
- * 74.1→88.2% (+14.1pp), DK 91.5→96.2%, CH 90.4→92.6%; +1.3pp overall (diluted by the already-100%
139
- * locales). Conservative by design — only the qualifier forms above; FI/PT/SI misses are
140
- * untouched.
202
+ * Measured (`scripts/eval/candidate-recall.ts --strip-fallback`, EU OA holdouts): recovers AT 74.1→88.2% (+14.1pp), DK
203
+ * 91.5→96.2%, CH 90.4→92.6%; +1.3pp overall (diluted by the already-100% locales). Conservative by design — only the
204
+ * qualifier forms above; FI/PT/SI misses are untouched.
141
205
  */
142
206
  export function stripLocalityQualifier(locality) {
143
207
  let s = locality.trim();
@@ -150,22 +214,20 @@ export function stripLocalityQualifier(locality) {
150
214
  return s === locality.trim() ? "" : s;
151
215
  }
152
216
  /**
153
- * Fold numbered-route designators to a canonical key, applied AFTER {@link normalizeStreetForKey}.
154
- * Sources disagree systematically on how they spell a route: TIGER says `State Rte 100` / `US Hwy
155
- * 5` where E911/Overture say `VT ROUTE 100` / `US ROUTE 5` — the dominant street-name miss class in
156
- * the #483 interpolation eval (rural addresses live on routes). `us <designator> N…` folds to `us
157
- * route N…`; `state <designator> N…` and `<2-letter-prefix> <designator> N…` (the state
158
- * abbreviation form) fold to `state route N…`. Only digit-leading route numbers fold — `State
159
- * Street` and friends never match.
217
+ * Fold numbered-route designators to a canonical key, applied AFTER {@link normalizeStreetForKey}. Sources disagree
218
+ * systematically on how they spell a route: TIGER says `State Rte 100` / `US Hwy 5` where E911/Overture say `VT ROUTE
219
+ * 100` / `US ROUTE 5` — the dominant street-name miss class in the #483 interpolation eval (rural addresses live on
220
+ * routes). `us <designator> N…` folds to `us route N…`; `state <designator> N…` and `<2-letter-prefix> <designator> N…`
221
+ * (the state abbreviation form) fold to `state route N…`. Only digit-leading route numbers fold — `State Street` and
222
+ * friends never match.
160
223
  *
161
- * Used by BOTH the segment-shard builder (`scripts/build-interpolation-shard.ts`) and the
162
- * interpolation lookup — same one-function discipline as {@link normalizeStreetForKey}. The
163
- * address-point tier (#476) does NOT apply it yet: adopting it there requires a shard rebuild
164
- * (noted on #483).
224
+ * Used by BOTH the segment-shard builder (`scripts/build-interpolation-shard.ts`) and the interpolation lookup — same
225
+ * one-function discipline as {@link normalizeStreetForKey}. The address-point tier (#476) does NOT apply it yet:
226
+ * adopting it there requires a shard rebuild (noted on #483).
165
227
  *
166
- * A same-numbered US and state route stay DISTINCT keys (`us route 5` vs `state route 5`); only the
167
- * BARE `route N` form is ambiguous (designator unknown) and it stays unfolded — a bare-route query
168
- * therefore misses rather than guessing a designator.
228
+ * A same-numbered US and state route stay DISTINCT keys (`us route 5` vs `state route 5`); only the BARE `route N` form
229
+ * is ambiguous (designator unknown) and it stays unfolded — a bare-route query therefore misses rather than guessing a
230
+ * designator.
169
231
  */
170
232
  export function canonicalizeRouteKey(streetNorm) {
171
233
  const match = /^(us|state|[a-z]{2}) (?:route|rte|rt|highway|hwy) (\d.*)$/.exec(streetNorm);
@@ -1 +1 @@
1
- {"version":3,"file":"street-normalize.js","sourceRoot":"","sources":["../street-normalize.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"street-normalize.js","sourceRoot":"","sources":["../street-normalize.ts"],"names":[],"mappings":"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"}
@@ -16,9 +16,9 @@
16
16
  */
17
17
  import type { Kysely } from "kysely";
18
18
  /**
19
- * One TIGER street-segment edge: a `(from_hn, to_hn)` house-number range on one `side` of a named
20
- * street, with the geometry the interpolator walks. `min_hn`/`max_hn` are the sorted bounds (the
21
- * probe filters on them); `parity` is `odd`/`even`/`mixed`.
19
+ * One TIGER street-segment edge: a `(from_hn, to_hn)` house-number range on one `side` of a named street, with the
20
+ * geometry the interpolator walks. `min_hn`/`max_hn` are the sorted bounds (the probe filters on them); `parity` is
21
+ * `odd`/`even`/`mixed`.
22
22
  */
23
23
  export interface StreetSegmentTable {
24
24
  /** Shared {@link normalizeStreetForKey} of the street — the build/query-consistent probe key. */
@@ -50,8 +50,8 @@ export interface StreetSegmentDatabase {
50
50
  street_segment: StreetSegmentTable;
51
51
  }
52
52
  /**
53
- * The `street_segment` columns in INSERT order. The builder's positional prepared statement derives
54
- * its placeholder list from this, so the positional order can't drift from the DDL / the reader.
53
+ * The `street_segment` columns in INSERT order. The builder's positional prepared statement derives its placeholder
54
+ * list from this, so the positional order can't drift from the DDL / the reader.
55
55
  */
56
56
  export declare const STREET_SEGMENT_COLUMNS: readonly ["street_norm", "side", "from_hn", "to_hn", "min_hn", "max_hn", "parity", "postcode", "county_fips", "street_raw", "geometry", "source", "release"];
57
57
  /** Create the `street_segment` table — called before the streaming bulk load. */
@@ -15,8 +15,8 @@
15
15
  * {@link STREET_SEGMENT_COLUMNS} so it can't drift from the DDL.
16
16
  */
17
17
  /**
18
- * The `street_segment` columns in INSERT order. The builder's positional prepared statement derives
19
- * its placeholder list from this, so the positional order can't drift from the DDL / the reader.
18
+ * The `street_segment` columns in INSERT order. The builder's positional prepared statement derives its placeholder
19
+ * list from this, so the positional order can't drift from the DDL / the reader.
20
20
  */
21
21
  export const STREET_SEGMENT_COLUMNS = [
22
22
  "street_norm",
package/out/types.d.ts CHANGED
@@ -7,33 +7,32 @@
7
7
  *
8
8
  * These mirror the conceptual model described in `docs/plan/phases/PHASE_4_2_wof_sqlite.md`. Phase
9
9
  * 4.3 will extend `PlaceCandidate` with the resolver-decorated fields that flow into
10
- * `AddressNode.source` / `sourceId` (e.g. an explicit `wofUri: "wof-admin:101751113"` form).
10
+ * `AddressNode.source` / `sourceID` (e.g. an explicit `wofURI: "wof-admin:101751113"` form).
11
11
  */
12
12
  /**
13
- * The placetype taxonomy used by Who's On First. Ordered roughly from coarsest (country) to finest
14
- * (address). See https://github.com/whosonfirst/whosonfirst-placetypes for the authoritative
15
- * definitions of each.
13
+ * The placetype taxonomy used by Who's On First. Ordered roughly from coarsest (country) to finest (address). See
14
+ * https://github.com/whosonfirst/whosonfirst-placetypes for the authoritative definitions of each.
16
15
  *
17
16
  * Phase 4.2 only emits the ones we actually look up; the union is open enough to extend later.
18
17
  */
19
- export type WofPlacetype = "country" | "macroregion" | "region" | "macrocounty" | "county" | "localadmin" | "locality" | "borough" | "neighbourhood" | "microhood" | "postalcode" | "venue" | "campus" | "address";
18
+ export type WOFPlacetype = "country" | "macroregion" | "region" | "macrocounty" | "county" | "localadmin" | "locality" | "borough" | "neighbourhood" | "microhood" | "postalcode" | "venue" | "campus" | "address";
20
19
  /**
21
20
  * One candidate match for a place lookup.
22
21
  *
23
- * `score` is the post-boost ranking number — higher is better, but the scale is implementation-
24
- * defined. Callers should treat it as ordinal, not absolute.
22
+ * `score` is the post-boost ranking number — higher is better, but the scale is implementation- defined. Callers should
23
+ * treat it as ordinal, not absolute.
25
24
  *
26
- * `id` is the WOF place id. It's named generically (not `wof_id`) so the shape stays structurally
27
- * compatible with `@mailwoman/resolver`'s `ResolvedPlace` — `WofSqlitePlaceLookup` satisfies the
28
- * generic `ResolverBackend` contract without an adapter shim.
25
+ * `id` is the WOF place id. It's named generically (not `wof_id`) so the shape stays structurally compatible with
26
+ * `@mailwoman/resolver`'s `ResolvedPlace` — `WOFSqlitePlaceLookup` satisfies the generic `ResolverBackend` contract
27
+ * without an adapter shim.
29
28
  *
30
- * `distanceKm` is populated only when the query carried `near` (and the place has a centroid).
31
- * Useful for downstream UIs that want to show "X km from you" alongside the result.
29
+ * `distanceKm` is populated only when the query carried `near` (and the place has a centroid). Useful for downstream
30
+ * UIs that want to show "X km from you" alongside the result.
32
31
  */
33
32
  export interface PlaceCandidate {
34
33
  id: number;
35
34
  name: string;
36
- placetype: WofPlacetype;
35
+ placetype: WOFPlacetype;
37
36
  /** ISO 3166-1 alpha-2 country code. */
38
37
  country: string;
39
38
  lat: number;
@@ -43,31 +42,28 @@ export interface PlaceCandidate {
43
42
  distanceKm?: number;
44
43
  /**
45
44
  * True when this candidate's name OR an alias EXACTLY equals the query (the exact-match tier from
46
- * {@link RankingWeights.exactMatchTiering}). Surfaced so a downstream country re-rank (#369's
47
- * postcode anchor in `resolveTree`) can pin the country without crossing the tier — see the
48
- * `exactMatch` field on `@mailwoman/core`'s `ResolvedPlace`.
45
+ * {@link RankingWeights.exactMatchTiering}). Surfaced so a downstream country re-rank (#369's postcode anchor in
46
+ * `resolveTree`) can pin the country without crossing the tier — see the `exactMatch` field on `@mailwoman/core`'s
47
+ * `ResolvedPlace`.
49
48
  */
50
49
  exactMatch?: boolean;
51
50
  /**
52
- * Population from WOF's `wof:population` property. Only present when the candidate has it on
53
- * record — WOF carries population for ~15% of localities (mostly larger ones). Absent does NOT
54
- * mean zero, just unknown.
51
+ * Population from WOF's `wof:population` property. Only present when the candidate has it on record — WOF carries
52
+ * population for ~15% of localities (mostly larger ones). Absent does NOT mean zero, just unknown.
55
53
  */
56
54
  population?: number;
57
55
  /**
58
- * Bounding box from WOF's `spr.{min,max}_{latitude,longitude}` columns. Coarse outline for the
59
- * place — a city's bbox is the city's full extent, a postcode's is roughly the postcode polygon's
60
- * envelope. Optional because not all callers ask for it; implementations are free to omit when
61
- * the underlying schema lacks the columns.
56
+ * Bounding box from WOF's `spr.{min,max}_{latitude,longitude}` columns. Coarse outline for the place — a city's bbox
57
+ * is the city's full extent, a postcode's is roughly the postcode polygon's envelope. Optional because not all
58
+ * callers ask for it; implementations are free to omit when the underlying schema lacks the columns.
62
59
  */
63
60
  bbox?: GeoBbox;
64
61
  /**
65
- * Set by the coordinate-first path when the chosen locality and the sibling postcode's containing
66
- * locality are geographically far apart — the postcode and the parsed city name disagree (a
67
- * transposed / wrong-for-the-city postcode). The candidate is still returned (the name wins for
68
- * the locality), but the flag lets callers lower confidence / surface the conflict rather than
69
- * silently mislocate. A retrieval/BM25 geocoder can't raise this — it's the falsehood-detection
70
- * differentiator.
62
+ * Set by the coordinate-first path when the chosen locality and the sibling postcode's containing locality are
63
+ * geographically far apart — the postcode and the parsed city name disagree (a transposed / wrong-for-the-city
64
+ * postcode). The candidate is still returned (the name wins for the locality), but the flag lets callers lower
65
+ * confidence / surface the conflict rather than silently mislocate. A retrieval/BM25 geocoder can't raise this — it's
66
+ * the falsehood-detection differentiator.
71
67
  */
72
68
  mismatch?: boolean;
73
69
  }
@@ -90,30 +86,29 @@ export interface GeoBbox {
90
86
  /**
91
87
  * Query against the resolver.
92
88
  *
93
- * `text` is the only required field; everything else narrows the search. When `country` and
94
- * `parentId` are both set, `parentId` wins (it's more specific).
89
+ * `text` is the only required field; everything else narrows the search. When `country` and `parentID` are both set,
90
+ * `parentID` wins (it's more specific).
95
91
  *
96
- * `near` and `bbox` are independent. `near` is a soft signal — candidates close to the point get a
97
- * ranking boost but distant candidates aren't dropped. `bbox` is a hard filter — only candidates
98
- * whose bbox intersects the query bbox are returned (uses the package-built R*Tree index when
99
- * present; if the index is missing the option is silently ignored to preserve backwards
100
- * compatibility).
92
+ * `near` and `bbox` are independent. `near` is a soft signal — candidates close to the point get a ranking boost but
93
+ * distant candidates aren't dropped. `bbox` is a hard filter — only candidates whose bbox intersects the query bbox are
94
+ * returned (uses the package-built R*Tree index when present; if the index is missing the option is silently ignored to
95
+ * preserve backwards compatibility).
101
96
  *
102
- * `near` may carry `maxDistanceKm` to escalate from a boost to a hard filter — candidates further
103
- * than that distance from the point are dropped at the SQL level via an R*Tree pre-filter.
97
+ * `near` may carry `maxDistanceKm` to escalate from a boost to a hard filter — candidates further than that distance
98
+ * from the point are dropped at the SQL level via an R*Tree pre-filter.
104
99
  */
105
100
  export interface FindPlaceQuery {
106
101
  text: string;
107
- placetype?: WofPlacetype | WofPlacetype[];
102
+ placetype?: WOFPlacetype | WOFPlacetype[];
108
103
  /** ISO 3166-1 alpha-2 — narrows to one country. */
109
104
  country?: string;
110
105
  /** WOF place id — narrows to descendants of this place. */
111
- parentId?: number;
106
+ parentID?: number;
112
107
  /**
113
- * Sibling postcode. When set on a `locality` query AND a `postcode_locality` table is present,
114
- * triggers the coordinate-first soft-score path: postcode→candidate localities are injected and
115
- * scored `0.6·S_pc + 0.3·S_name + 0.1·S_pop` against the FTS name-match set, recovering small
116
- * localities the name-match alone misses. Ignored when no postcode_locality shard is present.
108
+ * Sibling postcode. When set on a `locality` query AND a `postcode_locality` table is present, triggers the
109
+ * coordinate-first soft-score path: postcode→candidate localities are injected and scored `0.6·S_pc + 0.3·S_name +
110
+ * 0.1·S_pop` against the FTS name-match set, recovering small localities the name-match alone misses. Ignored when no
111
+ * postcode_locality shard is present.
117
112
  */
118
113
  postcode?: string;
119
114
  /** Proximity hint — candidates close to this point get a ranking boost. */
@@ -126,9 +121,9 @@ export interface FindPlaceQuery {
126
121
  limit?: number;
127
122
  }
128
123
  /**
129
- * The pull-based lookup surface. Implementations resolve a `FindPlaceQuery` to a ranked list of
130
- * `PlaceCandidate`s. The interface is async even though `node:sqlite` is sync — leaves room for
131
- * `Worker`-backed implementations later without a public API break.
124
+ * The pull-based lookup surface. Implementations resolve a `FindPlaceQuery` to a ranked list of `PlaceCandidate`s. The
125
+ * interface is async even though `node:sqlite` is sync — leaves room for `Worker`-backed implementations later without
126
+ * a public API break.
132
127
  */
133
128
  export interface PlaceLookup {
134
129
  findPlace(query: FindPlaceQuery): Promise<PlaceCandidate[]>;