@minmaps-dev/mm-web-sdk 1.0.0-rc.3 → 1.0.0-rc.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,31 +1,79 @@
1
+ <div align="center">
2
+
1
3
  # MinuteMaps Web SDK
2
4
 
3
- `@minmaps-dev/mm-web-sdk` is the official MinuteMaps SDK for the web. It renders indoor venues — floors, POIs, amenities, destinations, and wayfinding routes — on top of [MapLibre GL JS](https://maplibre.org/), with data sourced from JACS.
5
+ **Render indoor venues — floors, POIs, amenities, destinations, and wayfinding routes — on top of [MapLibre GL JS](https://maplibre.org/).**
4
6
 
5
- ## Features
7
+ [![npm](https://img.shields.io/npm/v/@minmaps-dev/mm-web-sdk?label=npm)](https://www.npmjs.com/package/@minmaps-dev/mm-web-sdk)
8
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
9
+ [![types](https://img.shields.io/badge/types-included-blue)](./dist/index.d.ts)
6
10
 
7
- - **Venue + floors** — load a venue by `customerId` / `venueId`, switch active floor, and let the SDK manage layer visibility.
8
- - **POIs, amenities, destinations** — query the venue, filter by floor, and run keyword searches.
9
- - **Wayfinding** — compute kiosk-to-destination or waypoint-to-waypoint routes and render them on the map.
10
- - **View modes** — toggle 3D, flat (top-down), and 2D-units modes at runtime.
11
- - **Camera control** — `setView` / `resetView` / `getCameraPosition`, plus a live `cameraChange` event for compass UIs.
12
- - **React entrypoint** — drop-in `<MinuteMapsView />` for React 18/19 apps.
13
- - **JACS proxy or direct mode** — keep credentials server-side with the proxy mode, or call JACS directly from trusted environments.
11
+ </div>
14
12
 
15
- ## Installation
13
+ `@minmaps-dev/mm-web-sdk` is the official MinuteMaps SDK for the web. It loads venues from JACS, manages floors, POIs, amenities, destinations, and the camera, and gives you a small, well-typed surface for building modern kiosks and indoor mapping web apps.
16
14
 
17
15
  ```bash
18
16
  npm install @minmaps-dev/mm-web-sdk maplibre-gl @turf/turf
19
17
  ```
20
18
 
21
- `maplibre-gl` (v4) and `@turf/turf` (v7) are peer dependencies. `react` / `react-dom` (v18 or v19) are optional peers, only required if you use the `/react` entrypoint.
22
-
23
- Don't forget to import the MapLibre stylesheet once in your app:
24
-
25
19
  ```ts
20
+ import { MinuteMaps } from '@minmaps-dev/mm-web-sdk'
26
21
  import 'maplibre-gl/dist/maplibre-gl.css'
22
+
23
+ const sdk = new MinuteMaps({
24
+ container: 'map',
25
+ jmap: { host: '', customerId: 123, venueId: 456 },
26
+ jacs: { mode: 'proxy', proxyBaseUrl: '/api/jacs' },
27
+ options: { styleMode: 'sdkTemplate' },
28
+ })
29
+
30
+ sdk.on('ready', ({ venue }) => console.log('venue ready', venue?.name))
31
+ await sdk.init()
27
32
  ```
28
33
 
34
+ ---
35
+
36
+ ## Status
37
+
38
+ This SDK is on a pre-1.0 release candidate (`1.0.0-rc.24`). A few capabilities remain **dormant pending backend support** — they are not yet functional in the published build:
39
+
40
+ | Area | Status | Notes |
41
+ | --- | --- | --- |
42
+ | Floors, POIs, amenities, destinations | ✅ Shipped | Loads via JACS `building/full` + `venue/full`. |
43
+ | Camera + view modes (3D/2D/flat) | ✅ Shipped | Style toggles work against the bundled `alt3-hybrid-style.json`. |
44
+ | Wayfinding | ✅ Shipped | Built-in JACS path-graph routing (rc.18). `JacsWayfindingProvider` is wired by default; route computation runs inside the SDK (`src/data/wayfinding/`). No provider injection needed. |
45
+ | Contextual map APIs | ✅ Shipped | `highlightPOI`/`highlightAmenity`/`clearHighlight`, `setPOIFilter`/`clearPOIFilter`, `amenities.getDistinct`, `findClosestWaypoint`, `searchAllPOIs`, `navigateFromKioskToPOI`, `refit`. See `docs/API.md#contextual-map`. |
46
+ | Venue-served stylesheets | 🚧 Roadmap | SDK currently uses its bundled style; `loadAndPatchVenueStyle()` is bypassed. |
47
+ | Polygon layers + 3D map templates | 🚧 Roadmap | `buildPolygonLayers` / `applyMapTemplate3d` imports are commented in `src/sdk.ts`. |
48
+
49
+ Track re-enable points by grepping `// TODO: Re-enable` in `src/sdk.ts` and `src/data/jacsDataProvider.ts`.
50
+
51
+ ---
52
+
53
+ ## What's in the box
54
+
55
+ - **Venue + floors** — load a venue by `customerId` / `venueId`, switch active floor, let the SDK manage layer visibility.
56
+ - **POIs, amenities, destinations** — query by floor, run keyword searches, find the kiosk's "You are here" location.
57
+ - **View modes** — toggle 3D extrusion, flat (top-down), and 2D-units modes at runtime.
58
+ - **Camera control** — `setView` / `resetView` / `getCameraPosition`, plus a live `cameraChange` event for compass UIs.
59
+ - **React entrypoint** — drop-in `<MinuteMapsView />` for React 18/19.
60
+ - **JACS proxy or direct mode** — keep credentials server-side (recommended) or call JACS directly from trusted environments.
61
+
62
+ ---
63
+
64
+ ## Documentation
65
+
66
+ The lean root README intentionally stops here. For depth, see:
67
+
68
+ - [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) — module map, init flow, JACS data path, style patching, dormant 3D notes.
69
+ - [`docs/API.md`](./docs/API.md) — full public API surface grouped by lifecycle, floors, POIs, amenities, wayfinding, camera, events.
70
+ - [`docs/KIOSK.md`](./docs/KIOSK.md) — kiosk integration patterns (You-Are-Here, kiosk-to-destination wayfinding once enabled, view-mode UX, sprite hosting, idle reset).
71
+ - [`docs/ICONS.md`](./docs/ICONS.md) — the curated icon registry, how amenity/connector/destination icons resolve and render, the CMS upload flow, and the release coupling between the icon-set and SDK packages.
72
+
73
+ External integrators will usually only need the [API](./docs/API.md) and [Kiosk](./docs/KIOSK.md) docs. Internal MTS engineers should also read [Architecture](./docs/ARCHITECTURE.md) before touching `src/sdk.ts` or the JACS provider.
74
+
75
+ ---
76
+
29
77
  ## Quick start (vanilla)
30
78
 
31
79
  ```ts
@@ -51,9 +99,8 @@ const sdk = new MinuteMaps({
51
99
  },
52
100
  })
53
101
 
54
- sdk.on('ready', ({ venue }) => {
55
- console.log('venue ready', venue?.name)
56
- })
102
+ sdk.on('ready', ({ venue }) => console.log('venue ready', venue?.name))
103
+ sdk.on('floorChanged', ({ floor }) => console.log('now showing', floor?.name))
57
104
 
58
105
  await sdk.init()
59
106
  ```
@@ -79,9 +126,11 @@ export function Map() {
79
126
  }
80
127
  ```
81
128
 
82
- For a more involved integration that wires events, floors, search, and wayfinding into React state, see the [`mm-web-sdk-example`](../mm-web-sdk-example) Next.js app particularly [`hooks/useMap.ts`](../mm-web-sdk-example/hooks/useMap.ts).
129
+ The React entry is intentionally minimal: it owns its own `<div>`, calls `init()` on mount, and `destroy()` on unmount. Reach for the vanilla `MinuteMaps` class when you need imperative control (floor switching from a side panel, camera animations driven by Redux, etc.).
130
+
131
+ ---
83
132
 
84
- ## Configuration
133
+ ## Configuration at a glance
85
134
 
86
135
  ```ts
87
136
  type SDKConfig = {
@@ -95,37 +144,29 @@ type SDKConfig = {
95
144
  }
96
145
  jacs: {
97
146
  mode: 'proxy' | 'direct'
98
- host?: string // 'direct' only
147
+ host?: string // 'direct' only
99
148
  auth?: { clientId: string; username: string; password: string } // 'direct' only
100
149
  proxyBaseUrl?: string // default '/api/jacs'
101
150
  }
102
151
  options?: SDKOptions
103
152
  }
104
-
105
- type SDKOptions = {
106
- debug?: boolean
107
- initialFloor?: string | number
108
- customSprite?: string // sprite URL prefix (no extension)
109
- minIndoorZoom?: number
110
- boundsPadding?: number // default 50
111
- styleMode?: 'venueStyleUrl' | 'sdkTemplate'
112
- templateOverrideMode?: 'colorsOnly' | 'colorsAndConstants' | 'all'
113
- }
114
153
  ```
115
154
 
155
+ Full option reference and an annotated `SDKOptions` shape live in [`docs/API.md`](./docs/API.md#configuration).
156
+
116
157
  ### JACS proxy mode (recommended)
117
158
 
118
- Browser apps should use `mode: 'proxy'` and forward requests through your own server so JACS credentials never reach the client. The example app ships a Next.js route handler at [`app/api/jacs/[...path]/route.ts`](../mm-web-sdk-example/app/api/jacs/%5B...path%5D/route.ts) that:
159
+ Browser apps should use `mode: 'proxy'` and forward requests through your own server so JACS credentials never reach the client. Your proxy should:
119
160
 
120
- 1. Reads `JACS_HOST`, `JACS_CLIENT_ID`, `JACS_USERNAME`, `JACS_PASSWORD` from server env.
121
- 2. Exchanges the password grant for a bearer token (cached until expiry).
122
- 3. Forwards `GET /api/jacs/<path>` to `${JACS_HOST}/JACS/api/<path>` with the token attached.
161
+ 1. Read `JACS_HOST`, `JACS_CLIENT_ID`, `JACS_USERNAME`, `JACS_PASSWORD` from server env.
162
+ 2. Exchange the password grant for a bearer token (cache until expiry).
163
+ 3. Forward `GET /api/jacs/<path>` to `${JACS_HOST}/JACS/api/<path>` with the token attached.
123
164
 
124
- Copy that handler into your own backend (or adapt it to your framework) and point `jacs.proxyBaseUrl` at it.
165
+ A reference Next.js route handler ships in the example app at `apps/example/app/api/jacs/[...path]/route.ts`. Copy it into your own backend or adapt it to your framework, then point `jacs.proxyBaseUrl` at it.
125
166
 
126
167
  ### JACS direct mode
127
168
 
128
- For trusted environments (server-rendered pages, Electron kiosks, internal tools) you can call JACS directly:
169
+ For trusted environments server-rendered pages, Electron kiosks, internal tools call JACS directly:
129
170
 
130
171
  ```ts
131
172
  jacs: {
@@ -135,104 +176,56 @@ jacs: {
135
176
  }
136
177
  ```
137
178
 
138
- ## API
139
-
140
- ### Class `MinuteMaps`
141
-
142
- ```ts
143
- new MinuteMaps(config: SDKConfig)
144
- sdk.init(): Promise<void>
145
- sdk.destroy(): void
146
- sdk.isReady(): boolean
147
- sdk.getMap(): maplibregl.Map | null
148
- ```
149
-
150
- `createMinuteMapsSDK(config)` is a factory shorthand for `new MinuteMaps(config)`.
179
+ > ⚠ Never ship `direct` mode to a public browser bundle. Your JACS credentials would be visible to anyone with devtools.
151
180
 
152
- ### Floors
181
+ ---
153
182
 
154
- ```ts
155
- sdk.getFloors(): Floor[]
156
- sdk.getCurrentFloor(): Floor | null
157
- sdk.getDefaultFloor(): Floor | null
158
- sdk.setCurrentFloor(floor: Floor): Promise<void>
159
- ```
183
+ ## Sprites
160
184
 
161
- ### POIs, destinations, search
185
+ `options.customSprite` is a sprite URL **prefix without extension** — MapLibre appends `.json` and `.png` (and `@2x` variants) automatically. The example app serves its sprite from `apps/example/public/sprites/`.
162
186
 
163
- ```ts
164
- sdk.getAllPOIs(floor?: Floor): POI[]
165
- sdk.getDestinations(floor?: Floor): Destination[]
166
- sdk.searchPOIs(query: string, floor?: Floor): POI[]
167
- sdk.getYouAreHerePOI(floor?: Floor): POI | null
168
- sdk.getYouAreHereCoordinates(floor?: Floor): [number, number] | null
169
- ```
170
-
171
- ### Amenities (`sdk.amenities`)
187
+ ---
172
188
 
173
- ```ts
174
- sdk.amenities.getAll(): AmenityWithFloor[]
175
- sdk.amenities.getByFloorId(floorId): AmenityWithFloor[]
176
- sdk.amenities.getAllKiosks(): AmenityWithFloor[]
177
- sdk.amenities.getKioskForFloor(floorId): AmenityWithFloor | null
178
- ```
189
+ ## Development
179
190
 
180
- ### Wayfinding
191
+ Run commands from the **monorepo root** through pnpm/turbo (install pnpm via npm, not corepack):
181
192
 
182
- ```ts
183
- sdk.navigateFromKioskToDestination(destination): Promise<...>
184
- sdk.wayfindBetweenWaypoints(from, to, opts?: {
185
- centerMode?: 'none' | 'destination' | 'route'
186
- zoom?: number
187
- }): Promise<...>
188
- sdk.clearRoute(): void
193
+ ```bash
194
+ pnpm install # once, at the root — one lockfile for the whole monorepo
195
+ pnpm dev # turbo: SDK rollup --watch + example next dev together
196
+ pnpm build # turbo: production build of all packages
197
+ pnpm typecheck # turbo: tsc --noEmit
198
+ pnpm test # turbo: vitest run
189
199
  ```
190
200
 
191
- ### Camera + view modes
192
-
193
- ```ts
194
- sdk.setView({ center?, zoom?, pitch?, bearing?, animate?, duration? })
195
- sdk.resetView({ animate?, duration? })
196
- sdk.getCameraPosition(): CameraState | null
197
-
198
- sdk.set3dEnabled(enabled) / toggle3d() / getIs3dEnabled()
199
- sdk.setUnits2dEnabled(enabled) / toggleUnits2d() / getIsUnits2dEnabled()
200
- sdk.setFlatMode(enabled) / toggleFlatMode() / getIsFlatMode()
201
- ```
201
+ SDK-only build: `pnpm --filter @minmaps-dev/mm-web-sdk build`. Per-package scripts (`dev:sdk`, `test:watch`, `test:coverage`) still exist and can be run with `pnpm --filter @minmaps-dev/mm-web-sdk <script>`.
202
202
 
203
- ### MapLibre passthroughs
203
+ The build emits ESM, CJS, and types under `dist/` for both the root entry and the `/react` entry. Tests live in `tests/` and target the three highest-leverage modules: `JacsProvider`, `WayfindingManager`, and `ViewModeController`. Coverage thresholds are gated in `vitest.config.ts` (currently 60% lines/funcs/stmts, 50% branches).
204
204
 
205
- ```ts
206
- sdk.addControl(control, position?) // forwards to the underlying MapLibre map
207
- sdk.getMap() // escape hatch: the raw maplibregl.Map
208
- ```
205
+ ### Continuous integration
209
206
 
210
- ### Events
207
+ CI lives at the **monorepo root** in `.github/workflows/`:
211
208
 
212
- Subscribe with `sdk.on(event, cb)` / unsubscribe with `sdk.off(event, cb)`.
209
+ - **`ci.yml`** — runs typecheck, vitest with coverage, and the production build on every push and pull request to `main` / `dev`.
210
+ - **`release.yml`** — Changesets-driven releases. Write a changeset, merge to `main`, and a "Version Packages" PR is opened; merging it runs `changeset publish` to npm (access `public`). There is no tag-based publish workflow and no provenance flag.
211
+ - **`deploy-example.yml`** — deploys the example app.
213
212
 
214
- | Event | Payload | When |
215
- | --------------- | ----------------------------- | ---------------------------------------------------------- |
216
- | `ready` | `{ venue }` | Map loaded and the initial floor is rendered. |
217
- | `floorsLoaded` | `{}` | All floor geojson is available. |
218
- | `floorChanged` | `{ floor }` | After `setCurrentFloor` resolves. |
219
- | `cameraChange` | `{ camera: CameraState }` | On every map `move` (drives compass/heading UI). |
220
- | `error` | `{ error }` | Init or runtime error. |
213
+ > **Internal note:** future Claude sessions get oriented from [`CLAUDE.md`](./CLAUDE.md). Subagents at the monorepo-root `.claude/agents/` cover API doc sync, release notes, and style/template edits.
221
214
 
222
- ## Sprites
215
+ ---
223
216
 
224
- Pass `options.customSprite` as a sprite URL prefix without the extension (MapLibre will append `.json` and `.png` / `@2x`). The example app serves its sprite from [`public/sprites/`](../mm-web-sdk-example/public/sprites/).
217
+ ## Browser + framework support
225
218
 
226
- ## Development
219
+ | Target | Version |
220
+ | --- | --- |
221
+ | Node (build/dev) | ≥ 18 |
222
+ | `maplibre-gl` | ^4 |
223
+ | `@turf/turf` | ^7 |
224
+ | `react` / `react-dom` | ^18 or ^19 (only required for `/react` entry) |
227
225
 
228
- ```bash
229
- npm install
230
- npm run dev:sdk # rollup --watch
231
- npm run build # clean + production build
232
- npm run typecheck # tsc --noEmit
233
- ```
226
+ Modern evergreen browsers. Kiosk targets are typically pinned Chromium builds — if you need to support a specific minimum, open an issue.
234
227
 
235
- The build emits ESM, CJS, and types under `dist/` for both the root entry and the `/react` entry.
228
+ ---
236
229
 
237
230
  ## License
238
231