@nika-js/onlymap 0.2.2 → 0.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.
Files changed (50) hide show
  1. package/.vscode/onlymap.code-snippets +4 -4
  2. package/LICENSE.md +22 -12
  3. package/README.md +54 -11
  4. package/dist/actions.d.ts +2 -2
  5. package/dist/badge.d.ts +4 -0
  6. package/dist/{basemap-Bn4TmZtQ.js → basemap-DrK6zcu8.js} +2337 -2273
  7. package/dist/basemap-registry.d.ts +10 -0
  8. package/dist/basemap.d.ts +23 -0
  9. package/dist/color.d.ts +9 -0
  10. package/dist/ctx.d.ts +10 -1
  11. package/dist/deck.d.ts +28 -0
  12. package/dist/deck.js +16 -0
  13. package/dist/elements/om-map.d.ts +30 -0
  14. package/dist/error-reporting.d.ts +17 -0
  15. package/dist/history.d.ts +53 -0
  16. package/dist/html-data.d.ts +2 -2
  17. package/dist/{index-D2zVsZ79.js → index-C9tgnPNw.js} +1 -1
  18. package/dist/{index-BZs_x9Dx.js → index-CiuGqS0i.js} +2 -2
  19. package/dist/{index-oE1Kouy1.js → index-CsicbycJ.js} +18395 -16371
  20. package/dist/{index-3UyMg0Md.js → index-DXoRERAy.js} +1 -1
  21. package/dist/{index-DSjndBOf.js → index-Ztkd30f8.js} +1 -1
  22. package/dist/index.d.ts +19 -0
  23. package/dist/internal-ids.d.ts +7 -0
  24. package/dist/ir-diff.d.ts +1 -1
  25. package/dist/ir-snapshot.d.ts +2 -0
  26. package/dist/ir.d.ts +7 -0
  27. package/dist/license.d.ts +64 -0
  28. package/dist/onlymapjs.js +54 -32
  29. package/dist/onlymapjs.umd.cjs +426 -342
  30. package/dist/programmatic.d.ts +35 -0
  31. package/dist/react/om-layer.d.ts +2 -0
  32. package/dist/react.js +18 -16
  33. package/dist/runtime-core.d.ts +79 -1
  34. package/dist/scene-lighting.d.ts +83 -0
  35. package/dist/selection.d.ts +1 -1
  36. package/dist/snapshot.d.ts +14 -0
  37. package/dist/telemetry-schema.d.ts +53 -0
  38. package/dist/telemetry.d.ts +60 -0
  39. package/dist/terrain.d.ts +113 -0
  40. package/dist/version.d.ts +8 -0
  41. package/docs/custom-layers.md +99 -0
  42. package/docs/react.md +1 -0
  43. package/docs/telemetry.md +78 -0
  44. package/docs/testing.md +2 -2
  45. package/llms.txt +6 -5
  46. package/onlymapjs.html-data.json +172 -29
  47. package/package.json +25 -5
  48. package/skills/onlymapjs/SKILL.md +4 -1
  49. package/skills/onlymapjs/references/syntax.md +32 -1
  50. package/skills/onlymapjs/references/testing.md +2 -0
@@ -33,11 +33,20 @@ Common attributes:
33
33
  - `zoom="11"`
34
34
  - `pitch="55"`
35
35
  - `bearing="20"`
36
- - `basemap` — a free preset (`liberty`, `bright`, `positron`, `dark-matter`, `voyager`, `osm`; keyed `maptiler-streets|dataviz|satellite` with `basemap-key="…"` or `OmMap.configureBasemap({ maptilerKey })`), `maplibre` (bare demo style), a MapLibre style URL, or `none` (standalone canvas). The attribute is live: writing it switches the basemap in place (camera and layers survive). Register more with `OmMap.registerBasemap(name, { style })`.
36
+ - `basemap` — a free preset (`liberty`, `bright`, `positron`, `dark-matter`, `voyager`, `osm`; keyed `maptiler-streets|dataviz|satellite` with `basemap-key="…"` or `OmMap.configureBasemap({ maptilerKey })`), `maplibre` (bare demo style), a MapLibre style URL (any scheme fetch supports, including desktop asset protocols; query strings fine), or `none` (standalone canvas). The attribute is live: writing it switches the basemap in place (camera and layers survive). Register more with `OmMap.registerBasemap(name, { style })`.
37
37
  - `attribution="false"` to opt out of the automatic provider-attribution control (only if you render equivalent credits yourself)
