@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
@@ -16,8 +16,8 @@
16
16
  "</head>",
17
17
  "<body>",
18
18
  "",
19
- " <!-- validate → live error panel while you hand-author (strip for production) -->",
20
- " <om-map center=\"[-122.42, 37.77]\" zoom=\"${2:11}\" basemap=\"maplibre\" validate>",
19
+ " <!-- validate → live error panel while you hand-author (strip for production); map-id identifies this map artifact (delete to opt out of telemetry dedup) -->",
20
+ " <om-map center=\"[-122.42, 37.77]\" zoom=\"${2:11}\" basemap=\"maplibre\" map-id=\"$UUID\" validate>",
21
21
  "",
22
22
  " <!-- One data layer: type + data URL + accessors. pickable → behaviors can fire. -->",
23
23
  " <om-layer id=\"${3:points}\" type=\"ScatterplotLayer\"",
@@ -78,8 +78,8 @@
78
78
  "prefix": "!map",
79
79
  "description": "<om-map> root with camera + basemap + validate",
80
80
  "body": [
81
- "<!-- validate → on-page error panel; basemap=\"maplibre\" needs no token -->",
82
- "<om-map center=\"[-122.42, 37.77]\" zoom=\"${1:11}\" basemap=\"maplibre\" validate>",
81
+ "<!-- validate → on-page error panel; basemap=\"maplibre\" needs no token; map-id identifies this map artifact (delete to opt out of telemetry dedup) -->",
82
+ "<om-map center=\"[-122.42, 37.77]\" zoom=\"${1:11}\" basemap=\"maplibre\" map-id=\"$UUID\" validate>",
83
83
  "",
84
84
  " $0",
85
85
  "",
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # OnlyMap Commercial License Agreement
2
2
 
3
- **Last Updated:** July 9, 2026
3
+ **Last Updated:** July 14, 2026
4
4
 
5
5
  This OnlyMap Commercial License Agreement ("Agreement") governs access to and use of OnlyMap, published as the `OnlyMap` package or otherwise made available by the copyright holder ("Licensor"). By downloading, installing, accessing, or using the Software, you accept this Agreement.
6
6
 
@@ -27,9 +27,13 @@ Subject to Licensee's compliance with this Agreement and any applicable Order Fo
27
27
 
28
28
  No ownership rights are transferred. Licensor and its licensors retain all right, title, and interest in and to the Software.
29
29
 
30
- ## 3. Commercial Authorization Required
30
+ ## 3. Non-Commercial and Commercial Use
31
31
 
32
- The Software is commercial proprietary software. Unless Licensor has granted Licensee a written evaluation license, Licensee may use the Software only if Licensee has purchased and maintains a valid commercial license from Licensor.
32
+ The Software is commercial proprietary software.
33
+
34
+ **Non-Commercial Use.** Licensee may exercise the rights granted in Section 2 free of charge for Non-Commercial Use, provided that the Software's included attribution — the on-map "OnlyMap by NIKA" notice and other proprietary notices — remains visible, unmodified, and unobstructed in every Application. "Non-Commercial Use" means personal, educational, academic-research, or evaluation use that is not intended for or directed toward commercial advantage or monetary compensation, whether for Licensee or any third party. Use by or on behalf of a for-profit business (including internal business tools), in any product or service that generates revenue (including through advertising, subscriptions, or paid access), or in paid consulting or government work is not Non-Commercial Use. Non-Commercial Use may be subject to technical limits built into the Software.
35
+
36
+ **Commercial use.** Any use other than Non-Commercial Use requires a purchased and maintained valid commercial license from Licensor, unless Licensor has granted Licensee a separate written license.
33
37
 
34
38
  Access to an npm package, repository, package tarball, source archive, or build artifact does not by itself grant any rights beyond the rights expressly granted in this Agreement.
35
39
 
@@ -88,13 +92,19 @@ Licensor may provide updates, patches, or new versions at its discretion. Unless
88
92
 
89
93
  Updates are part of the Software and are governed by this Agreement unless Licensor provides different terms with the update.
90
94
 
91
- ## 11. Fees and Taxes
95
+ ## 11. Telemetry
96
+
97
+ The Software may transmit anonymous, deployment-scoped usage reports and error reports to Licensor's telemetry endpoint when the Software runs (for example, when a map finishes loading). These reports may include the Software version, feature and layer usage counts, widget types, the hostname of the page using the Software, an optional author-assigned map identifier, and, for errors caused by the Software, sanitized error signatures.
98
+
99
+ Telemetry reports do not include end-user identifiers, page URLs or paths, cookies, map data, or the contents of Licensee's Applications, and Licensor does not store IP addresses from telemetry requests. Telemetry can be disabled at any time, globally via `OmMap.configureTelemetry({ disabled: true })` or per map with the `telemetry="off"` attribute. The full payload schema and collection rules are documented in the Software's `docs/telemetry.md`.
100
+
101
+ ## 12. Fees and Taxes
92
102
 
93
103
  Licensee must pay all fees stated in the applicable Order Form. Fees are non-refundable except as expressly stated in the Order Form or required by law.
94
104
 
95
105
  Licensee is responsible for taxes, duties, levies, and similar governmental charges arising from its purchase or use of the Software, excluding taxes based on Licensor's net income.
96
106
 
97
- ## 12. Term and Termination
107
+ ## 13. Term and Termination
98
108
 
99
109
  This Agreement begins when Licensee first downloads, installs, accesses, or uses the Software and continues until terminated.
100
110
 
@@ -102,32 +112,32 @@ Licensor may terminate this Agreement immediately if Licensee breaches this Agre
102
112
 
103
113
  Sections that by their nature should survive termination will survive, including ownership, restrictions, payment obligations, warranty disclaimers, liability limits, and governing law.
104
114
 
105
- ## 13. Disclaimer of Warranty
115
+ ## 14. Disclaimer of Warranty
106
116
 
107
117
  TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS IS" AND "AS AVAILABLE," WITHOUT WARRANTIES OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, NON-INFRINGEMENT, ACCURACY, AVAILABILITY, SECURITY, OR ERROR-FREE OPERATION.
108
118
 
109
- ## 14. Limitation of Liability
119
+ ## 15. Limitation of Liability
110
120
 
111
121
  TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, LICENSOR WILL NOT BE LIABLE FOR INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, OR FOR LOST PROFITS, LOST REVENUE, LOST DATA, BUSINESS INTERRUPTION, OR PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF THOSE DAMAGES.
112
122
 
113
123
  TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, LICENSOR'S TOTAL LIABILITY ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT WILL NOT EXCEED THE AMOUNTS PAID BY LICENSEE TO LICENSOR FOR THE SOFTWARE DURING THE TWELVE MONTHS BEFORE THE EVENT GIVING RISE TO LIABILITY, OR USD 100 IF LICENSEE PAID NO AMOUNTS DURING THAT PERIOD.
114
124
 
115
- ## 15. Export and Compliance
125
+ ## 16. Export and Compliance
116
126
 
117
127
  Licensee must comply with all applicable export control, sanctions, anti-corruption, privacy, data protection, and other laws applicable to Licensee's use of the Software.
118
128
 
119
- ## 16. Assignment
129
+ ## 17. Assignment
120
130
 
121
131
  Licensee may not assign or transfer this Agreement, any Order Form, or any rights or obligations under them without Licensor's prior written consent. Any attempted assignment in violation of this section is void.
122
132
 
123
- ## 17. Governing Law
133
+ ## 18. Governing Law
124
134
 
125
135
  This Agreement is governed by the laws of the jurisdiction in which Licensor resides or is organized, without regard to conflict of law principles. The parties consent to the exclusive jurisdiction and venue of the courts located in that jurisdiction for disputes arising out of or relating to this Agreement.
126
136
 
127
- ## 18. Entire Agreement
137
+ ## 19. Entire Agreement
128
138
 
129
139
  This Agreement, together with any applicable Order Form, is the entire agreement between Licensor and Licensee regarding the Software and supersedes all prior or contemporaneous agreements, proposals, or understandings about the Software.
130
140
 
131
- ## 19. Contact
141
+ ## 20. Contact
132
142
 
133
143
  For licensing questions or requests for permissions beyond this Agreement, contact Licensor through the official repository, npm package page, website, or other distribution channel for the Software.
package/README.md CHANGED
@@ -4,7 +4,12 @@
4
4
 
5
5
  # OnlyMapJS
6
6
 
7
- **Interactive WebGL maps from plain HTML.** Write a declarative manifest — layers, widgets, popups, behaviors as custom elements — and OnlyMapJS drives [deck.gl](https://deck.gl) underneath: rendering, data loading, live updates, picking, and UI, with no build step and no imperative glue code.
7
+ [![npm version](https://img.shields.io/npm/v/%40nika-js%2Fonlymap?logo=npm&color=cb3837)](https://www.npmjs.com/package/@nika-js/onlymap)
8
+ [![npm downloads](https://img.shields.io/npm/dm/%40nika-js%2Fonlymap?color=8956ff)](https://www.npmjs.com/package/@nika-js/onlymap)
9
+ [![license](https://img.shields.io/badge/license-free%20for%20non--commercial-2f8fa6)](LICENSE.md)
10
+ [![docs](https://img.shields.io/badge/docs-nikaplanet-003646)](https://docs.nikaplanet.com/onlymap/overview)
11
+
12
+ **Interactive WebGL maps from plain HTML.** OnlyMapJS is a declarative mapping library built on [deck.gl](https://deck.gl), written in TypeScript, with first-class HTML and React APIs. Write a manifest — layers, widgets, popups, behaviors as custom elements — and it drives deck.gl underneath: rendering, GeoJSON/CSV/Arrow data loading, live updates, GPU picking, MapLibre basemaps, and UI, with no build step and no imperative glue code. If you've wanted a declarative deck.gl wrapper — for a geospatial dashboard, a React mapping component, or a single-file HTML map — that's the entire premise.
8
13
 
9
14
  ```html
10
15
  <script type="module" src="https://esm.sh/@nika-js/onlymap"></script>
@@ -30,7 +35,23 @@ That's a complete app: a no-token MapLibre basemap, data-driven colors and sizes
30
35
 
31
36
  It's also designed to be written **by AI agents**: HTML is a reliable generation target, [`llms.txt`](llms.txt) teaches the format, and `OmMap.validate()` returns structured errors with actionable fixes — a real feedback loop instead of a blank canvas.
32
37
 
33
- > ⚠️ **Status: v0.1.** Proprietary — commercial licensing terms are in [LICENSE.md](LICENSE.md); APIs may still move before 1.0.
38
+ > ⚠️ **Status: v0.2.** Proprietary — free for non-commercial use with attribution; commercial licensing terms are in [LICENSE.md](LICENSE.md). APIs may still move before 1.0.
39
+
40
+ ## Why not deck.gl directly?
41
+
42
+ deck.gl is the best WebGL data-visualization engine there is — and OnlyMapJS is built on it, not against it. What it replaces is everything *around* deck.gl that every project rebuilds by hand:
43
+
44
+ | | Raw deck.gl | OnlyMapJS |
45
+ |---|---|---|
46
+ | Setup | `new Deck({...})`, canvas + basemap sync wiring | one `<om-map>` element (or `<OmMap>` in React) |
47
+ | State | your reducers/stores drive `setProps` | the manifest **is** the state — edit an attribute, the map reconciles; undo/redo built in |
48
+ | Data loading | fetch + parse + reload yourself | `data="…"` — GeoJSON, CSV, Arrow/GeoArrow, Shapefile, KML, WebSocket streams, polled REST |
49
+ | Accessors | JS functions + `updateTriggers` bookkeeping | `get-*` expressions; update triggers derived automatically |
50
+ | UI | build legends/popups/filters from scratch | built-in widgets, overlays, behaviors — declarative |
51
+ | Testing | mock WebGL or ship untested | `OmMap.validate`, IR snapshots, headless behavioral harness |
52
+ | Escape hatch | — | every deck.gl prop still passes through; custom layers register by name |
53
+
54
+ If you're comparing React mapping libraries: the React adapter (`@nika-js/onlymap/react`) gives you typed `<OmLayer>` components over the same core, so React owns state and deck.gl's `updateTriggers` gymnastics disappear. And when you need raw deck.gl behavior, every kebab-case attribute maps 1:1 to the underlying prop — it's a wrapper, not a wall.
34
55
 
35
56
  ## Install
36
57
 
@@ -44,9 +65,9 @@ Or with no build step at all, straight from a CDN:
44
65
  <script type="module" src="https://esm.sh/@nika-js/onlymap"></script>
45
66
  ```
46
67
 
47
- Then `npx @nika-js/onlymap init` wires up VS Code IntelliSense and `!`-prefixed manifest snippets for your project. The library ships with 297 unit/behavioral tests and 19 Playwright GPU tests.
68
+ Then `npx @nika-js/onlymap init` wires up VS Code IntelliSense and `!`-prefixed manifest snippets for your project. The library ships with 437 unit/behavioral tests and 25 Playwright GPU tests.
48
69
 
49
- The [examples](https://github.com/NikaGeospatial/onlymapjs/tree/main/examples) are the best tour: widgets, behaviors & overlays, basemaps, columnar/Arrow data, manual drawing, 3D models, a live WebSocket ship feed, and a polled driver fleet.
70
+ The [examples](https://github.com/NikaGeospatial/onlymapjs/tree/main/examples) are the best tour: widgets, behaviors & overlays, basemaps, columnar/Arrow data, manual drawing, 3D models, scene lighting (with the native lighting widget), DEM terrain, a live WebSocket ship feed, and a polled driver fleet.
50
71
 
51
72
  ## The manifest
52
73
 
@@ -56,7 +77,7 @@ A handful of elements, one rule: **attributes are kebab-case versions of deck.gl
56
77
  |---|---|
57
78
  | `<om-map>` | The map. `center`, `zoom`, `pitch`, `bearing`; `basemap` takes a free preset (`positron`, `liberty`, `dark-matter`, `osm`, …), a style URL, or `"none"` (standalone canvas) — and switches **live**; `validate` for a live on-page error panel. |
58
79
  | `<om-layer>` | Any of **33 layer types** by name — all of deck.gl's core, geo, aggregation, and mesh layers (Scatterplot, GeoJson, Arc, Path, Heatmap, Hexagon, Trips, Tile, Tile3D, Scenegraph, …) plus the built-in `PopupLayer` for WebGL badges/labels at scale. `id` required; `label`/`color` feed the legend. |
59
- | `<om-widget>` | UI panels. Built-ins: `legend`, `layer-switcher`, `basemap-switcher`, `zoom-controls`, `scale-bar`, `attribution`, `filter`, `draw`, `vega-lite` (live charts). Or write your own inline with HTML + a `<script type="om/widget">`. |
80
+ | `<om-widget>` | UI panels. Built-ins: `legend`, `layer-switcher`, `basemap-switcher`, `lighting`, `zoom-controls`, `undo-redo`, `scale-bar`, `attribution`, `filter`, `draw`, `vega-lite` (live charts). Or write your own inline with HTML + a `<script type="om/widget">`. |
60
81
  | `<om-overlay>` | Rich HTML anchored to a map location — a static `anchor="[lng, lat]"`, the current selection, or a feature's own geometry via `anchor-layer`/`anchor-feature-id`. `{{field}}` interpolates the picked feature, HTML-escaped by default. |
61
82
  | `<om-behavior>` | Declarative interactions: `on="click|hover|drag|load|data-loaded"` → a named action. |
62
83
  | `<om-story>` | A storyboard: `<om-step>` children fire actions on a timeline. Controlled by the `player` widget, behaviors, or `storyEl.play()/pause()/seek()`. |
@@ -94,7 +115,9 @@ Private endpoints: `OmMap.configureData({ headers, credentials, fetch })` — ap
94
115
 
95
116
  ### Interaction
96
117
 
97
- Built-in actions wire to picks, widget buttons (`data-emit`), or script (`ctx.emit`) with one shared payload contract: `show-overlay`, `hide-overlay`, `show-tooltip`, `hide-tooltip`, `toggle-layer`, `highlight-feature`, `zoom-to-feature`, `filter-layer`, `set-basemap`, `zoom-in`, `zoom-out` — plus `OmMap.registerAction` for your own.
118
+ Built-in actions wire to picks, widget buttons (`data-emit`), or script (`ctx.emit`) with one shared payload contract: `show-overlay`, `hide-overlay`, `show-tooltip`, `hide-tooltip`, `toggle-layer`, `highlight-feature`, `zoom-to-feature`, `filter-layer`, `set-basemap`, `zoom-in`, `zoom-out`, `undo`, `redo` — plus `OmMap.registerAction` for your own.
119
+
120
+ **Undo/redo:** user-facing manifest changes — layer toggles, filter changes, basemap switches, element edits, drawn sketches — are undoable out of the box; the manifest *is* the state, so history is recorded from the DOM itself. Add `<om-widget type="undo-redo">` for buttons, or just press Cmd/Ctrl-Z (Shift-Cmd/Ctrl-Z or Ctrl-Y to redo). Camera moves, hover effects, and story playback are deliberately not undo steps.
98
121
 
99
122
  **Basemaps:** free presets out of the box — OpenFreeMap `liberty`/`bright`/`positron` (no key, no limits), CARTO `dark-matter`/`voyager`, classic `osm` raster, and keyed `maptiler-*` presets (MapTiler's style editor is the visual way to customize basemap JSON; keys are publishable, via `basemap-key` or `OmMap.configureBasemap`). The `basemap` attribute switches **live** — camera and layers survive — from a hand edit, the `set-basemap` action, or `<om-widget type="basemap-switcher">`. Add your own with `OmMap.registerBasemap(name, { style })`; required attribution renders automatically. Guide: [docs/basemaps.md](docs/basemaps.md).
100
123
 
@@ -189,15 +212,35 @@ Plus `OmMap.snapshotIR(html)` to lock down what a manifest *means* in a snapshot
189
212
 
190
213
  ## 3D
191
214
 
192
- `ScenegraphLayer` instances glTF/GLB models at coordinates (no three.js, no loader wiring), `Tile3DLayer` consumes OGC 3D Tiles, and the camera tilts via `pitch`/`bearing` attributes. Converting IFC/CAD upstream: [docs/3d-assets.md](docs/3d-assets.md).
215
+ `ScenegraphLayer` instances glTF/GLB models at coordinates (no three.js, no loader wiring), `Tile3DLayer` consumes OGC 3D Tiles, `GeoJsonLayer` extrudes polygons (`extruded get-elevation="$height"`), and the camera tilts via `pitch`/`bearing` attributes. Terrain is one attribute: `<om-map terrain="terrarium">` raises a real DEM surface (keyless AWS tiles; `maptiler-terrain` keyed; or a bring-your-own `{z}/{x}/{y}` DEM URL + `terrain-decoder`), geographic layers drape onto it automatically (per-layer `terrain="drape|offset|off"` overrides; 3D models sit ON the surface), `terrain-exaggeration` scales the relief, and `terrain-texture` drapes imagery. Terrain replaces an active basemap while on (flat canvas vs raised surface) and restores it when off. Scene lighting is declarative: `<om-map lighting="daylight">` (presets `daylight`/`studio`/`flat`/`custom`, tuned via `lighting-ambient`, `lighting-sun`, `lighting-sun-azimuth`/`-elevation`, or `lighting-sun-date` for a solar-position sun) — attribute-backed, so lighting changes are undoable and story-steppable via the `set-lighting` action. `<om-widget type="lighting">` gives users native preset radios + tuning sliders over the same attributes. Converting IFC/CAD upstream: [docs/3d-assets.md](docs/3d-assets.md).
193
216
 
194
217
  ## Programmatic surface
195
218
 
196
- - **`OmMap.*`** — `validate`, `snapshotIR`, `registerLayer`, `registerWidget`, `registerAction`, `registerSource`, `registerFormat`, `registerBasemap`, `configureBasemap`, `configureData`, `getLayerSchema`
197
- - **On a `<om-map>` element** `ready` (promise), `flyTo(coords, zoom?)`, `setLayerVisible(id, bool)`, `getLayers()`, `emit(action, payload)`; `document.querySelector("om-map")` is fully typed
198
- - **`MapController`**the framework-grade programmatic front-end (typed `LayerDescriptor`s the same reconcile core, no DOM manifest): `setLayers`, `watch`, `emit`, camera methods, `injectPick`, `ready`. The React adapter rides it; usable directly from vanilla TS or other frameworks
219
+ - **`OmMap.*`** — `validate`, `snapshotIR`, `registerLayer`, `registerWidget`, `registerAction`, `registerSource`, `registerFormat`, `registerBasemap`, `configureBasemap`, `configureData`, `configureTelemetry`, `configureLicense`, `getLayerSchema`
220
+ - **`@nika-js/onlymap/deck`** the bundled deck.gl classes (`CompositeLayer`, `TileLayer`, ) for building custom layer types: shims must extend the same class hierarchy the core renders with, not a second installed deck.gl copy. Recipe: [docs/custom-layers.md](docs/custom-layers.md)
221
+ - **On a `<om-map>` element** `ready` (promise), `flyTo(coords, zoom?)`, `setLayerVisible(id, bool)`, `getLayers()`, `emit(action, payload)`, `snapshot(opts?)` (canvas-only PNG of basemap + layers at device pixels — DOM widgets/overlays and provider attribution are NOT captured, so exports must render credits themselves; `{as: "blob"}` for files, default dataURL); the `om-view-changed` event fires once the camera settles (debounced; `detail` = `{longitude, latitude, zoom, pitch, bearing}`) the camera-persistence hook; `document.querySelector("om-map")` is fully typed
222
+ - **`MapController`** — the framework-grade programmatic front-end (typed `LayerDescriptor`s → the same reconcile core, no DOM manifest): `setLayers`, `watch`, `emit`, camera methods, `injectPick`, `ready`, `snapshot`, an `onViewChange` option (the `om-view-changed` twin). The React adapter rides it; usable directly from vanilla TS or other frameworks
199
223
  - **Testing** — `mountForTest`, and imports are SSR-safe (importing in Node/jsdom never touches browser globals)
200
224
 
225
+ ## Free tier & licensing
226
+
227
+ **Non-commercial use is free with attribution** (LICENSE.md §3); commercial use requires a license. Without a license key, maps run on the **free plan**: up to **5 layers** and **25,000 rows per layer** (20 MB per data fetch), with a small "OnlyMap by NIKA. Free for non-commercial use." badge in the corner. Exceeding a limit never breaks the map — the offending layer simply doesn't render, and the validation stream/error panel tells you exactly which limit, why, and how to lift it. Limits apply identically everywhere (including localhost — no dev/prod surprises).
228
+
229
+ A license key lifts all limits and removes the badge:
230
+
231
+ ```html
232
+ <om-map license-key="om_live_…"> <!-- keys are publishable & origin-restricted — safe in page source -->
233
+ ```
234
+ ```ts
235
+ OmMap.configureLicense("om_live_…"); // or once, in code
236
+ ```
237
+
238
+ Keys are self-verifying signed tokens (no network round-trip, works offline and in CI) bound to your domains. Licensing: https://www.nikaplanet.com/onlymap.
239
+
240
+ ## Telemetry
241
+
242
+ The library reports one **deployment-scoped** usage snapshot per map per page load — layer types and counts, widget types, renderer; hostname only, no page URLs, no visitor identifiers, and `headless` (test) maps never report — plus errors caused by the library's own code (own-bundle stack filtering, scrubbed, rate-limited). Reports go to a first-party endpoint, never a third-party domain. Opt out globally with `OmMap.configureTelemetry({ disabled: true })` or per map with `telemetry="off"`. Full schema, rules, and the license disclosure: [docs/telemetry.md](docs/telemetry.md), LICENSE.md §11.
243
+
201
244
  ## Not implemented yet (honestly)
202
245
 
203
246
  Mapbox GL basemaps, depth-interleaved 3D compositing, globe projection, SSE transport, multi-field filters, `dblclick` behaviors, the `transform` data pipeline, the typed fluent builder, and stories/draw as React components (both work via the HTML manifest).
@@ -206,6 +249,6 @@ Mapbox GL basemaps, depth-interleaved 3D compositing, globe projection, SSE tran
206
249
 
207
250
  | | |
208
251
  |---|---|
209
- | [docs/react.md](docs/react.md) · [docs/basemaps.md](docs/basemaps.md) · [docs/testing.md](docs/testing.md) · [docs/live-data.md](docs/live-data.md) · [docs/3d-assets.md](docs/3d-assets.md) · [docs/stories.md](docs/stories.md) | Consumer guides |
252
+ | [docs/react.md](docs/react.md) · [docs/basemaps.md](docs/basemaps.md) · [docs/testing.md](docs/testing.md) · [docs/live-data.md](docs/live-data.md) · [docs/3d-assets.md](docs/3d-assets.md) · [docs/stories.md](docs/stories.md) · [docs/telemetry.md](docs/telemetry.md) | Consumer guides |
210
253
  | [llms.txt](llms.txt) | The agent-facing quick reference |
211
254
  | `skills/onlymapjs` | Installable LLM skill for OnlyMapJS authoring |
package/dist/actions.d.ts CHANGED
@@ -14,8 +14,8 @@ export type ActionHandler = (payload: Record<string, unknown>, mapEl: Element, c
14
14
  export declare function hasAction(name: string): boolean;
15
15
  export declare function registerAction(name: string, handler: ActionHandler): void;
16
16
  export declare function dispatchAction(name: string, payload: Record<string, unknown>, mapEl: Element, core: RuntimeCore, layerIRs?: ReadonlyMap<string, LayerIR>): void;
17
- /** Ids in this namespace are runtime-managed plumbing — excluded from ctx.layers (legend, layer-list, user widgets). */
18
- export declare const RUNTIME_INTERNAL_PREFIX = "__onlymapjs-";
17
+ /** Ids in this namespace are runtime-managed plumbing — excluded from ctx.layers (legend, layer-list, user widgets). Defined in internal-ids.ts (dependency-free); re-exported here as the historical home. */
18
+ export { RUNTIME_INTERNAL_PREFIX } from "./internal-ids";
19
19
  /** The overlay anchor for a feature: its bbox center for geojson geometry, else its point (flat lon/lat). */
20
20
  export declare function featureAnchorPoint(feature: unknown): [number, number] | undefined;
21
21
  /**
@@ -0,0 +1,4 @@
1
+ export interface BadgeHandle {
2
+ destroy(): void;
3
+ }
4
+ export declare function mountBadge(container: HTMLElement): BadgeHandle;