mailwoman 4.8.1 → 4.10.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.
- package/out/commands/geocode.d.ts.map +1 -1
- package/out/commands/geocode.js +25 -0
- package/out/commands/geocode.js.map +1 -1
- package/out/commands/registry.d.ts.map +1 -0
- package/out/commands/registry.js +326 -0
- package/out/commands/registry.js.map +1 -0
- package/out/default-placer.d.ts.map +1 -0
- package/out/default-placer.js +47 -0
- package/out/default-placer.js.map +1 -0
- package/out/geocode-core.d.ts.map +1 -1
- package/out/geocode-core.js +28 -5
- package/out/geocode-core.js.map +1 -1
- package/out/region-recognition.d.ts.map +1 -0
- package/out/region-recognition.js +192 -0
- package/out/region-recognition.js.map +1 -0
- package/out/runtime-pipeline.d.ts.map +1 -1
- package/out/runtime-pipeline.js +19 -1
- package/out/runtime-pipeline.js.map +1 -1
- package/package.json +11 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geocode.d.ts","sourceRoot":"","sources":["../../commands/geocode.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;
|
|
1
|
+
{"version":3,"file":"geocode.d.ts","sourceRoot":"","sources":["../../commands/geocode.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AASH,OAAO,GAAG,MAAM,KAAK,CAAA;AAGrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAOrD,QAAA,MAAM,eAAe,6BAA4E,CAAA;AACjG,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,aAAa,IAAI,OAAO,EAAE,CAAA;AAE5D,QAAA,MAAM,aAAa;;;;;;;;;;;;;;qBAwEjB,CAAA;AAiIF,QAAA,MAAM,cAAc,EAAE,gBAAgB,CAAC,OAAO,aAAa,EAAE,OAAO,eAAe,CAgClF,CAAA;AAED,eAAe,cAAc,CAAA"}
|
package/out/commands/geocode.js
CHANGED
|
@@ -27,6 +27,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
27
27
|
* - 1 bad arguments, missing required DB, or fatal parse/resolve error
|
|
28
28
|
*/
|
|
29
29
|
import { Spinner } from "@inkjs/ui";
|
|
30
|
+
import { CoarsePlacer } from "@mailwoman/core/coarse-placer";
|
|
30
31
|
import { createWofResolver } from "@mailwoman/core/resolver";
|
|
31
32
|
import { NeuralAddressClassifier } from "@mailwoman/neural";
|
|
32
33
|
import { Text } from "ink";
|
|
@@ -81,6 +82,19 @@ const OptionsSchema = zod.object({
|
|
|
81
82
|
"The raw half-segment radius covers only ~72% of true errors. Default (unset): the per-region " +
|
|
82
83
|
"table (#584) selects by parsed region — 1.44 (DC) … 3.12 (AZ), 1.95 for unmeasured states — " +
|
|
83
84
|
"for a ~90% bound. Pass an explicit number to force a single multiplier everywhere (1 = raw)."),
|
|
85
|
+
placeCountry: zod
|
|
86
|
+
.boolean()
|
|
87
|
+
.optional()
|
|
88
|
+
.default(true)
|
|
89
|
+
.describe("The #244 coarse-placer soft country prior (open-set rule). A confident whole-string country guess biases " +
|
|
90
|
+
"the resolver's locality/region ranking toward the right country (never filters); most useful when no " +
|
|
91
|
+
"--default-country / locale pins it. ON by default after the M2 misroute gate (0 misroutes); pass " +
|
|
92
|
+
"--no-place-country to disable."),
|
|
93
|
+
placeCountryThreshold: zod
|
|
94
|
+
.number()
|
|
95
|
+
.optional()
|
|
96
|
+
.default(0.9)
|
|
97
|
+
.describe("Abstention threshold for --place-country: below this calibrated confidence the prior is skipped. Default 0.9."),
|
|
84
98
|
format: zod
|
|
85
99
|
.enum(["json", "text"])
|
|
86
100
|
.optional()
|
|
@@ -137,6 +151,15 @@ async function runGeocode(input, options) {
|
|
|
137
151
|
return { addressPoints: explicitAp ?? base.addressPoints, interpolation: explicitIp ?? base.interpolation };
|
|
138
152
|
}
|
|
139
153
|
: shardProvider.for;
|
|
154
|
+
// Coarse-placer soft country prior (#244) — opt-in. Loads the int8 model bundled in @mailwoman/core
|
|
155
|
+
// at the requested abstention threshold; a confident in-map guess feeds the resolver's anchorPosterior.
|
|
156
|
+
// The M2 open-set reject rule (reject on in-map MASS 1-P(OTHER), route on the in-map argmax) lifts in-map
|
|
157
|
+
// right-country 85.3→91.2% with 0 regressions / 0 misroutes (the pipeline + misroute gates), so it's ON
|
|
158
|
+
// by default. --no-place-country disables it (passes `false`); a custom --place-country-threshold builds
|
|
159
|
+
// an explicit placer instead of the default-on bundled one.
|
|
160
|
+
const placer = options.placeCountry
|
|
161
|
+
? await CoarsePlacer.fromBundled({ abstainBelow: options.placeCountryThreshold, openSet: true })
|
|
162
|
+
: undefined;
|
|
140
163
|
try {
|
|
141
164
|
const resolver = createWofResolver(lookup);
|
|
142
165
|
const result = await geocodeAddress(input, {
|
|
@@ -146,6 +169,8 @@ async function runGeocode(input, options) {
|
|
|
146
169
|
defaultCountry: resolverDefaultCountry(options) || undefined,
|
|
147
170
|
// Explicit --interp-calibration forces a single multiplier; unset → the per-region table (#584).
|
|
148
171
|
interpCalibration: options.interpCalibration ?? INTERP_RADIUS_CALIBRATION,
|
|
172
|
+
// Enabled → our threshold-honoring placer; --no-place-country → `false` (disable the default-on prior).
|
|
173
|
+
placeCountry: placer ? (t) => placer.predict(t) : false,
|
|
149
174
|
});
|
|
150
175
|
return options.format === "text" ? formatText(result) : JSON.stringify(result, null, 2);
|
|
151
176
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geocode.js","sourceRoot":"","sources":["../../commands/geocode.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"geocode.js","sourceRoot":"","sources":["../../commands/geocode.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../commands/registry.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,OAAO,EAQN,KAAK,aAAa,EAGlB,MAAM,qBAAqB,CAAA;AAK5B,OAAO,GAAG,MAAM,KAAK,CAAA;AAGrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAOrD,QAAA,MAAM,eAAe,8CAG+E,CAAA;AAEpG,QAAA,MAAM,aAAa;;;;;;;;;;;;;;qBAuEjB,CAAA;AAEF,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,aAAa,IAAI,OAAO,EAAE,CAAA;AAM5D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,aAO7B,CAAA;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,IAAI,GAAE,aAA+B,GACnC,aAAa,CAWf;AAiED;;;GAGG;AACH,UAAU,eAAe;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;IAC3B,OAAO,EAAE,aAAa,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;iBACgB;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACd;AAED,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,EAAE,CAY7D;AAmGD,QAAA,MAAM,eAAe,EAAE,gBAAgB,CAAC,OAAO,aAAa,EAAE,OAAO,eAAe,CAuCnF,CAAA;AAED,eAAe,eAAe,CAAA"}
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* @copyright Sister Software
|
|
4
|
+
* @license AGPL-3.0
|
|
5
|
+
* @author Teffen Ellis, et al.
|
|
6
|
+
*
|
|
7
|
+
* `mailwoman registry <csv>` — the geocode-first record matcher, end to end (#613).
|
|
8
|
+
*
|
|
9
|
+
* This is the integration that runs `@mailwoman/registry`'s cascade on real data: it constructs the
|
|
10
|
+
* heavy geocoder (neural parser + WOF resolver + per-state situs/interp shards — the same wiring
|
|
11
|
+
* as `geocode`) and injects it into the matcher's `GeocodeAddress` seam, so the registry package
|
|
12
|
+
* itself never imports the runtime. Then:
|
|
13
|
+
*
|
|
14
|
+
* CSV → ingest (column-map + normalize) → geocode (the seam) → resolveEntities (block →
|
|
15
|
+
* Fellegi-Sunter score, EM-trained label-free → cluster) → GeoJSON.
|
|
16
|
+
*
|
|
17
|
+
* The thesis it grades: two rows reading `123 Main St` and `123 Main Street Apt 2` — different
|
|
18
|
+
* strings — collapse to one entity because they resolve to the same place. Blocking is
|
|
19
|
+
* geographic, not textual. Needs the weights + shards in hand, so the real run is
|
|
20
|
+
* operator-verifiable (not CI).
|
|
21
|
+
*/
|
|
22
|
+
import { Spinner } from "@inkjs/ui";
|
|
23
|
+
import { decodeAsJson } from "@mailwoman/core/decoder";
|
|
24
|
+
import { createWofResolver } from "@mailwoman/core/resolver";
|
|
25
|
+
import { NeuralAddressClassifier } from "@mailwoman/neural";
|
|
26
|
+
import { geocodeAddressVia, inferMapping, ingestRows, parseCsv, resolveEntities, streamRows, toGeoJSON, } from "@mailwoman/registry";
|
|
27
|
+
import { Text } from "ink";
|
|
28
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
29
|
+
import { setImmediate } from "node:timers/promises";
|
|
30
|
+
import { useEffect, useState } from "react";
|
|
31
|
+
import zod from "zod";
|
|
32
|
+
import { geocodeAddress, ShardProvider } from "../geocode-core.js";
|
|
33
|
+
import { INTERP_RADIUS_CALIBRATION } from "../interp-calibration.js";
|
|
34
|
+
import { resolverDefaultCountry } from "./parse.js";
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// CLI contract — args + options
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
const ArgumentsSchema = zod
|
|
39
|
+
.array(zod.string().describe("Path to a CSV file of contact / organization records"))
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("CSV path(s). Optional when --sources is given (multi-source mode supplies the inputs).");
|
|
42
|
+
const OptionsSchema = zod.object({
|
|
43
|
+
mapping: zod
|
|
44
|
+
.string()
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("Column mapping: a path to a JSON file (or inline JSON) of { id?, source?, name?, organization?, address?, " +
|
|
47
|
+
"phone?, email? }, where each field names the CSV column(s) to draw from. Merged over the base (the built-in " +
|
|
48
|
+
"default, or --infer-mapping's inference); column names are matched case-sensitively."),
|
|
49
|
+
inferMapping: zod
|
|
50
|
+
.boolean()
|
|
51
|
+
.optional()
|
|
52
|
+
.default(false)
|
|
53
|
+
.describe("Infer the column mapping from the header by keyword (best-effort — point it at any reasonably-named CSV). " +
|
|
54
|
+
"Used as the base instead of the built-in default; an explicit --mapping still merges on top. Single-CSV mode."),
|
|
55
|
+
sources: zod
|
|
56
|
+
.string()
|
|
57
|
+
.optional()
|
|
58
|
+
.describe("Multi-source mode: a path to a JSON file (or inline JSON) of [{ path, delimiter?, mapping, source?, limit? }] " +
|
|
59
|
+
"— each dataset gets its own column mapping + provenance label, all resolved into ONE entity set across " +
|
|
60
|
+
"sources with no shared key. An entity spanning ≥2 sources is a cross-dataset link. The positional CSV is " +
|
|
61
|
+
"ignored when --sources is set. Inputs are streamed as UNQUOTED delimited files (tab inferred from .tsv) — " +
|
|
62
|
+
"right for the big government TSVs; convert a quoted CSV first or use the single-CSV path for those."),
|
|
63
|
+
out: zod.string().optional().describe("Write the GeoJSON FeatureCollection here. Default: print to stdout."),
|
|
64
|
+
trainEm: zod
|
|
65
|
+
.boolean()
|
|
66
|
+
.optional()
|
|
67
|
+
.default(true)
|
|
68
|
+
.describe("Fit the Fellegi-Sunter m/u + prior to the data with EM (label-free) before scoring. --no-train-em uses the seeds."),
|
|
69
|
+
threshold: zod
|
|
70
|
+
.number()
|
|
71
|
+
.optional()
|
|
72
|
+
.default(0)
|
|
73
|
+
.describe("Link two records into one entity at or above this match weight (bits). Higher = stricter. Default 0."),
|
|
74
|
+
maxBlockSize: zod
|
|
75
|
+
.number()
|
|
76
|
+
.optional()
|
|
77
|
+
.describe("Skip + report blocks larger than this rather than scanning them (recall vs cost). Default: scan all."),
|
|
78
|
+
source: zod.string().optional().describe("A provenance label stamped on every record (e.g. the dataset name)."),
|
|
79
|
+
locale: zod
|
|
80
|
+
.string()
|
|
81
|
+
.regex(/^[a-z]{2}(-[A-Z]{2})?$/u, "Expected a BCP-47 tag like en-US or fr-FR")
|
|
82
|
+
.optional()
|
|
83
|
+
.default("en-US")
|
|
84
|
+
.describe("Locale tag matching an installed weights package. Default en-US."),
|
|
85
|
+
defaultCountry: zod
|
|
86
|
+
.string()
|
|
87
|
+
.optional()
|
|
88
|
+
.describe("ISO-3166 country to scope the resolver. Defaults from --locale's region subtag (en-US → US)."),
|
|
89
|
+
placeCountry: zod
|
|
90
|
+
.boolean()
|
|
91
|
+
.optional()
|
|
92
|
+
.default(true)
|
|
93
|
+
.describe("The #244 coarse-placer soft country prior (on by default). --no-place-country disables it."),
|
|
94
|
+
resolveDb: zod
|
|
95
|
+
.string()
|
|
96
|
+
.optional()
|
|
97
|
+
.describe("Path to a WOF admin SQLite distribution. Defaults to $MAILWOMAN_WOF_DB; errors if neither is set."),
|
|
98
|
+
dataRoot: zod
|
|
99
|
+
.string()
|
|
100
|
+
.optional()
|
|
101
|
+
.default("/mnt/playpen/mailwoman-data")
|
|
102
|
+
.describe("Root directory for per-state address-point + interpolation shards. Default: /mnt/playpen/mailwoman-data."),
|
|
103
|
+
});
|
|
104
|
+
export { ArgumentsSchema as args, OptionsSchema as options };
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
// Column mapping
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
/**
|
|
109
|
+
* Built-in best-effort mapping for tidy contact/org CSVs. Multi-column fields are joined (so a CSV
|
|
110
|
+
* that splits the address across columns composes one string). Real datasets with bespoke headers
|
|
111
|
+
* (e.g. NPPES "Provider First Line Business Practice Location Address") pass an explicit --mapping;
|
|
112
|
+
* inferring it from the header is the #603 fast-follow.
|
|
113
|
+
*/
|
|
114
|
+
export const DEFAULT_MAPPING = {
|
|
115
|
+
id: "id",
|
|
116
|
+
name: ["name", "full_name", "first_name", "last_name"],
|
|
117
|
+
organization: ["organization", "org", "company"],
|
|
118
|
+
address: ["address", "address1", "street", "city", "state", "zip", "postal_code"],
|
|
119
|
+
phone: "phone",
|
|
120
|
+
email: "email",
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Resolve --mapping (a file path or inline JSON) and merge it over `base` (default
|
|
124
|
+
* {@link DEFAULT_MAPPING}).
|
|
125
|
+
*/
|
|
126
|
+
export function loadMapping(option, source, base = DEFAULT_MAPPING) {
|
|
127
|
+
let provided = {};
|
|
128
|
+
if (option) {
|
|
129
|
+
const text = option.trim().startsWith("{") ? option : readFileSync(option, "utf8");
|
|
130
|
+
try {
|
|
131
|
+
provided = JSON.parse(text);
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
throw new Error(`--mapping is neither a readable file nor valid JSON: ${err.message}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return { ...base, ...provided, ...(source ? { source } : {}) };
|
|
138
|
+
}
|
|
139
|
+
function resolveWofPath(options) {
|
|
140
|
+
const path = options.resolveDb ?? process.env["MAILWOMAN_WOF_DB"];
|
|
141
|
+
if (!path) {
|
|
142
|
+
throw new Error("registry needs a WOF admin SQLite path. Set $MAILWOMAN_WOF_DB or pass --resolve-db <path>.");
|
|
143
|
+
}
|
|
144
|
+
return path;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Construct the heavy geocoder once (neural parser + WOF resolver + per-state shards) and wire it
|
|
148
|
+
* into the matcher's {@link GeocodeAddress} seam. Returns the seam plus a `close` to release the DB
|
|
149
|
+
* handles. Shared by the single-CSV and multi-source paths.
|
|
150
|
+
*/
|
|
151
|
+
async function buildGeocoder(options) {
|
|
152
|
+
const wofPath = resolveWofPath(options);
|
|
153
|
+
let classifier;
|
|
154
|
+
try {
|
|
155
|
+
classifier = await NeuralAddressClassifier.loadFromWeights({ locale: options.locale });
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
throw new Error("registry requires the neural weights. Install @mailwoman/neural-weights-en-us (or a --locale match).");
|
|
159
|
+
}
|
|
160
|
+
let mod;
|
|
161
|
+
try {
|
|
162
|
+
mod = await import("@mailwoman/resolver-wof-sqlite");
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
throw new Error("registry requires `@mailwoman/resolver-wof-sqlite` to be installed.");
|
|
166
|
+
}
|
|
167
|
+
const lookup = new mod.WofSqlitePlaceLookup({ databasePath: wofPath });
|
|
168
|
+
const shardProvider = new ShardProvider(mod, options.dataRoot);
|
|
169
|
+
const shards = shardProvider.for;
|
|
170
|
+
const defaultCountry = resolverDefaultCountry(options) || undefined;
|
|
171
|
+
const resolver = createWofResolver(lookup);
|
|
172
|
+
const seam = geocodeAddressVia({
|
|
173
|
+
parse: async (raw) => decodeAsJson(await classifier.parse(raw, { postcodeRepair: true })),
|
|
174
|
+
geocode: (raw) => geocodeAddress(raw, {
|
|
175
|
+
classifier,
|
|
176
|
+
resolver,
|
|
177
|
+
shards,
|
|
178
|
+
defaultCountry,
|
|
179
|
+
interpCalibration: INTERP_RADIUS_CALIBRATION,
|
|
180
|
+
...(options.placeCountry ? {} : { placeCountry: false }),
|
|
181
|
+
}),
|
|
182
|
+
country: defaultCountry,
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
seam,
|
|
186
|
+
close: () => {
|
|
187
|
+
shardProvider.close();
|
|
188
|
+
lookup.close();
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/** Parse `--sources` (a file path or inline JSON) into specs. */
|
|
193
|
+
export function loadSources(option) {
|
|
194
|
+
const text = /^[[{]/.test(option.trim()) ? option : readFileSync(option, "utf8");
|
|
195
|
+
let parsed;
|
|
196
|
+
try {
|
|
197
|
+
parsed = JSON.parse(text);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
throw new Error(`--sources is neither a readable file nor valid JSON: ${err.message}`);
|
|
201
|
+
}
|
|
202
|
+
if (!Array.isArray(parsed) || parsed.some((s) => !s || typeof s.path !== "string")) {
|
|
203
|
+
throw new Error("--sources must be a JSON array of { path, mapping, source?, delimiter?, limit? }.");
|
|
204
|
+
}
|
|
205
|
+
return parsed;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Multi-source mode (#618): stream each dataset under its own mapping + provenance label into ONE
|
|
209
|
+
* combined record set, geocode, resolve, and report the entities that span ≥2 sources — the
|
|
210
|
+
* cross-dataset links. No shared key required; geography is the join.
|
|
211
|
+
*/
|
|
212
|
+
async function runMultiSource(specs, options) {
|
|
213
|
+
const { seam, close } = await buildGeocoder(options);
|
|
214
|
+
try {
|
|
215
|
+
const records = [];
|
|
216
|
+
const perSource = [];
|
|
217
|
+
for (const spec of specs) {
|
|
218
|
+
const label = spec.source ?? spec.path;
|
|
219
|
+
const mapping = { ...spec.mapping, source: label };
|
|
220
|
+
let read = 0;
|
|
221
|
+
const rows = (async function* () {
|
|
222
|
+
for await (const row of streamRows(spec.path, spec.delimiter ? { delimiter: spec.delimiter } : {})) {
|
|
223
|
+
if (spec.limit !== undefined && read >= spec.limit)
|
|
224
|
+
break;
|
|
225
|
+
read++;
|
|
226
|
+
yield row;
|
|
227
|
+
}
|
|
228
|
+
})();
|
|
229
|
+
const recs = await ingestRows(rows, mapping, { geocodeAddress: seam });
|
|
230
|
+
for (const record of recs)
|
|
231
|
+
record.id = `${label}:${record.id}`; // namespace ids so cross-source ids never collide
|
|
232
|
+
records.push(...recs);
|
|
233
|
+
perSource.push(`${label} ${recs.length}`);
|
|
234
|
+
}
|
|
235
|
+
// learnedScorer:false — multi-source is CROSS-dataset link discovery (recall-oriented): the same
|
|
236
|
+
// facility under different operational names across sources is the signal we want. The default GBT is
|
|
237
|
+
// dedup-calibrated and rejects exactly that (it learned "same place + name drift = distinct"), so the
|
|
238
|
+
// cross-dataset path uses the FS spine. (Single-CSV dedup below keeps the GBT default.)
|
|
239
|
+
const result = resolveEntities(records, {
|
|
240
|
+
trainEM: options.trainEm,
|
|
241
|
+
threshold: options.threshold,
|
|
242
|
+
learnedScorer: false,
|
|
243
|
+
...(options.maxBlockSize !== undefined ? { maxBlockSize: options.maxBlockSize } : {}),
|
|
244
|
+
});
|
|
245
|
+
const geojson = toGeoJSON(result.entities);
|
|
246
|
+
const crossSource = result.entities.filter((e) => new Set(e.records.map((r) => r.source).filter(Boolean)).size >= 2).length;
|
|
247
|
+
const geocoded = records.filter((r) => r.address?.geocode).length;
|
|
248
|
+
const summary = `registry --sources: ${specs.length} sources (${perSource.join(", ")}) → ${records.length} records ` +
|
|
249
|
+
`(${geocoded} geocoded) → ${result.entities.length} entities; ${crossSource} span ≥2 sources (cross-dataset links)`;
|
|
250
|
+
if (options.out) {
|
|
251
|
+
writeFileSync(options.out, JSON.stringify(geojson, null, 2));
|
|
252
|
+
return `${summary}\nwrote ${geojson.features.length} features → ${options.out}`;
|
|
253
|
+
}
|
|
254
|
+
return JSON.stringify(geojson, null, 2);
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
close();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
// Core
|
|
262
|
+
// ---------------------------------------------------------------------------
|
|
263
|
+
async function runRegistry(csvPath, options) {
|
|
264
|
+
const rows = parseCsv(readFileSync(csvPath, "utf8"));
|
|
265
|
+
// --infer-mapping reads the header (the first row's keys) and guesses the mapping; an explicit --mapping
|
|
266
|
+
// still merges on top of it. Otherwise the base is the built-in default.
|
|
267
|
+
const base = options.inferMapping && rows[0] ? inferMapping(Object.keys(rows[0])) : DEFAULT_MAPPING;
|
|
268
|
+
const mapping = loadMapping(options.mapping, options.source, base);
|
|
269
|
+
const { seam, close } = await buildGeocoder(options);
|
|
270
|
+
try {
|
|
271
|
+
const records = await ingestRows(rows, mapping, { geocodeAddress: seam });
|
|
272
|
+
const result = resolveEntities(records, {
|
|
273
|
+
trainEM: options.trainEm,
|
|
274
|
+
threshold: options.threshold,
|
|
275
|
+
...(options.maxBlockSize !== undefined ? { maxBlockSize: options.maxBlockSize } : {}),
|
|
276
|
+
});
|
|
277
|
+
const geojson = toGeoJSON(result.entities);
|
|
278
|
+
const geocoded = records.filter((r) => r.address?.geocode).length;
|
|
279
|
+
const summary = `registry: ${rows.length} rows → ${records.length} records (${geocoded} geocoded) → ` +
|
|
280
|
+
`${result.entities.length} entities ` +
|
|
281
|
+
`(${result.candidatePairs} candidate pairs${result.droppedBlocks.length ? `, ${result.droppedBlocks.length} oversized blocks skipped` : ""})`;
|
|
282
|
+
if (options.out) {
|
|
283
|
+
writeFileSync(options.out, JSON.stringify(geojson, null, 2));
|
|
284
|
+
return `${summary}\nwrote ${geojson.features.length} features → ${options.out}`;
|
|
285
|
+
}
|
|
286
|
+
return JSON.stringify(geojson, null, 2);
|
|
287
|
+
}
|
|
288
|
+
finally {
|
|
289
|
+
close();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// ---------------------------------------------------------------------------
|
|
293
|
+
// React command component
|
|
294
|
+
// ---------------------------------------------------------------------------
|
|
295
|
+
const RegistryCommand = ({ args, options }) => {
|
|
296
|
+
const [output, setOutput] = useState();
|
|
297
|
+
const [error, setError] = useState();
|
|
298
|
+
useEffect(() => {
|
|
299
|
+
if (error) {
|
|
300
|
+
setImmediate().then(() => process.exit(1));
|
|
301
|
+
}
|
|
302
|
+
}, [error]);
|
|
303
|
+
useEffect(() => {
|
|
304
|
+
// `loadSources` can throw on a malformed config — wrap so its error routes to the same handler.
|
|
305
|
+
const task = options.sources
|
|
306
|
+
? Promise.resolve().then(() => runMultiSource(loadSources(options.sources), options))
|
|
307
|
+
: (() => {
|
|
308
|
+
const csv = args?.[0];
|
|
309
|
+
if (!csv || csv.trim().length === 0) {
|
|
310
|
+
return Promise.reject(new Error("registry requires a positional CSV path (or --sources <config.json> for multi-source). " +
|
|
311
|
+
"e.g. mailwoman registry contacts.csv --out entities.geojson"));
|
|
312
|
+
}
|
|
313
|
+
return runRegistry(csv.trim(), options);
|
|
314
|
+
})();
|
|
315
|
+
task.then(setOutput).catch((err) => setError(err.message));
|
|
316
|
+
}, [args, options]);
|
|
317
|
+
if (error) {
|
|
318
|
+
return _jsx(Text, { color: "red", children: error });
|
|
319
|
+
}
|
|
320
|
+
if (!output) {
|
|
321
|
+
return _jsx(Spinner, {});
|
|
322
|
+
}
|
|
323
|
+
return _jsx(Text, { children: output });
|
|
324
|
+
};
|
|
325
|
+
export default RegistryCommand;
|
|
326
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../commands/registry.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-placer.d.ts","sourceRoot":"","sources":["../default-placer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,uGAAuG;AACvG,MAAM,MAAM,cAAc,GAAG,CAAC,cAAc,EAAE,MAAM,KAAK;IACxD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,kGAAkG;IAClG,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC,CAAA;AAOD;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAmBxE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The default coarse-placer (#244) for the user-facing geocoding surfaces. As of the M2 misrouting
|
|
7
|
+
* gate (0 misroutes across 2 000 in-map addresses, 10 countries — see
|
|
8
|
+
* docs/articles/evals/2026-06-14-coarse-placer-inmap-misroute.md) the soft country prior runs
|
|
9
|
+
* **on by default**: `geocodeAddress` and `createRuntimePipeline` load THIS bundled placer unless
|
|
10
|
+
* the caller passes their own `placeCountry` or opts out with `placeCountry: false`.
|
|
11
|
+
*
|
|
12
|
+
* Loaded LAZILY + cached once per process: the int8 model is ~0.79 MB and `predict` is
|
|
13
|
+
* microseconds, but the bundled-artifact read is async, so callers `await` it the first time and
|
|
14
|
+
* reuse the cached promise after. Returns `null` (no prior, graceful) when the bundled model
|
|
15
|
+
* can't be resolved — a stripped-down install, a missing `data/` dir — so a default-on consumer
|
|
16
|
+
* degrades to plain resolution instead of throwing.
|
|
17
|
+
*/
|
|
18
|
+
// Abstention threshold for the default prior — the open-set rule's flat-optimum operating point (#244 M2).
|
|
19
|
+
const DEFAULT_ABSTAIN_BELOW = 0.9;
|
|
20
|
+
let cached = null;
|
|
21
|
+
/**
|
|
22
|
+
* Lazy-load + cache the coarse-placer bundled in `@mailwoman/core` as a place-country fn (the M2
|
|
23
|
+
* open-set rule at the 0.9 operating point). The result is cached for the process; `null` means the
|
|
24
|
+
* model couldn't be loaded and the caller should proceed with no prior.
|
|
25
|
+
*/
|
|
26
|
+
export function loadDefaultPlaceCountry() {
|
|
27
|
+
if (!cached) {
|
|
28
|
+
cached = (async () => {
|
|
29
|
+
try {
|
|
30
|
+
const { CoarsePlacer, inMapPosterior } = await import("@mailwoman/core/coarse-placer");
|
|
31
|
+
const placer = await CoarsePlacer.fromBundled({ abstainBelow: DEFAULT_ABSTAIN_BELOW, openSet: true });
|
|
32
|
+
return (text) => {
|
|
33
|
+
const p = placer.predict(text);
|
|
34
|
+
// Hand the resolver the full in-map distribution (#244 residual): it boosts every plausible
|
|
35
|
+
// country and breaks ambiguous ties with its own evidence, instead of the lossy one-hot argmax.
|
|
36
|
+
const posterior = inMapPosterior(p);
|
|
37
|
+
return { country: p.country, confidence: p.confidence, ...(posterior ? { posterior } : {}) };
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
})();
|
|
44
|
+
}
|
|
45
|
+
return cached;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=default-placer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-placer.js","sourceRoot":"","sources":["../default-placer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAUH,2GAA2G;AAC3G,MAAM,qBAAqB,GAAG,GAAG,CAAA;AAEjC,IAAI,MAAM,GAA0C,IAAI,CAAA;AAExD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,GAAG,CAAC,KAAK,IAAoC,EAAE;YACpD,IAAI,CAAC;gBACJ,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAA;gBACtF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,EAAE,YAAY,EAAE,qBAAqB,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;gBACrG,OAAO,CAAC,IAAY,EAAE,EAAE;oBACvB,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;oBAC9B,4FAA4F;oBAC5F,gGAAgG;oBAChG,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;oBACnC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;gBAC7F,CAAC,CAAA;YACF,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,IAAI,CAAA;YACZ,CAAC;QACF,CAAC,CAAC,EAAE,CAAA;IACL,CAAC;IACD,OAAO,MAAM,CAAA;AACd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geocode-core.d.ts","sourceRoot":"","sources":["../geocode-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAe,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAG9G,OAAO,EAAE,KAAK,mBAAmB,EAAyC,MAAM,mBAAmB,CAAA;AACnG,OAAO,EAAE,KAAK,sBAAsB,
|
|
1
|
+
{"version":3,"file":"geocode-core.d.ts","sourceRoot":"","sources":["../geocode-core.ts"],"names":[],"mappings":"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"}
|
package/out/geocode-core.js
CHANGED
|
@@ -23,7 +23,14 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import { existsSync } from "node:fs";
|
|
25
25
|
import { readReleaseManifest, resolveShardPath } from "./data-release.js";
|
|
26
|
+
import { loadDefaultPlaceCountry } from "./default-placer.js";
|
|
26
27
|
import { interpCalibrationForRegion } from "./interp-calibration.js";
|
|
28
|
+
import { recognizeUsRegions } from "./region-recognition.js";
|
|
29
|
+
/**
|
|
30
|
+
* Anchor weight for the coarse-placer's country prior. Matches the runtime-pipeline default — a
|
|
31
|
+
* whole-string country guess is broader/softer than a postcode anchor (2.0), so it blends gently.
|
|
32
|
+
*/
|
|
33
|
+
const COARSE_PLACER_ANCHOR_WEIGHT = 1.0;
|
|
27
34
|
/** Lowercase 2-letter state slug from a parsed region value / resolver name, else null. */
|
|
28
35
|
export function regionToStateSlug(regionValue, resolverName) {
|
|
29
36
|
for (const candidate of [regionValue, resolverName]) {
|
|
@@ -35,8 +42,10 @@ export function regionToStateSlug(regionValue, resolverName) {
|
|
|
35
42
|
}
|
|
36
43
|
return null;
|
|
37
44
|
}
|
|
38
|
-
/**
|
|
39
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Walk a (parsed or resolved) tree for its region → the per-state shard slug (e.g. `"tx"`), else
|
|
47
|
+
* null.
|
|
48
|
+
*/
|
|
40
49
|
export function regionSlugFromTree(tree) {
|
|
41
50
|
let regionValue = null;
|
|
42
51
|
let regionResolverName = null;
|
|
@@ -51,8 +60,10 @@ export function regionSlugFromTree(tree) {
|
|
|
51
60
|
}
|
|
52
61
|
return regionToStateSlug(regionValue, regionResolverName);
|
|
53
62
|
}
|
|
54
|
-
/**
|
|
55
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Per-state situs shard path under `<dataRoot>/address-points/`, or null if the slug/file is
|
|
65
|
+
* absent.
|
|
66
|
+
*/
|
|
56
67
|
export function selectAddressPointsDb(dataRoot, stateSlug) {
|
|
57
68
|
if (!stateSlug)
|
|
58
69
|
return null;
|
|
@@ -147,12 +158,24 @@ export class ShardProvider {
|
|
|
147
158
|
* parse/resolve error — callers doing batch work should catch per-row.
|
|
148
159
|
*/
|
|
149
160
|
export async function geocodeAddress(input, deps) {
|
|
150
|
-
const tree = await deps.classifier.parse(input, { postcodeRepair: true });
|
|
161
|
+
const tree = recognizeUsRegions(await deps.classifier.parse(input, { postcodeRepair: true }));
|
|
151
162
|
const stateSlug = regionSlugFromTree(tree);
|
|
152
163
|
const { addressPoints, interpolation } = deps.shards?.(stateSlug) ?? {};
|
|
153
164
|
const opts = {};
|
|
154
165
|
if (deps.defaultCountry)
|
|
155
166
|
opts.defaultCountry = deps.defaultCountry;
|
|
167
|
+
// Coarse country router (#244, soft prior) — DEFAULT-ON (#244 M2). undefined → the bundled placer;
|
|
168
|
+
// a function → that placer; false → disabled. A confident in-map guess feeds the resolver's
|
|
169
|
+
// anchorPosterior re-rank; abstain/OTHER are no-ops and an explicit defaultCountry isn't disturbed.
|
|
170
|
+
const placeCountry = deps.placeCountry === false ? null : (deps.placeCountry ?? (await loadDefaultPlaceCountry()));
|
|
171
|
+
if (placeCountry) {
|
|
172
|
+
const placed = placeCountry(input);
|
|
173
|
+
if (placed.country && placed.country !== "OTHER" && !opts.anchorPosterior) {
|
|
174
|
+
// The full in-map distribution when supplied (resolver breaks ties); else the one-hot argmax.
|
|
175
|
+
opts.anchorPosterior = placed.posterior ?? { [placed.country]: placed.confidence };
|
|
176
|
+
opts.anchorWeight = COARSE_PLACER_ANCHOR_WEIGHT;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
156
179
|
if (addressPoints)
|
|
157
180
|
opts.addressPoints = addressPoints;
|
|
158
181
|
if (interpolation) {
|
package/out/geocode-core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geocode-core.js","sourceRoot":"","sources":["../geocode-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,EAA4B,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACnG,OAAO,EAA+B,
|
|
1
|
+
{"version":3,"file":"geocode-core.js","sourceRoot":"","sources":["../geocode-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"region-recognition.d.ts","sourceRoot":"","sources":["../region-recognition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAe,WAAW,EAAgB,MAAM,yBAAyB,CAAA;AA2DrF;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMxD;AAuFD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,CAGjE"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* US region recognition (#642) — a rule-based parse-tree correction for the case the neural parser
|
|
7
|
+
* under-handles: a postcode-less "City, State" string. Without a postcode/street anchor the model
|
|
8
|
+
* mis-tags the state — it labels "Texas" a `locality` ("Dublin, Texas" → two localities), or
|
|
9
|
+
* merges the whole string into one locality ("Dublin, TX" / "Athens, Texas"). With no `region`
|
|
10
|
+
* node, the resolver can't scope the locality to its state, so "Dublin, Texas" resolves to the
|
|
11
|
+
* more-populous Dublin, OHIO (the #619 admin-tier >1000 km tail).
|
|
12
|
+
*
|
|
13
|
+
* This is a legitimate atlas/conventions correction: the US states are a CLOSED, known gazetteer,
|
|
14
|
+
* so we can confidently re-tag a state token the grammar missed. It restructures the affected
|
|
15
|
+
* nodes into `region → locality` NESTING, which the resolver's existing parent-scoping then
|
|
16
|
+
* constrains correctly (no resolver change). Two shapes are handled:
|
|
17
|
+
*
|
|
18
|
+
* - A `locality` whose WHOLE value is a US state → it becomes a `region`, and sibling `locality`
|
|
19
|
+
* (city) nodes are nested under it;
|
|
20
|
+
* - A `locality` whose value is a merged `"City, ST"` → split into `region(ST) → locality(City)`.
|
|
21
|
+
*
|
|
22
|
+
* US-scoped by design (the gazetteer is US states). The principled long-term fix is the model
|
|
23
|
+
* recognizing the region; this closes the gap for the bare-`City, State` class today.
|
|
24
|
+
*/
|
|
25
|
+
/** Canonical 2-letter slug for a US state/territory NAME or 2-letter abbreviation, else null. */
|
|
26
|
+
const STATE_NAME_TO_SLUG = {
|
|
27
|
+
alabama: "al",
|
|
28
|
+
alaska: "ak",
|
|
29
|
+
arizona: "az",
|
|
30
|
+
arkansas: "ar",
|
|
31
|
+
california: "ca",
|
|
32
|
+
colorado: "co",
|
|
33
|
+
connecticut: "ct",
|
|
34
|
+
delaware: "de",
|
|
35
|
+
"district of columbia": "dc",
|
|
36
|
+
florida: "fl",
|
|
37
|
+
georgia: "ga",
|
|
38
|
+
hawaii: "hi",
|
|
39
|
+
idaho: "id",
|
|
40
|
+
illinois: "il",
|
|
41
|
+
indiana: "in",
|
|
42
|
+
iowa: "ia",
|
|
43
|
+
kansas: "ks",
|
|
44
|
+
kentucky: "ky",
|
|
45
|
+
louisiana: "la",
|
|
46
|
+
maine: "me",
|
|
47
|
+
maryland: "md",
|
|
48
|
+
massachusetts: "ma",
|
|
49
|
+
michigan: "mi",
|
|
50
|
+
minnesota: "mn",
|
|
51
|
+
mississippi: "ms",
|
|
52
|
+
missouri: "mo",
|
|
53
|
+
montana: "mt",
|
|
54
|
+
nebraska: "ne",
|
|
55
|
+
nevada: "nv",
|
|
56
|
+
"new hampshire": "nh",
|
|
57
|
+
"new jersey": "nj",
|
|
58
|
+
"new mexico": "nm",
|
|
59
|
+
"new york": "ny",
|
|
60
|
+
"north carolina": "nc",
|
|
61
|
+
"north dakota": "nd",
|
|
62
|
+
ohio: "oh",
|
|
63
|
+
oklahoma: "ok",
|
|
64
|
+
oregon: "or",
|
|
65
|
+
pennsylvania: "pa",
|
|
66
|
+
"rhode island": "ri",
|
|
67
|
+
"south carolina": "sc",
|
|
68
|
+
"south dakota": "sd",
|
|
69
|
+
tennessee: "tn",
|
|
70
|
+
texas: "tx",
|
|
71
|
+
utah: "ut",
|
|
72
|
+
vermont: "vt",
|
|
73
|
+
virginia: "va",
|
|
74
|
+
washington: "wa",
|
|
75
|
+
"west virginia": "wv",
|
|
76
|
+
wisconsin: "wi",
|
|
77
|
+
wyoming: "wy",
|
|
78
|
+
"puerto rico": "pr",
|
|
79
|
+
};
|
|
80
|
+
const STATE_SLUGS = new Set(Object.values(STATE_NAME_TO_SLUG));
|
|
81
|
+
/**
|
|
82
|
+
* Is `value` exactly a US state — its full name (e.g. "Texas") or 2-letter abbreviation (e.g.
|
|
83
|
+
* "TX")? Returns the canonical 2-letter slug, else null. Whitespace/case-insensitive; rejects
|
|
84
|
+
* anything with extra tokens (so a city literally named after a state is only matched when it's the
|
|
85
|
+
* WHOLE value).
|
|
86
|
+
*/
|
|
87
|
+
export function usStateSlug(value) {
|
|
88
|
+
const v = value.trim().toLowerCase();
|
|
89
|
+
if (!v)
|
|
90
|
+
return null;
|
|
91
|
+
if (STATE_NAME_TO_SLUG[v])
|
|
92
|
+
return STATE_NAME_TO_SLUG[v];
|
|
93
|
+
if (/^[a-z]{2}$/.test(v) && STATE_SLUGS.has(v))
|
|
94
|
+
return v;
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
/** Build a region node covering the state token, carrying a (lightly-confident) provenance marker. */
|
|
98
|
+
function makeRegionNode(value, start, end, confidence) {
|
|
99
|
+
return {
|
|
100
|
+
tag: "region",
|
|
101
|
+
value,
|
|
102
|
+
start,
|
|
103
|
+
end,
|
|
104
|
+
confidence,
|
|
105
|
+
children: [],
|
|
106
|
+
metadata: { region_recognition: "us-state" },
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Correct one container (an array of sibling nodes — the tree roots, or a node's children) for the
|
|
111
|
+
* two mis-tag shapes, producing `region → locality` nesting. Returns the rewritten sibling list.
|
|
112
|
+
*/
|
|
113
|
+
function correctSiblings(siblings) {
|
|
114
|
+
// --- Pass 1: split a merged "City, ST" locality into region(ST) → locality(City). ---
|
|
115
|
+
const afterSplit = [];
|
|
116
|
+
for (const node of siblings) {
|
|
117
|
+
const split = node.tag === "locality" ? splitMergedCityState(node) : null;
|
|
118
|
+
afterSplit.push(split ?? node);
|
|
119
|
+
}
|
|
120
|
+
// --- Pass 2: a locality whose WHOLE value is a state becomes a region; sibling city localities
|
|
121
|
+
// nest under it. Only fires when there's exactly one state-name locality in the container (the
|
|
122
|
+
// unambiguous "City, State" shape) — avoids reparenting in a multi-locality list we don't model. ---
|
|
123
|
+
const stateIdxs = afterSplit
|
|
124
|
+
.map((n, i) => (n.tag === "locality" && usStateSlug(n.value) ? i : -1))
|
|
125
|
+
.filter((i) => i >= 0);
|
|
126
|
+
if (stateIdxs.length !== 1)
|
|
127
|
+
return afterSplit;
|
|
128
|
+
const si = stateIdxs[0];
|
|
129
|
+
const stateNode = afterSplit[si];
|
|
130
|
+
const region = makeRegionNode(stateNode.value, stateNode.start, stateNode.end, stateNode.confidence);
|
|
131
|
+
const out = [];
|
|
132
|
+
for (let i = 0; i < afterSplit.length; i++) {
|
|
133
|
+
if (i === si)
|
|
134
|
+
continue;
|
|
135
|
+
const n = afterSplit[i];
|
|
136
|
+
if (n.tag === "locality")
|
|
137
|
+
region.children.push(n); // nest sibling cities under the region
|
|
138
|
+
else
|
|
139
|
+
out.push(n);
|
|
140
|
+
}
|
|
141
|
+
// Only convert when there's a sibling city to nest — the unambiguous "City, State" shape. A LONE
|
|
142
|
+
// state-name locality ("Washington", "Florida") is genuinely a city in this context as often as a
|
|
143
|
+
// state, so leave it untouched rather than risk a mis-fire.
|
|
144
|
+
if (region.children.length === 0)
|
|
145
|
+
return afterSplit;
|
|
146
|
+
out.push(region);
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Split a `locality` whose value is `"City, ST"` (state in the LAST comma segment) into
|
|
151
|
+
* region(ST) → locality(City). Returns null when the tail isn't a US state.
|
|
152
|
+
*/
|
|
153
|
+
function splitMergedCityState(node) {
|
|
154
|
+
const comma = node.value.lastIndexOf(",");
|
|
155
|
+
if (comma < 0)
|
|
156
|
+
return null;
|
|
157
|
+
const head = node.value.slice(0, comma).trim();
|
|
158
|
+
const tail = node.value.slice(comma + 1).trim();
|
|
159
|
+
const slug = usStateSlug(tail);
|
|
160
|
+
if (!slug || !head)
|
|
161
|
+
return null;
|
|
162
|
+
// Offsets: the region covers the tail's char span; the locality the head's (relative to node.start).
|
|
163
|
+
const tailStart = node.start + node.value.indexOf(tail, comma);
|
|
164
|
+
const region = makeRegionNode(tail, tailStart, node.end, node.confidence);
|
|
165
|
+
region.children.push({
|
|
166
|
+
tag: "locality",
|
|
167
|
+
value: head,
|
|
168
|
+
start: node.start,
|
|
169
|
+
end: node.start + head.length,
|
|
170
|
+
confidence: node.confidence,
|
|
171
|
+
children: node.children, // keep any real children (rare for a locality)
|
|
172
|
+
...(node.metadata ? { metadata: node.metadata } : {}),
|
|
173
|
+
});
|
|
174
|
+
return region;
|
|
175
|
+
}
|
|
176
|
+
/** Recursively correct a node's children. */
|
|
177
|
+
function correctNode(node) {
|
|
178
|
+
if (node.children.length > 0) {
|
|
179
|
+
node.children = correctSiblings(node.children).map(correctNode);
|
|
180
|
+
}
|
|
181
|
+
return node;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Recognize US regions the parser missed and restructure `"City, State"` into `region → locality`
|
|
185
|
+
* nesting so the resolver scopes the locality to its state (#642). Mutates + returns the tree. A
|
|
186
|
+
* no-op when no US state token is found mis-tagged — byte-stable for already-correct parses.
|
|
187
|
+
*/
|
|
188
|
+
export function recognizeUsRegions(tree) {
|
|
189
|
+
tree.roots = correctSiblings(tree.roots).map(correctNode);
|
|
190
|
+
return tree;
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=region-recognition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"region-recognition.js","sourceRoot":"","sources":["../region-recognition.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-pipeline.d.ts","sourceRoot":"","sources":["../runtime-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"runtime-pipeline.d.ts","sourceRoot":"","sources":["../runtime-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,MAAM,0BAA0B,CAAA;AAQjC,MAAM,WAAW,yBAAyB;IACzC,sEAAsE;IACtE,UAAU,CAAC,EAAE,qBAAqB,CAAC,YAAY,CAAC,CAAA;IAChD,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,qBAAqB,CAAC,UAAU,CAAC,CAAA;IAC5C;;;OAGG;IACH,GAAG,CAAC,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAA;IAClC;;;;OAIG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAA;IACpD;;;;OAIG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAA;IACpD;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAA;IACpD;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC,cAAc,CAAC,GAAG,KAAK,CAAA;CAC5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACpC,IAAI,GAAE,yBAA8B,GAClC,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,cAAc,CAAC,CAqClE;AAKD,YAAY,EACX,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,UAAU,EACV,mBAAmB,EACnB,aAAa,EACb,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,EACf,cAAc,EACd,qBAAqB,GACrB,MAAM,0BAA0B,CAAA;AACjC,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA"}
|
package/out/runtime-pipeline.js
CHANGED
|
@@ -19,6 +19,7 @@ import { detectLocale as defaultDetectLocale } from "@mailwoman/locale-gate";
|
|
|
19
19
|
import { normalize } from "@mailwoman/normalize";
|
|
20
20
|
import { groupPhrases as defaultGroupPhrases } from "@mailwoman/phrase-grouper";
|
|
21
21
|
import { computeQueryShape } from "@mailwoman/query-shape";
|
|
22
|
+
import { loadDefaultPlaceCountry } from "./default-placer.js";
|
|
22
23
|
/**
|
|
23
24
|
* Build a runtime pipeline pre-wired with the default normalize + queryShape implementations.
|
|
24
25
|
*
|
|
@@ -43,11 +44,28 @@ export function createRuntimePipeline(opts = {}) {
|
|
|
43
44
|
classifier: opts.classifier,
|
|
44
45
|
fst: opts.fst,
|
|
45
46
|
resolver: opts.resolver,
|
|
47
|
+
// Coarse country router (#244) — DEFAULT-ON (#244 M2). A function override is wired here; the
|
|
48
|
+
// `undefined` default is lazy-loaded on the first call (below) so the sync factory stays sync;
|
|
49
|
+
// `false` disables it. A confident in-map guess feeds the resolver's anchorPosterior re-rank.
|
|
50
|
+
placeCountry: typeof opts.placeCountry === "function" ? opts.placeCountry : undefined,
|
|
46
51
|
// Default locale gate: rule-based from @mailwoman/locale-gate. Derives locale from
|
|
47
52
|
// QueryShape character class (CJK→ja-JP, Cyrillic→ru-RU, Arabic→ar) + known-format
|
|
48
53
|
// hits (us_zip→en-US, fr_postcode→fr-FR, uk_postcode→en-GB). Caller-hint wins when set.
|
|
49
54
|
detectLocale: opts.detectLocale ?? defaultDetectLocale,
|
|
50
55
|
};
|
|
51
|
-
|
|
56
|
+
// Default-on lazy wiring: when the caller neither supplied a placeCountry fn nor disabled it
|
|
57
|
+
// (`false`), load the bundled placer once on the first call and inject it. Done in the returned
|
|
58
|
+
// (async) function so the factory itself stays synchronous.
|
|
59
|
+
const autoPlaceCountry = opts.placeCountry === undefined;
|
|
60
|
+
let placeCountryResolved = !autoPlaceCountry;
|
|
61
|
+
return async (raw, runOpts) => {
|
|
62
|
+
if (!placeCountryResolved) {
|
|
63
|
+
placeCountryResolved = true;
|
|
64
|
+
const fn = await loadDefaultPlaceCountry();
|
|
65
|
+
if (fn)
|
|
66
|
+
stages.placeCountry = fn;
|
|
67
|
+
}
|
|
68
|
+
return runPipeline(raw, stages, runOpts);
|
|
69
|
+
};
|
|
52
70
|
}
|
|
53
71
|
//# sourceMappingURL=runtime-pipeline.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-pipeline.js","sourceRoot":"","sources":["../runtime-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACN,WAAW,GAIX,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAChF,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"runtime-pipeline.js","sourceRoot":"","sources":["../runtime-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACN,WAAW,GAIX,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAChF,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAgD7D;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CACpC,OAAkC,EAAE;IAEpC,MAAM,MAAM,GAA0B;QACrC,SAAS;QACT,iBAAiB;QACjB,4FAA4F;QAC5F,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,mBAAmB;QACtD,0FAA0F;QAC1F,0FAA0F;QAC1F,yFAAyF;QACzF,4FAA4F;QAC5F,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,mBAAmB;QACtD,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,8FAA8F;QAC9F,+FAA+F;QAC/F,8FAA8F;QAC9F,YAAY,EAAE,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;QACrF,mFAAmF;QACnF,mFAAmF;QACnF,wFAAwF;QACxF,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,mBAAmB;KACtD,CAAA;IAED,6FAA6F;IAC7F,gGAAgG;IAChG,4DAA4D;IAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,KAAK,SAAS,CAAA;IACxD,IAAI,oBAAoB,GAAG,CAAC,gBAAgB,CAAA;IAC5C,OAAO,KAAK,EAAE,GAAW,EAAE,OAAsB,EAA2B,EAAE;QAC7E,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC3B,oBAAoB,GAAG,IAAI,CAAA;YAC3B,MAAM,EAAE,GAAG,MAAM,uBAAuB,EAAE,CAAA;YAC1C,IAAI,EAAE;gBAAE,MAAM,CAAC,YAAY,GAAG,EAAE,CAAA;QACjC,CAAC;QACD,OAAO,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IACzC,CAAC,CAAA;AACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mailwoman",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.10.0",
|
|
4
4
|
"description": "Utilities for working with contacts for email, phone, and postal addresses.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"contributors": [
|
|
@@ -33,15 +33,16 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@fragaria/address-formatter": "^6.7.1",
|
|
35
35
|
"@inkjs/ui": "^2.0.0",
|
|
36
|
-
"@mailwoman/classifiers": "4.
|
|
37
|
-
"@mailwoman/core": "4.
|
|
38
|
-
"@mailwoman/corpus": "4.
|
|
39
|
-
"@mailwoman/kind-classifier": "4.
|
|
40
|
-
"@mailwoman/locale-gate": "4.
|
|
41
|
-
"@mailwoman/neural": "4.
|
|
42
|
-
"@mailwoman/normalize": "4.
|
|
43
|
-
"@mailwoman/phrase-grouper": "4.
|
|
44
|
-
"@mailwoman/query-shape": "4.
|
|
36
|
+
"@mailwoman/classifiers": "4.10.0",
|
|
37
|
+
"@mailwoman/core": "4.10.0",
|
|
38
|
+
"@mailwoman/corpus": "4.10.0",
|
|
39
|
+
"@mailwoman/kind-classifier": "4.10.0",
|
|
40
|
+
"@mailwoman/locale-gate": "4.10.0",
|
|
41
|
+
"@mailwoman/neural": "4.10.0",
|
|
42
|
+
"@mailwoman/normalize": "4.10.0",
|
|
43
|
+
"@mailwoman/phrase-grouper": "4.10.0",
|
|
44
|
+
"@mailwoman/query-shape": "4.10.0",
|
|
45
|
+
"@mailwoman/registry": "4.10.0",
|
|
45
46
|
"chalk": "^5.6.2",
|
|
46
47
|
"change-case": "^5.4.4",
|
|
47
48
|
"d3-scale-chromatic": "^3.1.0",
|