38
38
  - `validate` to show live validation errors during authoring
39
+ - `map-id="<random UUID>"` — identifies the map artifact for usage telemetry (not a visitor id). Include one on new complete pages, freshly generated — never copied from an example; deleting it is the opt-out.
40
+ - `telemetry="off"` disables usage telemetry for this map (global: `OmMap.configureTelemetry({ disabled: true })`)
41
+ - `license-key="om_live_…"` — lifts the free-plan limits (5 layers, 25k rows per layer) and removes the corner badge; publishable origin-restricted token, safe in page source (or `OmMap.configureLicense(key)` once). Free-plan violations don't break the map: the offending layer isn't rendered and validation names the limit.
42
+ - `terrain="terrarium|<preset>|<{z}/{x}/{y} DEM URL>|off"` — 3D elevation surface. `terrarium` is keyless (AWS); `maptiler-terrain` needs `basemap-key`/`configureBasemap`; raw DEM URLs need `terrain-decoder` (`terrarium`, `mapbox-rgb`, or `{rScaler,gScaler,bScaler,offset}` JSON). `terrain-exaggeration` scales relief (1 = true); `terrain-max-zoom` = the provider's REAL tileset cap; `terrain-texture` drapes a `{z}/{x}/{y}` imagery template. Geographic layers drape automatically; per-layer `terrain="drape|offset|off"` overrides (3D-model layers default to `offset`). Terrain REPLACES an active basemap while on (restored when off) — validation warns. Register presets with `OmMap.registerTerrain(name, {...})`; `set-terrain` action + `terrain` watch token; attribute-backed (undoable).
43
+ - `lighting="daylight|studio|flat|custom"` — scene lighting for 3D content (extruded polygons, models); absent = deck defaults. Preset seeds values; `lighting-ambient`, `lighting-sun` (intensity; 0 removes the sun), `lighting-sun-azimuth` (° CW from north), `lighting-sun-elevation` (° above horizon), `lighting-camera` (model-inspection fill) override individual fields; `lighting-sun-date` (ISO 8601 or epoch ms) computes the sun from solar position at the map center and wins over azimuth/elevation. Attribute-backed: changes are undoable, and the `set-lighting {lighting, sunAzimuth, …}` action makes lighting story-steppable (`lighting="default"` removes the whole attribute set; a bare preset is a clean reset). `<om-widget type="lighting">` is the native UI. Widget scripts can `watch = ["lighting"]`.
39
44
  - `headless width="800" height="600"` for test harness use
40
45
 
46
+ Events: `om-map-ready` (boot complete; `await mapEl.ready` is the promise twin), `om-validation-error`, and `om-view-changed` — fires once the camera settles after a move (debounced; `detail = {longitude, latitude, zoom, pitch, bearing}`), the hook for persisting the camera. `MapController` takes an `onViewChange` option for the same signal.
47
+
48
+ `await mapEl.snapshot()` (also on `MapController`) returns a canvas-only PNG dataURL of the scene — basemap + layers composited at device pixels (`{as: "blob"}` for files; `type`/`quality` for jpeg/webp). DOM widgets, overlays, and the provider attribution are NOT in the pixels: exports must render credits themselves. Await `ready` first; headless maps reject.
49
+
41
50
  Example:
42
51
 
43
52
  ```html
@@ -102,6 +111,8 @@ Common choices:
102
111
  - Tiles: `TileLayer`, `MVTLayer`, `Tile3DLayer`.
103
112
  - 3D models: `ScenegraphLayer`, `SimpleMeshLayer`, `PointCloudLayer`, `Tile3DLayer`.
104
113
 
114
+ External layer classes become manifest types via `OmMap.registerLayer({type, deckClass, props})`. Build them on `@nika-js/onlymap/deck` (the bundled `CompositeLayer`/`TileLayer`/… re-exports — a separately-installed deck.gl is a different class hierarchy and breaks in the renderer); function-valued props ride the subclass's `static defaultProps`; register at module top level before the manifest mounts. Full recipe: docs/custom-layers.md.
115
+
105
116
  ### Data Sources
106
117
 
107
118
  | Source | Manifest | Notes |
@@ -117,6 +128,8 @@ Common choices:
117
128
  | Polling | `data="/api/fleet.json" refresh="5s"` | Snapshot replace. |
118
129
  | Draw store | `data="draw:sketch"` | Written by draw widget. |
119
130
 
131
+ Data URLs accept any scheme the runtime's `fetch` supports — desktop webviews (Tauri, Electron) pass asset-protocol URLs (`asset://localhost/…`, custom schemes) straight in; format detection reads the path extension either way.
132
+
120
133
  Authenticated fetches:
