@nika-js/onlymap 0.6.19 → 0.6.21
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 +18 -0
- package/README.md +1 -1
- package/dist/{LercDecode.es-Butn4LVX.js → LercDecode.es-B_dD2_mY.js} +1 -1
- package/dist/actions.d.ts +94 -1
- package/dist/attribute-resolution.d.ts +12 -0
- package/dist/{basemap-qZH_aNYE.js → basemap-DK0AJ6ZH.js} +341 -313
- package/dist/basemap.d.ts +17 -1
- package/dist/declarative-filter.d.ts +2 -16
- package/dist/effect-track.d.ts +94 -0
- package/dist/effects.d.ts +2 -0
- package/dist/elements/om-map.d.ts +11 -8
- package/dist/elements/om-story.d.ts +18 -0
- package/dist/{geoparquet-DWQCUg6N.js → geoparquet-fc2daxMh.js} +1 -1
- package/dist/{index-CeeQ7CH4.js → index-9EEyGbU1.js} +1 -1
- package/dist/{index-4St6BumW.js → index-BNZFF535.js} +2 -2
- package/dist/{index-BTM6Mblt.js → index-BwoceNAo.js} +1 -1
- package/dist/{index-CagRqDDL.js → index-CuBGRyG-.js} +13970 -13685
- package/dist/{index-CNlULiHm.js → index-DOPjev5l.js} +1 -1
- package/dist/internal-ids.d.ts +2 -0
- package/dist/{lerc-cWjnr__g.js → lerc-CMJO8KZO.js} +2 -2
- package/dist/onlymap.standalone.js +24388 -24075
- package/dist/onlymapjs.js +1 -1
- package/dist/programmatic.d.ts +1 -2
- package/dist/{raster-BxxtJxxs.js → raster-GMsuQARC.js} +2 -2
- package/dist/{raster-pipeline-DlppdBYw.js → raster-pipeline-DNpKXgO3.js} +1 -1
- package/dist/runtime-core.d.ts +22 -0
- package/dist/snapshot.d.ts +15 -0
- package/dist/version.d.ts +1 -1
- package/dist/{zarr-BtxMPczZ.js → zarr-KiXluGoJ.js} +2 -2
- package/docs/stories.md +2 -0
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/skills/onlymapjs/SKILL.md +1 -1
- package/skills/onlymapjs/references/syntax.md +3 -3
package/dist/basemap.d.ts
CHANGED
|
@@ -49,8 +49,24 @@ export declare class MapLibreBasemapAdapter {
|
|
|
49
49
|
pitch?: number;
|
|
50
50
|
bearing?: number;
|
|
51
51
|
}, deckProps: DeckProps, showAttribution?: boolean, attributionHost?: HTMLElement, deterministic?: boolean);
|
|
52
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* whenSettled's basemap gate (issue #37 follow-up), as an EVENT LATCH
|
|
54
|
+
* rather than a polling predicate: MapLibre's `idle` event is its own
|
|
55
|
+
* definition of done — camera transitions finished, all requested tiles
|
|
56
|
+
* loaded, all fades/transitions complete — which is strictly stronger
|
|
57
|
+
* than `loaded() && areTilesLoaded()` (those say nothing about label
|
|
58
|
+
* fade/collision animation, the measured source of warm-page frame
|
|
59
|
+
* nondeterminism). The latch clears on anything that restarts work
|
|
60
|
+
* (camera writes, a source starting to load, a style change) and sets
|
|
61
|
+
* again only on the next `idle`, so `isIdle()` stays a synchronous read —
|
|
62
|
+
* settleOnce's `loaded()` shape — and both lanes plus `onlymapjs record`
|
|
63
|
+
* inherit it unchanged.
|
|
64
|
+
*/
|
|
65
|
+
private idleLatch;
|
|
66
|
+
private wireIdleLatch;
|
|
53
67
|
isIdle(): boolean;
|
|
68
|
+
/** Camera writes from OUR side must clear the latch immediately — the map's own movestart fires a tick later, and a settle read in that gap would see stale idle. */
|
|
69
|
+
private markBusy;
|
|
54
70
|
/** The overlay deck's live layers — whenSettled's readiness gate (issue #37). */
|
|
55
71
|
getDeckLayers(): {
|
|
56
72
|
isLoaded: boolean;
|
|
@@ -1,22 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
* CPU-side mirror of the GPU `DataFilterExtension` test (spec: "Filter-aware
|
|
3
|
-
* stats & data (the coherence rule)") — `ctx.stats`/`ctx.dataInViewport`
|
|
4
|
-
* apply the SAME field+range/category test(s) by default, so a chart/stat
|
|
5
|
-
* reflects what the map visibly shows. A row whose field isn't a finite
|
|
6
|
-
* number (numeric) or isn't in the keep-list (categorical) is treated as
|
|
7
|
-
* filtered-out, matching the GPU path. With more than one dimension of
|
|
8
|
-
* EITHER kind a row passes only if every dimension's test passes (AND
|
|
9
|
-
* across dimensions) — the same semantics deck.gl's own packed
|
|
10
|
-
* `filterRange`/`filterCategories` arrays apply GPU-side. Numeric and
|
|
11
|
-
* categorical are independent mechanisms (see `applyFilterWiring`'s doc
|
|
12
|
-
* comment) but combine the same way: a row must pass BOTH kinds when both
|
|
13
|
-
* are active on a layer.
|
|
14
|
-
*/
|
|
15
|
-
import type { Shape, LayerFilter, LayerCategoryFilter } from "./ir";
|
|
1
|
+
import type { Shape, LayerFilter, LayerCategoryFilter, LayerData } from "./ir";
|
|
16
2
|
export declare function applyDeclarativeFilter(rows: readonly unknown[], shape: Shape, filter: LayerFilter): unknown[];
|
|
17
3
|
/** The same test as a reusable predicate — the columnar viewport filter runs it inside its index-aligned loop. */
|
|
18
4
|
export declare function declarativeFilterPredicate(shape: Shape, filter: LayerFilter): (row: unknown) => boolean;
|
|
19
5
|
export declare function applyDeclarativeCategoryFilter(rows: readonly unknown[], shape: Shape, categoryFilter: LayerCategoryFilter): unknown[];
|
|
20
6
|
/** Categorical twin of `declarativeFilterPredicate` — set membership instead of a range test. */
|
|
21
7
|
export declare function declarativeCategoryFilterPredicate(shape: Shape, categoryFilter: LayerCategoryFilter): (row: unknown) => boolean;
|
|
22
|
-
export declare function warnCategoryCardinality(categoryFilter: LayerCategoryFilter | undefined,
|
|
8
|
+
export declare function warnCategoryCardinality(categoryFilter: LayerCategoryFilter | undefined, data: LayerData, shape: Shape, warnLabel: string): void;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story-time effect evaluation (spec: "Map Stories" / issue #37's pull
|
|
3
|
+
* model, completed for layer effects). `buildCameraLegs`/`cameraAtTime`
|
|
4
|
+
* already make the camera a pure function of story time; this module does
|
|
5
|
+
* the same for the animated verbs (fade / pulse / trace / populate). When
|
|
6
|
+
* the story owns the clock — a paced story (the recorder) or the
|
|
7
|
+
* determinism switch (frame renderers seeking) — those steps are NOT
|
|
8
|
+
* dispatched as actions: the story builds one EffectTrack from its timeline
|
|
9
|
+
* and evaluates every leg at the current story time on each tick or seek.
|
|
10
|
+
* A trace 40% drawn is then just a scene, reproducible at any t, instead
|
|
11
|
+
* of a wall-clock rAF loop racing the capture.
|
|
12
|
+
*
|
|
13
|
+
* Interactive wall-clock playback is untouched: it keeps dispatching the
|
|
14
|
+
* verbs through actions.ts, whose rAF path (effects.ts) remains the clock
|
|
15
|
+
* for anything without a timeline (click-to-trace behaviors, ctx.emit).
|
|
16
|
+
* Both clocks share the same underlying builders — the pure math
|
|
17
|
+
* (traceProgress, pulseOpacity, EASINGS), the populate sweep, the trace
|
|
18
|
+
* target/temp element — so a verb renders identically whichever clock
|
|
19
|
+
* drives it.
|
|
20
|
+
*
|
|
21
|
+
* Evaluation contract: legs are stateless functions of t, EXCEPT the
|
|
22
|
+
* documented enter/exit hooks (temp-layer DOM, trace hide sets), which the
|
|
23
|
+
* evaluator invokes on phase transitions. Seek resets are handled by the
|
|
24
|
+
* story's existing scrub model — restore-initial clears every channel patch
|
|
25
|
+
* and temp layer, then resetState() forgets all phases and applyAt(t)
|
|
26
|
+
* rebuilds the scene from pristine. Follow cameras are the one exception:
|
|
27
|
+
* during a paced run the driver owns the camera, so `follow` is skipped
|
|
28
|
+
* (warned once per track).
|
|
29
|
+
*/
|
|
30
|
+
import type { RuntimeCore } from "./runtime-core";
|
|
31
|
+
import type { LayerIR } from "./ir";
|
|
32
|
+
import type { StepInterval } from "./timeline";
|
|
33
|
+
/** The verbs the track owns — fireDueSteps suppresses exactly these while the story clock drives effects. */
|
|
34
|
+
export declare const EFFECT_TRACK_ACTIONS: Set<string>;
|
|
35
|
+
export interface EffectTrackDeps {
|
|
36
|
+
core: RuntimeCore;
|
|
37
|
+
mapEl: Element;
|
|
38
|
+
/**
|
|
39
|
+
* LIVE accessor, never a snapshot: om-map REASSIGNS its IR map on every
|
|
40
|
+
* reconcile (`this.layerIRs = next`), so a captured reference goes stale
|
|
41
|
+
* after the first reconcile of a run — which is guaranteed (the trace
|
|
42
|
+
* leg's own temp-element append triggers one). Legs re-init when a
|
|
43
|
+
* layer's data identity changes (URL arrival), which only works read
|
|
44
|
+
* through here.
|
|
45
|
+
*/
|
|
46
|
+
getLayerIRs(): ReadonlyMap<string, LayerIR>;
|
|
47
|
+
}
|
|
48
|
+
/** A leg's resolved behavior — chosen lazily on first need, when the layer's data is in hand. */
|
|
49
|
+
interface LegImpl {
|
|
50
|
+
/** Eased t01 → per-layer patches (the same shapes the wall-clock path writes through patchAnimatedProps). */
|
|
51
|
+
frame(t01: number): Record<string, Record<string, unknown>>;
|
|
52
|
+
/** "hold": past the leg, keep frame(1) applied. "clear": past the leg, the authored state IS the end state. */
|
|
53
|
+
end: "hold" | "clear";
|
|
54
|
+
/** Phase-entry hook (idempotent per activation): temp layers, trace hides. */
|
|
55
|
+
enter?(): void;
|
|
56
|
+
/** Phase-exit hook: teardown of whatever enter() built. */
|
|
57
|
+
exit?(): void;
|
|
58
|
+
}
|
|
59
|
+
interface Leg {
|
|
60
|
+
layerId: string;
|
|
61
|
+
start: number;
|
|
62
|
+
duration: number;
|
|
63
|
+
easing?: (t: number) => number;
|
|
64
|
+
init(deps: EffectTrackDeps): LegImpl | null;
|
|
65
|
+
}
|
|
66
|
+
export declare class EffectTrack {
|
|
67
|
+
private readonly legs;
|
|
68
|
+
private readonly deps;
|
|
69
|
+
private states;
|
|
70
|
+
/** Set by deactivate() (including ensureImpl's re-init teardown) — the heal pass re-applies what a removeEffectKeys may have stripped from a shared layer. */
|
|
71
|
+
private keysRemoved;
|
|
72
|
+
constructor(legs: Leg[], deps: EffectTrackDeps);
|
|
73
|
+
/** Forget all phase state WITHOUT teardown — call only after the story's restore-initial has already cleared patches and temp layers. */
|
|
74
|
+
resetState(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Evaluate every leg at story time t. CONTRACT: t is monotonically
|
|
77
|
+
* non-decreasing between resetState() calls — every caller guarantees it
|
|
78
|
+
* (advanceBy is monotone; seek and the loop restart reset first), so
|
|
79
|
+
* phases only ever move forward here and no backward transition exists.
|
|
80
|
+
* Legs are pre-sorted by start, so cross-leg chains resolve in timeline
|
|
81
|
+
* order.
|
|
82
|
+
*/
|
|
83
|
+
applyAt(t: number): void;
|
|
84
|
+
/** Re-applies leg i's current value: frame(1) for a settled hold, the eased frame at t for an active leg, nothing otherwise. Idempotent. */
|
|
85
|
+
private applyLegFrame;
|
|
86
|
+
private ensureImpl;
|
|
87
|
+
private apply;
|
|
88
|
+
private deactivate;
|
|
89
|
+
}
|
|
90
|
+
export declare function buildEffectTrack(steps: readonly {
|
|
91
|
+
action: string;
|
|
92
|
+
payload: Record<string, unknown>;
|
|
93
|
+
}[], intervals: readonly StepInterval[], deps: EffectTrackDeps): EffectTrack;
|
|
94
|
+
export {};
|
package/dist/effects.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ export declare const EASINGS: Record<string, (t: number) => number>;
|
|
|
18
18
|
export declare function traceProgress(t01: number, t0: number, t1: number): number;
|
|
19
19
|
/** Oscillates 1 → low → 1 per cycle (cosine), ending exactly at 1 for whole cycles. */
|
|
20
20
|
export declare function pulseOpacity(t01: number, cycles: number, low?: number): number;
|
|
21
|
+
/** Removes exactly one effect's keys from the layer's channel entry, preserving keys other writers own. (Exported for the story-time EffectTrack, which manages its own written-key sets.) */
|
|
22
|
+
export declare function removeEffectKeys(core: RuntimeCore, layerId: string, keys: Set<string>): void;
|
|
21
23
|
export declare function prefersReducedMotion(): boolean;
|
|
22
24
|
export interface LayerEffect {
|
|
23
25
|
/** t01 ∈ [0, 1] → the plain-prop patch for this frame. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HTMLElementBase } from "../env";
|
|
2
|
+
import { RuntimeCore } from "../runtime-core";
|
|
2
3
|
import { type RuntimeContext } from "../ctx";
|
|
3
4
|
import { type LightingIR } from "../scene-lighting";
|
|
4
5
|
import { type ClipBoxIR } from "../clip-box";
|
|
@@ -54,7 +55,6 @@ export declare class OmMapElement extends HTMLElementBase {
|
|
|
54
55
|
/** Dedup guard for the no-terrain-for-elevation error — same shape as `warnedApproximatePlacement`. */
|
|
55
56
|
private erroredNoTerrainForElevation;
|
|
56
57
|
private readyFired;
|
|
57
|
-
private firstSettleDrawDone;
|
|
58
58
|
/** Custom-state holder for the `om-collapsed` height-floor marker — see applyHeightFloor. */
|
|
59
59
|
private internals;
|
|
60
60
|
private resolveReady;
|
|
@@ -260,19 +260,22 @@ export declare class OmMapElement extends HTMLElementBase {
|
|
|
260
260
|
* same path a real deck click/hover coordinate takes, so the om-map-point
|
|
261
261
|
* event and custom capture tools are testable without a GPU. */
|
|
262
262
|
/**
|
|
263
|
-
* The map's "done drawing" promise (issue #37)
|
|
264
|
-
*
|
|
265
|
-
* frame has been painted — the await a pull-model frame renderer (or a
|
|
266
|
-
* consumer Playwright test) needs before screenshotting. Resolves
|
|
267
|
-
* `{settled:false}` with a console warning on timeout rather than
|
|
268
|
-
* rejecting (a late frame is ordinary pop-in, not an error). v1 gates 3D
|
|
269
|
-
* tilesets only — basemap raster tiles are not yet awaited.
|
|
263
|
+
* The map's "done drawing" promise (issue #37) — delegates to
|
|
264
|
+
* RuntimeCore.whenSettled, the single owner of the settle contract.
|
|
270
265
|
*/
|
|
271
266
|
whenSettled(opts?: {
|
|
272
267
|
timeout?: number;
|
|
273
268
|
}): Promise<{
|
|
274
269
|
settled: boolean;
|
|
275
270
|
}>;
|
|
271
|
+
/** Test surface: is the determinism switch active on the core (issue #37 — must be true BEFORE the first render when data-om-recording is authored; the basemap adapter reads it in its constructor). */
|
|
272
|
+
isDeterministicInternal(): boolean;
|
|
273
|
+
/** What the story-time EffectTrack needs to evaluate legs (om-story builds one when the story clock owns effects — paced stories, determinism). getLayerIRs is a LIVE accessor: reconcile REASSIGNS this.layerIRs, so a captured map reference would go stale after the first reconcile of a run. */
|
|
274
|
+
getEffectDepsInternal(): {
|
|
275
|
+
core: RuntimeCore;
|
|
276
|
+
mapEl: Element;
|
|
277
|
+
getLayerIRs(): ReadonlyMap<string, LayerIR>;
|
|
278
|
+
} | null;
|
|
276
279
|
injectMapPointInternal(coordinate: [number, number] | null, kind?: "click" | "hover", pointerType?: string): void;
|
|
277
280
|
/** Harness setView (spec: "Consumer Testing Surface") — the one path that reaches pitch/bearing. */
|
|
278
281
|
setViewInternal(partial: {
|
|
@@ -15,6 +15,8 @@ export declare class OmStoryElement extends HTMLElementBase {
|
|
|
15
15
|
private pacedGen;
|
|
16
16
|
/** True while the paced driver owns the camera — fireDueSteps must not dispatch camera actions against it. */
|
|
17
17
|
private pacedDriving;
|
|
18
|
+
/** Story-time effect evaluation (effect-track.ts) — built lazily when the story clock owns effects, invalidated whenever steps rebuild. */
|
|
19
|
+
private effectTrack;
|
|
18
20
|
private warnedPacedCameraSkip;
|
|
19
21
|
private pacedCapture;
|
|
20
22
|
private captured;
|
|
@@ -64,6 +66,22 @@ export declare class OmStoryElement extends HTMLElementBase {
|
|
|
64
66
|
*/
|
|
65
67
|
private startPaced;
|
|
66
68
|
private advanceBy;
|
|
69
|
+
/**
|
|
70
|
+
* The story clock owns effects when playback is pull-model: a PACED STORY
|
|
71
|
+
* (the recorder — wall-clock rAF effects would race the capture clock) or
|
|
72
|
+
* the determinism switch (frame renderers seek; runLayerEffect snaps
|
|
73
|
+
* there). Keyed on the `paced` ATTRIBUTE, deliberately not the transient
|
|
74
|
+
* pacedDriving flag: the flag drops asynchronously on pause, and a
|
|
75
|
+
* scrubber seek in that window would otherwise dispatch the verbs
|
|
76
|
+
* wall-clock (stamping end-state attributes, starting real rAF runners)
|
|
77
|
+
* that the resumed track then double-drives. The clock authority must be
|
|
78
|
+
* stable for a whole playback; flipping it mid-story is out of contract
|
|
79
|
+
* (the next seek re-evaluates cleanly). Interactive wall-clock playback
|
|
80
|
+
* keeps dispatching the verbs as actions — the rAF path in effects.ts is
|
|
81
|
+
* untouched.
|
|
82
|
+
*/
|
|
83
|
+
private storyClockOwnsEffects;
|
|
84
|
+
private ensureEffectTrack;
|
|
67
85
|
private fireDueSteps;
|
|
68
86
|
/** Steps and the timeline are (re)built lazily when idle — mid-play DOM edits apply on the next play/seek. */
|
|
69
87
|
private ensureBuilt;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as E, j as S, k as R, o as N, p as h, q as w, s as O, t as W, v as x, w as I, x as B, y as _, A as P, B as k, E as $, F as z, H as v, I as F, J as C, K as U, N as p, O as M } from "./index-
|
|
2
|
-
import { P as $e, R as ze, _ as ve, Q as Ce, S as Ue, T as Me, U as je, X as De, Y as Je, Z as qe, $ as He, a0 as Ve, a1 as Ge, a2 as Ke, a3 as Qe, a4 as Xe, a5 as Ye, a6 as Ze, a7 as et, a8 as tt, a9 as nt, aa as rt, ab as at, ac as st, ad as ot } from "./index-
|
|
1
|
+
import { i as E, j as S, k as R, o as N, p as h, q as w, s as O, t as W, v as x, w as I, x as B, y as _, A as P, B as k, E as $, F as z, H as v, I as F, J as C, K as U, N as p, O as M } from "./index-CuBGRyG-.js";
|
|
2
|
+
import { P as $e, R as ze, _ as ve, Q as Ce, S as Ue, T as Me, U as je, X as De, Y as Je, Z as qe, $ as He, a0 as Ve, a1 as Ge, a2 as Ke, a3 as Qe, a4 as Xe, a5 as Ye, a6 as Ze, a7 as et, a8 as tt, a9 as nt, aa as rt, ab as at, ac as st, ad as ot } from "./index-CuBGRyG-.js";
|
|
3
3
|
import { g as j, i as D } from "./table-accessors-CYWTzpQI.js";
|
|
4
4
|
async function J(t, e, n = {}, r = {}) {
|
|
5
5
|
const a = E(t), s = S.getWorkerFarm(n), { source: o } = n, c = { name: a, source: o };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ag as Be, ah as le, ai as ce, aj as De, ak as Oe, al as ke } from "./index-
|
|
1
|
+
import { ag as Be, ah as le, ai as ce, aj as De, ak as Oe, al as ke } from "./index-CuBGRyG-.js";
|
|
2
2
|
import { y as ve, a as he, z as G, R as J, A as ue, C as Fe, F as je, n as xe, S as Ie, E as Ne } from "./recordbatch-Bpc0uxFn.js";
|
|
3
3
|
import { g as V, a as fe, b as Le, c as Ue, d as Me, e as qe, m as Ve } from "./table-accessors-CYWTzpQI.js";
|
|
4
4
|
import { c as $e } from "./convert-arrow-schema-DrAihRf9.js";
|