@kahwee/sf-map-svg 5.0.0 → 5.1.1
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/CHANGELOG.md +19 -0
- package/README.md +17 -2
- package/SOURCES.md +53 -0
- package/dist/data/index.d.ts +1 -0
- package/dist/data/index.js +1 -0
- package/dist/data/precincts-2022.json +1 -0
- package/dist/data/precincts.d.ts +2 -0
- package/dist/data/precincts.js +5 -0
- package/dist/data/types.d.ts +5 -0
- package/dist/src/district-controller.d.ts +64 -0
- package/dist/src/district-controller.js +215 -0
- package/dist/src/explorer-core.js +52 -181
- package/llms-full.txt +114 -13
- package/llms.txt +1 -1
- package/package.json +37 -24
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,25 @@ User-visible changes are recorded here. Unreleased entries describe changes on `
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 5.1.1 — 2026-11-05
|
|
8
|
+
|
|
9
|
+
- Reserve precinct report controls and status space during loading to prevent phone layout shifts when multiple reports are available.
|
|
10
|
+
|
|
11
|
+
- Isolate district selection, style revisions and cancellable motion in an internal controller while preserving public map behavior. Document interactive state ownership and verify district lifecycle callbacks.
|
|
12
|
+
|
|
13
|
+
## 5.1.0 — 2026-11-05
|
|
14
|
+
|
|
15
|
+
- Add official November 2026 precinct aggregates (`data/elections/precincts-<report time>.json` with a time-ordered `precincts-index.json`) and the 2022 precinct boundaries (`data/precincts-2022.json`), reconciled with the department's summary report. Only aggregates are committed, never the ballot-level export. Export the boundaries as `precinctMaps` from `@kahwee/sf-map-svg/data` and `@kahwee/sf-map-svg/data/precincts`; results snapshots stay Pages data.
|
|
16
|
+
- Update Biome to 2.6.3 and the aligned Storybook packages to 10.6.4.
|
|
17
|
+
- Gate library output replacement on Bun source checking, then emit JavaScript, declarations, and JSON with TypeScript `--noCheck`; install pinned Bun in every build job.
|
|
18
|
+
- Align Storybook on 10.6.3 and Vitest/browser/coverage tooling on 5.0.5, with compatible dependency updates for current security fixes.
|
|
19
|
+
- Record identical-output library build benchmarks alongside the earlier build-reuse measurements.
|
|
20
|
+
- Reuse completed library builds in CI demo, Storybook, coverage, and Pages steps; retain fresh builds for standalone commands and archive packing.
|
|
21
|
+
- Add a reproducible compilation-phase benchmark that checks emitted-output equivalence.
|
|
22
|
+
- Use Bun for consumer, Storybook, and website project checks; run them once in the Bun CI job instead of repeating them in the Node matrix.
|
|
23
|
+
- Add a Pages precinct results page (`precincts.html`) that shades the 514 precincts by any contest in the latest official snapshot, and compact the committed precinct snapshot to about 0.6 MB with a 5 KB reconciliation fixture.
|
|
24
|
+
- Fix election page checks on 390 px phones and in macOS Chromium, and wait for the scrollbar gutter in popover checks.
|
|
25
|
+
|
|
7
26
|
## 5.0.0 — 2026-10-19
|
|
8
27
|
|
|
9
28
|
- Breaking: controller `setMode` and `setSource` preserve the camera; remove their `{ resetView }` argument. Call `camera.reset()` or `camera.fit()` explicitly.
|
package/README.md
CHANGED
|
@@ -81,7 +81,7 @@ function disposeMap() {
|
|
|
81
81
|
}
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
`createMap(data, options)` returns a controller. Use `map.element` for mounting, `map.configure({ features, layers, controls, appearance, mode, source, year, labels })` for runtime switches, `map.camera` for pan/zoom/fit/reset, and `map.on()` for typed events. Appearance can change live while preserving camera, selection, and focus. `getResolvedConfiguration()` explains effective layers; `getCapabilities()` reports supplied geography. SFAR realtor neighborhoods are the default when supplied; SF Find and analysis are explicit alternate sources. The `/data/full` preset includes all three collections and historical districts.
|
|
84
|
+
`createMap(data, options)` returns a controller. Use `map.element` for mounting, `map.configure({ features, layers, controls, appearance, mode, source, year, labels })` for runtime switches, `map.camera` for pan/zoom/fit/reset, and `map.on()` for typed events. Appearance can change live while preserving camera, selection, and focus. `getResolvedConfiguration()` explains effective layers; `getCapabilities()` reports supplied geography. SFAR realtor neighborhoods are the default when supplied; SF Find and analysis are explicit alternate sources. The `/data/full` preset includes all three collections and historical districts. `precinctMaps[2022]` from `@kahwee/sf-map-svg/data/precincts` holds the 514 Department of Elections precinct boundaries (data only, not a rendered layer).
|
|
85
85
|
|
|
86
86
|
See [controller options, events, and lifecycle](docs/API.md#interactive-maps),
|
|
87
87
|
[examples](docs/EXAMPLES.md), and [consumer integration](docs/consumer-integration.md).
|
|
@@ -122,7 +122,7 @@ and [coordinate units](docs/API.md#coordinates-and-units).
|
|
|
122
122
|
|
|
123
123
|
Canonical geography is in [`data/`](data/README.md), with provenance in [`SOURCES.md`](SOURCES.md). The public `/data` entry exposes lookup, catalog, district maps, and source-specific neighborhood collections. These are deeply frozen; clone before editing.
|
|
124
124
|
|
|
125
|
-
Install with `pnpm install --frozen-lockfile`. Bun 1.4.
|
|
125
|
+
Install with `pnpm install --frozen-lockfile`. Bun 1.4.4 is pinned in `.bun-version` for development builds and type checks; `pnpm test:bun` also checks compiled-package imports and static rendering. Strict TypeScript 7.0.2 declarations and packed consumers remain part of the Node/pnpm checks. See the [contributing guide](CONTRIBUTING.md) for architecture and the [validation and release runbook](https://github.com/kahwee/sf-map-svg/blob/main/docs/maintenance.md) for checks, browser inspection, and publishing. If you are upgrading from v2, follow the [v3 migration guide](docs/migration-v3.md).
|
|
126
126
|
|
|
127
127
|
## Browser checks and marker performance
|
|
128
128
|
|
|
@@ -237,3 +237,18 @@ pnpm benchmark:markers --counts=2000 --mode=neighborhoods \
|
|
|
237
237
|
## CI maintenance
|
|
238
238
|
|
|
239
239
|
[GitHub Actions maintenance](.github/ACTIONS.md) covers workflows, parallel checks, action versions, and weekly updates.
|
|
240
|
+
|
|
241
|
+
Project type checks use Bun: `pnpm check:types:built` checks compiled-package
|
|
242
|
+
consumers, Storybook, and the website in parallel after a build. `pnpm check` runs
|
|
243
|
+
the full gate. CI runs `check:node` on Node 24/26 and these Bun checks once in the
|
|
244
|
+
Bun job. TypeScript remains responsible for declaration emission and packed-package
|
|
245
|
+
consumer compatibility tests. Published consumers do not need Bun.
|
|
246
|
+
|
|
247
|
+
On the session’s Linux executor, three-run median project checks measured
|
|
248
|
+
0.402/0.688/0.209 seconds with Bun for consumers/stories/website, versus
|
|
249
|
+
3.156/4.110/2.496 seconds with `pnpm exec tsc -p <project>`. These include command
|
|
250
|
+
startup; they do not predict hosted CI duration.
|
|
251
|
+
|
|
252
|
+
CI reuses completed library output for demos, Storybook, and Pages. Standalone
|
|
253
|
+
commands still build from a clean checkout. See the [toolchain benchmark report](docs/toolchain-benchmarks.md)
|
|
254
|
+
for raw samples, output-equivalence checks, and reproducible commands.
|
package/SOURCES.md
CHANGED
|
@@ -177,3 +177,56 @@ index is https://sfelections.org/results/20121106/detail.php .
|
|
|
177
177
|
reconciles all 2002, 2012, and 2022 district totals. The election JSON files
|
|
178
178
|
are Pages datasets; the historical district maps retain their existing
|
|
179
179
|
display geometry, and no precinct polygons or raw workbook data are shipped.
|
|
180
|
+
|
|
181
|
+
## November 2026 ballot and pending results
|
|
182
|
+
|
|
183
|
+
Downloaded November 4, 2026 UTC (November 3 Pacific):
|
|
184
|
+
https://media.api.sf.gov/documents/N26_EN_VIP.pdf .
|
|
185
|
+
`elections/2026-11-03.json` records its SHA-256 and verification time. Printed
|
|
186
|
+
page 248 lists all 14 state, one regional and ten local measures. Pages 24–51
|
|
187
|
+
supply candidate statement names. The official roster at
|
|
188
|
+
https://www.sf.gov/candidates-november-3-2026-general-election was verified
|
|
189
|
+
on November 4 UTC to complete the 15 displayed candidate contests, adding
|
|
190
|
+
Charles Hoelter, Manuel Noris-Barrera, Philip Louis Wing, Nicholas Berg and
|
|
191
|
+
Jamo Muhammad. The California Secretary of State certified list, downloaded
|
|
192
|
+
November 4 UTC from
|
|
193
|
+
https://elections.cdn.sos.ca.gov/statewide-elections/2026-general/cert-list-candidates.pdf
|
|
194
|
+
(certified August 27, 2026; SHA-256 in the feed), supplies nine additional
|
|
195
|
+
state/Board of Equalization contests on printed pages 1–2 and 13 Supreme Court
|
|
196
|
+
and First Appellate District retention contests on pages 33–34. The latter
|
|
197
|
+
explicitly includes San Francisco County and matches SF pamphlet pp. 246–247.
|
|
198
|
+
Other appellate districts are excluded. Printed candidate coverage does not
|
|
199
|
+
assert independently verified late statewide write-in qualifications.
|
|
200
|
+
The November results endpoint
|
|
201
|
+
https://www.sfelections.org/results/20261103w/index.html returned HTTP 403;
|
|
202
|
+
no November vote totals, report time, winners or geographic results are asserted.
|
|
203
|
+
The existing 2022 supervisorial boundaries are reused only for ballot district
|
|
204
|
+
selection, with neutral fills. See `elections/README.md` for the feed contract
|
|
205
|
+
and the ingestion blocker. Historical snapshots remain separate elections.
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
The independent California Secretary of State public media index at
|
|
209
|
+
https://media.sos.ca.gov/media/json-endpoints.csv identifies the November 3,
|
|
210
|
+
2026 election and links JSON reports. Downloaded November 4 UTC: the reports
|
|
211
|
+
still carry the November 2, 6:28 p.m. zero-report time. The adapter extracts
|
|
212
|
+
only exact San Francisco County rows for 40 supported state/federal candidate, proposition and judicial
|
|
213
|
+
contests. It does not use statewide totals, infer precinct boundaries, or map
|
|
214
|
+
county totals onto districts. Actual extracted fixtures and their URLs are
|
|
215
|
+
recorded in `test/fixtures/sos/README.md`. Zero reports stay pending, and report
|
|
216
|
+
time is preserved verbatim separately from fetch time.
|
|
217
|
+
|
|
218
|
+
### November 2026 plain-language ballot descriptions (verified November 3, 2026 Pacific)
|
|
219
|
+
|
|
220
|
+
- SF official voter pamphlet: https://media.api.sf.gov/documents/N26_EN_VIP.pdf — printed pp. 52–53 (regional transit), 64 (A), 70–71 (B), 78 (C), 84 (D), 94–95 (E), 100–101 (F), 108 (G), 124–125 (H), 132–133 (I), 144 (J). Summaries use impartial digests, not campaign arguments. PDF viewer page numbers are two higher than printed pages.
|
|
221
|
+
- California Secretary of State official November 3, 2026 voter guide: https://vig.cdn.sos.ca.gov/2026/general/pdf/complete-vig.pdf, downloaded November 4 UTC; SHA-256 `9509a4e3ac10b09e3c36d8b9b6c5d2f3935af3c7e2473c392b64352811cac1d8`. Official titles/summaries and Legislative Analyst analysis: printed pp. 14 (1), 20–23 (2), 26–27 (3), 30 (4), 34–37 (5), 40–41 (37), 44 (38), 48–51 (39), 54–55 (40), 58–59 (41), 62–63 (42), 66–67 (43), 70–71 (44), 74–77 (45).
|
|
222
|
+
- `shortTitle`, `summary`, and `summarySource` in the shared election feed preserve official full titles and source page provenance. Descriptions are neutral paraphrases; no endorsements or outcome predictions.
|
|
223
|
+
|
|
224
|
+
The November 3 impartiality review checked all 25 descriptions against the official digests and legislative analyses. Clarifications include SF C printed pp. 78–79 (freeze annual increases, not all contributions), F p. 100 (Board objection), E p. 94 (60-day default approval); California 2 pp. 22–23, 38 pp. 44–45, 39 p. 50, 40 pp. 54–55, 41 pp. 58–59, 43 pp. 66–67, 44 pp. 70–71 (operative scope/waivers pp. 153–156), and 45 pp. 75–76. Each feed record carries its revised printed-page reference.
|
|
225
|
+
|
|
226
|
+
Report-history points preserve only actual validated source counts and their distinct first observation times. Tests use explicitly synthetic mutations of the official zero-report fixtures; no synthetic counts or history points are in the checked-in ballot seed or deployed as results.
|
|
227
|
+
|
|
228
|
+
## November 2026 precinct results and boundaries
|
|
229
|
+
|
|
230
|
+
- `data/elections/precincts-<report time>.json`, such as `precincts-2026-11-03-230421.json` (local department clock, `YYYY-MM-DD-HHmmss`), aggregates the San Francisco Department of Elections cast vote record export `CVR_Export_20261103231904.zip` (downloaded November 5, 2026; the department's report time was supplied as 11/3/2026 11:04:21 PM, kept verbatim with no timezone conversion) to per-precinct, per-contest counts in a compact format (`precincts[id].c[contestIndex] = [undervotes, overvotes, ...votes in option order]`, with `contests[]` giving each index's options; schema version 2, about 0.6 MB). Generate it with `scripts/import-cvr-precincts.mjs --zip <export> --report-time "<M/D/YYYY h:mm:ss AM|PM>" --out-dir data/elections`. Each report time keeps its own file, and `data/elections/precincts-index.json` lists them in time order; consumers read `latest`, the newest report time. The export, which is ballot-level, is an ingestion input and is never committed; its SHA-256 is recorded in the file. Counts use each ballot card's current record (`Modified` when adjudicated). Ranked-choice contests count a single rank-1 mark only, matching the department's first-round figures. These are not winners.
|
|
231
|
+
- Reconciliation: `test/election-precincts.test.mjs` sums the precincts and compares every candidate and option of all 65 contests with the official Election Summary Report 4 (`test/fixtures/sfelections/summary-report-4.json`, a 5 KB extract of the report's option totals made with `scripts/extract-summary-totals.mjs`, with the XML's SHA-256 recorded; 514 of 514 precincts reported). Every total matches exactly. Five precincts have no ballots in the export and are absent from the file.
|
|
232
|
+
- `data/precincts-2022.json` holds the 514 polygons of DataSF "Election Precincts - Current, Defined 2022" (`d6x4-hefw`, https://data.sfgov.org/resource/d6x4-hefw.geojson, downloaded November 5, 2026), reduced to the precinct ID with coordinates rounded to six decimals. All 514 IDs match the export's precinct manifest exactly.
|
package/dist/data/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { districtMaps } from './districts.js';
|
|
|
4
4
|
export { highways } from './highways.js';
|
|
5
5
|
export { landmarks } from './landmarks.js';
|
|
6
6
|
export { getNeighborhood, neighborhoodCollections, neighborhoodSources } from './lookup.js';
|
|
7
|
+
export { precinctMaps } from './precincts.js';
|
|
7
8
|
export { getRealtorNeighborhood, neighborhoods } from './realtor.js';
|
|
8
9
|
export { keyRoads } from './roads.js';
|
|
9
10
|
export { bartStations } from './stations.js';
|
package/dist/data/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export { districtMaps } from './districts.js';
|
|
|
4
4
|
export { highways } from './highways.js';
|
|
5
5
|
export { landmarks } from './landmarks.js';
|
|
6
6
|
export { getNeighborhood, neighborhoodCollections, neighborhoodSources } from './lookup.js';
|
|
7
|
+
export { precinctMaps } from './precincts.js';
|
|
7
8
|
export { getRealtorNeighborhood, neighborhoods } from './realtor.js';
|
|
8
9
|
export { keyRoads } from './roads.js';
|
|
9
10
|
export { bartStations } from './stations.js';
|