@kahwee/sf-map-svg 4.1.0 → 4.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/CHANGELOG.md +23 -0
- package/README.md +11 -15
- package/dist/src/appearance.d.ts +5 -0
- package/dist/src/appearance.js +54 -0
- package/dist/src/configuration.d.ts +3 -1
- package/dist/src/configuration.js +32 -23
- package/dist/src/controller-types.d.ts +81 -8
- package/dist/src/explorer-core.d.ts +14 -2
- package/dist/src/explorer-core.js +174 -38
- package/dist/src/guide-map.js +1 -1
- package/dist/src/guide-static.js +3 -3
- package/dist/src/map-core.d.ts +14 -0
- package/dist/src/map-core.js +4 -1
- package/dist/src/map.js +164 -18
- package/dist/src/static.d.ts +6 -3
- package/dist/src/static.js +57 -2
- package/dist/src/types.d.ts +10 -2
- package/docs/API.md +67 -1
- package/docs/api-audit.md +7 -7
- package/docs/consumer-integration.md +35 -11
- package/docs/developer-guide.md +6 -4
- package/llms-full.txt +263 -54
- package/llms.txt +1 -1
- package/package.json +3 -2
package/llms-full.txt
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
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 4.
|
|
5
|
+
@kahwee/sf-map-svg 4.3.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 4.
|
|
11
|
+
<!-- Generated from README.md; @kahwee/sf-map-svg 4.3.0 · local working tree. -->
|
|
12
12
|
|
|
13
13
|
# SF Map SVG
|
|
14
14
|
|
|
15
15
|
Offline, self-contained San Francisco SVG maps. The package has no runtime dependencies. Geography is always an explicit import; the root entry does not bundle data.
|
|
16
16
|
|
|
17
|
-
[Live examples](https://kahwee.github.io/sf-map-svg/examples.html) · [Storybook source](https://github.com/kahwee/sf-map-svg/blob/main/stories/) · [Geographic sources](https://github.com/kahwee/sf-map-svg/blob/main/SOURCES.md) · [v3 migration](https://github.com/kahwee/sf-map-svg/blob/main/docs/migration-v3.md)
|
|
17
|
+
[Getting started](https://github.com/kahwee/sf-map-svg/blob/main/docs/developer-guide.md) · [API reference](https://github.com/kahwee/sf-map-svg/blob/main/docs/API.md) · [Design playground](https://kahwee.github.io/sf-map-svg/playground.html) · [Live examples](https://kahwee.github.io/sf-map-svg/examples.html) · [Storybook source](https://github.com/kahwee/sf-map-svg/blob/main/stories/) · [Geographic sources](https://github.com/kahwee/sf-map-svg/blob/main/SOURCES.md) · [v3 migration](https://github.com/kahwee/sf-map-svg/blob/main/docs/migration-v3.md)
|
|
18
18
|
|
|
19
19
|
## Install
|
|
20
20
|
|
|
@@ -57,14 +57,19 @@ const map = createMap(fullMapData, {
|
|
|
57
57
|
features: { motion: true },
|
|
58
58
|
appearance: { theme: 'districts' },
|
|
59
59
|
});
|
|
60
|
-
document.querySelector('#map')
|
|
60
|
+
const host = document.querySelector('#map');
|
|
61
|
+
if (!host) throw new Error('Missing #map container');
|
|
62
|
+
host.append(map.element);
|
|
61
63
|
map.on('neighborhoodchange', ({ name }) => console.log(name));
|
|
62
64
|
map.camera.zoom(1.5);
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
+
// Call when your application removes this view.
|
|
66
|
+
function disposeMap() {
|
|
67
|
+
map.destroy();
|
|
68
|
+
map.element.remove();
|
|
69
|
+
}
|
|
65
70
|
```
|
|
66
71
|
|
|
67
|
-
`createMap(data, options)` returns a controller. Use `map.element` for mounting, `map.configure({ features, layers, controls })` for runtime switches, `map.camera` for pan/zoom/fit/reset, and `map.on()` for typed events. Appearance
|
|
72
|
+
`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.
|
|
68
73
|
|
|
69
74
|
See [controller options, events, and lifecycle](https://github.com/kahwee/sf-map-svg/blob/main/docs/API.md#interactive-maps),
|
|
70
75
|
[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).
|
|
@@ -78,20 +83,11 @@ Call `destroy()` when removing an interactive map.
|
|
|
78
83
|
|
|
79
84
|
Canonical geography is in [`data/`](https://github.com/kahwee/sf-map-svg/blob/main/data/README.md), with provenance in [`SOURCES.md`](https://github.com/kahwee/sf-map-svg/blob/main/SOURCES.md). The public `/data` entry exposes lookup, catalog, district maps, and source-specific neighborhood collections. These are deeply frozen; clone before editing.
|
|
80
85
|
|
|
81
|
-
|
|
82
|
-
pnpm install --frozen-lockfile
|
|
83
|
-
pnpm check
|
|
84
|
-
pnpm demo
|
|
85
|
-
pnpm build-storybook
|
|
86
|
-
pnpm test:stories:coverage
|
|
87
|
-
pnpm test:package
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
The [contributing guide](https://github.com/kahwee/sf-map-svg/blob/main/CONTRIBUTING.md) explains the geographic and release checks. If you are upgrading from v2, follow the [v3 migration guide](https://github.com/kahwee/sf-map-svg/blob/main/docs/migration-v3.md).
|
|
86
|
+
Install with `pnpm install --frozen-lockfile`. See the [contributing guide](https://github.com/kahwee/sf-map-svg/blob/main/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](https://github.com/kahwee/sf-map-svg/blob/main/docs/migration-v3.md).
|
|
91
87
|
|
|
92
88
|
---
|
|
93
89
|
|
|
94
|
-
<!-- Generated from docs/developer-guide.md; @kahwee/sf-map-svg 4.
|
|
90
|
+
<!-- Generated from docs/developer-guide.md; @kahwee/sf-map-svg 4.3.0 · local working tree. -->
|
|
95
91
|
|
|
96
92
|
# Developer guide
|
|
97
93
|
|
|
@@ -175,7 +171,7 @@ function disposeMap() {
|
|
|
175
171
|
| Visible labels | On | On, subject to zoom/collisions |
|
|
176
172
|
| Motion features | Static animation off | Off; opt in via `features` |
|
|
177
173
|
|
|
178
|
-
A layer switch does not download missing geography. `fullMapData` has `.map` for static rendering and separate lookup collections for interactive use. `staticMapData` is already a static data object. Use `renderMap(guideMapData
|
|
174
|
+
A layer switch does not download missing geography. `fullMapData` has `.map` for static rendering and separate lookup collections for interactive use. `staticMapData` is already a static data object. Use `renderMap(guideMapData, options)` or `renderMap(fullMapData, { source: 'sf-find' })` to share source-aware geography with the browser controller. Passing `.map` remains supported as compact static geography; it already chooses its neighborhoods and does not accept a `source` option.
|
|
179
175
|
|
|
180
176
|
SFAR realtor neighborhoods are the default when supplied. If only an alternative collection is supplied, the controller selects that available source. Choose `source` explicitly when comparing definitions. Sources retain separate identities; they are not interchangeable polygons.
|
|
181
177
|
|
|
@@ -183,13 +179,15 @@ SFAR realtor neighborhoods are the default when supplied. If only an alternative
|
|
|
183
179
|
|
|
184
180
|
| Change | Call |
|
|
185
181
|
| --- | --- |
|
|
186
|
-
|
|
|
182
|
+
| Presentation, layers, controls, behaviors | `map.configure({ layers, controls, features, appearance, mode, source, year, labels })` |
|
|
187
183
|
| Map mode or neighborhood source | `map.setMode(mode)`, `map.setSource(source)` |
|
|
188
184
|
| District boundaries or choropleth | `map.setDistrictYear(year)`, `map.setDistrictStyle(callback)` |
|
|
189
185
|
| Master text visibility | `map.setLabels(visible)` |
|
|
190
186
|
| Markers or route overlays | `map.setMarkers(items)`, `map.setOverlays(items)` |
|
|
191
187
|
| Camera | `map.camera.set/pan/zoom/fit/reset(...)` |
|
|
192
|
-
| Palette, typography, control styling |
|
|
188
|
+
| Palette, typography, control styling | `map.configure({ appearance })`; retains camera, selection and focus |
|
|
189
|
+
|
|
190
|
+
Appearance token objects merge by key; `undefined` removes an override and `appearance: undefined` resets the group. Static maps accept grouped `layers` and the shared `appearance` keys (`theme`, `colors`, `districtStyle`) too. See [the API contract](https://github.com/kahwee/sf-map-svg/blob/main/docs/API.md#live-configuration-and-inspection) and [the design playground](https://kahwee.github.io/sf-map-svg/playground.html).
|
|
193
191
|
|
|
194
192
|
`configure` merges supplied keys; omitted keys keep their existing values. Set a layer or control key to `undefined` to remove its override. Set a whole group to `undefined` to reset that group. Set a feature to `false` to disable it. Explicit layer overrides keep winning after mode changes.
|
|
195
193
|
|
|
@@ -200,7 +198,7 @@ map.configure({ features: { motion: false } });
|
|
|
200
198
|
map.configure({ layers: undefined }); // clear all explicit layer overrides
|
|
201
199
|
```
|
|
202
200
|
|
|
203
|
-
`getConfiguration()` returns a detached snapshot of
|
|
201
|
+
`getConfiguration()` returns current mode/source/year/labels and a detached snapshot of the presentation groups, including explicit layer and appearance overrides. Camera and selection remain separate runtime state. Use `getResolvedConfiguration()` for current mode/source/year/labels and effective layer switches, and `getCapabilities()` for supplied geography. Invalid configuration patches leave the current map unchanged. Convenience methods use the same atomic update path: pass `map.setMode(mode, { resetView: false })` or `map.setSource(source, { resetView: false })` to keep the camera. Their default still resets the view.
|
|
204
202
|
|
|
205
203
|
## Markers, routes and camera coordinates
|
|
206
204
|
|
|
@@ -233,7 +231,7 @@ See [API options](https://github.com/kahwee/sf-map-svg/blob/main/docs/API.md), [
|
|
|
233
231
|
|
|
234
232
|
---
|
|
235
233
|
|
|
236
|
-
<!-- Generated from docs/API.md; @kahwee/sf-map-svg 4.
|
|
234
|
+
<!-- Generated from docs/API.md; @kahwee/sf-map-svg 4.3.0 · local working tree. -->
|
|
237
235
|
|
|
238
236
|
# Map options and lifecycle
|
|
239
237
|
|
|
@@ -243,7 +241,22 @@ and event types are exported by [src/api.ts](https://github.com/kahwee/sf-map-sv
|
|
|
243
241
|
|
|
244
242
|
## Static maps
|
|
245
243
|
|
|
246
|
-
Static
|
|
244
|
+
Static maps accept compact `StaticMapData` or the same source-aware `MapData` as interactive maps. With `MapData`, `source` selects a supplied neighborhood definition; SFAR realtor is preferred by default, followed by SF Find and analysis when available. A requested unavailable source throws before styling callbacks run. Compact `StaticMapData` already chooses its neighborhoods, so it rejects a `source` option. Both data shapes retain the static renderer defaults.
|
|
245
|
+
|
|
246
|
+
Static maps accept the same grouped presentation vocabulary as interactive maps:
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
const presentation = {
|
|
250
|
+
layers: { landmarks: true, bartStations: true },
|
|
251
|
+
appearance: { theme: 'districts' as const, colors: { water: '#e7f0f3' } },
|
|
252
|
+
};
|
|
253
|
+
const { svg } = renderMap(staticMapData, presentation);
|
|
254
|
+
const map = createMap(fullMapData, presentation);
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Static `layers` supports every interactive layer switch except `neighborhoodLabels`. Static `appearance` supports `theme`, `colors`, and `districtStyle`; browser typography, area interaction styles, and screen-space marker sizing remain interactive settings. Unknown grouped keys are rejected. Supplied grouped keys override flat compatibility keys; omitted or `undefined` grouped keys preserve the flat value or renderer default. The two renderers retain their existing defaults. Marker arrays accept readonly inputs.
|
|
258
|
+
|
|
259
|
+
Flat compatibility options include `theme`, `width`, `height`, `padding`, `year` (2002, 2012, 2022), `districtLines`, `districtFills`, `districtStyle`, `districtLabels`, `neighborhoodLines`, `labels`, `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.
|
|
247
260
|
|
|
248
261
|
Custom district IDs must be finite numbers. An empty `labelPoints` array uses the district's primary `label` position.
|
|
249
262
|
|
|
@@ -269,9 +282,60 @@ Two opt-in features animate the map's lines and layers. `features.layerTransitio
|
|
|
269
282
|
|
|
270
283
|
District style callbacks are evaluated once per district at construction and on style or year updates. Hover, selection, and layer toggles reuse the prepared styles; call `setDistrictStyle()` again when external styling data changes. Invalid styles leave the current map unchanged. District fades respect reduced motion and are removed on interruption or destruction.
|
|
271
284
|
|
|
285
|
+
## Live configuration and inspection
|
|
286
|
+
|
|
287
|
+
`map.configure({ appearance, mode, source, year, labels, layers, features, controls })` updates an existing map. Appearance updates preserve the camera, selections, retained marker nodes, and keyboard focus. Mode/source changes through `configure` preserve the camera; the `setMode(mode, { resetView: false })` and `setSource(source, { resetView: false })` convenience methods use the same atomic update path and preserve the camera. Omit the second argument to retain their existing reset behavior. Invalid view-update options fail before changing configuration. Switching neighborhood source clears the neighborhood selection. Changing district year retains a selected district when it exists in the new year. Unsupported datasets, invalid appearance values, and invalid district-style callback results fail during preparation before commit. A reentrant styling callback can supersede the pending patch.
|
|
288
|
+
|
|
289
|
+
Appearance token objects (`colors`, `style`, `labelStyle`, `labelSize`, `areaStyle`) merge supplied keys; other appearance properties replace. Omitted keys retain their value, an explicit `undefined` property removes that override, and `appearance: undefined` resets the whole appearance group. Feature objects retain their existing replacement semantics. Mode/source/year/labels ignore `undefined`; reset them with an explicit value. Patch types explicitly permit these resets with TypeScript’s `exactOptionalPropertyTypes` enabled.
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
map.configure({
|
|
293
|
+
appearance: { colors: { water: '#142d45' }, labelStyle: { fontFamily: 'Georgia,serif' } },
|
|
294
|
+
layers: { bartStations: false },
|
|
295
|
+
});
|
|
296
|
+
map.configure({ appearance: undefined }); // restore construction defaults, not initial overrides
|
|
297
|
+
|
|
298
|
+
const overrides = map.getConfiguration();
|
|
299
|
+
const effective = map.getResolvedConfiguration();
|
|
300
|
+
const available = map.getCapabilities();
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
`getConfiguration()` returns the current mode, source, year and master labels, together with detached feature, layer, control, and appearance overrides; district style callbacks retain their function identity. `getResolvedConfiguration()` adds the current mode, source, year and master labels and resolves **layer switches** through mode defaults, available data, and the master label switch. Appearance/control fields remain overrides. It does not claim that every label is visible: zoom and collision filtering still apply. `getCapabilities()` returns supplied `sources`, usable district `years`, and layer data availability for the current source/year, independent of visibility overrides. These reads throw after destruction.
|
|
304
|
+
|
|
305
|
+
## Common selection event
|
|
306
|
+
|
|
307
|
+
`selectionchange` adds a consistent envelope without changing existing event payloads:
|
|
308
|
+
|
|
309
|
+
```ts
|
|
310
|
+
map.on('selectionchange', (event) => {
|
|
311
|
+
// kind narrows current and previous to the corresponding selection type.
|
|
312
|
+
if (event.kind === 'marker') console.log(event.current?.id, event.previous?.id);
|
|
313
|
+
});
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
`kind` is `marker`, `neighborhood`, or `district`. `current` and `previous` are detached selection snapshots or `null`. The event follows committed selection changes, including clearing and a changed district vintage; it does not represent every activation. Existing `markerchange`, `neighborhoodchange`, and `districtchange` events remain supported.
|
|
317
|
+
|
|
318
|
+
## Source-aware feature selection
|
|
319
|
+
|
|
320
|
+
`selectFeature(reference, options)` accepts one typed identity for each selectable kind:
|
|
321
|
+
|
|
322
|
+
```ts
|
|
323
|
+
map.selectFeature({ kind: 'marker', id: 'ferry' }, { fit: false });
|
|
324
|
+
map.selectFeature({ kind: 'neighborhood', source: 'realtor', id: 'inner-mission' });
|
|
325
|
+
map.selectFeature({ kind: 'district', year: 2022, id: 3 });
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Neighborhood IDs are exact source-scoped feature IDs, rather than display names or aliases. District identity includes the boundary year. This operation returns `false` for a missing feature or a source/year other than the map's current supplied geography; it never silently switches definitions or years. Choose geography through `configure` first. An `id` of `null` clears that kind in the referenced current geography. Malformed references throw. Existing `selectMarker`, `selectNeighborhood`, and `selectDistrict` shortcuts remain supported.
|
|
329
|
+
|
|
330
|
+
## Coordinates and units
|
|
331
|
+
|
|
332
|
+
GeoJSON and static projection inputs use `[longitude, latitude]` in WGS84; markers use `{ lng, lat }`. Static `project` returns SVG units. `projectToScreen(lng, lat)` returns pixels relative to the mounted canvas. Camera viewports and pan deltas use the fixed 800 × 800 projected map space, independent of canvas size. Marker radius uses screen pixels in browser maps and SVG units in static output.
|
|
333
|
+
|
|
334
|
+
Explore presentation options in the [live map design playground](https://kahwee.github.io/sf-map-svg/playground.html). The page identifies its package version; released builds use compatible options for that installed version.
|
|
335
|
+
|
|
272
336
|
---
|
|
273
337
|
|
|
274
|
-
<!-- Generated from docs/EXAMPLES.md; @kahwee/sf-map-svg 4.
|
|
338
|
+
<!-- Generated from docs/EXAMPLES.md; @kahwee/sf-map-svg 4.3.0 · local working tree. -->
|
|
275
339
|
|
|
276
340
|
# Examples
|
|
277
341
|
|
|
@@ -382,35 +446,59 @@ For the controller and explicit data imports, see [the v3 migration guide](https
|
|
|
382
446
|
|
|
383
447
|
---
|
|
384
448
|
|
|
385
|
-
<!-- Generated from docs/consumer-integration.md; @kahwee/sf-map-svg 4.
|
|
449
|
+
<!-- Generated from docs/consumer-integration.md; @kahwee/sf-map-svg 4.3.0 · local working tree. -->
|
|
450
|
+
|
|
451
|
+
# Embedding and progressive enhancement
|
|
386
452
|
|
|
387
|
-
|
|
453
|
+
For basic mounting, events and cleanup, start with the [developer guide](https://github.com/kahwee/sf-map-svg/blob/main/docs/developer-guide.md). The root controller takes explicit geography; the guide entry offers a smaller preset with the same grouped `configure()`, `camera`, `on()`, and `destroy()` contract. See the [migration guide](https://github.com/kahwee/sf-map-svg/blob/main/docs/migration-v3.md) for removed v2 imports.
|
|
388
454
|
|
|
389
|
-
|
|
455
|
+
## Render a guide before JavaScript loads
|
|
390
456
|
|
|
391
|
-
|
|
457
|
+
On the server or in a build step, render a compact frame:
|
|
392
458
|
|
|
393
459
|
```ts
|
|
394
|
-
import {
|
|
460
|
+
import { createGuideShell } from '@kahwee/sf-map-svg/guide/static';
|
|
395
461
|
|
|
396
|
-
const
|
|
462
|
+
const markup = createGuideShell({ title: 'Explore San Francisco' });
|
|
463
|
+
// Insert markup into your server-rendered HTML.
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
The shell uses an 800 × 800 projection with 28 units of padding, matching the interactive map. Use `createGuideSVG()` for custom dimensions. Rendering is offline, with zero runtime dependencies.
|
|
467
|
+
|
|
468
|
+
## Enhance the existing frame
|
|
469
|
+
|
|
470
|
+
In your browser entry, mount the controller into that shell:
|
|
471
|
+
|
|
472
|
+
```ts
|
|
473
|
+
import { mountGuideController } from '@kahwee/sf-map-svg/guide';
|
|
474
|
+
|
|
475
|
+
const shell = document.querySelector<HTMLElement>('.sf-guide-shell');
|
|
476
|
+
if (!shell) throw new Error('Missing guide shell');
|
|
477
|
+
const guide = mountGuideController(shell, {
|
|
478
|
+
attribution: 'compact',
|
|
397
479
|
features: { motion: { duration: 400 }, markerEntrance: true },
|
|
398
480
|
appearance: { theme: 'transit' },
|
|
399
481
|
});
|
|
400
|
-
|
|
401
|
-
//
|
|
402
|
-
|
|
482
|
+
|
|
483
|
+
// Call before your application removes the containing view.
|
|
484
|
+
function disposeGuide() {
|
|
485
|
+
guide.destroy();
|
|
486
|
+
}
|
|
403
487
|
```
|
|
404
488
|
|
|
405
|
-
|
|
489
|
+
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.
|
|
490
|
+
|
|
491
|
+
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.
|
|
492
|
+
|
|
493
|
+
## Choose the data boundary
|
|
406
494
|
|
|
407
|
-
|
|
495
|
+
`createMap(guideMapData, guideOptions)` remains available through `/guide/data` and `/presets`. For server rendering, pass `guideMapData.map` or `/data/static` to `renderMap()`. Use `/data/full` when interactive lookup collections are needed. The guide's detailed geography loads only on an explicit `loadGuideDetailedData()` call; enabling a layer does not download it.
|
|
408
496
|
|
|
409
|
-
|
|
497
|
+
See the [exact API contract](https://github.com/kahwee/sf-map-svg/blob/main/docs/API.md), [worked examples](https://github.com/kahwee/sf-map-svg/blob/main/docs/EXAMPLES.md), and [bundle measurements](https://github.com/kahwee/sf-map-svg/blob/main/docs/guide-bundle-report.md).
|
|
410
498
|
|
|
411
499
|
---
|
|
412
500
|
|
|
413
|
-
<!-- Generated from docs/migration-v3.md; @kahwee/sf-map-svg 4.
|
|
501
|
+
<!-- Generated from docs/migration-v3.md; @kahwee/sf-map-svg 4.3.0 · local working tree. -->
|
|
414
502
|
|
|
415
503
|
# Migrate to version 3
|
|
416
504
|
|
|
@@ -451,7 +539,7 @@ District styles are now prepared once per district on construction and style/yea
|
|
|
451
539
|
|
|
452
540
|
---
|
|
453
541
|
|
|
454
|
-
<!-- Generated from SOURCES.md; @kahwee/sf-map-svg 4.
|
|
542
|
+
<!-- Generated from SOURCES.md; @kahwee/sf-map-svg 4.3.0 · local working tree. -->
|
|
455
543
|
|
|
456
544
|
# Geometry and provenance
|
|
457
545
|
|
|
@@ -635,12 +723,35 @@ display geometry, and no precinct polygons or raw workbook data are shipped.
|
|
|
635
723
|
|
|
636
724
|
---
|
|
637
725
|
|
|
638
|
-
<!-- Generated from CHANGELOG.md; @kahwee/sf-map-svg 4.
|
|
726
|
+
<!-- Generated from CHANGELOG.md; @kahwee/sf-map-svg 4.3.0 · local working tree. -->
|
|
639
727
|
|
|
640
728
|
# Changelog
|
|
641
729
|
|
|
642
730
|
User-visible changes are recorded here. Unreleased entries describe changes on `main` that are not part of a tagged package release.
|
|
643
731
|
|
|
732
|
+
## Unreleased
|
|
733
|
+
|
|
734
|
+
## 4.3.0 — 2026-10-02
|
|
735
|
+
|
|
736
|
+
- Add `selectFeature` with typed marker, neighborhood source/ID and district year/ID references. Missing or mismatched identities preserve current geography and selection.
|
|
737
|
+
- Accept the same source-aware map data in static and interactive rendering. Static maps can explicitly select a supplied neighborhood definition without manually rebuilding renderer rows; compact static inputs remain supported.
|
|
738
|
+
- Include current mode, source, year and labels in configuration snapshots. Route controller mode/source/label setters through atomic configuration and support explicit camera preservation with `{ resetView: false }`.
|
|
739
|
+
- Refine the Pages atlas opening with concise copy, a map ahead of statistics on phones, coordinate captions and three direct paths into designing, exploring and building. Improve shared theme-button touch targets and stack API reference records on phones while retaining table semantics.
|
|
740
|
+
|
|
741
|
+
- Clarify the documentation paths, progressive enhancement and cleanup examples; consolidate browser validation and release instructions into one maintenance runbook. Check README and integration recipes against the packed package.
|
|
742
|
+
|
|
743
|
+
## 4.2.0 — 2026-10-01
|
|
744
|
+
|
|
745
|
+
- Reuse one native dropdown treatment across Pages, with an inset chevron, a reserved end gutter, and preserved labels, keyboard behavior, and mobile pickers.
|
|
746
|
+
- Strengthen the playground with strict TypeScript, checked JavaScript/TypeScript snippets, versioned design links, persistent explicit layer choices and independent static rendering. Keep mobile controls unobstructed and picker labels legible in dark mode.
|
|
747
|
+
- Express explicit configuration resets for consumers using `exactOptionalPropertyTypes`, including nested appearance tokens. Make Pages API and guide references describe their actual package version without internal preview warnings.
|
|
748
|
+
|
|
749
|
+
- Share grouped `layers` and supported `appearance` options between static and interactive maps, retaining flat static options and existing defaults; accept readonly static marker arrays.
|
|
750
|
+
- Update interactive appearance, mode, source, district year and labels through `configure`, preserving camera and retained marker nodes. Merge appearance tokens by key and validate combined patches before commit.
|
|
751
|
+
- Add `getResolvedConfiguration()` and `getCapabilities()` for effective layer switches and supplied geography, plus an additive `selectionchange` event with consistent current/previous snapshots.
|
|
752
|
+
- Add a live Pages map design playground with six editable palettes, layers, typography, sample pins/routes, browser/static previews, undo/redo, shareable designs, copyable code and full-city SVG export. Keep released-package previews compatible with their installed API.
|
|
753
|
+
- Refresh the Pages site: a new SF Map SVG mark traced from the real coastline, a reframed header with a release link, card-style reference tables that no longer collapse, a live filter for the API reference, an aligned playground with one-row-per-colour inks, and 12px minimum type for labels and badges.
|
|
754
|
+
|
|
644
755
|
## 4.1.0 — 2026-10-01
|
|
645
756
|
|
|
646
757
|
- Validate canonical and generated GeoJSON during data checks, rejecting invalid WGS84 coordinates and malformed polygon rings before release.
|
|
@@ -932,7 +1043,7 @@ consistent home, and makes animation and subscription ownership predictable.
|
|
|
932
1043
|
|
|
933
1044
|
# Published type contracts
|
|
934
1045
|
|
|
935
|
-
@kahwee/sf-map-svg 4.
|
|
1046
|
+
@kahwee/sf-map-svg 4.3.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.
|
|
936
1047
|
|
|
937
1048
|
| Public import | Declaration |
|
|
938
1049
|
| --- | --- |
|
|
@@ -987,25 +1098,85 @@ export declare function createMap(data: InteractiveSFMapData, options?: MapOptio
|
|
|
987
1098
|
```ts
|
|
988
1099
|
import type { Geometry, NeighborhoodSource } from '../data/types.js';
|
|
989
1100
|
import type { CameraOptions, DistrictSelection, DistrictStyle, DistrictYear, InteractiveLayers, MapFeatures, MapMarker, MapOverlay, MapPadding, MapViewport, NeighborhoodExplorerOptions, NeighborhoodSelection } from './types.js';
|
|
990
|
-
|
|
1101
|
+
/** Patch properties can explicitly remove overrides, including with exactOptionalPropertyTypes. */
|
|
1102
|
+
type Resettable<T> = {
|
|
1103
|
+
[K in keyof T]?: T[K] | undefined;
|
|
1104
|
+
};
|
|
1105
|
+
type AppearanceOptions = Pick<NeighborhoodExplorerOptions, 'theme' | 'colors' | 'labelStyle' | 'areaStyle' | 'districtStyle' | 'labelSize' | 'style' | 'markerRadius' | 'markerHitSize' | 'markerColor' | 'selectedMarkerColor'>;
|
|
1106
|
+
export type MapAppearance = {
|
|
1107
|
+
[K in keyof AppearanceOptions]?: K extends 'colors' | 'style' | 'labelStyle' | 'labelSize' | 'areaStyle' ? Resettable<NonNullable<AppearanceOptions[K]>> | undefined : AppearanceOptions[K] | undefined;
|
|
1108
|
+
};
|
|
991
1109
|
export type MapControls = NonNullable<NeighborhoodExplorerOptions['controls']>;
|
|
992
|
-
/** Omitted
|
|
1110
|
+
/** Omitted keys retain values. Undefined presentation groups reset; undefined mode/source/year/labels retain their current value. */
|
|
993
1111
|
export interface MapConfiguration {
|
|
994
|
-
features?: MapFeatures;
|
|
995
|
-
layers?: InteractiveLayers;
|
|
996
|
-
controls?: MapControls;
|
|
1112
|
+
features?: Resettable<MapFeatures> | undefined;
|
|
1113
|
+
layers?: Resettable<InteractiveLayers> | undefined;
|
|
1114
|
+
controls?: Resettable<MapControls> | undefined;
|
|
1115
|
+
appearance?: MapAppearance | undefined;
|
|
1116
|
+
mode?: NonNullable<NeighborhoodExplorerOptions['mode']> | undefined;
|
|
1117
|
+
source?: NeighborhoodSource | undefined;
|
|
1118
|
+
year?: DistrictYear | undefined;
|
|
1119
|
+
labels?: boolean | undefined;
|
|
997
1120
|
}
|
|
998
1121
|
export interface MapOptions extends Omit<NeighborhoodExplorerOptions, keyof MapFeatures | keyof MapAppearance | 'interface' | 'onMarkerActivate' | 'onOverlayActivate'> {
|
|
999
1122
|
features?: MapFeatures;
|
|
1000
|
-
appearance?: MapAppearance;
|
|
1123
|
+
appearance?: MapAppearance | undefined;
|
|
1001
1124
|
}
|
|
1125
|
+
/** Current geographic choices and detached presentation overrides; excludes camera and selection. */
|
|
1002
1126
|
export interface MapConfigurationSnapshot {
|
|
1127
|
+
mode: NonNullable<MapOptions['mode']>;
|
|
1128
|
+
source: NeighborhoodSource;
|
|
1129
|
+
year: DistrictYear;
|
|
1130
|
+
labels: boolean;
|
|
1003
1131
|
features: MapFeatures;
|
|
1004
1132
|
/** Explicit overrides; absent values continue to follow the current mode. */
|
|
1005
1133
|
layers: InteractiveLayers;
|
|
1006
1134
|
controls: MapControls;
|
|
1135
|
+
appearance: MapAppearance;
|
|
1136
|
+
}
|
|
1137
|
+
export interface MapCapabilities {
|
|
1138
|
+
sources: readonly NeighborhoodSource[];
|
|
1139
|
+
years: readonly DistrictYear[];
|
|
1140
|
+
/** Data availability, independent of requested layer visibility. */
|
|
1141
|
+
layers: Readonly<Record<keyof InteractiveLayers, boolean>>;
|
|
1142
|
+
}
|
|
1143
|
+
export interface ResolvedMapConfiguration extends MapConfigurationSnapshot {
|
|
1144
|
+
mode: NonNullable<MapOptions['mode']>;
|
|
1145
|
+
source: NeighborhoodSource;
|
|
1146
|
+
year: DistrictYear;
|
|
1147
|
+
labels: boolean;
|
|
1148
|
+
/** Effective switches after mode defaults and data availability; label switches honor labels. */
|
|
1149
|
+
layers: Record<keyof InteractiveLayers, boolean>;
|
|
1007
1150
|
}
|
|
1151
|
+
export type MapSelectionChange = {
|
|
1152
|
+
kind: 'marker';
|
|
1153
|
+
current: MapMarker | null;
|
|
1154
|
+
previous: MapMarker | null;
|
|
1155
|
+
} | {
|
|
1156
|
+
kind: 'neighborhood';
|
|
1157
|
+
current: NeighborhoodSelection | null;
|
|
1158
|
+
previous: NeighborhoodSelection | null;
|
|
1159
|
+
} | {
|
|
1160
|
+
kind: 'district';
|
|
1161
|
+
current: DistrictSelection | null;
|
|
1162
|
+
previous: DistrictSelection | null;
|
|
1163
|
+
};
|
|
1164
|
+
/** Dataset identity is explicit; selection never switches geography implicitly. */
|
|
1165
|
+
export type MapFeatureReference = {
|
|
1166
|
+
kind: 'marker';
|
|
1167
|
+
id: string | null;
|
|
1168
|
+
} | {
|
|
1169
|
+
kind: 'neighborhood';
|
|
1170
|
+
source: NeighborhoodSource;
|
|
1171
|
+
id: string | null;
|
|
1172
|
+
} | {
|
|
1173
|
+
kind: 'district';
|
|
1174
|
+
year: DistrictYear;
|
|
1175
|
+
id: number | null;
|
|
1176
|
+
};
|
|
1008
1177
|
export interface MapEvents {
|
|
1178
|
+
/** Common selection envelope; existing change events retain their payloads. */
|
|
1179
|
+
selectionchange: MapSelectionChange;
|
|
1009
1180
|
districtchange: DistrictSelection | {
|
|
1010
1181
|
id: null;
|
|
1011
1182
|
year: DistrictYear;
|
|
@@ -1042,12 +1213,18 @@ export interface MapEvents {
|
|
|
1042
1213
|
};
|
|
1043
1214
|
mapresize: undefined;
|
|
1044
1215
|
}
|
|
1216
|
+
/** Convenience setters retain their historic reset default; false preserves the camera. */
|
|
1217
|
+
export interface MapViewUpdateOptions {
|
|
1218
|
+
resetView?: boolean;
|
|
1219
|
+
}
|
|
1045
1220
|
export interface MapCamera {
|
|
1221
|
+
/** Fixed 800 × 800 projected space, not longitude/latitude. */
|
|
1046
1222
|
get(): MapViewport;
|
|
1047
1223
|
set(view: MapViewport, options?: CameraOptions): void;
|
|
1048
1224
|
fit(geometry: Geometry, options?: CameraOptions & {
|
|
1049
1225
|
padding?: number | MapPadding;
|
|
1050
1226
|
}): void;
|
|
1227
|
+
/** Delta in projected map units. */
|
|
1051
1228
|
pan(x: number, y: number, options?: CameraOptions): void;
|
|
1052
1229
|
zoom(factor: number, options?: CameraOptions): void;
|
|
1053
1230
|
reset(options?: CameraOptions): void;
|
|
@@ -1061,10 +1238,16 @@ export interface MapController {
|
|
|
1061
1238
|
readonly destroyed: boolean;
|
|
1062
1239
|
configure(patch: MapConfiguration): void;
|
|
1063
1240
|
getConfiguration(): MapConfigurationSnapshot;
|
|
1241
|
+
getResolvedConfiguration(): ResolvedMapConfiguration;
|
|
1242
|
+
getCapabilities(): MapCapabilities;
|
|
1064
1243
|
on<K extends keyof MapEvents>(type: K, listener: (detail: MapEvents[K]) => void): () => void;
|
|
1065
1244
|
/** Reconcile stable IDs; retained markers preserve nodes, focus, and entrance animations. */
|
|
1066
1245
|
setMarkers(markers: readonly MapMarker[]): void;
|
|
1067
1246
|
setOverlays(overlays: readonly MapOverlay[]): void;
|
|
1247
|
+
/** False for missing IDs or a source/year other than the current geography. */
|
|
1248
|
+
selectFeature(reference: MapFeatureReference, options?: CameraOptions & {
|
|
1249
|
+
fit?: boolean;
|
|
1250
|
+
}): boolean;
|
|
1068
1251
|
selectMarker(id: string | null, options?: CameraOptions & {
|
|
1069
1252
|
fit?: boolean;
|
|
1070
1253
|
}): boolean;
|
|
@@ -1079,8 +1262,8 @@ export interface MapController {
|
|
|
1079
1262
|
getSelectedDistrict(): DistrictSelection | null;
|
|
1080
1263
|
setDistrictYear(year: DistrictYear, options?: CameraOptions): void;
|
|
1081
1264
|
setDistrictStyle(style: ((district: DistrictSelection['district']) => DistrictStyle) | undefined): void;
|
|
1082
|
-
setSource(source: NeighborhoodSource): void;
|
|
1083
|
-
setMode(mode: NonNullable<MapOptions['mode']
|
|
1265
|
+
setSource(source: NeighborhoodSource, options?: MapViewUpdateOptions): void;
|
|
1266
|
+
setMode(mode: NonNullable<MapOptions['mode']>, options?: MapViewUpdateOptions): void;
|
|
1084
1267
|
setLabels(visible: boolean): void;
|
|
1085
1268
|
setTouchNavigation(enabled: boolean): void;
|
|
1086
1269
|
projectToScreen(lng: number, lat: number): {
|
|
@@ -1091,6 +1274,7 @@ export interface MapController {
|
|
|
1091
1274
|
/** Idempotent; stops work and managed subscriptions. Does not remove host-owned DOM. */
|
|
1092
1275
|
destroy(): void;
|
|
1093
1276
|
}
|
|
1277
|
+
export {};
|
|
1094
1278
|
```
|
|
1095
1279
|
|
|
1096
1280
|
### dist/data/types.d.ts
|
|
@@ -1264,11 +1448,16 @@ export interface MapOverlay {
|
|
|
1264
1448
|
label?: string;
|
|
1265
1449
|
}
|
|
1266
1450
|
export interface SFMapOptions {
|
|
1451
|
+
/** Grouped presentation; supplied keys take precedence over flat compatibility options. */
|
|
1452
|
+
layers?: StaticMapLayers;
|
|
1453
|
+
appearance?: StaticMapAppearance;
|
|
1267
1454
|
theme?: 'districts' | 'transit';
|
|
1268
1455
|
width?: number;
|
|
1269
1456
|
height?: number;
|
|
1270
1457
|
padding?: number;
|
|
1271
1458
|
year?: DistrictYear;
|
|
1459
|
+
/** Select a supplied neighborhood definition when rendering source-aware MapData. */
|
|
1460
|
+
source?: NeighborhoodSource;
|
|
1272
1461
|
districtLines?: boolean;
|
|
1273
1462
|
neighborhoodLines?: boolean;
|
|
1274
1463
|
districtFills?: boolean;
|
|
@@ -1282,7 +1471,7 @@ export interface SFMapOptions {
|
|
|
1282
1471
|
roadLabels?: boolean;
|
|
1283
1472
|
landmarks?: boolean;
|
|
1284
1473
|
bartStations?: boolean;
|
|
1285
|
-
markers?: MapMarker[];
|
|
1474
|
+
markers?: readonly MapMarker[];
|
|
1286
1475
|
overlays?: readonly MapOverlay[];
|
|
1287
1476
|
title?: string;
|
|
1288
1477
|
idPrefix?: string;
|
|
@@ -1298,6 +1487,9 @@ export interface SFMapOptions {
|
|
|
1298
1487
|
};
|
|
1299
1488
|
colors?: Partial<Record<'water' | 'land' | 'district' | 'neighborhood' | 'highway' | 'road' | 'park' | 'landmark' | 'bart' | 'label' | 'marker' | 'selected', string>>;
|
|
1300
1489
|
}
|
|
1490
|
+
/** Presentation supported by both the static and interactive renderers. */
|
|
1491
|
+
export type StaticMapLayers = Omit<InteractiveLayers, 'neighborhoodLabels'>;
|
|
1492
|
+
export type StaticMapAppearance = Pick<SFMapOptions, 'theme' | 'colors' | 'districtStyle'>;
|
|
1301
1493
|
/** Serializable viewport in the interactive map's fixed 800 × 800 projected space. */
|
|
1302
1494
|
export type MapViewport = readonly [x: number, y: number, size: number];
|
|
1303
1495
|
export type ExplorerMode = 'neighborhoods' | 'districts' | 'basemap';
|
|
@@ -1476,7 +1668,7 @@ export interface NeighborhoodExplorerElement extends HTMLElement {
|
|
|
1476
1668
|
export interface TransitAnimationElement extends HTMLElement {
|
|
1477
1669
|
destroy(): void;
|
|
1478
1670
|
}
|
|
1479
|
-
export type { MapAppearance, MapCamera, MapConfiguration, MapController, MapEvents, MapOptions, } from './controller-types.js';
|
|
1671
|
+
export type { MapAppearance, MapCamera, MapCapabilities, MapConfiguration, MapConfigurationSnapshot, MapController, MapControls, MapEvents, MapFeatureReference, MapOptions, MapSelectionChange, MapViewUpdateOptions, ResolvedMapConfiguration, } from './controller-types.js';
|
|
1480
1672
|
```
|
|
1481
1673
|
|
|
1482
1674
|
### dist/src/explorer-data.d.ts
|
|
@@ -1578,6 +1770,20 @@ export declare function getLayerPathsWithData(options: SFMapOptions, data: SFMap
|
|
|
1578
1770
|
point: [number, number];
|
|
1579
1771
|
}[];
|
|
1580
1772
|
};
|
|
1773
|
+
export declare function resolveMapColors(theme: SFMapOptions['theme'], colors?: SFMapOptions['colors']): {
|
|
1774
|
+
water: string;
|
|
1775
|
+
land: string;
|
|
1776
|
+
district: string;
|
|
1777
|
+
neighborhood: string;
|
|
1778
|
+
highway: string;
|
|
1779
|
+
road: string;
|
|
1780
|
+
park: string;
|
|
1781
|
+
landmark: string;
|
|
1782
|
+
bart: string;
|
|
1783
|
+
label: string;
|
|
1784
|
+
marker: string;
|
|
1785
|
+
selected: string;
|
|
1786
|
+
};
|
|
1581
1787
|
/** Make an offline SVG and the matching longitude/latitude projection. */
|
|
1582
1788
|
export declare function createSFMapWithData(options: SFMapOptions, data: SFMapData): {
|
|
1583
1789
|
svg: string;
|
|
@@ -1589,18 +1795,21 @@ export declare function createSFMapWithData(options: SFMapOptions, data: SFMapDa
|
|
|
1589
1795
|
### dist/src/static.d.ts
|
|
1590
1796
|
|
|
1591
1797
|
```ts
|
|
1798
|
+
import type { InteractiveSFMapData } from './explorer-data.js';
|
|
1592
1799
|
import { type SFMapData } from './map-core.js';
|
|
1593
1800
|
import type { SFMapOptions } from './types.js';
|
|
1801
|
+
/** Either compact static geography or the same source-aware geography used by createMap. */
|
|
1802
|
+
export type StaticMapInput = SFMapData | InteractiveSFMapData;
|
|
1594
1803
|
export type { DistrictRowData, SFMapData as StaticMapData } from './map-core.js';
|
|
1595
|
-
export type { DistrictStyle, DistrictYear, SFMapOptions as StaticMapOptions } from './types.js';
|
|
1804
|
+
export type { DistrictStyle, DistrictYear, SFMapOptions as StaticMapOptions, StaticMapAppearance, StaticMapLayers, } from './types.js';
|
|
1596
1805
|
/** Server-safe SVG rendering with explicit data; returns SVG plus projection helpers. */
|
|
1597
|
-
export declare function renderMap(data:
|
|
1806
|
+
export declare function renderMap(data: StaticMapInput, options?: SFMapOptions): {
|
|
1598
1807
|
svg: string;
|
|
1599
1808
|
project: (coordinates: import("../data/types.js").Position) => [number, number];
|
|
1600
1809
|
viewBox: [number, number, number, number];
|
|
1601
1810
|
};
|
|
1602
1811
|
/** Project canonical layer geometry without constructing an SVG string. */
|
|
1603
|
-
export declare function getLayerPaths(data:
|
|
1812
|
+
export declare function getLayerPaths(data: StaticMapInput, options?: SFMapOptions): {
|
|
1604
1813
|
year: import("./types.js").DistrictYear;
|
|
1605
1814
|
viewBox: [number, number, number, number];
|
|
1606
1815
|
project: (coordinates: import("../data/types.js").Position) => [number, number];
|
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 4.
|
|
5
|
+
@kahwee/sf-map-svg 4.3.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
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kahwee/sf-map-svg",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.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",
|
|
@@ -175,13 +175,14 @@
|
|
|
175
175
|
"demo": "pnpm build && node examples/build.mjs",
|
|
176
176
|
"format": "biome check --write .",
|
|
177
177
|
"format:check": "biome format .",
|
|
178
|
-
"check": "pnpm peers check && pnpm lint && pnpm check:docs && pnpm data:check && pnpm typecheck && pnpm typecheck:stories && pnpm test && pnpm test:bundle",
|
|
178
|
+
"check": "pnpm peers check && pnpm lint && pnpm check:docs && pnpm data:check && pnpm typecheck && pnpm typecheck:stories && pnpm typecheck:website && pnpm test && pnpm test:bundle",
|
|
179
179
|
"check:docs": "pnpm build && node scripts/check-docs.mjs && node scripts/build-llm-docs.mjs --check",
|
|
180
180
|
"storybook": "pnpm build && storybook dev -p 6006 --host 127.0.0.1 --no-open",
|
|
181
181
|
"build-storybook": "pnpm build && storybook build",
|
|
182
182
|
"data:catalog": "node scripts/build-data-catalog.mjs",
|
|
183
183
|
"data:check": "node scripts/build-data-catalog.mjs --check",
|
|
184
184
|
"typecheck": "pnpm build && tsc -p tsconfig.json",
|
|
185
|
+
"typecheck:website": "pnpm build && tsc -p tsconfig.website.json",
|
|
185
186
|
"typecheck:stories": "tsc -p tsconfig.stories.json",
|
|
186
187
|
"data:normalize-realtor": "node scripts/normalize-realtor.mjs",
|
|
187
188
|
"data:guide": "node scripts/build-guide-data.mjs",
|