@kahwee/sf-map-svg 5.1.3 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +1 -5
  3. package/dist/data/README.md +1 -1
  4. package/dist/src/cluster-renderer.d.ts +1 -1
  5. package/dist/src/district-layer.d.ts +4 -4
  6. package/dist/src/district-layer.js +1 -1
  7. package/dist/src/district-style.d.ts +3 -3
  8. package/dist/src/explorer-data.d.ts +1 -1
  9. package/dist/src/guide-map.d.ts +0 -7
  10. package/dist/src/guide-map.js +0 -33
  11. package/dist/src/guide-static.d.ts +4 -4
  12. package/dist/src/guide-static.js +14 -11
  13. package/dist/src/guide.d.ts +2 -2
  14. package/dist/src/guide.js +1 -1
  15. package/dist/src/{configuration-controller.d.ts → interactive/configuration-controller.d.ts} +7 -7
  16. package/dist/src/{configuration-controller.js → interactive/configuration-controller.js} +2 -2
  17. package/dist/src/{district-controller.d.ts → interactive/district-controller.d.ts} +12 -12
  18. package/dist/src/{district-controller.js → interactive/district-controller.js} +9 -9
  19. package/dist/src/{explorer-sidebar.d.ts → interactive/explorer-sidebar.d.ts} +6 -6
  20. package/dist/src/{explorer-sidebar.js → interactive/explorer-sidebar.js} +4 -4
  21. package/dist/src/{label-coordinator.d.ts → interactive/label-coordinator.d.ts} +7 -7
  22. package/dist/src/{label-coordinator.js → interactive/label-coordinator.js} +2 -2
  23. package/dist/src/{label-renderer.d.ts → interactive/label-renderer.d.ts} +2 -2
  24. package/dist/src/{label-renderer.js → interactive/label-renderer.js} +2 -2
  25. package/dist/src/{explorer-controls.d.ts → interactive/map-controls.d.ts} +4 -4
  26. package/dist/src/{explorer-controls.js → interactive/map-controls.js} +4 -4
  27. package/dist/src/{explorer-core.d.ts → interactive/map-engine.d.ts} +7 -7
  28. package/dist/src/{explorer-core.js → interactive/map-engine.js} +40 -40
  29. package/dist/src/{explorer-shell.d.ts → interactive/map-shell.d.ts} +2 -2
  30. package/dist/src/{explorer-shell.js → interactive/map-shell.js} +2 -2
  31. package/dist/src/{marker-controller.d.ts → interactive/marker-controller.d.ts} +8 -8
  32. package/dist/src/{marker-controller.js → interactive/marker-controller.js} +3 -3
  33. package/dist/src/{marker-layer.d.ts → interactive/marker-renderer.d.ts} +3 -3
  34. package/dist/src/{marker-layer.js → interactive/marker-renderer.js} +2 -2
  35. package/dist/src/map.js +4 -4
  36. package/dist/src/marker-catalog.d.ts +2 -2
  37. package/dist/src/palettes.d.ts +2 -2
  38. package/dist/src/{layers.d.ts → rendering/svg-layers.d.ts} +7 -7
  39. package/dist/src/{layers.js → rendering/svg-layers.js} +1 -1
  40. package/dist/src/{map-core.d.ts → rendering/svg-map-renderer.d.ts} +7 -7
  41. package/dist/src/{map-core.js → rendering/svg-map-renderer.js} +6 -6
  42. package/dist/src/static-animation.d.ts +2 -2
  43. package/dist/src/static-labels.d.ts +3 -3
  44. package/dist/src/static-labels.js +2 -2
  45. package/dist/src/static.d.ts +6 -6
  46. package/dist/src/static.js +4 -9
  47. package/dist/src/transit.js +1 -1
  48. package/dist/src/types.d.ts +13 -11
  49. package/docs/API.md +7 -11
  50. package/docs/EXAMPLES.md +2 -7
  51. package/docs/api-audit.md +3 -3
  52. package/docs/consumer-integration.md +1 -1
  53. package/docs/developer-guide.md +1 -6
  54. package/docs/migration-v6.md +57 -0
  55. package/llms-full.txt +132 -82
  56. package/llms.txt +2 -1
  57. package/package.json +2 -1
  58. /package/dist/src/{svg.d.ts → rendering/svg-primitives.d.ts} +0 -0
  59. /package/dist/src/{svg.js → rendering/svg-primitives.js} +0 -0
package/llms-full.txt CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  > Offline San Francisco SVG maps with explicit geographic imports, no runtime dependencies, static rendering, and a browser controller.
4
4
 
5
- @kahwee/sf-map-svg 5.1.3 · local working tree. Node >=24.0.0 for server rendering; browsers need a DOM and a JSON-capable bundler.
5
+ @kahwee/sf-map-svg 6.0.0 · local working tree. Node >=24.0.0 for server rendering; browsers need a DOM and a JSON-capable bundler.
6
6
 
7
7
  These are working-tree docs. Unreleased changelog entries may describe APIs absent from npm; verify the installed version before copying them.
8
8
 
9
9
  Use renderMap(data, options) for SVG strings; createMap(data, options) returns a controller. Mount map.element and destroy it on unmount. Choose mode explicitly: createMap defaults to basemap. Geography is separate; staticMapData and fullMapData have different shapes.
10
10
 
11
- <!-- Generated from README.md; @kahwee/sf-map-svg 5.1.3 · local working tree. -->
11
+ <!-- Generated from README.md; @kahwee/sf-map-svg 6.0.0 · local working tree. -->
12
12
 
