@honua/react 0.1.4-beta.0 → 0.1.7-beta.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.
@@ -61,6 +61,13 @@ export interface HoverHandlerOptions {
61
61
  stateKey?: string;
62
62
  /** Source layer (required for vector-tile sources). */
63
63
  sourceLayer?: string;
64
+ /**
65
+ * Called whenever the hovered feature changes, with the source-qualified
66
+ * target or `undefined` when the pointer leaves the layer. Mirrors
67
+ * {@link SelectionHandlerOptions.onSelectionTargetsChange} so a hover, like
68
+ * a selection, can be published without re-reading `hoveredId` on a timer.
69
+ */
70
+ onHoverTargetChange?: (hovered: SourceQualifiedFeatureSelectionTarget | undefined) => void;
64
71
  }
65
72
  /** Handle returned by {@link createHoverHandler} for cleanup. */
66
73
  export interface HoverHandle {
@@ -1 +1 @@
1
- {"version":3,"file":"feature-state.d.ts","sourceRoot":"","sources":["../../../src/interactions/feature-state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feature-state.d.ts","sourceRoot":"","sources":["../../../src/interactions/feature-state.ts"],"names":[],"mappings":"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"}
@@ -50,23 +50,31 @@ export function removeFeatureState(map, source, id, key, sourceLayer) {
50
50
  * ```
51
51
  */
52
52
  export function createHoverHandler(map, options) {
53
- const { source, layer, stateKey = "hover", sourceLayer } = options;
53
+ const { source, layer, stateKey = "hover", sourceLayer, onHoverTargetChange } = options;
54
54
  let hoveredId;
55
55
  function onMouseMove(...args) {
56
56
  const e = args[0];
57
57
  const featureId = e?.features?.[0]?.id;
58
58
  if (featureId === undefined || featureId === null)
59
59
  return;
60
- if (hoveredId !== undefined && hoveredId !== featureId) {
60
+ const changed = hoveredId !== featureId;
61
+ if (hoveredId !== undefined && changed) {
61
62
  map.setFeatureState({ source, id: hoveredId, sourceLayer }, { [stateKey]: false });
62
63
  }
63
64
  hoveredId = featureId;
64
65
  map.setFeatureState({ source, id: hoveredId, sourceLayer }, { [stateKey]: true });
66
+ // Feature-state is re-set idempotently on every mousemove (unchanged
67
+ // behavior); the callback fires only on an actual hover *change* so a
68
+ // declarative binding sees one event per hovered feature, not one per
69
+ // pointer sample.
70
+ if (changed)
71
+ onHoverTargetChange?.(sourceFeatureSelectionTarget(source, featureId, { sourceLayer }));
65
72
  }
66
73
  function onMouseLeave() {
67
74
  if (hoveredId !== undefined) {
68
75
  map.setFeatureState({ source, id: hoveredId, sourceLayer }, { [stateKey]: false });
69
76
  hoveredId = undefined;
77
+ onHoverTargetChange?.(undefined);
70
78
  }
71
79
  }
72
80
  map.on("mousemove", layer, onMouseMove);
@@ -89,7 +89,7 @@ export function createHonuaMapLibreStyle(options = {}) {
89
89
  ...(options.name ? { name: options.name } : {}),
90
90
  ...(options.center ? { center: options.center } : {}),
91
91
  ...(options.zoom !== undefined ? { zoom: options.zoom } : {}),
92
- metadata: options.basemap ? { "honua:arcgis-basemap": options.basemap } : undefined,
92
+ ...(options.basemap ? { metadata: { "honua:arcgis-basemap": options.basemap } } : {}),
93
93
  sources,
94
94
  layers,
95
95
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@honua/react",
3
- "version": "0.1.4-beta.0",
3
+ "version": "0.1.7-beta.0",
4
4
  "description": "React bindings for the Honua SDK: provider, hooks, and map components",
5
5
  "keywords": [
6
6
  "gis",
@@ -34,7 +34,7 @@
34
34
  "@maplibre/maplibre-gl-style-spec": "^24.7.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "@honua/sdk": "0.1.4-beta.0",
37
+ "@honua/sdk": "0.1.7-beta.0",
38
38
  "react": "^18.2.0 || ^19.0.0",
39
39
  "react-dom": "^18.2.0 || ^19.0.0",
40
40
  "maplibre-gl": "^5.0.0 || ^6.0.0"
@@ -1 +1 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/realtime/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EAExB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACzC,KAAK,IAAI,IAAI,CAAC;IACd,gBAAgB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACvF,mBAAmB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;CAC3F;AAED,MAAM,MAAM,oCAAoC,GAAG,CACjD,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,eAAe,KACnB,6BAA6B,CAAC;AAEnC,MAAM,WAAW,wCAAwC,CAAC,QAAQ,GAAG,OAAO;IAC1E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,oCAAoC,CAAC;IACnE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAC;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,oBAAoB,CAAC,QAAQ,CAAC,CAAC;CAC7E;AAID,wBAAgB,uCAAuC,CAAC,QAAQ,GAAG,OAAO,EACxE,OAAO,EAAE,wCAAwC,CAAC,QAAQ,CAAC,GAC1D,wBAAwB,CAAC,QAAQ,CAAC,CAgGpC;AAED,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,GAAG,GAAG,CAsBhG;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAElH"}
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/realtime/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EAExB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACzC,KAAK,IAAI,IAAI,CAAC;IACd,gBAAgB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACvF,mBAAmB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;CAC3F;AAED,MAAM,MAAM,oCAAoC,GAAG,CACjD,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,eAAe,KACnB,6BAA6B,CAAC;AAEnC,MAAM,WAAW,wCAAwC,CAAC,QAAQ,GAAG,OAAO;IAC1E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,oCAAoC,CAAC;IACnE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAC;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,oBAAoB,CAAC,QAAQ,CAAC,CAAC;CAC7E;AAID,wBAAgB,uCAAuC,CAAC,QAAQ,GAAG,OAAO,EACxE,OAAO,EAAE,wCAAwC,CAAC,QAAQ,CAAC,GAC1D,wBAAwB,CAAC,QAAQ,CAAC,CAqGpC;AAED,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,GAAG,GAAG,CAsBhG;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAElH"}
package/realtime/sse.js CHANGED
@@ -66,7 +66,13 @@ export function createRealtimeServerSentEventsTransport(options) {
66
66
  for (const type of options.eventTypes ?? DEFAULT_EVENT_TYPES) {
67
67
  if (!source.addEventListener)
68
68
  break;
69
- const listener = (event) => emitPayload(event.data);
69
+ const listener = (event) => {
70
+ // EventSource also dispatches its native connection-error Event
71
+ // under the name "error". It has no data payload and must remain
72
+ // the responsibility of `source.onerror` below.
73
+ if (typeof event.data === "string")
74
+ emitPayload(event.data);
75
+ };
70
76
  source.addEventListener(type, listener);
71
77
  listeners.push([type, listener]);
72
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"style-compose.d.ts","sourceRoot":"","sources":["../../../src/runtime/style-compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAA2B,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAElG,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,iBAAiB,EAElB,MAAM,kBAAkB,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAElG,4FAA4F;AAC5F,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;AAEnF,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,YAAY,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED,4DAA4D;AAC5D,wBAAsB,YAAY,CAChC,GAAG,EAAE,eAAe,EACpB,kBAAkB,EAAE,uBAAuB,EAC3C,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,uBAAuB,CAAC,CAalC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,uBAAuB,EAC7B,GAAG,EAAE,eAAe,EACpB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,uBAAuB,CAAC,CAuBlC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,uBAAuB,EAAE,KAAK,EAAE,wBAAwB,GAAG,uBAAuB,CAMnH"}
1
+ {"version":3,"file":"style-compose.d.ts","sourceRoot":"","sources":["../../../src/runtime/style-compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAA2B,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAElG,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,iBAAiB,EAElB,MAAM,kBAAkB,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAElG,4FAA4F;AAC5F,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;AAEnF,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,YAAY,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED,4DAA4D;AAC5D,wBAAsB,YAAY,CAChC,GAAG,EAAE,eAAe,EACpB,kBAAkB,EAAE,uBAAuB,EAC3C,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,uBAAuB,CAAC,CAclC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,uBAAuB,EAC7B,GAAG,EAAE,eAAe,EACpB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,uBAAuB,CAAC,CAuBlC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,uBAAuB,EAAE,KAAK,EAAE,wBAAwB,GAAG,uBAAuB,CAMnH"}
@@ -20,7 +20,8 @@ export async function composeStyle(pkg, mapSpecWithSources, options) {
20
20
  try {
21
21
  const withStyleRefs = await applyStyleRefs(mapSpecWithSources, pkg, options.resolveStyleRef);
22
22
  const theme = await resolveTheme(pkg, options.resolveTheme);
23
- return theme ? applyTheme(withStyleRefs, theme) : withStyleRefs;
23
+ const composed = theme ? applyTheme(withStyleRefs, theme) : withStyleRefs;
24
+ return pruneUndefined(composed);
24
25
  }
25
26
  catch (cause) {
26
27
  if (cause instanceof HonuaMapPackageError)
@@ -97,26 +98,94 @@ function mergeLayerOverride(layer, override) {
97
98
  ...(override.filter !== undefined ? { filter: override.filter } : {}),
98
99
  ...(override.minzoom !== undefined ? { minzoom: override.minzoom } : {}),
99
100
  ...(override.maxzoom !== undefined ? { maxzoom: override.maxzoom } : {}),
100
- paint: { ...(layer.paint ?? {}), ...(override.paint ?? {}) },
101
- layout: { ...(layer.layout ?? {}), ...(override.layout ?? {}) },
102
- metadata: { ...(layer.metadata ?? {}), ...(override.metadata ?? {}) },
101
+ ...optionalRecord("paint", { ...(layer.paint ?? {}), ...(override.paint ?? {}) }),
102
+ ...optionalRecord("layout", { ...(layer.layout ?? {}), ...(override.layout ?? {}) }),
103
+ ...optionalRecord("metadata", { ...(layer.metadata ?? {}), ...(override.metadata ?? {}) }),
103
104
  };
104
105
  }
105
106
  function cloneLayer(layer) {
106
107
  return {
107
108
  ...layer,
108
- paint: layer.paint ? { ...layer.paint } : undefined,
109
- layout: layer.layout ? { ...layer.layout } : undefined,
110
- metadata: layer.metadata ? { ...layer.metadata } : undefined,
109
+ ...optionalRecord("paint", layer.paint ? { ...layer.paint } : undefined),
110
+ ...optionalRecord("layout", layer.layout ? { ...layer.layout } : undefined),
111
+ ...optionalRecord("metadata", layer.metadata ? { ...layer.metadata } : undefined),
111
112
  };
112
113
  }
113
114
  function substituteLayerTokens(layer, tokens) {
114
115
  return {
115
116
  ...layer,
116
- paint: layer.paint ? substituteTokens(layer.paint, tokens) : layer.paint,
117
- layout: layer.layout ? substituteTokens(layer.layout, tokens) : layer.layout,
117
+ ...optionalRecord("paint", layer.paint ? substituteTokens(layer.paint, tokens) : undefined),
118
+ ...optionalRecord("layout", layer.layout ? substituteTokens(layer.layout, tokens) : undefined),
118
119
  };
119
120
  }
121
+ /**
122
+ * Spread helper for optional MapLibre layer properties: contributes the key
123
+ * only when there is something to contribute.
124
+ *
125
+ * `{ layout: undefined }` and "no `layout` key" are indistinguishable to
126
+ * `JSON.stringify`, but not to MapLibre's style validator — it reads the own
127
+ * property and rejects the layer with `layers[n].layout: object expected,
128
+ * undefined found`. A rejected style makes `setStyle(style, { diff: true })`
129
+ * a silent no-op, so the map stops updating with nothing thrown and nothing
130
+ * logged. An empty object is dropped for the same reason in spirit: it is
131
+ * meaningless in the document and only adds diff noise.
132
+ */
133
+ function optionalRecord(key, value) {
134
+ if (!value || Object.keys(value).length === 0)
135
+ return {};
136
+ return { [key]: value };
137
+ }
138
+ /**
139
+ * Drop present-but-`undefined` properties from the composed document.
140
+ *
141
+ * The composition helpers above never introduce them, but the input
142
+ * `mapSpec` can arrive with them already (hand-built styles, projections
143
+ * from another shape, `JSON`-roundtripped packages that were assembled with
144
+ * explicit `undefined`s). Composition is the last hop before `setStyle`, so
145
+ * it is the right place to guarantee the invariant for every consumer rather
146
+ * than have each one re-implement the pruning.
147
+ *
148
+ * Structure-sharing: a subtree with no `undefined` values is returned by
149
+ * reference, so a clean style allocates nothing. Only plain objects and
150
+ * arrays are traversed; anything else (class instances, typed arrays) is
151
+ * passed through untouched.
152
+ */
153
+ function pruneUndefined(value) {
154
+ return pruneUnknown(value);
155
+ }
156
+ function pruneUnknown(value) {
157
+ if (Array.isArray(value)) {
158
+ let changed = false;
159
+ const next = value.map((item) => {
160
+ const pruned = pruneUnknown(item);
161
+ if (pruned !== item)
162
+ changed = true;
163
+ return pruned;
164
+ });
165
+ return changed ? next : value;
166
+ }
167
+ if (!isPlainObject(value))
168
+ return value;
169
+ let changed = false;
170
+ const next = {};
171
+ for (const [key, entry] of Object.entries(value)) {
172
+ if (entry === undefined) {
173
+ changed = true;
174
+ continue;
175
+ }
176
+ const pruned = pruneUnknown(entry);
177
+ if (pruned !== entry)
178
+ changed = true;
179
+ next[key] = pruned;
180
+ }
181
+ return changed ? next : value;
182
+ }
183
+ function isPlainObject(value) {
184
+ if (typeof value !== "object" || value === null)
185
+ return false;
186
+ const proto = Object.getPrototypeOf(value);
187
+ return proto === Object.prototype || proto === null;
188
+ }
120
189
  function substituteTokens(obj, tokens) {
121
190
  const out = {};
122
191
  for (const [key, value] of Object.entries(obj)) {