121
134
 
122
135
  ```js
@@ -180,6 +193,8 @@ Built-ins:
180
193
  - `vega-lite`
181
194
  - `player`
182
195
  - `basemap-switcher` — radio list of presets; `options="positron dark-matter osm"` (default: every keyless registered preset)
196
+ - `lighting` — scene-lighting controller: preset radios (Off/daylight/studio/flat/custom) + ambient/sun/azimuth/elevation/camera sliders, all over the lighting* attributes via `set-lighting` (undoable; re-syncs when anything else writes them). A bare preset click is a clean RESET (stale lighting-* overrides removed); a slider edit flips to `custom` and sets only the touched key.
197
+ - `undo-redo` — undo/redo buttons over the manifest history (layer toggles, filters, basemap switches, element edits, drawn sketches). Keyboard works without the widget: Cmd/Ctrl-Z, Shift-Cmd/Ctrl-Z, Ctrl-Y. Camera moves, hover effects, and story playback are not undo steps.
183
198
 
184
199
  Positions: `top-left`, `top-right`, `bottom-left`, `bottom-right`.
185
200
 
@@ -215,8 +230,11 @@ Widget context:
215
230
  - `ctx.stats(id, field, { scope: "viewport" })`
216
231
  - `ctx.selection`
217
232
  - `ctx.viewport`
233
+ - `ctx.history` — `{ canUndo, canRedo }`; re-render on changes via the `history` watch token
218
234
  - `ctx.emit(action, payload)`
219
235
 
236
+ Watch tokens: `data:<layerId>`, `viewport`, `selection`, `layers` (fires on layer add/remove, visibility, and filter changes), `basemap`, `history`.
237
+
220
238
  Use `this.$()` and `this.root`; widgets render in shadow DOM.
221
239
 
222
240
  ### `<om-overlay>`
@@ -278,6 +296,7 @@ Common built-in actions:
278
296
  - `zoom-to-feature`
279
297
  - `filter-layer`
280
298
  - `set-basemap` — payload `{ basemap }`; writes the `<om-map basemap>` attribute
299
+ - `undo`, `redo` — step the manifest history (no payload)
281
300
  - `zoom-in`, `zoom-out`
282
301
  - `fly-to`
283
302
  - story actions: `story-play`, `story-pause`, `story-seek`
@@ -314,6 +333,18 @@ Story timing attributes:
314
333
 
315
334
  Use declarative payloads for scrub-safe state: `visible="true"` when toggling, explicit `filter-range`, explicit camera target.
316
335
 
336
+ Scene actions (`set-basemap`, `set-lighting`, `set-terrain`) are story-steppable AND scrub-capturable — the story snapshots the map's scene attributes before first play, so seeking rewinds basemap/lighting/terrain exactly like layer attributes. A sunset storyboard is just steps:
337
+
338
+ ```html
339
+ <om-story id="sunset">
340
+ <om-step duration="2s" action="set-lighting" lighting="custom" sun-elevation="35" sun-azimuth="245"></om-step>
341
+ <om-step duration="2s" action="set-lighting" lighting="custom" sun-elevation="8" sun-azimuth="270" ambient="0.5"></om-step>
342
+ <om-step duration="1s" action="set-lighting" lighting="flat"></om-step> <!-- bare preset = clean reset -->
343
+ </om-story>
344
+ ```
345
+
346
+ Lighting swaps are stepwise (the LightingEffect changes at each step's start — no tweening between steps); more steps = smoother sunsets.
347
+
317
348
  ### Manual Drawing
318
349
 
319
350
  Use a normal GeoJSON layer bound to a draw store plus a draw widget:
@@ -92,6 +92,8 @@ Harness operations:
92
92
 
93
93
  Use `vi.stubGlobal("fetch", ...)` for URL data and `vi.stubGlobal("WebSocket", ...)` for streams.
94
94
 
95
+ Free-plan license gates (5 layers, 25k rows per layer) apply in headless tests exactly as in production — gated layers emit errors on the validation stream instead of rendering. If the page under test legitimately exceeds the limits, call `OmMap.configureLicense("om_live_…")` in test setup; keys verify offline, so CI needs no network. Telemetry never fires from headless maps.
96
+
95
97
  ## Browser/E2E Testing
96
98
 
97
99
  Use Playwright only for pixels, real GPU picking, basemap composition, or asset rendering.