13
13
  # SF Map SVG
14
14
 
@@ -39,11 +39,7 @@ Upgrading from v3 to v4: update your Node runtime to 24 or newer. The map API, b
39
39
  import { renderMap } from '@kahwee/sf-map-svg';
40
40
  import { staticMapData } from '@kahwee/sf-map-svg/data/static';
41
41
 
42
- const { svg, project, viewBox } = renderMap(staticMapData, {
43
- year: 2022,
44
- landmarks: true,
45
- bartStations: true,
46
- });
42
+ const { svg, project, viewBox } = renderMap(staticMapData, { year: 2022, layers: { landmarks: true, bartStations: true } });
47
43
  ```
48
44
 
49
45
  `renderMap(data, options)` returns SVG markup and matching projection helpers. `/data/static` includes the complete static map without interactive lookup collections. Small maps can compose selected JSON exports from `/data/*` and pass them as `StaticMapData`. `getLayerPaths(data, options)` returns fitted geographic paths without SVG markup.
@@ -267,7 +263,7 @@ for raw samples, output-equivalence checks, and reproducible commands.
267
263
 
268
264
  ---
269
265
 
270
- <!-- Generated from docs/developer-guide.md; @kahwee/sf-map-svg 5.1.3 · local working tree. -->
266
+ <!-- Generated from docs/developer-guide.md; @kahwee/sf-map-svg 6.0.0 · local working tree. -->
271
267
 
272
268
  # Developer guide
273
269
 
@@ -293,12 +289,7 @@ import { writeFile } from 'node:fs/promises';
293
289
  import { renderMap } from '@kahwee/sf-map-svg/static';
294
290
  import { staticMapData } from '@kahwee/sf-map-svg/data/static';
295
291
 
296
- const { svg } = renderMap(staticMapData, {
297
- year: 2022,
298
- landmarks: true,
299
- bartStations: true,
300
- title: 'San Francisco districts, 2022',
301
- });
292
+ const { svg } = renderMap(staticMapData, { year: 2022, title: 'San Francisco districts, 2022', layers: { landmarks: true, bartStations: true } });
302
293
  await writeFile('san-francisco.svg', svg);
303
294
  ```
304
295
 
@@ -433,7 +424,7 @@ See [API options](https://github.com/kahwee/sf-map-svg/blob/main/docs/API.md), [
433
424
 
434
425
  ---
435
426
 
436
- <!-- Generated from docs/API.md; @kahwee/sf-map-svg 5.1.3 · local working tree. -->
427
+ <!-- Generated from docs/API.md; @kahwee/sf-map-svg 6.0.0 · local working tree. -->
437
428
 
438
429
  # Map options and lifecycle
439
430
 
@@ -491,9 +482,9 @@ const { svg } = renderMap(staticMapData, presentation);
491
482
  const map = createMap(fullMapData, presentation);
492
483
  ```
493
484
 
494
- Static `layers` supports every interactive layer switch. `neighborhoodLabels` applies to the opt-in `labelLayout` described below. Static `appearance` supports `theme`, `colors`, and `districtStyle`; browser typography, area interaction styles, and screen-space marker sizing remain interactive settings. Unknown keys and invalid values are rejected for both flat and grouped options. Supplied grouped keys override flat compatibility keys; omitted or `undefined` grouped keys preserve the flat value or renderer default. Undefined color tokens use the theme default instead of entering SVG attributes. The two renderers retain their existing defaults. Marker arrays accept readonly inputs.
485
+ Static `layers` supports every interactive layer switch. `neighborhoodLabels` applies to the opt-in `labelLayout` described below. Static `appearance` supports `theme`, `colors`, and `districtStyle`; browser typography, area interaction styles, and screen-space marker sizing remain interactive settings. Unknown keys and invalid values are rejected. Presentation belongs under `layers` and `appearance`; flat presentation keys are rejected. Omitted or `undefined` grouped keys preserve renderer defaults. Undefined color tokens use the theme default instead of entering SVG attributes. The two renderers retain their existing defaults. Marker arrays accept readonly inputs.
495
486
 
496
- Flat compatibility options include `theme`, `width`, `height`, `padding`, `year` (2002, 2012, 2022), `districtLines`, `districtFills`, `districtStyle`, `districtLabels`, `neighborhoodLines`, `neighborhoodLabels`, `labels`, `labelLayout`, `highways`, `keyRoads`, `roadLabels`, `landmarks`, `bartStations`, `markers`, `overlays`, `title`, `idPrefix`, `colors`, and `animation`. Each optional layer is independent. User-supplied text and attributes are escaped in SVG output.
487
+ Top-level static options are `width`, `height`, `padding`, `year`, `source`, `labels`, `labelLayout`, `markers`, `overlays`, `title`, `idPrefix`, and `animation`, alongside `layers` and `appearance`. Each optional layer is independent. User-supplied text and attributes are escaped in SVG output.
497
488
 
498
489
  Custom district IDs must be finite numbers. An empty `labelPoints` array uses the district's primary `label` position.
499
490
 
@@ -501,22 +492,18 @@ The SVG description names the selected neighborhood source for source-aware data
501
492
 
502
493
  `animation: true` (or `{ duration, delay }`) makes a static map draw itself with self-contained, scoped CSS: land fades in, the coast and lines draw, districts grow, then labels and points appear. It plays when the SVG is inserted into a page or loaded as an image, needs no JavaScript, and stays still under `prefers-reduced-motion`. Re-insert the markup to replay it. Default output is unchanged.
503
494
 
504
- Static `labelLayout: { width: 390 }` opts into shared interactive **overview** label priorities, sizes, anchors and collision rules. `width` must be a positive finite CSS canvas width; it does not alter the SVG viewBox. Set `neighborhoodLabels: true` (flat or under `layers`) to add area names in this layout. Guide SVGs and shells enable neighborhood names by default only when opting into `labelLayout`. `labels: false` remains the master switch. Default static output is unchanged.
495
+ Static `labelLayout: { width: 390 }` opts into shared interactive **overview** label priorities, sizes, anchors and collision rules. `width` must be a positive finite CSS canvas width; it does not alter the SVG viewBox. Set `layers: { neighborhoodLabels: true }` to add area names in this layout. Guide SVGs and shells enable neighborhood names by default only when opting into `labelLayout`. `labels: false` remains the master switch. Default static output is unchanged.
505
496
 
506
497
  For editorial previews, `labelLayout` also accepts `maxLabels` (a nonnegative safe integer), `haloColor` (an SVG color string), and `compact: { width, maxLabels }`. The compact width must be positive, finite, and smaller than the main layout width. Each layout places labels around pins independently, then chooses up to its budget for spatial coverage and nearby-pin context (selected marker first when it fits). Without a budget the existing overview order is unchanged. Equal spatial scores retain the original priority order. A zero budget hides text, never pins. The default halo remains white; use the land color for a quieter dark map.
507
498
 
508
499
  Compact mode embeds two label groups and a media query in the same SVG. At or below the compact width it shows the compact group; above it shows the main group. In an `<img>` or standalone SVG, the breakpoint follows the SVG viewport. In inline SVG it follows the document viewport, so use `<img>` for cards whose width differs from the page. No JavaScript, duplicated geometry, external fonts, or extra image requests are needed. The compact width is also its font-layout hint; very narrow images still scale the text. The interactive renderer continues to use its live collision layout after enhancement.
509
500
 
510
501
  ```js
511
- createGuideSVG({
512
- labelLayout: {
502
+ createGuideSVG({ labelLayout: {
513
503
  width: 800,
514
504
  haloColor: '#1b2c28',
515
505
  compact: { width: 480, maxLabels: 4 },
516
- },
517
- colors: { water: '#0a1412', land: '#1b2c28', label: '#d5e3e8' },
518
- markers: places,
519
- });
506
+ }, markers: places, appearance: { colors: { water: '#0a1412', land: '#1b2c28', label: '#d5e3e8' } } });
520
507
  ```
521
508
 
522
509
  See the [field-guide preview recipe](https://github.com/kahwee/sf-map-svg/blob/main/docs/consumer-integration.md#editorial-map-previews) for a complete build-time example.
@@ -547,9 +534,9 @@ Visible markers and clusters share one tab stop. Use `[` and `]` to move focus,
547
534
 
548
535
  Activating coincident pins opens a place chooser, including when compact embeds hide the native marker picker. Clusters zoom when their members can separate at maximum zoom; otherwise they open the chooser. Escape or Close returns focus to the originating pin or cluster when it remains visible. Choosing a place selects its marker; replacing markers or destroying the map closes the chooser. `clusteractivate` still reports the activated cluster's markers.
549
536
 
550
- For a small guide, import `guideMapData` from `/guide/data` and pass it to `createMap`. The optional `/guide` entry also provides `createGuideMap`, `mountGuideMap`, and detailed-data loading for existing guide layouts. `/transit` provides the standalone schematic transit animation. See [examples](https://github.com/kahwee/sf-map-svg/blob/main/docs/EXAMPLES.md) and [consumer integration](https://github.com/kahwee/sf-map-svg/blob/main/docs/consumer-integration.md).
537
+ For a small guide, import `guideMapData` from `/guide/data` and pass it to `createMap`. The optional `/guide` entry also provides `createGuideController`, `mountGuideController`, and detailed-data loading for existing guide layouts. `/transit` provides the standalone schematic transit animation. See [examples](https://github.com/kahwee/sf-map-svg/blob/main/docs/EXAMPLES.md) and [consumer integration](https://github.com/kahwee/sf-map-svg/blob/main/docs/consumer-integration.md).
551
538
 
552
- For the guide preset with the same controller API, use `createGuideController(options)` from `/guide` (or `/guide/map`). It accepts grouped `MapOptions` and returns `MapController`; `mountGuideController(shell, options)` enhances a `createGuideShell()` container. Both use the lightweight guide geography. Existing `createGuideMap` and `mountGuideMap` calls retain their element-based API.
539
+ For the guide preset with the same controller API, use `createGuideController(options)` from `/guide` (or `/guide/map`). It accepts grouped `MapOptions` and returns `MapController`; `mountGuideController(shell, options)` enhances a `createGuideShell()` container. Both use the lightweight guide geography. See [migration to v6](https://github.com/kahwee/sf-map-svg/blob/main/docs/migration-v6.md) for removed compatibility APIs.
553
540
 
554
541
  Two opt-in features animate the map's lines and layers. `features.layerTransitions` fades layers as `configure({ layers })` and `setMode()` switch them, crossfades neighborhood boundaries when `setSource()` changes the definition, and crossfades district fills on `setDistrictStyle()`. `features.districtMorph` moves district outlines from one map year to the next on `setDistrictYear()`, then settles on the exact published geometry; pass `{ animate: false }` for an instant change. Both default off, own and cancel their animations, and yield to reduced motion.
555
542
 
@@ -619,7 +606,7 @@ Call `binding.setMarkers(next)` after `map.setMarkers(next)` when the catalog ch
619
606
 
620
607
  ---
621
608
 
622
- <!-- Generated from docs/EXAMPLES.md; @kahwee/sf-map-svg 5.1.3 · local working tree. -->
609
+ <!-- Generated from docs/EXAMPLES.md; @kahwee/sf-map-svg 6.0.0 · local working tree. -->
623
610
 
624
611
  # Examples
625
612
 
@@ -643,18 +630,13 @@ import { writeFile } from 'node:fs/promises';
643
630
  import { renderMap } from '@kahwee/sf-map-svg';
644
631
  import { staticMapData } from '@kahwee/sf-map-svg/data/static';
645
632
 
646
- const svg = renderMap(staticMapData, {
647
- year: 2022,
648
- landmarks: true,
649
- bartStations: true,
650
- idPrefix: 'example',
651
- }).svg;
633
+ const svg = renderMap(staticMapData, { year: 2022, idPrefix: 'example', layers: { landmarks: true, bartStations: true } }).svg;
652
634
  await writeFile('districts.svg', svg);
653
635
  ```
654
636
 
655
637
  The static preset includes the packaged map layers without interactive lookup collections. For smaller bundles, pass selected data to the root or `/static` renderer. See the [static recipe](https://github.com/kahwee/sf-map-svg/blob/main/README.md#static-svg).
656
638
 
657
- For an election choropleth, use `renderMap(data, { year, districtStyle })` or
639
+ For an election choropleth, use `renderMap(data, { year, appearance: { districtStyle } })` or
658
640
  `createMap({ map: data, districts: districtMaps, neighborhoods: {} }, options)`.
659
641
  The controller exposes `setDistrictYear`, `setDistrictStyle`, `selectDistrict`, and typed
660
642
  district events; `getLayerPaths(data, { year })` returns fitted paths without SVG markup.
@@ -760,7 +742,7 @@ See [query semantics and limitations](https://github.com/kahwee/sf-map-svg/blob/
760
742
 
761
743
  ---
762
744
 
763
- <!-- Generated from docs/consumer-integration.md; @kahwee/sf-map-svg 5.1.3 · local working tree. -->
745
+ <!-- Generated from docs/consumer-integration.md; @kahwee/sf-map-svg 6.0.0 · local working tree. -->
764
746
 
765
747
  # Embedding and progressive enhancement
766
748
 
@@ -844,7 +826,7 @@ function disposeGuide() {
844
826
 
845
827
  Compact attribution is required for an existing shell. Invalid configuration leaves its static frame intact. `destroy()` disposes listeners and animation work; your application owns removal of the containing view. Motion is opt-in and follows reduced-motion preferences.
846
828
 
847
- For a new browser-only guide, use `createGuideController()` and mount its `.element` as shown in the developer guide. Existing `createGuideMap()` and `mountGuideMap()` retain their augmented-element return types and flat options for compatibility.
829
+ For a new browser-only guide, use `createGuideController()` and mount its `.element` as shown in the developer guide. Both guide factories return controllers; mount `map.element` and dispose with `map.destroy()`.
848
830
 
849
831
  ## Choose the data boundary
850
832
 
@@ -938,7 +920,69 @@ keyboard, focus, and dismissal behavior. See [coordinates and units](https://git
938
920
 
939
921
  ---
940
922
 
941
- <!-- Generated from docs/migration-v5.md; @kahwee/sf-map-svg 5.1.3 · local working tree. -->
923
+ <!-- Generated from docs/migration-v6.md; @kahwee/sf-map-svg 6.0.0 · local working tree. -->
924
+
925
+ # Migrating to v6
926
+
927
+ Version 6 removes the remaining compatibility APIs. Geographic datasets, coordinate
928
+ conventions, defaults and rendering precision are unchanged.
929
+
930
+ ## Static presentation
931
+
932
+ Move flat geographic switches into `layers`, and `theme`, `colors` and
933
+ `districtStyle` into `appearance`. Flat presentation keys now throw.
934
+
935
+ ```js
936
+ const { svg } = renderMap(staticMapData, {
937
+ width: 800,
938
+ labels: true,
939
+ layers: { landmarks: true, bartStations: true, districtFills: false },
940
+ appearance: { theme: 'transit', colors: { water: '#e7f0f3' } },
941
+ });
942
+ ```
943
+
944
+ The same contract applies to `getLayerPaths`, `createGuideSVG` and
945
+ `createGuideShell`. Dimensions, year, source, master labels, label layout,
946
+ markers, overlays, title, ID prefix and animation remain top-level options.
947
+
948
+ ## Guide controllers
949
+
950
+ Replace `createGuideMap` with `createGuideController`, and `mountGuideMap` with
951
+ `mountGuideController`. Both return `MapController`; DOM methods live on `.element`.
952
+ The `InteractiveSFMapElement` and `InteractiveSFMapOptions` guide aliases are removed.
953
+ Use `MapController` and `MapOptions`.
954
+
955
+ ```js
956
+ import { createGuideController } from '@kahwee/sf-map-svg/guide';
957
+ const map = createGuideController({
958
+ features: { motion: true, clustering: true },
959
+ appearance: { colors: { water: '#e7f0f3' } },
960
+ });
961
+ document.querySelector('#map').append(map.element);
962
+ map.configure({ layers: { landmarks: false } });
963
+ map.camera.reset();
964
+ map.on('markerchange', ({ marker }) => console.log(marker));
965
+ // On unmount:
966
+ map.destroy();
967
+ map.element.remove();
968
+ ```
969
+
970
+ Use `configure` for feature, layer, control and appearance changes; use `camera`
971
+ for viewport operations. Replace construction callbacks with `map.on` subscriptions.
972
+ For static-shell enhancement, call `mountGuideController(shell, options)` and keep
973
+ the returned controller for disposal.
974
+
975
+ ## Site integrations
976
+
977
+ Pages builds require a v6-or-newer package and generate examples directly for that
978
+ contract. Older-package feature detection and flat-option fallback generation are
979
+ removed. Playground links must include `version: 1` in their design payload;
980
+ links produced by the current Share control already include it. Unversioned
981
+ handwritten links must add that field.
982
+
983
+ ---
984
+
985
+ <!-- Generated from docs/migration-v5.md; @kahwee/sf-map-svg 6.0.0 · local working tree. -->
942
986
 
943
987
  # Migrating to v5
944
988
 
@@ -1043,7 +1087,7 @@ collections. Shared edges can match more than one feature. See the
1043
1087
 
1044
1088
  ---
1045
1089
 
1046
- <!-- Generated from docs/migration-v3.md; @kahwee/sf-map-svg 5.1.3 · local working tree. -->
1090
+ <!-- Generated from docs/migration-v3.md; @kahwee/sf-map-svg 6.0.0 · local working tree. -->
1047
1091
 
1048
1092
  # Migrate to version 3
1049
1093
 
@@ -1084,7 +1128,7 @@ District styles are now prepared once per district on construction and style/yea
1084
1128
 
1085
1129
  ---
1086
1130
 
1087
- <!-- Generated from SOURCES.md; @kahwee/sf-map-svg 5.1.3 · local working tree. -->
1131
+ <!-- Generated from SOURCES.md; @kahwee/sf-map-svg 6.0.0 · local working tree. -->
1088
1132
 
1089
1133
  # Geometry and provenance
1090
1134
 
@@ -1321,7 +1365,7 @@ Report-history points preserve only actual validated source counts and their dis
1321
1365
 
1322
1366
  ---
1323
1367
 
1324
- <!-- Generated from CHANGELOG.md; @kahwee/sf-map-svg 5.1.3 · local working tree. -->
1368
+ <!-- Generated from CHANGELOG.md; @kahwee/sf-map-svg 6.0.0 · local working tree. -->
1325
1369
 
1326
1370
  # Changelog
1327
1371
 
@@ -1329,6 +1373,17 @@ User-visible changes are recorded here. Unreleased entries describe changes on `
1329
1373
 
1330
1374
  ## Unreleased
1331
1375
 
1376
+ ## 6.0.0 — 2026-11-05
1377
+
1378
+ - Breaking: remove flat static presentation options. Use `layers` for geographic switches and `appearance` for theme, colors and district styles.
1379
+ - Breaking: remove element-based `createGuideMap` and `mountGuideMap` factories and their option/element aliases. Use `createGuideController` and `mountGuideController`, mount `.element`, and dispose the controller.
1380
+ - Remove older-package capability adapters from the site and snippet generator; require v6 or newer for Pages builds and versioned playground share links. Add a v6 migration guide and rejection coverage for removed contracts.
1381
+ - Use official sources only on the Pages election views: remove all newspaper and agency-compilation tallies, projections, history and their validation from the feed, views, trend charts and tests. Local measures without official counts read Pending until official counts are imported.
1382
+
1383
+ ## 5.1.4 — 2026-11-05
1384
+
1385
+ - Group internal browser controllers, renderers and shells under `src/interactive`, and SVG generation under `src/rendering`. Rename the general map engine, controls and marker renderer to match their responsibilities; clarify selection-detail, neighborhood-results and layer-composition operations. Keep public package entry points unchanged.
1386
+
1332
1387
  ## 5.1.3 — 2026-11-05
1333
1388
 
1334
1389
  - Give configuration snapshots and revisions a dedicated internal owner. Split presentation preparation from a guarded, single-use commit, rejecting stale or disposed updates before mutating presentation. Preserve public configuration and reset behavior.
@@ -1725,7 +1780,7 @@ consistent home, and makes animation and subscription ownership predictable.
1725
1780
 
1726
1781
  # Published type contracts
1727
1782
 
1728
- @kahwee/sf-map-svg 5.1.3 · local working tree. These declarations are generated by TypeScript. Use package export paths, not the internal filenames below. Imported relative contracts are included for context, not as additional public entry points.
1783
+ @kahwee/sf-map-svg 6.0.0 · local working tree. These declarations are generated by TypeScript. Use package export paths, not the internal filenames below. Imported relative contracts are included for context, not as additional public entry points.
1729
1784
 
1730
1785
  | Public import | Declaration |
1731
1786
  | --- | --- |
@@ -2111,7 +2166,7 @@ export type DistrictYear = 2002 | 2012 | 2022;
2111
2166
  export interface DistrictSelection {
2112
2167
  id: number;
2113
2168
  year: DistrictYear;
2114
- district: import('./map-core.js').DistrictRowData;
2169
+ district: import('./rendering/svg-map-renderer.js').DistrictRowData;
2115
2170
  }
2116
2171
  export interface DistrictStyle {
2117
2172
  fill?: string;
@@ -2139,10 +2194,7 @@ export interface MapOverlay {
2139
2194
  visible?: boolean;
2140
2195
  label?: string;
2141
2196
  }
2142
- export interface SFMapOptions {
2143
- /** Grouped presentation; supplied keys take precedence over flat compatibility options. */
2144
- layers?: StaticMapLayers;
2145
- appearance?: StaticMapAppearance;
2197
+ export interface SvgRenderOptions {
2146
2198
  theme?: 'districts' | 'transit';
2147
2199
  width?: number;
2148
2200
  height?: number;
@@ -2156,7 +2208,7 @@ export interface SFMapOptions {
2156
2208
  neighborhoodLabels?: boolean;
2157
2209
  districtFills?: boolean;
2158
2210
  /** Evaluated once per district at construction/style/year updates; call setDistrictStyle again when external data changes. */
2159
- districtStyle?: (district: import('./map-core.js').DistrictRowData) => DistrictStyle;
2211
+ districtStyle?: (district: import('./rendering/svg-map-renderer.js').DistrictRowData) => DistrictStyle;
2160
2212
  districtLabels?: boolean;
2161
2213
  /** Hide all visible text labels while retaining geographic symbols and accessible titles. */
2162
2214
  labels?: boolean;
@@ -2196,7 +2248,12 @@ export interface SFMapOptions {
2196
2248
  }
2197
2249
  /** Presentation supported by both the static and interactive renderers. */
2198
2250
  export type StaticMapLayers = InteractiveLayers;
2199
- export type StaticMapAppearance = Pick<SFMapOptions, 'theme' | 'colors' | 'districtStyle'>;
2251
+ export type StaticMapAppearance = Pick<SvgRenderOptions, 'theme' | 'colors' | 'districtStyle'>;
2252
+ /** Public static presentation uses the same grouped vocabulary as the map controller. */
2253
+ export type StaticMapOptions = Omit<SvgRenderOptions, keyof StaticMapLayers | keyof StaticMapAppearance> & {
2254
+ layers?: StaticMapLayers;
2255
+ appearance?: StaticMapAppearance;
2256
+ };
2200
2257
  /** Serializable viewport in the interactive map's fixed 800 × 800 projected space. */
2201
2258
  export type MapViewport = readonly [x: number, y: number, size: number];
2202
2259
  export type ExplorerMode = 'neighborhoods' | 'districts' | 'basemap';
@@ -2266,8 +2323,8 @@ export interface NeighborhoodExplorerOptions extends MapFeatures {
2266
2323
  source?: NeighborhoodSource;
2267
2324
  neighborhood?: string;
2268
2325
  year?: DistrictYear;
2269
- theme?: SFMapOptions['theme'];
2270
- colors?: SFMapOptions['colors'];
2326
+ theme?: SvgRenderOptions['theme'];
2327
+ colors?: SvgRenderOptions['colors'];
2271
2328
  labelStyle?: {
2272
2329
  fontFamily?: string;
2273
2330
  fontWeight?: number;
@@ -2279,7 +2336,7 @@ export interface NeighborhoodExplorerOptions extends MapFeatures {
2279
2336
  hoverFill?: string;
2280
2337
  hoverStroke?: string;
2281
2338
  };
2282
- districtStyle?: SFMapOptions['districtStyle'];
2339
+ districtStyle?: SvgRenderOptions['districtStyle'];
2283
2340
  legend?: {
2284
2341
  builtins?: boolean;
2285
2342
  hidden?: readonly ('bart' | 'park' | 'highway' | 'road')[];
@@ -2345,7 +2402,7 @@ export interface NeighborhoodExplorerElement extends HTMLElement {
2345
2402
  } & CameraOptions): boolean;
2346
2403
  getSelectedDistrict(): DistrictSelection | null;
2347
2404
  setDistrictYear(year: DistrictYear, options?: CameraOptions): void;
2348
- setDistrictStyle(style: SFMapOptions['districtStyle']): void;
2405
+ setDistrictStyle(style: SvgRenderOptions['districtStyle']): void;
2349
2406
  setSource(source: NeighborhoodSource): void;
2350
2407
  setMode(mode: ExplorerMode): void;
2351
2408
  setLabels(visible: boolean): void;
@@ -2378,7 +2435,7 @@ export type { MapAppearance, MapCamera, MapCapabilities, MapConfiguration, MapCo
2378
2435
 
2379
2436
  ```ts
2380
2437
  import type { DistrictProperties, FeatureCollection, NeighborhoodProperties, NeighborhoodSource } from '../data/types.js';
2381
- import type { SFMapData } from './map-core.js';
2438
+ import type { SFMapData } from './rendering/svg-map-renderer.js';
2382
2439
  import type { DistrictYear } from './types.js';
2383
2440
  /** Geographic inputs for the data-injected interactive map entry point. */
2384
2441
  export interface InteractiveSFMapData {
@@ -2388,13 +2445,13 @@ export interface InteractiveSFMapData {
2388
2445
  }
2389
2446
  ```
2390
2447
 
2391
- ### dist/src/map-core.d.ts
2448
+ ### dist/src/rendering/svg-map-renderer.d.ts
2392
2449
 
2393
2450
  ```ts
2394
- import type { Geometry, Position } from '../data/types.js';
2395
- import type { DistrictYear, SFMapOptions } from './types.js';
2396
- export type { DistrictYear, MapMarker, MapOverlay, SFMapOptions } from './types.js';
2397
- import { type Project } from './geometry.js';
2451
+ import type { Geometry, Position } from '../../data/types.js';
2452
+ import type { DistrictYear, SvgRenderOptions } from '../types.js';
2453
+ export type { DistrictYear, MapMarker, MapOverlay, SvgRenderOptions } from '../types.js';
2454
+ import { type Project } from '../geometry.js';
2398
2455
  export interface SFMapData {
2399
2456
  coast: Geometry;
2400
2457
  districts?: Readonly<Partial<Record<DistrictYear, readonly DistrictRowData[]>>>;
@@ -2443,7 +2500,7 @@ export interface BartStationData {
2443
2500
  export declare const districtYears: readonly DistrictYear[];
2444
2501
  export declare const districtColors: readonly string[];
2445
2502
  /** Canonical geometry in the same fitted coordinate space used by renderMap. */
2446
- export declare function getLayerPathsWithData(options: SFMapOptions, data: SFMapData, complete?: boolean): {
2503
+ export declare function getLayerPathsWithData(options: SvgRenderOptions, data: SFMapData, complete?: boolean): {
2447
2504
  year: DistrictYear;
2448
2505
  viewBox: [number, number, number, number];
2449
2506
  project: (coordinates: Position) => [number, number];
@@ -2475,7 +2532,7 @@ export declare function getLayerPathsWithData(options: SFMapOptions, data: SFMap
2475
2532
  point: [number, number];
2476
2533
  }[];
2477
2534
  };
2478
- export declare function resolveMapColors(theme: SFMapOptions['theme'], colors?: SFMapOptions['colors']): {
2535
+ export declare function resolveMapColors(theme: SvgRenderOptions['theme'], colors?: SvgRenderOptions['colors']): {
2479
2536
  water: string;
2480
2537
  land: string;
2481
2538
  district: string;
@@ -2490,7 +2547,7 @@ export declare function resolveMapColors(theme: SFMapOptions['theme'], colors?:
2490
2547
  selected: string;
2491
2548
  };
2492
2549
  /** Make an offline SVG and the matching longitude/latitude projection. */
2493
- export declare function createSFMapWithData(options: SFMapOptions, data: SFMapData, renderLabels?: (project: Project) => string): {
2550
+ export declare function createSFMapWithData(options: SvgRenderOptions, data: SFMapData, renderLabels?: (project: Project) => string): {
2494
2551
  svg: string;
2495
2552
  project: (coordinates: Position) => [number, number];
2496
2553
  viewBox: [number, number, number, number];
@@ -2516,20 +2573,20 @@ export declare function geometryContainsPoint(geometry: Geometry | null | undefi
2516
2573
 
2517
2574
  ```ts
2518
2575
  import type { InteractiveSFMapData } from './explorer-data.js';
2519
- import { type SFMapData } from './map-core.js';
2520
- import type { SFMapOptions } from './types.js';
2576
+ import { type SFMapData } from './rendering/svg-map-renderer.js';
2577
+ import type { StaticMapOptions } from './types.js';
2521
2578
  /** Either compact static geography or the same source-aware geography used by createMap. */
2522
2579
  export type StaticMapInput = SFMapData | InteractiveSFMapData;
2523
- export type { DistrictRowData, SFMapData as StaticMapData } from './map-core.js';
2524
- export type { DistrictStyle, DistrictYear, SFMapOptions as StaticMapOptions, StaticMapAppearance, StaticMapLayers, } from './types.js';
2580
+ export type { DistrictRowData, SFMapData as StaticMapData } from './rendering/svg-map-renderer.js';
2581
+ export type { DistrictStyle, DistrictYear, StaticMapAppearance, StaticMapLayers, StaticMapOptions, } from './types.js';
2525
2582
  /** Server-safe SVG rendering with explicit data; returns SVG plus projection helpers. */
2526
- export declare function renderMap(data: StaticMapInput, options?: SFMapOptions): {
2583
+ export declare function renderMap(data: StaticMapInput, options?: StaticMapOptions): {
2527
2584
  svg: string;
2528
2585
  project: (coordinates: import("./geometry.js").Position) => [number, number];
2529
2586
  viewBox: [number, number, number, number];
2530
2587
  };
2531
2588
  /** Project canonical layer geometry without constructing an SVG string. */
2532
- export declare function getLayerPaths(data: StaticMapInput, options?: SFMapOptions): {
2589
+ export declare function getLayerPaths(data: StaticMapInput, options?: StaticMapOptions): {
2533
2590
  year: import("./types.js").DistrictYear;
2534
2591
  viewBox: [number, number, number, number];
2535
2592
  project: (coordinates: import("./geometry.js").Position) => [number, number];
@@ -2703,8 +2760,8 @@ export type { MapController, MapOptions } from './controller-types.js';
2703
2760
  export type { InteractiveSFMapData } from './explorer-data.js';
2704
2761
  export { guideMapData } from './guide-data.js';
2705
2762
  export { loadGuideDetailedData } from './guide-detailed.js';
2706
- export { createGuideController, createGuideMap, mountGuideController, mountGuideMap, } from './guide-map.js';
2707
- export type { CameraOptions, MapFeatures, MapMarker, NeighborhoodExplorerElement as InteractiveSFMapElement, NeighborhoodExplorerOptions as InteractiveSFMapOptions, } from './types.js';
2763
+ export { createGuideController, mountGuideController, } from './guide-map.js';
2764
+ export type { CameraOptions, MapFeatures, MapMarker, } from './types.js';
2708
2765
  ```
2709
2766
 
2710
2767
  ### dist/src/guide-data.d.ts
@@ -2727,17 +2784,10 @@ export declare function loadGuideDetailedData(): Promise<InteractiveSFMapData>;
2727
2784
 
2728
2785
  ```ts
2729
2786
  import type { MapController, MapOptions } from './controller-types.js';
2730
- import type { NeighborhoodExplorerElement as InteractiveSFMapElement, NeighborhoodExplorerOptions as InteractiveSFMapOptions } from './types.js';
2731
2787
  /** Preferred guide API: the same grouped options, events, camera and lifecycle as createMap. */
2732
2788
  export declare function createGuideController(options?: MapOptions): MapController;
2733
2789
  /** Enhance a static guide shell and return its owning controller. */
2734
2790
  export declare function mountGuideController(shell: HTMLElement, options?: MapOptions): MapController;
2735
- /** Element-based compatibility API. Prefer createGuideController for new integrations. */
2736
- export declare function createGuideMap(options?: InteractiveSFMapOptions): InteractiveSFMapElement;
2737
- /** Enhance createGuideShell() in place with a fixed compact chrome layout.
2738
- * Keep an accessible external place list when hiding the native pickers.
2739
- */
2740
- export declare function mountGuideMap(shell: HTMLElement, options?: InteractiveSFMapOptions): InteractiveSFMapElement;
2741
2791
  ```
2742
2792
 
2743
2793
  ### ./dist/src/transit.d.ts
@@ -2751,15 +2801,15 @@ export declare function createTransitAnimation(): TransitAnimationElement;
2751
2801
  ### ./dist/src/guide-static.d.ts
2752
2802
 
2753
2803
  ```ts
2754
- import type { SFMapOptions } from './types.js';
2804
+ import type { StaticMapOptions } from './types.js';
2755
2805
  /** Server-safe overview using exactly the guide browser geography. */
2756
- export declare function createGuideSVG(options?: SFMapOptions): {
2806
+ export declare function createGuideSVG(options?: StaticMapOptions): {
2757
2807
  svg: string;
2758
2808
  project: (coordinates: import("./geometry.js").Position) => [number, number];
2759
2809
  viewBox: [number, number, number, number];
2760
2810
  };
2761
- /** Stable compact frame, progressively enhanced with mountGuideMap(). No browser globals. */
2762
- export declare function createGuideShell(options?: SFMapOptions): string;
2811
+ /** Stable compact frame, progressively enhanced with mountGuideController(). No browser globals. */
2812
+ export declare function createGuideShell(options?: StaticMapOptions): string;
2763
2813
  ```
2764
2814
 
2765
2815
  ### ./dist/src/presets.d.ts
@@ -2774,10 +2824,10 @@ export { type MapPalette, mapPalettes } from './palettes.js';
2774
2824
  ### dist/src/palettes.d.ts
2775
2825
 
2776
2826
  ```ts
2777
- import type { SFMapOptions } from './types.js';
2827
+ import type { SvgRenderOptions } from './types.js';
2778
2828
  /** Shared tokens for static SVGs, interactive maps, and consumer-owned place cards. */
2779
2829
  export interface MapPalette {
2780
- readonly colors: NonNullable<SFMapOptions['colors']>;
2830
+ readonly colors: NonNullable<SvgRenderOptions['colors']>;
2781
2831
  readonly haloColor: string;
2782
2832
  readonly markerColor: string;
2783
2833
  readonly selectedMarkerColor: string;
package/llms.txt CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Offline San Francisco SVG maps with explicit geographic imports, no runtime dependencies, static rendering, and a browser controller.
4
4
 
5
- @kahwee/sf-map-svg 5.1.3 · local working tree. Node >=24.0.0 for server rendering; browsers need a DOM and a JSON-capable bundler.
5
+ @kahwee/sf-map-svg 6.0.0 · local working tree. Node >=24.0.0 for server rendering; browsers need a DOM and a JSON-capable bundler.
6
6
 
7
7
  These are working-tree docs. Unreleased changelog entries may describe APIs absent from npm; verify the installed version before copying them.
8
8
 
@@ -15,6 +15,7 @@ Use renderMap(data, options) for SVG strings; createMap(data, options) returns a
15
15
  - [API options and lifecycle](https://kahwee.github.io/sf-map-svg/api-options.md)
16
16
  - [Worked examples](https://kahwee.github.io/sf-map-svg/examples.md)
17
17
  - [Consumer integration](https://kahwee.github.io/sf-map-svg/consumer-integration.md)
18
+ - [Migration to v6](https://kahwee.github.io/sf-map-svg/migration-v6.md)
18
19
  - [Migration to v5](https://kahwee.github.io/sf-map-svg/migration-v5.md)
19
20
  - [Migration from removed APIs](https://kahwee.github.io/sf-map-svg/migration-v3.md)
20
21
  - [Exact TypeScript contracts](https://kahwee.github.io/sf-map-svg/types.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kahwee/sf-map-svg",
3
- "version": "5.1.3",
3
+ "version": "6.0.0",
4
4
  "description": "Offline SVG maps of San Francisco with district boundaries, parks, landmarks, and BART stations.",
5
5
  "type": "module",
6
6
  "main": "./dist/src/api.js",
@@ -128,6 +128,7 @@
128
128
  "docs/guide-bundle-report.md",
129
129
  "docs/migration-v3.md",
130
130
  "docs/migration-v5.md",
131
+ "docs/migration-v6.md",
131
132
  "CHANGELOG.md",
132
133
  "docs/API.md",
133
134
  "docs/developer-guide.md",