@nika-js/onlymap 0.1.1 → 0.2.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/.vscode/onlymap.code-snippets +4 -4
- package/README.md +22 -2
- package/dist/attribute-resolution.d.ts +39 -0
- package/dist/{basemap-D95W0IIA.js → basemap-C0RKcLaL.js} +1 -1
- package/dist/{index-C9w78NS9.js → index-BDJ9hHXv.js} +1 -1
- package/dist/{index-Do7hmHwi.js → index-CZf9WlZe.js} +1 -1
- package/dist/{index-D74olQ9w.js → index-DeEur5Xk.js} +1 -1
- package/dist/{index-CU-iOTdr.js → index-DnvxPnDF.js} +12090 -11820
- package/dist/{index-BFjXVHly.js → index-GTGi85ZO.js} +2 -2
- package/dist/index.d.ts +5 -0
- package/dist/ir-diff.d.ts +16 -0
- package/dist/onlymapjs.js +18 -16
- package/dist/onlymapjs.umd.cjs +281 -281
- package/dist/programmatic.d.ts +176 -0
- package/dist/react/context.d.ts +25 -0
- package/dist/react/index.d.ts +20 -0
- package/dist/react/om-layer.d.ts +38 -0
- package/dist/react/om-map.d.ts +29 -0
- package/dist/react/om-overlay.d.ts +27 -0
- package/dist/react/om-widget.d.ts +9 -0
- package/dist/react/use-om-map.d.ts +2 -0
- package/dist/react.js +272 -0
- package/docs/3d-assets.md +74 -0
- package/docs/live-data.md +83 -0
- package/docs/react.md +120 -0
- package/docs/stories.md +134 -0
- package/docs/testing.md +165 -0
- package/llms.txt +5 -1
- package/package.json +24 -2
- package/skills/onlymapjs/SKILL.md +1 -1
- package/skills/onlymapjs/references/patterns.md +2 -2
- package/skills/onlymapjs/references/syntax.md +1 -1
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
" <meta charset=\"utf-8\" />",
|
|
11
11
|
" <title>${1:My map}</title>",
|
|
12
12
|
" <script type=\"module\">",
|
|
13
|
-
" import \"
|
|
14
|
-
" import \"
|
|
13
|
+
" import \"@nika-js/onlymap\";",
|
|
14
|
+
" import \"@nika-js/onlymap/onlymapjs.css\";",
|
|
15
15
|
" </script>",
|
|
16
16
|
"</head>",
|
|
17
17
|
"<body>",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
" <meta charset=\"utf-8\" />",
|
|
56
56
|
" <title>${1:My map}</title>",
|
|
57
57
|
" <script type=\"module\">",
|
|
58
|
-
" import \"
|
|
59
|
-
" import \"
|
|
58
|
+
" import \"@nika-js/onlymap\";",
|
|
59
|
+
" import \"@nika-js/onlymap/onlymapjs.css\";",
|
|
60
60
|
" </script>",
|
|
61
61
|
"</head>",
|
|
62
62
|
"<body>",
|
package/README.md
CHANGED
|
@@ -105,6 +105,25 @@ GPU filtering is declarative — `filter-field="magnitude" filter-range="[4,10]"
|
|
|
105
105
|
|
|
106
106
|
Custom widget scripts receive `ctx`: layer metadata, `viewport` (bounds/zoom/project), the current `selection`, `emit()`, and data access — `ctx.data(id)`, `ctx.dataInViewport(id)`, `ctx.stats(id, field)` (count/min/max/mean/stddev/percentiles/histogram, viewport-scoped on request). Declare `watch` tokens (`data:quakes viewport selection layers`) and the runtime re-renders you only when relevant state changes. `vegaEmbed` and `d3` are available as globals for charts.
|
|
107
107
|
|
|
108
|
+
## React
|
|
109
|
+
|
|
110
|
+
The same engine, as real components — `@nika-js/onlymap/react` (React ≥ 18, optional peer). No `om-*` elements are rendered, so React and the library never fight over the DOM: components feed a typed programmatic front-end that produces the same layer IR the HTML manifest does. Accessors are plain functions (no expression language), interactions are event handlers, and `useOmMap()` is the widget `ctx` contract as a fully-typed hook:
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
import { OmMap, OmLayer, OmWidget, OmOverlay, useOmMap } from "@nika-js/onlymap/react";
|
|
114
|
+
|
|
115
|
+
<OmMap center={[-119, 36]} zoom={5} basemap="maplibre">
|
|
116
|
+
<OmLayer id="quakes" type="ScatterplotLayer" data={features} pickable
|
|
117
|
+
getPosition={d => [d.lon, d.lat]}
|
|
118
|
+
getFillColor={d => (d.mag >= 6 ? [214, 40, 40] : [252, 191, 73])}
|
|
119
|
+
onClick={sel => setSelected(sel.object)} />
|
|
120
|
+
<OmWidget position="top-left"><StatsPanel /></OmWidget>
|
|
121
|
+
<OmOverlay anchorFrom="selection">{sel => sel && <Card feature={sel.object} />}</OmOverlay>
|
|
122
|
+
</OmMap>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`<OmOverlay>` manages projection, per-frame tracking, and off-screen culling for you; `<OmMap headless>` makes the whole tree testable in jsdom/happy-dom. Full guide: [docs/react.md](docs/react.md).
|
|
126
|
+
|
|
108
127
|
## Editor IntelliSense
|
|
109
128
|
|
|
110
129
|
`onlymapjs.html-data.json` (generated from the layer registry — `npm run gen:html-data`) gives autocomplete and hover docs for every `om-*` element and attribute in VS Code and any editor speaking the [html-customData](https://github.com/microsoft/vscode-custom-data) format:
|
|
@@ -173,16 +192,17 @@ Plus `OmMap.snapshotIR(html)` to lock down what a manifest *means* in a snapshot
|
|
|
173
192
|
|
|
174
193
|
- **`OmMap.*`** — `validate`, `snapshotIR`, `registerLayer`, `registerWidget`, `registerAction`, `registerSource`, `registerFormat`, `configureData`, `getLayerSchema`
|
|
175
194
|
- **On a `<om-map>` element** — `ready` (promise), `flyTo(coords, zoom?)`, `setLayerVisible(id, bool)`, `getLayers()`, `emit(action, payload)`; `document.querySelector("om-map")` is fully typed
|
|
195
|
+
- **`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
|
|
176
196
|
- **Testing** — `mountForTest`, and imports are SSR-safe (importing in Node/jsdom never touches browser globals)
|
|
177
197
|
|
|
178
198
|
## Not implemented yet (honestly)
|
|
179
199
|
|
|
180
|
-
Mapbox GL basemaps, depth-interleaved 3D compositing, globe projection, SSE transport, multi-field filters, `dblclick` behaviors, the `transform` data pipeline, and
|
|
200
|
+
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).
|
|
181
201
|
|
|
182
202
|
## Going deeper
|
|
183
203
|
|
|
184
204
|
| | |
|
|
185
205
|
|---|---|
|
|
186
|
-
| [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 |
|
|
206
|
+
| [docs/react.md](docs/react.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 |
|
|
187
207
|
| [llms.txt](llms.txt) | The agent-facing quick reference |
|
|
188
208
|
| `skills/onlymapjs` | Installable LLM skill for OnlyMapJS authoring |
|
|
@@ -24,6 +24,45 @@ export declare const RESERVED_ATTRS: Set<string>;
|
|
|
24
24
|
* dimensions" case is a documented future extension.
|
|
25
25
|
*/
|
|
26
26
|
export declare const FILTER_ATTRS: Set<string>;
|
|
27
|
+
/** Already-coerced filter declaration — attribute strings (DOM front-end) or typed values (programmatic front-end). */
|
|
28
|
+
export interface LayerFilterSpec {
|
|
29
|
+
filterField?: string;
|
|
30
|
+
filterRange?: [number, number];
|
|
31
|
+
filterSoftRange?: [number, number];
|
|
32
|
+
filterCategoryField?: string;
|
|
33
|
+
filterCategories?: unknown[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* GPU filter wiring (spec: "Filtering"), shared by both front-ends (HU2).
|
|
37
|
+
* `filterRange` is a plain prop (not an accessor): the filter-layer action
|
|
38
|
+
* just rewrites its attribute, which flows through the normal reconcile ->
|
|
39
|
+
* deck.gl setProps() diff as a cheap uniform update, never touching
|
|
40
|
+
* updateTriggers.
|
|
41
|
+
*
|
|
42
|
+
* EVERY layer mounts the extension at birth, filtered or not: adding or
|
|
43
|
+
* removing an extension on a LIVE layer recompiles shaders and corrupts
|
|
44
|
+
* attribute state (the per-feature-trace washed-out-fill bug), while an
|
|
45
|
+
* idle numeric slot is free — deck's default getFilterValue is the
|
|
46
|
+
* CONSTANT 0 (no attribute buffer) inside the default filterRange
|
|
47
|
+
* [-1, 1], so nothing is culled. A later filter-layer action then only
|
|
48
|
+
* swaps accessor + range props on the same shaders. The category slot is
|
|
49
|
+
* NOT pre-mounted: an idle categorySize binds a uint attribute against a
|
|
50
|
+
* float constant (GL_INVALID_OPERATION in real WebGL), so declaring a
|
|
51
|
+
* category filter re-mounts the extension — churn accepted for the rare
|
|
52
|
+
* case, never for the common numeric one.
|
|
53
|
+
*
|
|
54
|
+
* The unfiltered baseline is a FUNCTION accessor (a buffer of zeros, 4
|
|
55
|
+
* bytes/row) plus a baseline trigger — never deck's constant-0 default.
|
|
56
|
+
* Two empirically-found deck behaviors force this: trigger keys absent
|
|
57
|
+
* from the NEW props aren't diffed (a cleared patch would keep its stale
|
|
58
|
+
* buffer), and a buffer→constant accessor transition doesn't rebind the
|
|
59
|
+
* vertex attribute (the attribute state SAYS constant 0, the GPU still
|
|
60
|
+
* draws the old buffer). Function→function with a trigger change is the
|
|
61
|
+
* one transition that recomputes reliably, so every state a layer can
|
|
62
|
+
* reach — unfiltered, authored filter, runtime populate sweep — is
|
|
63
|
+
* buffer-backed.
|
|
64
|
+
*/
|
|
65
|
+
export declare function applyFilterWiring(props: Record<string, unknown>, updateTriggers: Record<string, string>, shape: Shape, spec: LayerFilterSpec, warnLabel: string): LayerFilter | undefined;
|
|
27
66
|
/**
|
|
28
67
|
* Standard global HTML attributes an author (or the library itself, e.g.
|
|
29
68
|
* OmLayerElement setting `style.display = "none"`) may set for reasons
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var ny = Object.defineProperty;
|
|
2
2
|
var sy = (_e, Q, me) => Q in _e ? ny(_e, Q, { enumerable: !0, configurable: !0, writable: !0, value: me }) : _e[Q] = me;
|
|
3
3
|
var oc = (_e, Q, me) => sy(_e, typeof Q != "symbol" ? Q + "" : Q, me);
|
|
4
|
-
import { a4 as oy, a5 as ay, a6 as ly, a7 as cy, a8 as ka, a9 as
|
|
4
|
+
import { a4 as oy, a5 as ay, a6 as ly, a7 as cy, a8 as ka, a9 as ac, aa as Pd, ab as sm, ac as uy, ad as hy, ae as dy, af as py, ag as ju, ah as Cd, ai as fy, aj as my, ak as gy, al as em, am as _y } from "./index-DnvxPnDF.js";
|
|
5
5
|
const Ad = Math.PI / 180, yy = 180 / Math.PI;
|
|
6
6
|
function tm(_e, Q = 0) {
|
|
7
7
|
const me = Math.min(180, _e) * Ad;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var Oe = Object.defineProperty;
|
|
2
2
|
var ke = (r, e, t) => e in r ? Oe(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
|
|
3
3
|
var l = (r, e, t) => ke(r, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import { g as ve, a as ce, b as he, i as Fe, t as je, l as xe } from "./index-
|
|
4
|
+
import { g as ve, a as ce, b as he, i as Fe, t as je, l as xe } from "./index-DnvxPnDF.js";
|
|
5
5
|
import { ai as Ie, h as ue, au as X, a2 as W, af as fe, Y as Ne, F as Le, aR as Ue, S as Me, bP as qe } from "./recordbatch-HRu0SMKp.js";
|
|
6
6
|
import { g as $, a as de, b as Ve, c as $e, d as Pe, e as He, m as ze } from "./table-accessors-DBjWgN0C.js";
|
|
7
7
|
import { c as Qe } from "./convert-arrow-schema-CvZ3cT5m.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var Ri = Object.defineProperty;
|
|
2
2
|
var Ii = (t, a, i) => a in t ? Ri(t, a, { enumerable: !0, configurable: !0, writable: !0, value: i }) : t[a] = i;
|
|
3
3
|
var N = (t, a, i) => Ii(t, typeof a != "symbol" ? a + "" : a, i);
|
|
4
|
-
import { t as zt, $ as ca, a0 as ua, a1 as wi } from "./index-
|
|
4
|
+
import { t as zt, $ as ca, a0 as ua, a1 as wi } from "./index-DnvxPnDF.js";
|
|
5
5
|
import { c as Si } from "./convert-arrow-schema-CvZ3cT5m.js";
|
|
6
6
|
import { ai as Ni, af as Nt, h as Ci, au as Pi, a2 as Oi } from "./recordbatch-HRu0SMKp.js";
|
|
7
7
|
class Ti {
|