@mailwoman/resolver-wof-sqlite 2.1.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 (158) hide show
  1. package/README.md +250 -0
  2. package/out/address-point-interpolation.d.ts +48 -0
  3. package/out/address-point-interpolation.d.ts.map +1 -0
  4. package/out/address-point-interpolation.js +164 -0
  5. package/out/address-point-interpolation.js.map +1 -0
  6. package/out/address-point-schema.d.ts +58 -0
  7. package/out/address-point-schema.d.ts.map +1 -0
  8. package/out/address-point-schema.js +67 -0
  9. package/out/address-point-schema.js.map +1 -0
  10. package/out/address-point.d.ts +29 -0
  11. package/out/address-point.d.ts.map +1 -0
  12. package/out/address-point.js +62 -0
  13. package/out/address-point.js.map +1 -0
  14. package/out/ancestry.d.ts +40 -0
  15. package/out/ancestry.d.ts.map +1 -0
  16. package/out/ancestry.js +53 -0
  17. package/out/ancestry.js.map +1 -0
  18. package/out/build-candidate-cli.d.ts +16 -0
  19. package/out/build-candidate-cli.d.ts.map +1 -0
  20. package/out/build-candidate-cli.js +80 -0
  21. package/out/build-candidate-cli.js.map +1 -0
  22. package/out/build-candidate.d.ts +54 -0
  23. package/out/build-candidate.d.ts.map +1 -0
  24. package/out/build-candidate.js +230 -0
  25. package/out/build-candidate.js.map +1 -0
  26. package/out/build-coincident-roles-cli.d.ts +16 -0
  27. package/out/build-coincident-roles-cli.d.ts.map +1 -0
  28. package/out/build-coincident-roles-cli.js +94 -0
  29. package/out/build-coincident-roles-cli.js.map +1 -0
  30. package/out/build-fts-cli.d.ts +23 -0
  31. package/out/build-fts-cli.d.ts.map +1 -0
  32. package/out/build-fts-cli.js +117 -0
  33. package/out/build-fts-cli.js.map +1 -0
  34. package/out/build-slim-cli.d.ts +14 -0
  35. package/out/build-slim-cli.d.ts.map +1 -0
  36. package/out/build-slim-cli.js +130 -0
  37. package/out/build-slim-cli.js.map +1 -0
  38. package/out/build-slim.d.ts +71 -0
  39. package/out/build-slim.d.ts.map +1 -0
  40. package/out/build-slim.js +267 -0
  41. package/out/build-slim.js.map +1 -0
  42. package/out/candidate-lookup.d.ts +43 -0
  43. package/out/candidate-lookup.d.ts.map +1 -0
  44. package/out/candidate-lookup.js +191 -0
  45. package/out/candidate-lookup.js.map +1 -0
  46. package/out/candidate-schema.d.ts +86 -0
  47. package/out/candidate-schema.d.ts.map +1 -0
  48. package/out/candidate-schema.js +109 -0
  49. package/out/candidate-schema.js.map +1 -0
  50. package/out/coincident-roles.d.ts +86 -0
  51. package/out/coincident-roles.d.ts.map +1 -0
  52. package/out/coincident-roles.js +160 -0
  53. package/out/coincident-roles.js.map +1 -0
  54. package/out/convention.d.ts +109 -0
  55. package/out/convention.d.ts.map +1 -0
  56. package/out/convention.js +94 -0
  57. package/out/convention.js.map +1 -0
  58. package/out/fst-autocomplete.d.ts +49 -0
  59. package/out/fst-autocomplete.d.ts.map +1 -0
  60. package/out/fst-autocomplete.js +124 -0
  61. package/out/fst-autocomplete.js.map +1 -0
  62. package/out/fst-builder.d.ts +20 -0
  63. package/out/fst-builder.d.ts.map +1 -0
  64. package/out/fst-builder.js +219 -0
  65. package/out/fst-builder.js.map +1 -0
  66. package/out/fst-deserialize-web.d.ts +16 -0
  67. package/out/fst-deserialize-web.d.ts.map +1 -0
  68. package/out/fst-deserialize-web.js +133 -0
  69. package/out/fst-deserialize-web.js.map +1 -0
  70. package/out/fst-matcher.d.ts +33 -0
  71. package/out/fst-matcher.d.ts.map +1 -0
  72. package/out/fst-matcher.js +117 -0
  73. package/out/fst-matcher.js.map +1 -0
  74. package/out/fst-serialize.d.ts +30 -0
  75. package/out/fst-serialize.d.ts.map +1 -0
  76. package/out/fst-serialize.js +261 -0
  77. package/out/fst-serialize.js.map +1 -0
  78. package/out/fst-types.d.ts +60 -0
  79. package/out/fst-types.d.ts.map +1 -0
  80. package/out/fst-types.js +11 -0
  81. package/out/fst-types.js.map +1 -0
  82. package/out/fts.d.ts +158 -0
  83. package/out/fts.d.ts.map +1 -0
  84. package/out/fts.js +261 -0
  85. package/out/fts.js.map +1 -0
  86. package/out/geo.d.ts +74 -0
  87. package/out/geo.d.ts.map +1 -0
  88. package/out/geo.js +88 -0
  89. package/out/geo.js.map +1 -0
  90. package/out/index.d.ts +27 -0
  91. package/out/index.d.ts.map +1 -0
  92. package/out/index.js +22 -0
  93. package/out/index.js.map +1 -0
  94. package/out/interpolation.d.ts +84 -0
  95. package/out/interpolation.d.ts.map +1 -0
  96. package/out/interpolation.js +150 -0
  97. package/out/interpolation.js.map +1 -0
  98. package/out/lookup.d.ts +156 -0
  99. package/out/lookup.d.ts.map +1 -0
  100. package/out/lookup.js +876 -0
  101. package/out/lookup.js.map +1 -0
  102. package/out/postal-city-alias-lookup.d.ts +50 -0
  103. package/out/postal-city-alias-lookup.d.ts.map +1 -0
  104. package/out/postal-city-alias-lookup.js +66 -0
  105. package/out/postal-city-alias-lookup.js.map +1 -0
  106. package/out/postal-city-alias-schema.d.ts +51 -0
  107. package/out/postal-city-alias-schema.d.ts.map +1 -0
  108. package/out/postal-city-alias-schema.js +47 -0
  109. package/out/postal-city-alias-schema.js.map +1 -0
  110. package/out/postal-city-candidate-schema.d.ts +58 -0
  111. package/out/postal-city-candidate-schema.d.ts.map +1 -0
  112. package/out/postal-city-candidate-schema.js +56 -0
  113. package/out/postal-city-candidate-schema.js.map +1 -0
  114. package/out/postcode-point-lookup.d.ts +38 -0
  115. package/out/postcode-point-lookup.d.ts.map +1 -0
  116. package/out/postcode-point-lookup.js +46 -0
  117. package/out/postcode-point-lookup.js.map +1 -0
  118. package/out/reverse.d.ts +99 -0
  119. package/out/reverse.d.ts.map +1 -0
  120. package/out/reverse.js +290 -0
  121. package/out/reverse.js.map +1 -0
  122. package/out/schema.d.ts +163 -0
  123. package/out/schema.d.ts.map +1 -0
  124. package/out/schema.js +18 -0
  125. package/out/schema.js.map +1 -0
  126. package/out/sharding.d.ts +96 -0
  127. package/out/sharding.d.ts.map +1 -0
  128. package/out/sharding.js +129 -0
  129. package/out/sharding.js.map +1 -0
  130. package/out/sqlite-convention-source.d.ts +29 -0
  131. package/out/sqlite-convention-source.d.ts.map +1 -0
  132. package/out/sqlite-convention-source.js +53 -0
  133. package/out/sqlite-convention-source.js.map +1 -0
  134. package/out/sqlite-utils.d.ts +17 -0
  135. package/out/sqlite-utils.d.ts.map +1 -0
  136. package/out/sqlite-utils.js +24 -0
  137. package/out/sqlite-utils.js.map +1 -0
  138. package/out/street-morphology-fst-builder.d.ts +59 -0
  139. package/out/street-morphology-fst-builder.d.ts.map +1 -0
  140. package/out/street-morphology-fst-builder.js +174 -0
  141. package/out/street-morphology-fst-builder.js.map +1 -0
  142. package/out/street-normalize.d.ts +66 -0
  143. package/out/street-normalize.d.ts.map +1 -0
  144. package/out/street-normalize.js +176 -0
  145. package/out/street-normalize.js.map +1 -0
  146. package/out/street-segment-schema.d.ts +61 -0
  147. package/out/street-segment-schema.d.ts.map +1 -0
  148. package/out/street-segment-schema.js +64 -0
  149. package/out/street-segment-schema.js.map +1 -0
  150. package/out/types.d.ts +137 -0
  151. package/out/types.d.ts.map +1 -0
  152. package/out/types.js +13 -0
  153. package/out/types.js.map +1 -0
  154. package/out/unified-schema.d.ts +25 -0
  155. package/out/unified-schema.d.ts.map +1 -0
  156. package/out/unified-schema.js +142 -0
  157. package/out/unified-schema.js.map +1 -0
  158. package/package.json +54 -0
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @copyright Sister Software
4
+ * @license AGPL-3.0
5
+ * @author Teffen Ellis, et al.
6
+ *
7
+ * `mailwoman-wof-build-coincident-roles <path-to-admin.db>... [--drop]`
8
+ *
9
+ * Operator-side one-shot CLI (#403, epic #402): derives the `coincident_roles` relation into an
10
+ * existing admin gazetteer — the dual-role places (city-states, capital-seat provinces,
11
+ * consolidated city-counties) the hierarchy-completion step (#405) consults. Additive +
12
+ * idempotent; re-run after refreshing `spr`/`ancestors`. Mirrors `build-fts-cli.ts`. Should also
13
+ * be invoked as a post-step of the main `scripts/build-unified-wof.ts`.
14
+ */
15
+ import { existsSync } from "node:fs";
16
+ import { exit, stderr } from "node:process";
17
+ import { DatabaseSync } from "node:sqlite";
18
+ import { buildCoincidentRoles } from "./coincident-roles.js";
19
+ function printUsageAndExit(code) {
20
+ stderr.write([
21
+ "usage: mailwoman-wof-build-coincident-roles <path-to-admin.db>... [--drop]",
22
+ "",
23
+ "Derives the coincident_roles relation (dual-role places — city-states, capital-seat",
24
+ "provinces, consolidated city-counties) into one or more admin gazetteers. The",
25
+ "hierarchy-completion resolver step (#405) consults it. Additive + idempotent.",
26
+ "",
27
+ " --drop Drop and rebuild coincident_roles if it already exists (default: rebuild).",
28
+ "",
29
+ "Example:",
30
+ " mailwoman-wof-build-coincident-roles /data/wof/admin-global-priority.db",
31
+ "",
32
+ ].join("\n"));
33
+ exit(code);
34
+ }
35
+ function buildOne(path, drop) {
36
+ if (!existsSync(path)) {
37
+ stderr.write(`mailwoman-wof-build-coincident-roles: file not found: ${path}\n`);
38
+ return 1;
39
+ }
40
+ stderr.write(`Opening ${path}…\n`);
41
+ const db = new DatabaseSync(path);
42
+ try {
43
+ const result = buildCoincidentRoles(db, {
44
+ drop,
45
+ onProgress: (phase, detail) => stderr.write(` [${phase}]${detail ? ` — ${detail}` : ""}\n`),
46
+ });
47
+ const top = Object.entries(result.byCountry)
48
+ .sort((a, b) => b[1] - a[1])
49
+ .map(([cc, n]) => `${cc} ${n}`)
50
+ .join(", ");
51
+ stderr.write(`Built: ${result.rowCount} coincident-role rows (${(result.durationMs / 1000).toFixed(2)}s)\n by country: ${top}\n`);
52
+ return 0;
53
+ }
54
+ catch (err) {
55
+ stderr.write(`mailwoman-wof-build-coincident-roles: ${err instanceof Error ? err.message : String(err)}\n`);
56
+ return 1;
57
+ }
58
+ finally {
59
+ db.close();
60
+ }
61
+ }
62
+ export function main(argv) {
63
+ const paths = [];
64
+ // The relation is a cheap (~2 s) derived table that must reflect the current spr/ancestors, so it
65
+ // rebuilds by default (idempotent). `--no-drop` appends instead — only useful for incremental tests.
66
+ let drop = true;
67
+ for (const a of argv) {
68
+ if (a === "--drop")
69
+ drop = true;
70
+ else if (a === "--no-drop")
71
+ drop = false;
72
+ else if (a === "--help" || a === "-h")
73
+ printUsageAndExit(0);
74
+ else if (a.startsWith("-")) {
75
+ stderr.write(`mailwoman-wof-build-coincident-roles: unknown flag ${JSON.stringify(a)}\n`);
76
+ printUsageAndExit(2);
77
+ }
78
+ else
79
+ paths.push(a);
80
+ }
81
+ if (paths.length === 0)
82
+ printUsageAndExit(2);
83
+ let worst = 0;
84
+ for (const path of paths) {
85
+ const rc = buildOne(path, drop);
86
+ if (rc > worst)
87
+ worst = rc;
88
+ }
89
+ return worst;
90
+ }
91
+ if (import.meta.url === `file://${process.argv[1]}`) {
92
+ exit(main(process.argv.slice(2)));
93
+ }
94
+ //# sourceMappingURL=build-coincident-roles-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-coincident-roles-cli.js","sourceRoot":"","sources":["../build-coincident-roles-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @copyright Sister Software
4
+ * @license AGPL-3.0
5
+ * @author Teffen Ellis, et al.
6
+ *
7
+ * `mailwoman-wof-build-fts <path-to-wof.db>... [--drop]`
8
+ *
9
+ * Operator-side one-shot CLI: takes one or more Who's On First SQLite distributions and adds the
10
+ * `place_search` FTS5 + `place_bbox` R*Tree virtual tables needed by `WofSqlitePlaceLookup`. Run
11
+ * this once per downloaded WOF shard so production callers can skip the (~minutes-long) lazy
12
+ * build.
13
+ *
14
+ * Multiple positional args process each DB in sequence — useful when you've just pulled the admin +
15
+ * postcode shards in one go.
16
+ *
17
+ * Why a plain-args CLI rather than Ink / Pastel: this is a one-shot operator script, not an
18
+ * interactive TUI. The dep weight of inkjs / pastel would dominate the script's footprint and
19
+ * doesn't match how operators expect to drive a build step (`script /path/to/db` + stderr
20
+ * progress). Matches the spirit of `corpus/scripts/*.ts`.
21
+ */
22
+ export declare function main(argv: readonly string[]): number;
23
+ //# sourceMappingURL=build-fts-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-fts-cli.d.ts","sourceRoot":"","sources":["../build-fts-cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;GAmBG;AA0FH,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CASpD"}
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @copyright Sister Software
4
+ * @license AGPL-3.0
5
+ * @author Teffen Ellis, et al.
6
+ *
7
+ * `mailwoman-wof-build-fts <path-to-wof.db>... [--drop]`
8
+ *
9
+ * Operator-side one-shot CLI: takes one or more Who's On First SQLite distributions and adds the
10
+ * `place_search` FTS5 + `place_bbox` R*Tree virtual tables needed by `WofSqlitePlaceLookup`. Run
11
+ * this once per downloaded WOF shard so production callers can skip the (~minutes-long) lazy
12
+ * build.
13
+ *
14
+ * Multiple positional args process each DB in sequence — useful when you've just pulled the admin +
15
+ * postcode shards in one go.
16
+ *
17
+ * Why a plain-args CLI rather than Ink / Pastel: this is a one-shot operator script, not an
18
+ * interactive TUI. The dep weight of inkjs / pastel would dominate the script's footprint and
19
+ * doesn't match how operators expect to drive a build step (`script /path/to/db` + stderr
20
+ * progress). Matches the spirit of `corpus/scripts/*.ts`.
21
+ */
22
+ import { existsSync } from "node:fs";
23
+ import { exit, stderr } from "node:process";
24
+ import { DatabaseSync } from "node:sqlite";
25
+ import { buildPlaceSearchFts } from "./fts.js";
26
+ function printUsageAndExit(code) {
27
+ stderr.write([
28
+ "usage: mailwoman-wof-build-fts <path-to-wof.db>... [--drop]",
29
+ "",
30
+ "Builds the place_search FTS5 + place_bbox R*Tree virtual tables in one or more",
31
+ "Who's On First SQLite distributions. Run this once per downloaded WOF shard so",
32
+ "production WofSqlitePlaceLookup instances skip the lazy-build cost at first open.",
33
+ "",
34
+ " --drop Drop and rebuild place_search + place_bbox if they already exist.",
35
+ " Apply after refreshing the spr / names tables from a newer dump.",
36
+ "",
37
+ "Examples:",
38
+ " mailwoman-wof-build-fts /data/wof/admin-us.db",
39
+ " mailwoman-wof-build-fts /data/wof/admin-us.db /data/wof/postalcode-us.db",
40
+ " mailwoman-wof-build-fts /data/wof/admin-us.db --drop",
41
+ "",
42
+ "See https://github.com/sister-software/mailwoman/tree/main/resolver-wof-sqlite for",
43
+ "the recommended WOF distribution sources + attribution requirements.",
44
+ "",
45
+ ].join("\n"));
46
+ exit(code);
47
+ }
48
+ function parseArgs(argv) {
49
+ const args = [];
50
+ let drop = false;
51
+ for (const a of argv) {
52
+ if (a === "--drop")
53
+ drop = true;
54
+ else if (a === "--help" || a === "-h")
55
+ printUsageAndExit(0);
56
+ else if (a.startsWith("-")) {
57
+ stderr.write(`mailwoman-wof-build-fts: unknown flag ${JSON.stringify(a)}\n`);
58
+ printUsageAndExit(2);
59
+ }
60
+ else
61
+ args.push(a);
62
+ }
63
+ if (args.length === 0) {
64
+ stderr.write(`mailwoman-wof-build-fts: expected at least one positional arg\n`);
65
+ printUsageAndExit(2);
66
+ }
67
+ return { databasePaths: args, drop };
68
+ }
69
+ /**
70
+ * Build indexes on a single DB. Returns 0 on success, 1 on failure. Errors are written to stderr
71
+ * but the call doesn't throw — `main()` aggregates the exit code across multi-DB invocations.
72
+ */
73
+ function buildOne(path, drop) {
74
+ if (!existsSync(path)) {
75
+ stderr.write(`mailwoman-wof-build-fts: file not found: ${path}\n`);
76
+ return 1;
77
+ }
78
+ stderr.write(`Opening ${path}…\n`);
79
+ const db = new DatabaseSync(path);
80
+ try {
81
+ const result = buildPlaceSearchFts(db, {
82
+ drop,
83
+ onProgress: (phase, detail) => {
84
+ const suffix = detail ? ` — ${detail}` : "";
85
+ stderr.write(` [${phase}]${suffix}\n`);
86
+ },
87
+ });
88
+ const verb = result.created ? "Built" : "Already present";
89
+ stderr.write(`${verb}: place_search has ${result.indexedRows.toLocaleString()} rows ` +
90
+ `(${(result.durationMs / 1000).toFixed(2)}s)\n`);
91
+ return 0;
92
+ }
93
+ catch (err) {
94
+ const message = err instanceof Error ? err.message : String(err);
95
+ stderr.write(`mailwoman-wof-build-fts: ${message}\n`);
96
+ return 1;
97
+ }
98
+ finally {
99
+ db.close();
100
+ }
101
+ }
102
+ export function main(argv) {
103
+ const args = parseArgs(argv);
104
+ // Process every DB; if any fail, the worst exit code wins (so CI / scripts see failure).
105
+ let worst = 0;
106
+ for (const path of args.databasePaths) {
107
+ const rc = buildOne(path, args.drop);
108
+ if (rc > worst)
109
+ worst = rc;
110
+ }
111
+ return worst;
112
+ }
113
+ // Entry point — only run when invoked directly, not when imported by tests.
114
+ if (import.meta.url === `file://${process.argv[1]}`) {
115
+ exit(main(process.argv.slice(2)));
116
+ }
117
+ //# sourceMappingURL=build-fts-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-fts-cli.js","sourceRoot":"","sources":["../build-fts-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @copyright Sister Software
4
+ * @license AGPL-3.0
5
+ * @author Teffen Ellis, et al.
6
+ *
7
+ * `mailwoman-wof-build-slim --in <wof.db>... --out <slim.db> [--top 1000] [--countries US]`
8
+ *
9
+ * Operator-side one-shot CLI that produces a "slim" WOF SQLite distribution sized for the
10
+ * browser-side mailwoman demo (Path B). Delegates to {@linkcode buildSlimWofDatabase}; the CLI is
11
+ * just argument parsing + stderr progress.
12
+ */
13
+ export declare function main(rawArgv: string[]): Promise<number>;
14
+ //# sourceMappingURL=build-slim-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-slim-cli.d.ts","sourceRoot":"","sources":["../build-slim-cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAmFH,wBAAsB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmC7D"}
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @copyright Sister Software
4
+ * @license AGPL-3.0
5
+ * @author Teffen Ellis, et al.
6
+ *
7
+ * `mailwoman-wof-build-slim --in <wof.db>... --out <slim.db> [--top 1000] [--countries US]`
8
+ *
9
+ * Operator-side one-shot CLI that produces a "slim" WOF SQLite distribution sized for the
10
+ * browser-side mailwoman demo (Path B). Delegates to {@linkcode buildSlimWofDatabase}; the CLI is
11
+ * just argument parsing + stderr progress.
12
+ */
13
+ import { exit, stderr } from "node:process";
14
+ import { buildSlimWofDatabase } from "./build-slim.js";
15
+ function printUsageAndExit(code) {
16
+ stderr.write([
17
+ "usage: mailwoman-wof-build-slim --in <wof.db>... --out <slim.db> [--top N] [--countries US,CA,...] [--drop-names]",
18
+ "",
19
+ "Builds a trimmed WOF SQLite distribution for the browser-side demo. Default selection:",
20
+ " - All ancestor placetypes (country/region/county/borough/macroregion) in scope",
21
+ " - Top --top localities by population (from the source place_population table, default 1000)",
22
+ " - All postalcodes in scope",
23
+ " - All names + place_population rows for selected IDs (+ coincident_roles, filtered)",
24
+ " - Fresh place_search FTS5 + place_bbox R*Tree (rebuilt from spr + names)",
25
+ "",
26
+ "--drop-names drops the names table after the FTS build (self-contained FTS5; ~2/3 size win,",
27
+ "the resolver never reads names at runtime — see #359). Empty --in values are skipped (pass",
28
+ '"" for a shard that isn\'t built yet).',
29
+ "",
30
+ "Examples:",
31
+ " mailwoman-wof-build-slim --in admin-us.db --in postalcode-us.db --out wof-hot.db",
32
+ " mailwoman-wof-build-slim --in admin-us.db --out wof-tiny.db --top 100",
33
+ " mailwoman-wof-build-slim --in admin-na.db --out wof-na.db --countries US,CA,MX",
34
+ "",
35
+ ].join("\n"));
36
+ exit(code);
37
+ }
38
+ function parseArgs(argv) {
39
+ const out = { inputs: [], output: "", topLocalities: 1000, countries: ["US"], dropNames: false };
40
+ for (let i = 0; i < argv.length; i++) {
41
+ const a = argv[i];
42
+ if (a === "--in") {
43
+ // Consume the value even when empty — callers pass `--in ""` for a shard (e.g. a custom
44
+ // postcode DB) that isn't built yet. Push only non-empty paths; build-slim skips the rest.
45
+ const v = argv[++i];
46
+ if (v === undefined)
47
+ printUsageAndExit(2);
48
+ if (v)
49
+ out.inputs.push(v);
50
+ }
51
+ else if (a === "--out") {
52
+ const v = argv[++i];
53
+ if (!v)
54
+ printUsageAndExit(2);
55
+ out.output = v;
56
+ }
57
+ else if (a === "--top") {
58
+ const v = argv[++i];
59
+ if (!v)
60
+ printUsageAndExit(2);
61
+ const n = Number(v);
62
+ if (!Number.isFinite(n) || n <= 0) {
63
+ stderr.write(`--top must be a positive number; got '${v}'\n`);
64
+ exit(2);
65
+ }
66
+ out.topLocalities = n;
67
+ }
68
+ else if (a === "--countries") {
69
+ const v = argv[++i];
70
+ if (!v)
71
+ printUsageAndExit(2);
72
+ out.countries = v
73
+ .split(",")
74
+ .map((c) => c.trim())
75
+ .filter(Boolean);
76
+ }
77
+ else if (a === "--drop-names") {
78
+ out.dropNames = true;
79
+ }
80
+ else if (a === "--help" || a === "-h") {
81
+ printUsageAndExit(0);
82
+ }
83
+ else {
84
+ stderr.write(`unknown argument: '${a}'\n`);
85
+ printUsageAndExit(2);
86
+ }
87
+ }
88
+ if (out.inputs.length === 0 || !out.output)
89
+ printUsageAndExit(2);
90
+ return out;
91
+ }
92
+ export async function main(rawArgv) {
93
+ let args;
94
+ try {
95
+ args = parseArgs(rawArgv);
96
+ }
97
+ catch {
98
+ return 2;
99
+ }
100
+ const opts = {
101
+ inputs: args.inputs,
102
+ output: args.output,
103
+ countries: args.countries,
104
+ topLocalitiesPerCountry: args.topLocalities,
105
+ dropNames: args.dropNames,
106
+ onProgress: (phase, detail) => {
107
+ stderr.write(`[${phase}] ${detail}\n`);
108
+ },
109
+ };
110
+ try {
111
+ const result = await buildSlimWofDatabase(opts);
112
+ const mb = (result.outputBytes / 1024 / 1024).toFixed(1);
113
+ stderr.write(`\nBuilt ${result.outputPath} (${mb} MB)\n` +
114
+ ` spr=${result.rowCounts.spr}` +
115
+ ` names=${result.rowCounts.names}${args.dropNames ? " (dropped)" : ""}` +
116
+ ` fts=${result.rowCounts.placeSearch}` +
117
+ ` bbox=${result.rowCounts.placeBbox}` +
118
+ ` pop=${result.rowCounts.placePopulation}\n`);
119
+ return 0;
120
+ }
121
+ catch (err) {
122
+ stderr.write(`build-slim failed: ${err.message}\n`);
123
+ return 1;
124
+ }
125
+ }
126
+ // Run when invoked as a script (not when imported by tests).
127
+ if (import.meta.url === `file://${process.argv[1]}`) {
128
+ main(process.argv.slice(2)).then((code) => exit(code));
129
+ }
130
+ //# sourceMappingURL=build-slim-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-slim-cli.js","sourceRoot":"","sources":["../build-slim-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Build a "slim" Who's On First SQLite distribution that's small enough to ship as a static asset
7
+ * for the browser-side mailwoman demo (Path B of the demo plan). The full admin distribution is
8
+ * ~2 GB; the slim variant aims for the ~50–100 MB range by keeping only the places a public demo
9
+ * will actually query for.
10
+ *
11
+ * Selection policy (v1, US-focused):
12
+ *
13
+ * - All countries / regions / counties / boroughs in the configured `countries` set, so the ancestor
14
+ * chain a locality / postcode reports through `parent_id` stays intact.
15
+ * - Top-K localities by population (read from the source's pre-built `place_population` aux table) in
16
+ * those countries.
17
+ * - All postcodes in those countries — they're small and addressing-relevant.
18
+ * - All `names` + `place_population` rows for selected place IDs.
19
+ * - The `coincident_roles` dual-role relation (#402), filtered to surviving spr ids.
20
+ *
21
+ * No geojson, by design. The upstream WOF GeoJSON bodies live ONLY in the raw `whosonfirst-data-*`
22
+ * repos; `scripts/build-unified-wof.ts` extracts `wof:population` straight into
23
+ * `place_population` (and the bbox into `spr`) at ingest and never persists a `geojson` table. So
24
+ * the source admin DB carries population in `place_population`, and this builder consumes it
25
+ * directly — there is nothing to extract from, and nothing to drop.
26
+ *
27
+ * The output DB has the resolver-facing schema: `spr`, `names`, `place_population`, plus the
28
+ * `place_search` FTS5 / `place_bbox` R*Tree virtual tables rebuilt against the trimmed row set
29
+ * (both derive purely from `spr` + `names` — see `fts.ts`). That means `WofSqlitePlaceLookup`
30
+ * opens the slim DB without any code change — it sees a smaller universe, nothing more.
31
+ *
32
+ * Multi-shard inputs (e.g. admin + postcode) are processed in sequence; selected rows accumulate
33
+ * into the single output DB. The postcode shard contributes only postcodes; admin contributes
34
+ * everything else. Empty / missing input paths are skipped (callers pass `""` when a shard, such
35
+ * as a custom postcode DB, isn't built yet).
36
+ */
37
+ export interface BuildSlimOptions {
38
+ /** Input WOF SQLite distributions. Each should already have spr / names / place_population tables. */
39
+ inputs: string[];
40
+ /** Output path for the slim DB. Will be overwritten if it exists. */
41
+ output: string;
42
+ /** Country codes to keep (ISO 2-letter). Defaults to `["US"]`. */
43
+ countries?: string[];
44
+ /** Cap on the number of localities to keep per country, by descending population. */
45
+ topLocalitiesPerCountry?: number;
46
+ /**
47
+ * Drop the `names` table after the FTS index is built (default false). `place_search` is a
48
+ * self-contained FTS5 (no external `content=`), so once it's built `names` is only the build-time
49
+ * source — the resolver queries `place_search` + `spr` + `place_population` + `coincident_roles`
50
+ * and never reads `names` at runtime. Dropping it is the single biggest size win (~2/3 of the
51
+ * file for a multi-locale build; see #359). A future consumer that needs raw alt-names at runtime
52
+ * should ship a SEPARATE shard rather than re-bloat the hot DB.
53
+ */
54
+ dropNames?: boolean;
55
+ /** Optional progress callback for CLI / test introspection. */
56
+ onProgress?: (phase: SlimBuildPhase, detail: string) => void;
57
+ }
58
+ export type SlimBuildPhase = "init" | "schema" | "country" | "region" | "county" | "locality" | "postcode" | "names" | "place_population" | "coincident_roles" | "place_abbr" | "fts" | "vacuum" | "done";
59
+ export interface BuildSlimResult {
60
+ outputPath: string;
61
+ outputBytes: number;
62
+ rowCounts: {
63
+ spr: number;
64
+ names: number;
65
+ placeSearch: number;
66
+ placeBbox: number;
67
+ placePopulation: number;
68
+ };
69
+ }
70
+ export declare function buildSlimWofDatabase(opts: BuildSlimOptions): Promise<BuildSlimResult>;
71
+ //# sourceMappingURL=build-slim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-slim.d.ts","sourceRoot":"","sources":["../build-slim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAYH,MAAM,WAAW,gBAAgB;IAChC,sGAAsG;IACtG,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CAC5D;AAED,MAAM,MAAM,cAAc,GACvB,MAAM,GACN,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,UAAU,GACV,OAAO,GACP,kBAAkB,GAClB,kBAAkB,GAClB,YAAY,GACZ,KAAK,GACL,QAAQ,GACR,MAAM,CAAA;AAET,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE;QACV,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,EAAE,MAAM,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;QACjB,eAAe,EAAE,MAAM,CAAA;KACvB,CAAA;CACD;AAgCD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAiH3F"}