@honua/react 0.1.0-beta.0 → 0.1.1-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.
- package/contract/discovery.d.ts +231 -0
- package/contract/discovery.d.ts.map +1 -0
- package/contract/discovery.js +554 -0
- package/contract/edit-sketch.d.ts +8 -0
- package/contract/edit-sketch.d.ts.map +1 -1
- package/contract/edit-sketch.js +15 -0
- package/contract/edit-snapping.d.ts +160 -0
- package/contract/edit-snapping.d.ts.map +1 -0
- package/contract/edit-snapping.js +675 -0
- package/contract/generated/projjson-v0.7-crs-validator.d.ts +35 -0
- package/contract/generated/projjson-v0.7-crs-validator.d.ts.map +1 -0
- package/contract/generated/projjson-v0.7-crs-validator.js +3941 -0
- package/contract/index.d.ts +11 -2
- package/contract/index.d.ts.map +1 -1
- package/contract/index.js +4 -1
- package/contract/pmtiles.d.ts +31 -0
- package/contract/pmtiles.d.ts.map +1 -1
- package/contract/pmtiles.js +60 -20
- package/contract/protocol-module.d.ts +70 -0
- package/contract/protocol-module.d.ts.map +1 -0
- package/contract/protocol-module.js +1 -0
- package/contract/schema-envelope.d.ts +26 -0
- package/contract/schema-envelope.d.ts.map +1 -0
- package/contract/schema-envelope.js +25 -0
- package/contract/schema.d.ts +582 -0
- package/contract/schema.d.ts.map +1 -0
- package/contract/schema.js +2483 -0
- package/contract/source-capability-support.d.ts +6 -0
- package/contract/source-capability-support.d.ts.map +1 -0
- package/contract/source-capability-support.js +154 -0
- package/contract/source.d.ts +35 -17
- package/contract/source.d.ts.map +1 -1
- package/contract/source.js +267 -71
- package/contract/types.d.ts +140 -4
- package/contract/types.d.ts.map +1 -1
- package/contract/types.js +6 -14
- package/core/bounded-json.d.ts +4 -0
- package/core/bounded-json.d.ts.map +1 -0
- package/core/bounded-json.js +38 -0
- package/core/cache-state.d.ts +9 -0
- package/core/cache-state.d.ts.map +1 -1
- package/core/cache-state.js +10 -0
- package/core/capabilities-xml.d.ts +33 -0
- package/core/capabilities-xml.d.ts.map +1 -0
- package/core/capabilities-xml.js +331 -0
- package/core/client.d.ts +4 -1
- package/core/client.d.ts.map +1 -1
- package/core/client.js +115 -29
- package/core/error-classifications.d.ts +153 -0
- package/core/error-classifications.d.ts.map +1 -0
- package/core/error-classifications.js +140 -0
- package/core/error-code-registry.d.ts +158 -0
- package/core/error-code-registry.d.ts.map +1 -0
- package/core/error-code-registry.js +143 -0
- package/core/error-envelope.d.ts +68 -0
- package/core/error-envelope.d.ts.map +1 -0
- package/core/error-envelope.js +357 -0
- package/core/errors.d.ts +45 -29
- package/core/errors.d.ts.map +1 -1
- package/core/errors.js +97 -50
- package/core/geoparquet-sql.d.ts +30 -2
- package/core/geoparquet-sql.d.ts.map +1 -1
- package/core/geoparquet-sql.js +38 -3
- package/core/odata-key-path.d.ts +12 -0
- package/core/odata-key-path.d.ts.map +1 -0
- package/core/odata-key-path.js +28 -0
- package/core/odata-write-codec.d.ts +66 -0
- package/core/odata-write-codec.d.ts.map +1 -0
- package/core/odata-write-codec.js +1083 -0
- package/core/odata.d.ts +59 -7
- package/core/odata.d.ts.map +1 -1
- package/core/odata.js +431 -99
- package/core/ogc-features.d.ts.map +1 -1
- package/core/ogc-features.js +3 -0
- package/core/ogc-maps.d.ts +7 -0
- package/core/ogc-maps.d.ts.map +1 -1
- package/core/ogc-maps.js +46 -7
- package/core/ogc-processes.d.ts +2 -1
- package/core/ogc-processes.d.ts.map +1 -1
- package/core/ogc-processes.js +33 -5
- package/core/ogc-records.d.ts +9 -0
- package/core/ogc-records.d.ts.map +1 -1
- package/core/ogc-records.js +78 -29
- package/core/ogc-tiles.d.ts +10 -1
- package/core/ogc-tiles.d.ts.map +1 -1
- package/core/ogc-tiles.js +56 -17
- package/core/path-utils.d.ts +9 -0
- package/core/path-utils.d.ts.map +1 -1
- package/core/path-utils.js +19 -0
- package/core/protocol-transport.d.ts +1 -0
- package/core/protocol-transport.d.ts.map +1 -1
- package/core/request-pipeline.d.ts.map +1 -1
- package/core/request-pipeline.js +1 -1
- package/core/spatial-filter.d.ts +8 -4
- package/core/spatial-filter.d.ts.map +1 -1
- package/core/spatial-filter.js +206 -16
- package/core/stac-static.d.ts +6 -2
- package/core/stac-static.d.ts.map +1 -1
- package/core/stac-static.js +260 -69
- package/core/surfaces.d.ts.map +1 -1
- package/core/surfaces.js +69 -5
- package/core/types.d.ts +125 -7
- package/core/types.d.ts.map +1 -1
- package/core/wfs-capabilities.d.ts +2 -0
- package/core/wfs-capabilities.d.ts.map +1 -1
- package/core/wfs-capabilities.js +8 -1
- package/core/wfs.d.ts.map +1 -1
- package/core/wfs.js +10 -0
- package/core/wms-capabilities.d.ts +56 -84
- package/core/wms-capabilities.d.ts.map +1 -1
- package/core/wms-capabilities.js +212 -509
- package/core/wmts-capabilities.d.ts +62 -62
- package/core/wmts-capabilities.d.ts.map +1 -1
- package/core/wmts-capabilities.js +224 -371
- package/esri-compat/editor.d.ts +8 -0
- package/esri-compat/editor.d.ts.map +1 -1
- package/esri-compat/editor.js +13 -0
- package/esri-compat/feature-layer.d.ts +2 -0
- package/esri-compat/feature-layer.d.ts.map +1 -1
- package/esri-compat/feature-layer.js +1 -0
- package/esri-compat/layer-list.d.ts +11 -0
- package/esri-compat/layer-list.d.ts.map +1 -1
- package/esri-compat/layer-list.js +49 -0
- package/esri-compat/legend.d.ts +10 -0
- package/esri-compat/legend.d.ts.map +1 -1
- package/esri-compat/legend.js +27 -0
- package/esri-compat/portal.d.ts +197 -0
- package/esri-compat/portal.d.ts.map +1 -0
- package/esri-compat/portal.js +251 -0
- package/esri-compat/renderer-objects.d.ts +40 -0
- package/esri-compat/renderer-objects.d.ts.map +1 -0
- package/esri-compat/renderer-objects.js +62 -0
- package/esri-compat/sketch.d.ts +43 -0
- package/esri-compat/sketch.d.ts.map +1 -1
- package/esri-compat/sketch.js +46 -0
- package/esri-compat/snapping.d.ts +43 -0
- package/esri-compat/snapping.d.ts.map +1 -0
- package/esri-compat/snapping.js +45 -0
- package/esri-compat/url.d.ts.map +1 -1
- package/esri-compat/url.js +1 -1
- package/esri-compat/widget-host.d.ts +84 -0
- package/esri-compat/widget-host.d.ts.map +1 -0
- package/esri-compat/widget-host.js +159 -0
- package/filter-registry/index.d.ts +145 -0
- package/filter-registry/index.d.ts.map +1 -0
- package/filter-registry/index.js +531 -0
- package/generated-app/errors.d.ts +18 -2
- package/generated-app/errors.d.ts.map +1 -1
- package/generated-app/errors.js +44 -11
- package/map/automatic-mount-integration.d.ts +134 -0
- package/map/automatic-mount-integration.d.ts.map +1 -0
- package/map/automatic-mount-integration.js +305 -0
- package/map/automatic-source-strategy.d.ts +125 -0
- package/map/automatic-source-strategy.d.ts.map +1 -0
- package/map/automatic-source-strategy.js +494 -0
- package/map/data-to-map-bridge.d.ts +293 -0
- package/map/data-to-map-bridge.d.ts.map +1 -0
- package/map/data-to-map-bridge.js +817 -0
- package/map/geojson-projection.d.ts +33 -0
- package/map/geojson-projection.d.ts.map +1 -0
- package/map/geojson-projection.js +118 -0
- package/map/index.d.ts +14 -0
- package/map/index.d.ts.map +1 -1
- package/map/index.js +8 -0
- package/map/raster-source-spec.d.ts +30 -0
- package/map/raster-source-spec.d.ts.map +1 -0
- package/map/raster-source-spec.js +190 -0
- package/map/raster-source-strategy.d.ts +65 -0
- package/map/raster-source-strategy.d.ts.map +1 -0
- package/map/raster-source-strategy.js +232 -0
- package/map/source-to-maplibre.d.ts +91 -0
- package/map/source-to-maplibre.d.ts.map +1 -0
- package/map/source-to-maplibre.js +454 -0
- package/map/temporal-playback.d.ts +139 -0
- package/map/temporal-playback.d.ts.map +1 -0
- package/map/temporal-playback.js +247 -0
- package/package.json +14 -1
- package/query-planner/canonical.d.ts +7 -0
- package/query-planner/canonical.d.ts.map +1 -0
- package/query-planner/canonical.js +145 -0
- package/query-planner/cql2-json.d.ts +17 -0
- package/query-planner/cql2-json.d.ts.map +1 -0
- package/query-planner/cql2-json.js +646 -0
- package/query-planner/diagnostics.d.ts +35 -0
- package/query-planner/diagnostics.d.ts.map +1 -0
- package/query-planner/diagnostics.js +373 -0
- package/query-planner/duckdb.d.ts +79 -0
- package/query-planner/duckdb.d.ts.map +1 -0
- package/query-planner/duckdb.js +758 -0
- package/query-planner/execution-context.d.ts +5 -0
- package/query-planner/execution-context.d.ts.map +1 -0
- package/query-planner/execution-context.js +50 -0
- package/query-planner/executor.d.ts +5 -0
- package/query-planner/executor.d.ts.map +1 -0
- package/query-planner/executor.js +223 -0
- package/query-planner/geoservices.d.ts +91 -0
- package/query-planner/geoservices.d.ts.map +1 -0
- package/query-planner/geoservices.js +667 -0
- package/query-planner/grpc.d.ts +100 -0
- package/query-planner/grpc.d.ts.map +1 -0
- package/query-planner/grpc.js +736 -0
- package/query-planner/index.d.ts +44 -0
- package/query-planner/index.d.ts.map +1 -0
- package/query-planner/index.js +30 -0
- package/query-planner/ir.d.ts +20 -0
- package/query-planner/ir.d.ts.map +1 -0
- package/query-planner/ir.js +417 -0
- package/query-planner/local-aggregate.d.ts +5 -0
- package/query-planner/local-aggregate.d.ts.map +1 -0
- package/query-planner/local-aggregate.js +126 -0
- package/query-planner/odata.d.ts +48 -0
- package/query-planner/odata.d.ts.map +1 -0
- package/query-planner/odata.js +662 -0
- package/query-planner/ogc-compiler.d.ts +55 -0
- package/query-planner/ogc-compiler.d.ts.map +1 -0
- package/query-planner/ogc-compiler.js +480 -0
- package/query-planner/ogc-features.d.ts +53 -0
- package/query-planner/ogc-features.d.ts.map +1 -0
- package/query-planner/ogc-features.js +617 -0
- package/query-planner/planner.d.ts +17 -0
- package/query-planner/planner.d.ts.map +1 -0
- package/query-planner/planner.js +818 -0
- package/query-planner/resource.d.ts +94 -0
- package/query-planner/resource.d.ts.map +1 -0
- package/query-planner/resource.js +526 -0
- package/query-planner/semantic-canonical.d.ts +15 -0
- package/query-planner/semantic-canonical.d.ts.map +1 -0
- package/query-planner/semantic-canonical.js +62 -0
- package/query-planner/semantic-compat.d.ts +10 -0
- package/query-planner/semantic-compat.d.ts.map +1 -0
- package/query-planner/semantic-compat.js +35 -0
- package/query-planner/semantic-compiler.d.ts +64 -0
- package/query-planner/semantic-compiler.d.ts.map +1 -0
- package/query-planner/semantic-compiler.js +81 -0
- package/query-planner/semantic-literals.d.ts +30 -0
- package/query-planner/semantic-literals.d.ts.map +1 -0
- package/query-planner/semantic-literals.js +133 -0
- package/query-planner/semantic-types.d.ts +265 -0
- package/query-planner/semantic-types.d.ts.map +1 -0
- package/query-planner/semantic-types.js +1 -0
- package/query-planner/semantic.d.ts +54 -0
- package/query-planner/semantic.d.ts.map +1 -0
- package/query-planner/semantic.js +1421 -0
- package/query-planner/types.d.ts +560 -0
- package/query-planner/types.d.ts.map +1 -0
- package/query-planner/types.js +49 -0
- package/query-planner/wfs-semantic.d.ts +58 -0
- package/query-planner/wfs-semantic.d.ts.map +1 -0
- package/query-planner/wfs-semantic.js +547 -0
- package/query-planner/wfs.d.ts +6 -0
- package/query-planner/wfs.d.ts.map +1 -0
- package/query-planner/wfs.js +71 -0
- package/react/external-map.d.ts +67 -0
- package/react/external-map.d.ts.map +1 -0
- package/react/external-map.js +63 -0
- package/react/honua-map.d.ts.map +1 -1
- package/react/honua-map.js +3 -2
- package/react/honua-source-layer.d.ts +110 -0
- package/react/honua-source-layer.d.ts.map +1 -0
- package/react/honua-source-layer.js +101 -0
- package/react/hooks.d.ts +28 -0
- package/react/hooks.d.ts.map +1 -1
- package/react/hooks.js +26 -4
- package/react/index.d.ts +8 -0
- package/react/index.d.ts.map +1 -1
- package/react/index.js +5 -0
- package/react/query-cache.d.ts +26 -4
- package/react/query-cache.d.ts.map +1 -1
- package/react/query-cache.js +51 -8
- package/react/selection.d.ts +177 -0
- package/react/selection.d.ts.map +1 -0
- package/react/selection.js +0 -0
- package/react/use-mounted-source.d.ts +69 -0
- package/react/use-mounted-source.d.ts.map +1 -0
- package/react/use-mounted-source.js +346 -0
- package/runtime/edit-snapping.d.ts +107 -0
- package/runtime/edit-snapping.d.ts.map +1 -0
- package/runtime/edit-snapping.js +190 -0
- package/runtime/errors.d.ts +3 -2
- package/runtime/errors.d.ts.map +1 -1
- package/runtime/errors.js +19 -2
- package/runtime/index.d.ts +6 -0
- package/runtime/index.d.ts.map +1 -1
- package/runtime/index.js +3 -0
- package/runtime/maplibre-renderer.d.ts +41 -0
- package/runtime/maplibre-renderer.d.ts.map +1 -0
- package/runtime/maplibre-renderer.js +322 -0
- package/runtime/query-tiles.d.ts +2 -1
- package/runtime/query-tiles.d.ts.map +1 -1
- package/runtime/query-tiles.js +6 -2
- package/runtime/source-bridge.d.ts +4 -4
- package/runtime/source-bridge.d.ts.map +1 -1
- package/runtime/source-bridge.js +9 -56
- package/runtime/style-interactions.d.ts +3 -2
- package/runtime/style-interactions.d.ts.map +1 -1
- package/runtime/style-interactions.js +11 -3
- package/runtime/terra-draw-sketch.d.ts +275 -0
- package/runtime/terra-draw-sketch.d.ts.map +1 -0
- package/runtime/terra-draw-sketch.js +404 -0
- package/source-capability-registry.d.ts +1 -0
- package/source-capability-registry.js +1 -0
- package/source-capability-types.d.ts +186 -0
- package/source-capability-types.js +7 -0
- package/style/index.d.ts +2 -0
- package/style/index.d.ts.map +1 -1
- package/style/index.js +2 -0
- package/style/renderers.d.ts +326 -0
- package/style/renderers.d.ts.map +1 -0
- package/style/renderers.js +517 -0
- package/webmap/convert-renderer.d.ts +24 -3
- package/webmap/convert-renderer.d.ts.map +1 -1
- package/webmap/convert-renderer.js +93 -112
- package/webmap/index.d.ts +1 -1
- package/webmap/index.d.ts.map +1 -1
- package/webmap/index.js +1 -1
package/react/query-cache.js
CHANGED
|
@@ -64,22 +64,46 @@ export class HonuaQueryCache {
|
|
|
64
64
|
error: undefined,
|
|
65
65
|
isLoading: false,
|
|
66
66
|
isFetching: false,
|
|
67
|
+
dataUpdatedAt: entry.snapshot.dataUpdatedAt,
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
};
|
|
71
72
|
}
|
|
72
73
|
/**
|
|
73
|
-
* Kick off a fetch for `key`
|
|
74
|
-
*
|
|
75
|
-
*
|
|
74
|
+
* Kick off a fetch for `key` when it has never resolved and is not already
|
|
75
|
+
* in flight. This is the idempotent entry point hooks call from an effect;
|
|
76
|
+
* StrictMode's double-invoke therefore does not double-fetch.
|
|
77
|
+
*
|
|
78
|
+
* With `options.staleTimeMs`, a resolved entry whose data is at least that
|
|
79
|
+
* old is additionally revalidated in the background (stale-while-revalidate:
|
|
80
|
+
* the cached data stays served while `isFetching` is true). `0` revalidates
|
|
81
|
+
* on every ensure; omitted keeps the historical never-revalidate behavior.
|
|
76
82
|
*/
|
|
77
|
-
ensure(key, fetcher) {
|
|
83
|
+
ensure(key, fetcher, options = {}) {
|
|
78
84
|
const entry = this.entryFor(key);
|
|
79
85
|
if (entry.snapshot.status === "idle") {
|
|
80
86
|
this.run(key, fetcher);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (options.staleTimeMs !== undefined &&
|
|
90
|
+
entry.snapshot.status === "success" &&
|
|
91
|
+
!entry.snapshot.isFetching &&
|
|
92
|
+
Date.now() - (entry.snapshot.dataUpdatedAt ?? 0) >= options.staleTimeMs) {
|
|
93
|
+
this.run(key, fetcher);
|
|
81
94
|
}
|
|
82
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* The promise of the in-flight run for `key`, or `undefined` when no fetch
|
|
98
|
+
* is running. Suspense-mode hooks throw this promise while the first load is
|
|
99
|
+
* pending; it never rejects (errors land on the snapshot instead).
|
|
100
|
+
*
|
|
101
|
+
* @experimental
|
|
102
|
+
*/
|
|
103
|
+
getPromise(key) {
|
|
104
|
+
const entry = this.entries.get(key);
|
|
105
|
+
return entry?.snapshot.isFetching ? entry.promise : undefined;
|
|
106
|
+
}
|
|
83
107
|
/**
|
|
84
108
|
* Force a (re)fetch for `key`, superseding any in-flight request. The last
|
|
85
109
|
* resolved `data` is preserved while the refetch runs.
|
|
@@ -97,8 +121,9 @@ export class HonuaQueryCache {
|
|
|
97
121
|
error: undefined,
|
|
98
122
|
isLoading: entry.snapshot.data === undefined,
|
|
99
123
|
isFetching: true,
|
|
124
|
+
dataUpdatedAt: entry.snapshot.dataUpdatedAt,
|
|
100
125
|
});
|
|
101
|
-
fetcher(controller.signal).then((value) => {
|
|
126
|
+
entry.promise = fetcher(controller.signal).then((value) => {
|
|
102
127
|
if (entry.token !== token)
|
|
103
128
|
return;
|
|
104
129
|
entry.controller = undefined;
|
|
@@ -108,6 +133,7 @@ export class HonuaQueryCache {
|
|
|
108
133
|
error: undefined,
|
|
109
134
|
isLoading: false,
|
|
110
135
|
isFetching: false,
|
|
136
|
+
dataUpdatedAt: Date.now(),
|
|
111
137
|
});
|
|
112
138
|
}, (error) => {
|
|
113
139
|
if (entry.token !== token || controller.signal.aborted)
|
|
@@ -119,6 +145,7 @@ export class HonuaQueryCache {
|
|
|
119
145
|
error,
|
|
120
146
|
isLoading: false,
|
|
121
147
|
isFetching: false,
|
|
148
|
+
dataUpdatedAt: entry.snapshot.dataUpdatedAt,
|
|
122
149
|
});
|
|
123
150
|
});
|
|
124
151
|
}
|
|
@@ -144,7 +171,7 @@ export class HonuaQueryCache {
|
|
|
144
171
|
entryFor(key) {
|
|
145
172
|
let entry = this.entries.get(key);
|
|
146
173
|
if (!entry) {
|
|
147
|
-
entry = { snapshot: IDLE_SNAPSHOT, listeners: new Set(), controller: undefined, token: 0 };
|
|
174
|
+
entry = { snapshot: IDLE_SNAPSHOT, listeners: new Set(), controller: undefined, token: 0, promise: undefined };
|
|
148
175
|
this.entries.set(key, entry);
|
|
149
176
|
}
|
|
150
177
|
return entry;
|
|
@@ -174,8 +201,8 @@ function stableStringify(value) {
|
|
|
174
201
|
if (Array.isArray(value)) {
|
|
175
202
|
return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
|
|
176
203
|
}
|
|
177
|
-
if (value
|
|
178
|
-
return `[${[...value]
|
|
204
|
+
if (isReadonlySet(value)) {
|
|
205
|
+
return `[${[...value.values()]
|
|
179
206
|
.map((entry) => stableStringify(entry))
|
|
180
207
|
.sort()
|
|
181
208
|
.join(",")}]`;
|
|
@@ -186,3 +213,19 @@ function stableStringify(value) {
|
|
|
186
213
|
.sort();
|
|
187
214
|
return `{${keys.map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`).join(",")}}`;
|
|
188
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* Recognize native, cross-realm, and intentionally branded immutable sets.
|
|
218
|
+
* Requiring the complete ReadonlySet surface plus the Set brand avoids
|
|
219
|
+
* consuming strings, maps, generators, or arbitrary domain iterables.
|
|
220
|
+
*/
|
|
221
|
+
function isReadonlySet(value) {
|
|
222
|
+
const candidate = value;
|
|
223
|
+
return (candidate[Symbol.toStringTag] === "Set" &&
|
|
224
|
+
typeof candidate.size === "number" &&
|
|
225
|
+
typeof candidate.has === "function" &&
|
|
226
|
+
typeof candidate.entries === "function" &&
|
|
227
|
+
typeof candidate.keys === "function" &&
|
|
228
|
+
typeof candidate.values === "function" &&
|
|
229
|
+
typeof candidate.forEach === "function" &&
|
|
230
|
+
typeof candidate[Symbol.iterator] === "function");
|
|
231
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared selection / hover state for `@honua/react` (REQ-004 of the react
|
|
3
|
+
* depth pass), built on the interactions layer's source-qualified selection
|
|
4
|
+
* targets and feature-state primitives so map and non-map components observe
|
|
5
|
+
* the same state.
|
|
6
|
+
*
|
|
7
|
+
* - {@link HonuaSelectionProvider} owns a {@link HonuaSelectionStore} (a plain
|
|
8
|
+
* external store read through `useSyncExternalStore`).
|
|
9
|
+
* - {@link useSelection} / {@link useHover} expose the state to any component.
|
|
10
|
+
* - {@link useMapSelectionBinding} / {@link useMapHoverBinding} wire a MapLibre
|
|
11
|
+
* layer set into the store: clicks toggle selection, pointer moves publish
|
|
12
|
+
* hover, and store changes are mirrored onto MapLibre feature-state (via the
|
|
13
|
+
* interactions layer's `setFeatureState`) so paint expressions react to
|
|
14
|
+
* selections made from a sidebar just like map clicks.
|
|
15
|
+
*
|
|
16
|
+
* SSR-safe: no `window` / `document` access at module scope.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
import { type ReactNode } from "react";
|
|
21
|
+
import type { SourceQualifiedFeatureSelectionTarget } from "../exploration/types.js";
|
|
22
|
+
import type { DataToMapLibreMap } from "../map/data-to-map-bridge.js";
|
|
23
|
+
/** Immutable snapshot of the shared selection / hover state. @experimental */
|
|
24
|
+
export interface HonuaSelectionSnapshot {
|
|
25
|
+
/** Source-qualified selected features, in selection order. */
|
|
26
|
+
readonly selected: readonly SourceQualifiedFeatureSelectionTarget[];
|
|
27
|
+
/** The feature currently under the pointer, or `null`. */
|
|
28
|
+
readonly hovered: SourceQualifiedFeatureSelectionTarget | null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Framework-neutral external store behind {@link HonuaSelectionProvider}.
|
|
32
|
+
* Exposed so tests and non-React integrations can drive the same state.
|
|
33
|
+
*
|
|
34
|
+
* @experimental
|
|
35
|
+
*/
|
|
36
|
+
export declare class HonuaSelectionStore {
|
|
37
|
+
private snapshot;
|
|
38
|
+
private readonly listeners;
|
|
39
|
+
subscribe: (listener: () => void) => (() => void);
|
|
40
|
+
getSnapshot: () => HonuaSelectionSnapshot;
|
|
41
|
+
isSelected(target: SourceQualifiedFeatureSelectionTarget): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Select a feature. Non-additive (default) replaces the selection —
|
|
44
|
+
* single-select semantics; `additive` appends (multi-select).
|
|
45
|
+
*/
|
|
46
|
+
select(target: SourceQualifiedFeatureSelectionTarget, options?: {
|
|
47
|
+
additive?: boolean;
|
|
48
|
+
}): void;
|
|
49
|
+
deselect(target: SourceQualifiedFeatureSelectionTarget): void;
|
|
50
|
+
/** Toggle a feature's membership (map-click semantics). */
|
|
51
|
+
toggle(target: SourceQualifiedFeatureSelectionTarget, options?: {
|
|
52
|
+
additive?: boolean;
|
|
53
|
+
}): void;
|
|
54
|
+
clear(): void;
|
|
55
|
+
setHovered(target: SourceQualifiedFeatureSelectionTarget | null): void;
|
|
56
|
+
private write;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Context carrying the shared selection store. `null` outside a
|
|
60
|
+
* {@link HonuaSelectionProvider}; the hooks throw a descriptive error then.
|
|
61
|
+
*
|
|
62
|
+
* @experimental
|
|
63
|
+
*/
|
|
64
|
+
export declare const HonuaSelectionContext: import("react").Context<HonuaSelectionStore | null>;
|
|
65
|
+
/** Props for {@link HonuaSelectionProvider}. @experimental */
|
|
66
|
+
export interface HonuaSelectionProviderProps {
|
|
67
|
+
/**
|
|
68
|
+
* Optional externally-owned store — share one across providers or pre-seed
|
|
69
|
+
* it in tests. Omit to let the provider own a fresh store.
|
|
70
|
+
*/
|
|
71
|
+
store?: HonuaSelectionStore;
|
|
72
|
+
/** Observe every selection change (fires after the state updates). */
|
|
73
|
+
onSelectionChange?: (selected: readonly SourceQualifiedFeatureSelectionTarget[]) => void;
|
|
74
|
+
children?: ReactNode;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Provide shared selection / hover state to the subtree. Map components bind
|
|
78
|
+
* through {@link useMapSelectionBinding} (or `HonuaSourceLayer`'s `selection`
|
|
79
|
+
* prop); sidebars, tables, and charts read/write the same state through
|
|
80
|
+
* {@link useSelection} and {@link useHover}.
|
|
81
|
+
*
|
|
82
|
+
* @experimental
|
|
83
|
+
*/
|
|
84
|
+
export declare function HonuaSelectionProvider({ store, onSelectionChange, children }: HonuaSelectionProviderProps): ReactNode;
|
|
85
|
+
/** Result of {@link useSelection}. @experimental */
|
|
86
|
+
export interface UseSelectionResult {
|
|
87
|
+
/** Source-qualified selected features, in selection order. */
|
|
88
|
+
selected: readonly SourceQualifiedFeatureSelectionTarget[];
|
|
89
|
+
isSelected(target: SourceQualifiedFeatureSelectionTarget): boolean;
|
|
90
|
+
/** Select (replace, or append with `{ additive: true }`). */
|
|
91
|
+
select(target: SourceQualifiedFeatureSelectionTarget, options?: {
|
|
92
|
+
additive?: boolean;
|
|
93
|
+
}): void;
|
|
94
|
+
deselect(target: SourceQualifiedFeatureSelectionTarget): void;
|
|
95
|
+
/** Toggle membership — map-click semantics. */
|
|
96
|
+
toggle(target: SourceQualifiedFeatureSelectionTarget, options?: {
|
|
97
|
+
additive?: boolean;
|
|
98
|
+
}): void;
|
|
99
|
+
clear(): void;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Read and mutate the shared selection. Works in any component under a
|
|
103
|
+
* {@link HonuaSelectionProvider} — map-attached or not.
|
|
104
|
+
*
|
|
105
|
+
* @throws outside a `HonuaSelectionProvider`.
|
|
106
|
+
* @experimental
|
|
107
|
+
*/
|
|
108
|
+
export declare function useSelection(): UseSelectionResult;
|
|
109
|
+
/** Result of {@link useHover}. @experimental */
|
|
110
|
+
export interface UseHoverResult {
|
|
111
|
+
/** The feature currently under the pointer, or `null`. */
|
|
112
|
+
hovered: SourceQualifiedFeatureSelectionTarget | null;
|
|
113
|
+
isHovered(target: SourceQualifiedFeatureSelectionTarget): boolean;
|
|
114
|
+
setHovered(target: SourceQualifiedFeatureSelectionTarget | null): void;
|
|
115
|
+
clearHovered(): void;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Read and publish the shared hover state.
|
|
119
|
+
*
|
|
120
|
+
* @throws outside a `HonuaSelectionProvider`.
|
|
121
|
+
* @experimental
|
|
122
|
+
*/
|
|
123
|
+
export declare function useHover(): UseHoverResult;
|
|
124
|
+
/** Options for {@link useMapSelectionBinding}. @experimental */
|
|
125
|
+
export interface MapSelectionBindingOptions {
|
|
126
|
+
/** MapLibre source id whose features participate. */
|
|
127
|
+
sourceId: string;
|
|
128
|
+
/** Layer ids whose clicks toggle selection. */
|
|
129
|
+
layerIds: readonly string[];
|
|
130
|
+
/** Vector `source-layer` (tile sources). */
|
|
131
|
+
sourceLayer?: string;
|
|
132
|
+
/** Feature-state key mirrored for selected features. @default "selected" */
|
|
133
|
+
stateKey?: string;
|
|
134
|
+
/** Map clicks add to the selection instead of replacing it. @default false */
|
|
135
|
+
multiSelect?: boolean;
|
|
136
|
+
/** Disable the binding without unmounting. @default true */
|
|
137
|
+
enabled?: boolean;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Two-way binding between a mounted MapLibre layer set and the enclosing
|
|
141
|
+
* {@link HonuaSelectionProvider}:
|
|
142
|
+
*
|
|
143
|
+
* - layer clicks toggle the clicked feature in the shared store;
|
|
144
|
+
* - every store change (from the map *or* from non-map components) is mirrored
|
|
145
|
+
* onto MapLibre feature-state under `stateKey`, so paint expressions like
|
|
146
|
+
* `["case", ["boolean", ["feature-state", "selected"], false], …]` respond.
|
|
147
|
+
*
|
|
148
|
+
* Requires a map with `on`/`off` and `setFeatureState` (any MapLibre map).
|
|
149
|
+
* No-ops while the map is `null` or there is no enclosing
|
|
150
|
+
* `HonuaSelectionProvider`. StrictMode-safe: listeners and mirrored
|
|
151
|
+
* feature-state are fully removed on cleanup.
|
|
152
|
+
*
|
|
153
|
+
* @experimental
|
|
154
|
+
*/
|
|
155
|
+
export declare function useMapSelectionBinding(map: DataToMapLibreMap | null | undefined, options: MapSelectionBindingOptions): void;
|
|
156
|
+
/** Options for {@link useMapHoverBinding}. @experimental */
|
|
157
|
+
export interface MapHoverBindingOptions {
|
|
158
|
+
/** MapLibre source id whose features participate. */
|
|
159
|
+
sourceId: string;
|
|
160
|
+
/** Layer ids whose pointer moves publish hover. */
|
|
161
|
+
layerIds: readonly string[];
|
|
162
|
+
/** Vector `source-layer` (tile sources). */
|
|
163
|
+
sourceLayer?: string;
|
|
164
|
+
/** Disable the binding without unmounting. @default true */
|
|
165
|
+
enabled?: boolean;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Publish the hovered feature of a MapLibre layer set into the enclosing
|
|
169
|
+
* {@link HonuaSelectionProvider}. Visual hover feature-state stays with the
|
|
170
|
+
* bridge's `hover` option (`createHoverHandler`); this binding only shares the
|
|
171
|
+
* hover *state* with non-map components. No-ops while the map is `null` or
|
|
172
|
+
* there is no enclosing `HonuaSelectionProvider`.
|
|
173
|
+
*
|
|
174
|
+
* @experimental
|
|
175
|
+
*/
|
|
176
|
+
export declare function useMapHoverBinding(map: DataToMapLibreMap | null | undefined, options: MapHoverBindingOptions): void;
|
|
177
|
+
//# sourceMappingURL=selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/react/selection.tsx"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {@link useMountedSource} — the React lifecycle wrapper around the
|
|
3
|
+
* data-to-map bridge's `mountSource` (REQ-002 of the react depth pass).
|
|
4
|
+
*
|
|
5
|
+
* One bridge mount per effect run: the mount effect creates a fresh
|
|
6
|
+
* `MountedSource` and its cleanup aborts any in-flight mount and disposes the
|
|
7
|
+
* handle (idempotent), so React 18/19 StrictMode's mount → unmount → mount
|
|
8
|
+
* never leaks MapLibre sources, layers, or listeners and never double-adds.
|
|
9
|
+
*
|
|
10
|
+
* Prop changes are diffed instead of torn down:
|
|
11
|
+
* - `query` → `handle.setFilter(query)` (GeoJSON `setData` / tile URL rewrite);
|
|
12
|
+
* - `renderer` (a first-class renderer object from `@honua/sdk-js/style`) →
|
|
13
|
+
* `handle.setRenderer(renderer)`, which diffs paint/layout in place and
|
|
14
|
+
* recreates only the owned layers on a structural renderer change;
|
|
15
|
+
* - `paint` / `layout` → per-property `map.setPaintProperty` /
|
|
16
|
+
* `map.setLayoutProperty` on the bridge-owned layers (falling back to a full
|
|
17
|
+
* remount when the host map does not expose those methods);
|
|
18
|
+
* - structural options (strategy, ids, custom `layers`, geometry, tiles…) →
|
|
19
|
+
* remount.
|
|
20
|
+
*
|
|
21
|
+
* SSR-safe: no `window` / `document` access at module scope.
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
import type { Source } from "../contract/types.js";
|
|
26
|
+
import type { DataToMapLibreMap, MountSourceOptions, MountedSource, MountedSourceDiagnostics } from "../map/data-to-map-bridge.js";
|
|
27
|
+
/** Options for {@link useMountedSource}. @experimental */
|
|
28
|
+
export interface UseMountedSourceOptions<T = Record<string, unknown>> extends Omit<MountSourceOptions<T>, "signal"> {
|
|
29
|
+
/** When `false`, nothing is mounted (and any existing mount is disposed). Default `true`. */
|
|
30
|
+
enabled?: boolean;
|
|
31
|
+
/** Called with fresh diagnostics after the mount and after every applied update. */
|
|
32
|
+
onDiagnostics?: (diagnostics: MountedSourceDiagnostics) => void;
|
|
33
|
+
/** Called when mounting or a diff update fails (aborted mounts are silent). */
|
|
34
|
+
onError?: (error: unknown) => void;
|
|
35
|
+
}
|
|
36
|
+
/** Result of {@link useMountedSource}. @experimental */
|
|
37
|
+
export interface UseMountedSourceResult<T = Record<string, unknown>> {
|
|
38
|
+
/** The live bridge handle, or `null` while unmounted / mounting / failed. */
|
|
39
|
+
handle: MountedSource<T> | null;
|
|
40
|
+
/** Diagnostics snapshot from the mount and the latest applied update. */
|
|
41
|
+
diagnostics: MountedSourceDiagnostics | null;
|
|
42
|
+
/** Mount or update failure, `undefined` while healthy. */
|
|
43
|
+
error: unknown;
|
|
44
|
+
/** True while the initial mount (or a structural remount) is in flight. */
|
|
45
|
+
isMounting: boolean;
|
|
46
|
+
/** Re-execute the current filter and diff-update the mounted data in place. */
|
|
47
|
+
refresh: () => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Mount a contract `Source` on a MapLibre map through the data-to-map bridge
|
|
51
|
+
* for the lifetime of the component.
|
|
52
|
+
*
|
|
53
|
+
* Pass the map explicitly, or pass `undefined` to resolve it from the nearest
|
|
54
|
+
* {@link HonuaMapProvider} / `HonuaMap` (external `@vis.gl/react-maplibre`
|
|
55
|
+
* interop works the same way — hand over `mapRef.getMap()`).
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```tsx
|
|
59
|
+
* const { diagnostics, error } = useMountedSource(map, source, {
|
|
60
|
+
* query: { where: "STATUS = 'OPEN'" },
|
|
61
|
+
* hover: true,
|
|
62
|
+
* onDiagnostics: (d) => console.log(d.strategy, d.featureCount),
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @experimental
|
|
67
|
+
*/
|
|
68
|
+
export declare function useMountedSource<T = Record<string, unknown>>(map: DataToMapLibreMap | null | undefined, source: Source<T> | null | undefined, options?: UseMountedSourceOptions<T>): UseMountedSourceResult<T>;
|
|
69
|
+
//# sourceMappingURL=use-mounted-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mounted-source.d.ts","sourceRoot":"","sources":["../../../src/react/use-mounted-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAGlB,aAAa,EACb,wBAAwB,EACzB,MAAM,8BAA8B,CAAC;AAOtC,0DAA0D;AAC1D,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC;IACjH,6FAA6F;IAC7F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oFAAoF;IACpF,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAChE,+EAA+E;IAC/E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAED,wDAAwD;AACxD,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACjE,6EAA6E;IAC7E,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAChC,yEAAyE;IACzE,WAAW,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAC7C,0DAA0D;IAC1D,KAAK,EAAE,OAAO,CAAC;IACf,2EAA2E;IAC3E,UAAU,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAyJD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1D,GAAG,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,EACzC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,GAAE,uBAAuB,CAAC,CAAC,CAAM,GACvC,sBAAsB,CAAC,CAAC,CAAC,CAgM3B"}
|