@mailwoman/bdc 8.3.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/README.md +7 -0
- package/index.ts +2 -0
- package/out/index.d.ts +3 -0
- package/out/index.d.ts.map +1 -0
- package/out/index.js +3 -0
- package/out/index.js.map +1 -0
- package/out/schema.d.ts +138 -0
- package/out/schema.d.ts.map +1 -0
- package/out/schema.js +88 -0
- package/out/schema.js.map +1 -0
- package/out/sdk/build-bdc.d.ts +214 -0
- package/out/sdk/build-bdc.d.ts.map +1 -0
- package/out/sdk/build-bdc.js +500 -0
- package/out/sdk/build-bdc.js.map +1 -0
- package/out/sdk/buildings.d.ts +84 -0
- package/out/sdk/buildings.d.ts.map +1 -0
- package/out/sdk/buildings.js +75 -0
- package/out/sdk/buildings.js.map +1 -0
- package/out/sdk/client.d.ts +237 -0
- package/out/sdk/client.d.ts.map +1 -0
- package/out/sdk/client.js +430 -0
- package/out/sdk/client.js.map +1 -0
- package/out/sdk/common.d.ts +279 -0
- package/out/sdk/common.d.ts.map +1 -0
- package/out/sdk/common.js +162 -0
- package/out/sdk/common.js.map +1 -0
- package/out/sdk/data-collection.d.ts +244 -0
- package/out/sdk/data-collection.d.ts.map +1 -0
- package/out/sdk/data-collection.js +50 -0
- package/out/sdk/data-collection.js.map +1 -0
- package/out/sdk/download.d.ts +36 -0
- package/out/sdk/download.d.ts.map +1 -0
- package/out/sdk/download.js +76 -0
- package/out/sdk/download.js.map +1 -0
- package/out/sdk/filing-dates.d.ts +57 -0
- package/out/sdk/filing-dates.d.ts.map +1 -0
- package/out/sdk/filing-dates.js +50 -0
- package/out/sdk/filing-dates.js.map +1 -0
- package/out/sdk/filing-landscape.d.ts +124 -0
- package/out/sdk/filing-landscape.d.ts.map +1 -0
- package/out/sdk/filing-landscape.js +216 -0
- package/out/sdk/filing-landscape.js.map +1 -0
- package/out/sdk/index.d.ts +15 -0
- package/out/sdk/index.d.ts.map +1 -0
- package/out/sdk/index.js +15 -0
- package/out/sdk/index.js.map +1 -0
- package/out/sdk/list-files.d.ts +39 -0
- package/out/sdk/list-files.d.ts.map +1 -0
- package/out/sdk/list-files.js +26 -0
- package/out/sdk/list-files.js.map +1 -0
- package/out/sdk/location.d.ts +40 -0
- package/out/sdk/location.d.ts.map +1 -0
- package/out/sdk/location.js +23 -0
- package/out/sdk/location.js.map +1 -0
- package/out/sdk/nearest-infrastructure.d.ts +84 -0
- package/out/sdk/nearest-infrastructure.d.ts.map +1 -0
- package/out/sdk/nearest-infrastructure.js +84 -0
- package/out/sdk/nearest-infrastructure.js.map +1 -0
- package/out/sdk/parsing.d.ts +57 -0
- package/out/sdk/parsing.d.ts.map +1 -0
- package/out/sdk/parsing.js +87 -0
- package/out/sdk/parsing.js.map +1 -0
- package/out/sdk/plausibility.d.ts +256 -0
- package/out/sdk/plausibility.d.ts.map +1 -0
- package/out/sdk/plausibility.js +334 -0
- package/out/sdk/plausibility.js.map +1 -0
- package/out/sdk/technologies.d.ts +229 -0
- package/out/sdk/technologies.d.ts.map +1 -0
- package/out/sdk/technologies.js +217 -0
- package/out/sdk/technologies.js.map +1 -0
- package/package.json +97 -0
- package/schema.ts +172 -0
- package/sdk/build-bdc.ts +810 -0
- package/sdk/buildings.ts +87 -0
- package/sdk/client.ts +643 -0
- package/sdk/common.ts +363 -0
- package/sdk/data-collection.ts +268 -0
- package/sdk/download.ts +91 -0
- package/sdk/filing-dates.ts +88 -0
- package/sdk/filing-landscape.ts +287 -0
- package/sdk/index.ts +14 -0
- package/sdk/list-files.ts +72 -0
- package/sdk/location.ts +45 -0
- package/sdk/nearest-infrastructure.ts +129 -0
- package/sdk/parsing.ts +124 -0
- package/sdk/plausibility.ts +512 -0
- package/sdk/technologies.ts +258 -0
package/README.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# @mailwoman/bdc
|
|
2
|
+
|
|
3
|
+
FCC Broadband Data Collection (BDC) availability data — fetch, parse, and ingest provider data, and the `bdc.db` layer reader. See the implementation plan at `.superpowers/sdd/2026-07-30-bdc-2a-plan/` for the spec. This workspace is a **data provider** — it reads/ingests raw BDC data and produces a queryable spatial layer; it is not part of the address parser itself.
|
|
4
|
+
|
|
5
|
+
## CostQuest Fabric boundary
|
|
6
|
+
|
|
7
|
+
The BDC Fabric (the BSL `location_id` → rooftop point/parcel map) is CostQuest-licensed. This workspace never ingests, ships, or derives data from the Fabric: `location_id` is carried only as an opaque join key that a licensed user may join against their own Fabric copy. All spatial work happens at census-block granularity plus mailwoman's own address spine.
|
package/index.ts
ADDED
package/out/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA"}
|
package/out/index.js
ADDED
package/out/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA"}
|
package/out/schema.d.ts
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software.
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* Typed schema for bdc.db — the FCC Broadband Data Collection availability read-side layer (2a
|
|
7
|
+
* decisions 4, 8). `bdc_availability` holds, in the default (non-`includeLocationIDs`) build mode, one
|
|
8
|
+
* row per DISTINCT (geoid, provider_id, technology_code, max_advertised_download_speed,
|
|
9
|
+
* max_advertised_upload_speed, low_latency, business_residential_code) tuple parsed from the FCC's
|
|
10
|
+
* per-provider CSV (see `sdk/parsing.ts`) — NOT one row per (block, provider, technology) triple: when
|
|
11
|
+
* two Broadband Serviceable Locations in the same block file different speeds/flags for the same
|
|
12
|
+
* provider/technology, both rows survive `build-bdc.ts`'s materialize-time collapse (see that file's
|
|
13
|
+
* docstring; accepted FCC filing behavior, not a bug). `bdc_provider` is a small dictionary
|
|
14
|
+
* keyed on `provider_id`, populated by a later registry-join task — decision 8 keeps FRN/brand/
|
|
15
|
+
* holding-company resolution out of 2a's scope. The DB also embeds the layer-contract tables from
|
|
16
|
+
* `@mailwoman/core/layers` (manifest tier `shipped`, license `public-domain` — FCC BDC block-level
|
|
17
|
+
* availability data, at the granularity this layer ships, is US government public-domain data, not
|
|
18
|
+
* redistribution-restricted; the CostQuest Fabric boundary this workspace never crosses is the
|
|
19
|
+
* licensing edge, see `bdc/README.md` — spine `h3` res 9 for availability rows, res 6 for coverage
|
|
20
|
+
* cells, matching poi.db's convention).
|
|
21
|
+
*
|
|
22
|
+
* Clustering decision (implementer's pick — the brief allows either): a PLAIN rowid table, NOT
|
|
23
|
+
* `WITHOUT ROWID`, and NOT a composite `(h3_cell, provider_id, technology_code)` primary key.
|
|
24
|
+
* `WITHOUT ROWID` earns its keep on small, PK-probed rows — poi.db's clustered key and
|
|
25
|
+
* `layer_coverage`'s per-cell probe both read by their exact PK and nothing else, so folding the row
|
|
26
|
+
* into the B-tree removes a second lookup. `bdc_availability` doesn't fit that shape: it's a wider,
|
|
27
|
+
* 10-column row read two different ways — an h3-range scan ("everything near this cell", the
|
|
28
|
+
* coverage/overlay path) and a geoid point lookup (the public spatial join key TIGER and callers
|
|
29
|
+
* actually probe by) — never a single composite-key point probe. Clustering the full row under a
|
|
30
|
+
* composite PK would also force the bulk loader to sort-then-insert in that exact key order across
|
|
31
|
+
* millions of rows spread over per-provider, per-state source files, for a locality win a plain
|
|
32
|
+
* index already delivers without constraining ingest order. So: a regular rowid table, an index on
|
|
33
|
+
* `h3_cell` bundled into {@link createBDCAvailabilityTable} (every reader depends on it, same as the
|
|
34
|
+
* table itself), and {@link createBDCGeoidIndex} as a separate, callable-after-bulk-load secondary
|
|
35
|
+
* index for the geoid path — the index-after-load discipline used elsewhere in this repo (see
|
|
36
|
+
* poi-schema.ts's name_key/brand indexes).
|
|
37
|
+
*/
|
|
38
|
+
import type { LayerContractDatabase } from "@mailwoman/core/layers";
|
|
39
|
+
import type { Kysely } from "kysely";
|
|
40
|
+
/**
|
|
41
|
+
* One availability row from the FCC's per-provider BDC CSV. In the default build mode this is one row per DISTINCT
|
|
42
|
+
* (geoid, provider_id, technology_code, speeds, low_latency, business_residential_code) tuple — NOT one row per (block,
|
|
43
|
+
* provider, technology) triple; a triple whose BSLs carry differing speed tiers keeps multiple rows here (see
|
|
44
|
+
* `build-bdc.ts`'s docstring).
|
|
45
|
+
*/
|
|
46
|
+
export interface BDCAvailabilityTable {
|
|
47
|
+
/**
|
|
48
|
+
* Res-9 integer short H3 cell of the block centroid (spine).
|
|
49
|
+
*/
|
|
50
|
+
h3_cell: number;
|
|
51
|
+
/**
|
|
52
|
+
* 15-char census block GEOID (public spatial key).
|
|
53
|
+
*/
|
|
54
|
+
geoid: string;
|
|
55
|
+
/**
|
|
56
|
+
* Block-centroid PIP at build time (spine).
|
|
57
|
+
*/
|
|
58
|
+
wof_id: number | null;
|
|
59
|
+
provider_id: number;
|
|
60
|
+
technology_code: number;
|
|
61
|
+
max_advertised_download_speed: number;
|
|
62
|
+
max_advertised_upload_speed: number;
|
|
63
|
+
low_latency: 0 | 1;
|
|
64
|
+
business_residential_code: string;
|
|
65
|
+
/**
|
|
66
|
+
* Opaque BSL join key — NEVER resolved (spec §2.2); null unless `--include-location-ids`.
|
|
67
|
+
*/
|
|
68
|
+
location_id: string | null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Provider dictionary keyed on `provider_id`. Populated by a later registry-join task (2a decision 8) — that task is 3a
|
|
72
|
+
* Task 8's optional `BuildBDCOptions.providers` (`bdc/sdk/build-bdc.ts`'s `populateBDCProviderTable`); when that option
|
|
73
|
+
* is omitted (the default), this table stays empty, exactly as it did before Task 8. No FK constraint against
|
|
74
|
+
* `bdc_availability.provider_id` — SQLite doesn't enforce FKs without `PRAGMA foreign_keys`, and the join happens at
|
|
75
|
+
* read time, not write time.
|
|
76
|
+
*
|
|
77
|
+
* **Decision 6 — this table is an explicitly LOSSY denormalization, not the source of truth.** `provider_id` is the PK
|
|
78
|
+
* (one row per provider), but the FCC's BDC provider list lets one `provider_id` carry MULTIPLE `frn` values — and
|
|
79
|
+
* conflicting `holding_company` strings — across its rows (Task 3's `parseProviderList` preserves every one of them;
|
|
80
|
+
* see `filer/sdk/provider-list.ts`). A single-row-per-provider table cannot express that cardinality. `filer.db`
|
|
81
|
+
* (`@mailwoman/filer`) is the source of truth: it retains every `provider_id`↔`frn` (and
|
|
82
|
+
* `provider_id`↔`holding_company_name`) edge, never folded or last-wins. When `bdc.db` is built with
|
|
83
|
+
* `BuildBDCOptions.providers` supplied:
|
|
84
|
+
*
|
|
85
|
+
* - `frn` holds only the PRIMARY FRN — the one carrying the most recent Form 499 filing date, per
|
|
86
|
+
* `@mailwoman/filer/sdk`'s `readFRNFilingCandidates` + `pickPrimaryFRN` (imported into `build-bdc.ts`, never
|
|
87
|
+
* reimplemented — Task 7's review found and fixed a temporal bug in that exact query, one a fresh implementation
|
|
88
|
+
* would reintroduce). Every OTHER FRN that `provider_id` carries is discarded here but stays fully recoverable from
|
|
89
|
+
* `filer.db`.
|
|
90
|
+
* - `holding_company` gets the SAME single-distinct-value shortcut `frn` gets (review fix round 1, IMPORTANT-3): when a
|
|
91
|
+
* `provider_id`'s rows carry exactly one distinct non-null `holding_company` string, there is no conflict to resolve,
|
|
92
|
+
* so it's populated directly — no rule needed, same as a single-FRN provider needs no `filerDB` query. When they
|
|
93
|
+
* carry MORE than one distinct value, that ambiguity is the real conflict decision 6 refuses to paper over with
|
|
94
|
+
* last-wins (`holding_company` has no most-recent-filing-date rule the way `frn` does), so it stays NULL and every
|
|
95
|
+
* discarded value remains recoverable from `filer.db`'s `holding_company_name` edges — the identical discipline
|
|
96
|
+
* `frn`'s primary pick already applies.
|
|
97
|
+
* - `brand_name` stays NULL unconditionally: the provider list carries no brand-name column at all, primary or otherwise,
|
|
98
|
+
* so there is nothing to populate it from.
|
|
99
|
+
*/
|
|
100
|
+
export interface BDCProviderTable {
|
|
101
|
+
/**
|
|
102
|
+
* PK.
|
|
103
|
+
*/
|
|
104
|
+
provider_id: number;
|
|
105
|
+
frn: string | null;
|
|
106
|
+
brand_name: string | null;
|
|
107
|
+
holding_company: string | null;
|
|
108
|
+
}
|
|
109
|
+
export interface BDCDatabase extends LayerContractDatabase {
|
|
110
|
+
bdc_availability: BDCAvailabilityTable;
|
|
111
|
+
bdc_provider: BDCProviderTable;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* H3 resolution for `bdc_availability.h3_cell` — the block-centroid spine resolution.
|
|
115
|
+
*/
|
|
116
|
+
export declare const BDC_H3_RESOLUTION = 9;
|
|
117
|
+
/**
|
|
118
|
+
* H3 resolution for `layer_coverage.h3_cell` in bdc.db — coarser than the availability spine, matching poi.db's res-6
|
|
119
|
+
* coverage-cell convention.
|
|
120
|
+
*/
|
|
121
|
+
export declare const BDC_COVERAGE_H3_RESOLUTION = 6;
|
|
122
|
+
/**
|
|
123
|
+
* Create `bdc_availability` as a plain rowid table, plus the `h3_cell` range-scan index (bundled here since every
|
|
124
|
+
* reader depends on it — see the file header for the clustering rationale). Call {@link createBDCGeoidIndex}
|
|
125
|
+
* separately, after bulk load, for the geoid point-lookup path.
|
|
126
|
+
*/
|
|
127
|
+
export declare function createBDCAvailabilityTable(db: Kysely<BDCDatabase>): Promise<void>;
|
|
128
|
+
/**
|
|
129
|
+
* Create `bdc_provider`. A single-column INTEGER PRIMARY KEY is already the SQLite rowid alias, so there's no `WITHOUT
|
|
130
|
+
* ROWID` win here — that modifier only pays off clustering a composite or non-integer PK.
|
|
131
|
+
*/
|
|
132
|
+
export declare function createBDCProviderTable(db: Kysely<BDCDatabase>): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Secondary index for the geoid point-lookup path (the public spatial join key). Call AFTER the bulk materialize
|
|
135
|
+
* (index-after-load), same discipline as poi.db's secondary indexes.
|
|
136
|
+
*/
|
|
137
|
+
export declare function createBDCGeoidIndex(db: Kysely<BDCDatabase>): Promise<void>;
|
|
138
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,6BAA6B,EAAE,MAAM,CAAA;IACrC,2BAA2B,EAAE,MAAM,CAAA;IACnC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAA;IAClB,yBAAyB,EAAE,MAAM,CAAA;IACjC;;OAEG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,gBAAgB;IAChC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B;AAED,MAAM,WAAW,WAAY,SAAQ,qBAAqB;IACzD,gBAAgB,EAAE,oBAAoB,CAAA;IACtC,YAAY,EAAE,gBAAgB,CAAA;CAC9B;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,IAAI,CAAA;AAElC;;;GAGG;AACH,eAAO,MAAM,0BAA0B,IAAI,CAAA;AAE3C;;;;GAIG;AACH,wBAAsB,0BAA0B,CAAC,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBvF;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAQnF;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhF"}
|
package/out/schema.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software.
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* Typed schema for bdc.db — the FCC Broadband Data Collection availability read-side layer (2a
|
|
7
|
+
* decisions 4, 8). `bdc_availability` holds, in the default (non-`includeLocationIDs`) build mode, one
|
|
8
|
+
* row per DISTINCT (geoid, provider_id, technology_code, max_advertised_download_speed,
|
|
9
|
+
* max_advertised_upload_speed, low_latency, business_residential_code) tuple parsed from the FCC's
|
|
10
|
+
* per-provider CSV (see `sdk/parsing.ts`) — NOT one row per (block, provider, technology) triple: when
|
|
11
|
+
* two Broadband Serviceable Locations in the same block file different speeds/flags for the same
|
|
12
|
+
* provider/technology, both rows survive `build-bdc.ts`'s materialize-time collapse (see that file's
|
|
13
|
+
* docstring; accepted FCC filing behavior, not a bug). `bdc_provider` is a small dictionary
|
|
14
|
+
* keyed on `provider_id`, populated by a later registry-join task — decision 8 keeps FRN/brand/
|
|
15
|
+
* holding-company resolution out of 2a's scope. The DB also embeds the layer-contract tables from
|
|
16
|
+
* `@mailwoman/core/layers` (manifest tier `shipped`, license `public-domain` — FCC BDC block-level
|
|
17
|
+
* availability data, at the granularity this layer ships, is US government public-domain data, not
|
|
18
|
+
* redistribution-restricted; the CostQuest Fabric boundary this workspace never crosses is the
|
|
19
|
+
* licensing edge, see `bdc/README.md` — spine `h3` res 9 for availability rows, res 6 for coverage
|
|
20
|
+
* cells, matching poi.db's convention).
|
|
21
|
+
*
|
|
22
|
+
* Clustering decision (implementer's pick — the brief allows either): a PLAIN rowid table, NOT
|
|
23
|
+
* `WITHOUT ROWID`, and NOT a composite `(h3_cell, provider_id, technology_code)` primary key.
|
|
24
|
+
* `WITHOUT ROWID` earns its keep on small, PK-probed rows — poi.db's clustered key and
|
|
25
|
+
* `layer_coverage`'s per-cell probe both read by their exact PK and nothing else, so folding the row
|
|
26
|
+
* into the B-tree removes a second lookup. `bdc_availability` doesn't fit that shape: it's a wider,
|
|
27
|
+
* 10-column row read two different ways — an h3-range scan ("everything near this cell", the
|
|
28
|
+
* coverage/overlay path) and a geoid point lookup (the public spatial join key TIGER and callers
|
|
29
|
+
* actually probe by) — never a single composite-key point probe. Clustering the full row under a
|
|
30
|
+
* composite PK would also force the bulk loader to sort-then-insert in that exact key order across
|
|
31
|
+
* millions of rows spread over per-provider, per-state source files, for a locality win a plain
|
|
32
|
+
* index already delivers without constraining ingest order. So: a regular rowid table, an index on
|
|
33
|
+
* `h3_cell` bundled into {@link createBDCAvailabilityTable} (every reader depends on it, same as the
|
|
34
|
+
* table itself), and {@link createBDCGeoidIndex} as a separate, callable-after-bulk-load secondary
|
|
35
|
+
* index for the geoid path — the index-after-load discipline used elsewhere in this repo (see
|
|
36
|
+
* poi-schema.ts's name_key/brand indexes).
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* H3 resolution for `bdc_availability.h3_cell` — the block-centroid spine resolution.
|
|
40
|
+
*/
|
|
41
|
+
export const BDC_H3_RESOLUTION = 9;
|
|
42
|
+
/**
|
|
43
|
+
* H3 resolution for `layer_coverage.h3_cell` in bdc.db — coarser than the availability spine, matching poi.db's res-6
|
|
44
|
+
* coverage-cell convention.
|
|
45
|
+
*/
|
|
46
|
+
export const BDC_COVERAGE_H3_RESOLUTION = 6;
|
|
47
|
+
/**
|
|
48
|
+
* Create `bdc_availability` as a plain rowid table, plus the `h3_cell` range-scan index (bundled here since every
|
|
49
|
+
* reader depends on it — see the file header for the clustering rationale). Call {@link createBDCGeoidIndex}
|
|
50
|
+
* separately, after bulk load, for the geoid point-lookup path.
|
|
51
|
+
*/
|
|
52
|
+
export async function createBDCAvailabilityTable(db) {
|
|
53
|
+
await db.schema
|
|
54
|
+
.createTable("bdc_availability")
|
|
55
|
+
.addColumn("h3_cell", "integer", (c) => c.notNull())
|
|
56
|
+
.addColumn("geoid", "text", (c) => c.notNull())
|
|
57
|
+
.addColumn("wof_id", "integer")
|
|
58
|
+
.addColumn("provider_id", "integer", (c) => c.notNull())
|
|
59
|
+
.addColumn("technology_code", "integer", (c) => c.notNull())
|
|
60
|
+
.addColumn("max_advertised_download_speed", "integer", (c) => c.notNull())
|
|
61
|
+
.addColumn("max_advertised_upload_speed", "integer", (c) => c.notNull())
|
|
62
|
+
.addColumn("low_latency", "integer", (c) => c.notNull())
|
|
63
|
+
.addColumn("business_residential_code", "text", (c) => c.notNull())
|
|
64
|
+
.addColumn("location_id", "text")
|
|
65
|
+
.execute();
|
|
66
|
+
await db.schema.createIndex("bdc_availability_h3_cell").on("bdc_availability").column("h3_cell").execute();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create `bdc_provider`. A single-column INTEGER PRIMARY KEY is already the SQLite rowid alias, so there's no `WITHOUT
|
|
70
|
+
* ROWID` win here — that modifier only pays off clustering a composite or non-integer PK.
|
|
71
|
+
*/
|
|
72
|
+
export async function createBDCProviderTable(db) {
|
|
73
|
+
await db.schema
|
|
74
|
+
.createTable("bdc_provider")
|
|
75
|
+
.addColumn("provider_id", "integer", (c) => c.primaryKey())
|
|
76
|
+
.addColumn("frn", "text")
|
|
77
|
+
.addColumn("brand_name", "text")
|
|
78
|
+
.addColumn("holding_company", "text")
|
|
79
|
+
.execute();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Secondary index for the geoid point-lookup path (the public spatial join key). Call AFTER the bulk materialize
|
|
83
|
+
* (index-after-load), same discipline as poi.db's secondary indexes.
|
|
84
|
+
*/
|
|
85
|
+
export async function createBDCGeoidIndex(db) {
|
|
86
|
+
await db.schema.createIndex("bdc_availability_geoid").on("bdc_availability").column("geoid").execute();
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAiFH;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAA;AAElC;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAA;AAE3C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,EAAuB;IACvE,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,kBAAkB,CAAC;SAC/B,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACnD,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC9C,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC;SAC9B,SAAS,CAAC,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACvD,SAAS,CAAC,iBAAiB,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC3D,SAAS,CAAC,+BAA+B,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACzE,SAAS,CAAC,6BAA6B,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACvE,SAAS,CAAC,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACvD,SAAS,CAAC,2BAA2B,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAClE,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC;SAChC,OAAO,EAAE,CAAA;IAEX,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAA;AAC3G,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAAuB;IACnE,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,cAAc,CAAC;SAC3B,SAAS,CAAC,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;SAC1D,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;SACxB,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC;SAC/B,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC;SACpC,OAAO,EAAE,CAAA;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EAAuB;IAChE,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAA;AACvG,CAAC"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The `bdc.db` builder (2a Task 8) — ingests parsed FCC BDC availability rows (Task 6's
|
|
7
|
+
* {@link BDCAvailabilityRow}) into Task 7's schema (`schema.ts`), producing a sealed layer database.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors `mailwoman/gazetteer-pipeline/poi/build-poi.ts`'s shape closely: the same build-tuning
|
|
10
|
+
* pragmas, the same single-pass `Map<number, number>` coverage aggregation taken during the load
|
|
11
|
+
* (no second scan), the same {@link asContractDB} Kysely-invariance cast for the shared
|
|
12
|
+
* `@mailwoman/core/layers` calls, and the same `writeLayerManifest` → `sealDatabase` tail.
|
|
13
|
+
*
|
|
14
|
+
* Two differences from that precedent, both deliberate:
|
|
15
|
+
*
|
|
16
|
+
* 1. **A staging-dedup pass.** BDC's per-provider CSVs can carry exact-duplicate rows (repeat
|
|
17
|
+
* filings, overlapping re-downloads); poi's Overture rows never needed this. `bdc_stage` is a
|
|
18
|
+
* plain Kysely-built table (not part of the public {@link BDCDatabase} — it never survives to the
|
|
19
|
+
* sealed artifact) carrying a composite PRIMARY KEY on the natural key
|
|
20
|
+
* `(geoid, provider_id, technology_code, location_id)`. Rows load via a RAW prepared
|
|
21
|
+
* `INSERT OR IGNORE` — the AGENTS.md "hot bulk write" carve-out, same discipline as the
|
|
22
|
+
* candidate-gazetteer builder — which is the direct replacement for the Redis
|
|
23
|
+
* set-membership check Nexus's `sync/commands/bdc/infer-locations.ts` used for this exact
|
|
24
|
+
* dedup (dedup semantics only; Nexus's Redis-backed location inference itself has no analog
|
|
25
|
+
* here). `h3_cell` is computed only AFTER staging, per distinct geoid, against the deduped set —
|
|
26
|
+
* so a duplicate row is never charged twice against `unknownGeoids` or `layer_coverage` either.
|
|
27
|
+
* The natural key's `location_id` component means the SAME (geoid, provider_id, technology_code)
|
|
28
|
+
* triple legitimately survives staging once per distinct BSL — correct when `includeLocationIDs`
|
|
29
|
+
* is true. The default (NULL `location_id`) mode collapses at MATERIALIZE time via `SELECT DISTINCT`
|
|
30
|
+
* over every column EXCEPT `location_id` — that is, to one row per distinct (geoid, provider_id,
|
|
31
|
+
* technology_code, max_advertised_download_speed, max_advertised_upload_speed, low_latency,
|
|
32
|
+
* business_residential_code) TUPLE, NOT one row per (geoid, provider_id, technology_code) triple.
|
|
33
|
+
* When every BSL in a block shares identical speeds/flags for a given provider/technology (the
|
|
34
|
+
* common case), those two are the same thing and the collapse yields exactly one row per triple.
|
|
35
|
+
* But when BSLs at the SAME triple carry DIFFERENT speeds/flags (a real, accepted FCC filing
|
|
36
|
+
* pattern — a provider filing different advertised speeds at different addresses in one block),
|
|
37
|
+
* the distinct rows survive collapse as multiple NULL-`location_id` rows at that one triple. This
|
|
38
|
+
* is deliberate, matches the FCC source data's own granularity, and is NOT a bug to fix — see
|
|
39
|
+
* `filing-landscape.ts`'s module docstring for the read-side consequence (the same provider/tech
|
|
40
|
+
* can surface in more than one `speed_bucket` for one queried block).
|
|
41
|
+
* 2. **Temp-path build + move-aside-first swap**, per AGENTS.md's database house rule ("build
|
|
42
|
+
* successfully, then move the previous version to a temp directory, and then move the new
|
|
43
|
+
* version into place... ensures the database is always in a consistent state, even if the build
|
|
44
|
+
* script fails halfway through"): build lands at `${out}.building`, seals there, then
|
|
45
|
+
* `${out}` (if present) is renamed to `${out}.prev` BEFORE the sealed build takes its place —
|
|
46
|
+
* mirroring `mailwoman/eval-harness/gauntlet/build-regression-db.ts`'s swap. `build-poi.ts`
|
|
47
|
+
* instead writes `out` directly (removing any stale file first) and records ITS OWN deviation
|
|
48
|
+
* from an even older staging-suffix convention — see that file's docstring. This builder takes
|
|
49
|
+
* the opposite fork on purpose: a from-scratch nationwide BDC ingest is long enough that a
|
|
50
|
+
* mid-build crash mustn't cost the previously-good artifact, which is exactly the failure mode
|
|
51
|
+
* the house rule exists for.
|
|
52
|
+
*/
|
|
53
|
+
import { DatabaseClient } from "@mailwoman/core/kysley/client";
|
|
54
|
+
import type { FilerDatabase } from "@mailwoman/filer";
|
|
55
|
+
import type { ProviderListRow } from "@mailwoman/filer/sdk";
|
|
56
|
+
import type { ProviderID } from "./common.ts";
|
|
57
|
+
import { type BDCAvailabilityRow } from "./parsing.ts";
|
|
58
|
+
/**
|
|
59
|
+
* The manifest's `attribution` — names the FCC as the source, then copies the Fabric-boundary sentence verbatim from
|
|
60
|
+
* `bdc/README.md`'s "CostQuest Fabric boundary" section (backticks stripped — this is plain prose, not markdown).
|
|
61
|
+
*/
|
|
62
|
+
export declare const BDC_ATTRIBUTION: string;
|
|
63
|
+
export interface BuildBDCOptions {
|
|
64
|
+
/**
|
|
65
|
+
* Injected row source — the test seam (mirrors `BuildPOIOptions.rows`). When given, `csvPaths` is ignored and no
|
|
66
|
+
* filesystem read happens.
|
|
67
|
+
*/
|
|
68
|
+
rows?: Iterable<BDCAvailabilityRow> | AsyncIterable<BDCAvailabilityRow>;
|
|
69
|
+
/**
|
|
70
|
+
* Per-provider availability CSVs for one state (as extracted by `downloadBDCFile`). Ignored when `rows` is given.
|
|
71
|
+
* Required unless `rows` is given. Each file's constant `provider_id` column is peeked off its first data row (see
|
|
72
|
+
* {@linkcode peekProviderID}) rather than threaded through as a parallel array — the FCC's per-provider files already
|
|
73
|
+
* carry it once per file, redundantly, in column 1.
|
|
74
|
+
*/
|
|
75
|
+
csvPaths?: string[];
|
|
76
|
+
/**
|
|
77
|
+
* Output `bdc.db` path. Built at `${out}.building` and moved into place last — see the module docstring.
|
|
78
|
+
*/
|
|
79
|
+
out: string;
|
|
80
|
+
/**
|
|
81
|
+
* The FCC filing's `as_of_date` (e.g. from Task 5's `resolveLatestVintage`) — becomes the manifest's `sourceVintage`
|
|
82
|
+
* AND `version` (BDC has no independent layer versioning yet, same deferral `build-poi.ts` makes for `release`).
|
|
83
|
+
*/
|
|
84
|
+
asOfDate: string;
|
|
85
|
+
/**
|
|
86
|
+
* `git rev-parse --short HEAD` — passed in by the command, not read from the repo here.
|
|
87
|
+
*/
|
|
88
|
+
buildSHA: string;
|
|
89
|
+
/**
|
|
90
|
+
* Populate `bdc_availability.location_id` (the opaque BSL join key — spec §2.2, NEVER resolved against the Fabric).
|
|
91
|
+
* Default `false`: the column stays `NULL` unless a caller explicitly opts in.
|
|
92
|
+
*/
|
|
93
|
+
includeLocationIDs?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Resolve a 15-char census block GEOID to its centroid. Injected so tests supply a small fixture `Map` lookup instead
|
|
96
|
+
* of touching a real TIGER database; the real (CLI-wired) implementation is
|
|
97
|
+
* {@linkcode createTIGERBlockCentroidLookup}, which reads `tabblock20.GEOID` (uppercase — `TIGERBlockTable`) block
|
|
98
|
+
* geometry. Returning `undefined` for an unknown geoid is load-bearing: the materialize pass counts it in
|
|
99
|
+
* `unknownGeoids` and skips the row — it must NEVER guess a cell.
|
|
100
|
+
*/
|
|
101
|
+
blockCentroids: (geoid: string) => {
|
|
102
|
+
lat: number;
|
|
103
|
+
lon: number;
|
|
104
|
+
} | undefined;
|
|
105
|
+
onProgress?: (message: string) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Provider-list rows (Task 3's {@link ProviderListRow}, `@mailwoman/filer/sdk`'s `parseProviderList`) — the test/CLI
|
|
108
|
+
* seam for populating `bdc_provider` (2a decision 8 / 3a decision 6, Task 8). When ABSENT (the default),
|
|
109
|
+
* `bdc_provider` stays empty and the rest of the build is byte-identical to the pre-Task-8 behavior: every code path
|
|
110
|
+
* this option touches is gated behind `if (options.providers)`, so omitting it changes nothing. When present,
|
|
111
|
+
* `buildBDCDatabase` groups rows by `providerID` and inserts one `bdc_provider` row per distinct provider — see
|
|
112
|
+
* {@link BuildBDCOptions.filerDB} for how the primary FRN is picked when a provider carries more than one, and
|
|
113
|
+
* `schema.ts`'s `BDCProviderTable` docstring for the full lossy-denormalization rationale (decision 6).
|
|
114
|
+
*/
|
|
115
|
+
providers?: Iterable<ProviderListRow> | AsyncIterable<ProviderListRow>;
|
|
116
|
+
/**
|
|
117
|
+
* Filer.db handle (`@mailwoman/filer`) used to resolve a multi-FRN provider's PRIMARY FRN via
|
|
118
|
+
* `readFRNFilingCandidates` + `pickPrimaryFRN` (`@mailwoman/filer/sdk`, decision 6) — imported rather than
|
|
119
|
+
* reimplemented, since Task 7's review found and fixed a temporal bug (the candidate query originally omitted the
|
|
120
|
+
* `valid_to` half of the half-open predicate) that a fresh implementation here would reintroduce. Only actually
|
|
121
|
+
* QUERIED for a `provider_id` whose rows carry more than one distinct `frn` — a single-FRN provider needs no lookup,
|
|
122
|
+
* since its lone FRN is already primary by construction. Required whenever `providers` is given AND at least one
|
|
123
|
+
* `provider_id` turns out to be multi-FRN; `buildBDCDatabase` throws a descriptive error naming the offending
|
|
124
|
+
* `provider_id` if it's needed but missing, rather than silently picking an arbitrary FRN.
|
|
125
|
+
*/
|
|
126
|
+
filerDB?: DatabaseClient<FilerDatabase>;
|
|
127
|
+
/**
|
|
128
|
+
* `asOf` date for the primary-FRN candidate query (`readFRNFilingCandidates`'s half-open `valid_from`/`valid_to`
|
|
129
|
+
* scoping — see `filer/sdk/filer-lookup.ts`). Defaults to {@link BuildBDCOptions.asOfDate} (this bdc.db build's own
|
|
130
|
+
* vintage) when omitted.
|
|
131
|
+
*/
|
|
132
|
+
primaryFRNAsOf?: string;
|
|
133
|
+
}
|
|
134
|
+
export interface BuildBDCResult {
|
|
135
|
+
out: string;
|
|
136
|
+
/**
|
|
137
|
+
* Rows materialized into `bdc_availability` (post-dedup, post-unknown-geoid-skip). In the default
|
|
138
|
+
* (`includeLocationIDs: false`) mode this is per DISTINCT (geoid, provider_id, technology_code, speeds, low_latency,
|
|
139
|
+
* business_residential_code) tuple, not per BSL — multiple BSLs at the same (geoid, provider_id, technology_code)
|
|
140
|
+
* triple collapse to one row ONLY when their speeds/flags also match; BSLs at the same triple with differing
|
|
141
|
+
* speeds/flags survive as separate rows (see the module docstring).
|
|
142
|
+
*/
|
|
143
|
+
rows: number;
|
|
144
|
+
/**
|
|
145
|
+
* Raw rows removed by the staging natural-key dedup (staged attempts minus distinct rows kept).
|
|
146
|
+
*/
|
|
147
|
+
deduped: number;
|
|
148
|
+
/**
|
|
149
|
+
* Distinct `provider_id` values among the materialized rows.
|
|
150
|
+
*/
|
|
151
|
+
providers: number;
|
|
152
|
+
/**
|
|
153
|
+
* Res-6 coverage cells written.
|
|
154
|
+
*/
|
|
155
|
+
coverageCells: number;
|
|
156
|
+
/**
|
|
157
|
+
* Rows whose `geoid` had no resolvable centroid — skipped, never inserted, never guessed at a cell.
|
|
158
|
+
*/
|
|
159
|
+
unknownGeoids: number;
|
|
160
|
+
/**
|
|
161
|
+
* `bdc_provider` rows written — 0 when `options.providers` was not supplied (the default path never touches this
|
|
162
|
+
* table, see {@link BuildBDCOptions.providers}).
|
|
163
|
+
*/
|
|
164
|
+
providersPopulated: number;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Peek the constant `provider_id` column (index 1) off an FCC BDC availability CSV's first data row.
|
|
168
|
+
*
|
|
169
|
+
* Production per-provider files carry the SAME `provider_id` in every row (the FCC partitions availability files per
|
|
170
|
+
* provider) — `parsing.ts`'s `takeAvailabilityLine` already assumes this, taking `providerID` as a parameter rather
|
|
171
|
+
* than re-slicing column 1 per row. This reads it once, directly off the raw bytes, rather than threading a parallel
|
|
172
|
+
* `providerID` array alongside `csvPaths` through the public options shape.
|
|
173
|
+
*
|
|
174
|
+
* `csvPath` is optional and used ONLY to name the offending file in a thrown error (the direct-buffer unit tests call
|
|
175
|
+
* this without one; {@linkcode readAvailabilityRowsFromCSVPaths} always supplies it). The `Number.isSafeInteger` guard
|
|
176
|
+
* below is load-bearing, not defensive dressing: `bdc_stage.provider_id` is `INTEGER NOT NULL`, and a bare
|
|
177
|
+
* `Number.parseInt` on a non-numeric field (a malformed/re-headered/truncated CSV) silently produces `NaN`. `NaN` binds
|
|
178
|
+
* to that NOT NULL column as SQLite `NULL`, `INSERT OR IGNORE` then drops the row without a constraint error, and every
|
|
179
|
+
* dropped row gets counted as `deduped` — the ENTIRE file's rows vanish silently, misreported as ordinary dedup. A
|
|
180
|
+
* malformed CSV must be loud, never silently absorbed, so this throws instead.
|
|
181
|
+
*/
|
|
182
|
+
export declare function peekProviderID(csvBuffer: Buffer, csvPath?: string): ProviderID;
|
|
183
|
+
/**
|
|
184
|
+
* Naive (vertex-average, NOT area-weighted) centroid of a GeoJSON `Polygon`/`MultiPolygon`'s EXTERIOR ring(s) only
|
|
185
|
+
* (interior rings/holes are ignored). A known simplification, not an oversight: census blocks are small relative to a
|
|
186
|
+
* res-9 H3 cell (~174m edge), so the vertex-average and a proper area-weighted centroid land in the same cell for all
|
|
187
|
+
* but pathologically elongated or holed block shapes. A precise area-weighted centroid is a reasonable future upgrade
|
|
188
|
+
* if that ever proves wrong in practice — no polygon-centroid library is pulled in for this first cut.
|
|
189
|
+
*
|
|
190
|
+
* Returns `undefined` for anything that doesn't parse as one of the two geometry types (including `null` geometry).
|
|
191
|
+
*/
|
|
192
|
+
export declare function geometryCentroid(geometryJSON: string | null): {
|
|
193
|
+
lat: number;
|
|
194
|
+
lon: number;
|
|
195
|
+
} | undefined;
|
|
196
|
+
/**
|
|
197
|
+
* The production `blockCentroids` supplier: opens the TIGER blocks database READ-ONLY and probes `tabblock20.GEOID`
|
|
198
|
+
* (uppercase) per lookup, decoding its GeoJSON `geometry` column via {@linkcode geometryCentroid}. Kept synchronous —
|
|
199
|
+
* `BuildBDCOptions.blockCentroids` is a plain sync function (the same sync-by-interface discipline AGENTS.md documents
|
|
200
|
+
* for the resolver ladder), so this uses `node:sqlite`'s raw `.prepare()`/`.get()` directly rather than Kysely. The
|
|
201
|
+
* connection is left open for the caller's process lifetime (a read-path lookup, not a build) — same lifecycle as the
|
|
202
|
+
* resolver-wof-sqlite lookups.
|
|
203
|
+
*/
|
|
204
|
+
export declare function createTIGERBlockCentroidLookup(tigerDBPath: string): (geoid: string) => {
|
|
205
|
+
lat: number;
|
|
206
|
+
lon: number;
|
|
207
|
+
} | undefined;
|
|
208
|
+
/**
|
|
209
|
+
* Build `bdc.db`: stage (raw dedup) → materialize (resolve `h3_cell` per geoid, skip+count unknown geoids) → drop stage
|
|
210
|
+
* → geoid index (index-after-load) → coverage → layer manifest → seal → atomic move-into-place. See the module
|
|
211
|
+
* docstring for the two deliberate deviations from `build-poi.ts`.
|
|
212
|
+
*/
|
|
213
|
+
export declare function buildBDCDatabase(options: BuildBDCOptions): Promise<BuildBDCResult>;
|
|
214
|
+
//# sourceMappingURL=build-bdc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-bdc.d.ts","sourceRoot":"","sources":["../../sdk/build-bdc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAOH,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAW9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAKrD,OAAO,KAAK,EAAO,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAchE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAwB,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAQ5E;;;GAGG;AACH,eAAO,MAAM,eAAe,QAEqF,CAAA;AAEjH,MAAM,WAAW,eAAe;IAC/B;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAA;IACvE;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IACX;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;;;OAMG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAA;IAC3E,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,aAAa,CAAC,eAAe,CAAC,CAAA;IACtE;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC,aAAa,CAAC,CAAA;IACvC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,cAAc;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,kBAAkB,EAAE,MAAM,CAAA;CAC1B;AAsDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,CA+B9E;AA8BD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAsCtG;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC7C,WAAW,EAAE,MAAM,GACjB,CAAC,KAAK,EAAE,MAAM,KAAK;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAS7D;AAmHD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CA6RxF"}
|