@honua/app-platform 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.
- package/app/index.d.ts.map +1 -1
- package/app/index.js +4 -0
- package/contract/types.d.ts +1 -1
- package/contract/types.d.ts.map +1 -1
- package/contract/types.js +4 -0
- package/core/client.d.ts +6 -0
- package/core/client.d.ts.map +1 -1
- package/core/client.js +11 -9
- package/core/error-classifications.d.ts +17 -0
- package/core/error-classifications.d.ts.map +1 -1
- package/core/error-classifications.js +17 -0
- package/core/error-code-registry.d.ts +18 -1
- package/core/error-code-registry.d.ts.map +1 -1
- package/core/error-code-registry.js +17 -0
- package/core/errors.d.ts +1 -1
- package/core/errors.d.ts.map +1 -1
- package/core/geoparquet-sql.d.ts +1 -1
- package/core/geoparquet-sql.js +2 -2
- package/core/stac.d.ts +2 -1
- package/core/stac.d.ts.map +1 -1
- package/core/stac.js +29 -11
- package/core/types.d.ts +15 -2
- package/core/types.d.ts.map +1 -1
- package/interactions/declarative-contract.d.ts +149 -0
- package/interactions/declarative-contract.d.ts.map +1 -0
- package/interactions/declarative-contract.js +293 -0
- package/interactions/declarative.d.ts +198 -0
- package/interactions/declarative.d.ts.map +1 -0
- package/interactions/declarative.js +470 -0
- package/interactions/feature-state.d.ts +7 -0
- package/interactions/feature-state.d.ts.map +1 -1
- package/interactions/feature-state.js +10 -2
- package/map/maplibre-target.js +1 -1
- package/package.json +2 -2
- package/realtime/sse.d.ts.map +1 -1
- package/realtime/sse.js +7 -1
- package/runtime/style-compose.d.ts.map +1 -1
- package/runtime/style-compose.js +78 -9
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@honua/sdk-js/interactions/declarative` — compiles a standard
|
|
3
|
+
* `interactions[]` block (geospatial-mcp ADR-0030) onto this SDK's existing
|
|
4
|
+
* imperative binding primitives.
|
|
5
|
+
*
|
|
6
|
+
* The standard constrains the *document*, not the dispatcher: "client
|
|
7
|
+
* runtimes implement dispatch by compiling bindings onto whatever imperative
|
|
8
|
+
* primitives they already have". That is exactly what this module does — it
|
|
9
|
+
* owns no event plumbing of its own, only a compile table from the closed
|
|
10
|
+
* (`on.event`, `do.verb`) vocabulary onto `createSelectionHandler`,
|
|
11
|
+
* `createHoverHandler`, `bindTableSelectionToExploration`,
|
|
12
|
+
* `bindFilterControlsToExploration`, and `subscribeExplorationSelector`.
|
|
13
|
+
*
|
|
14
|
+
* Three properties are load-bearing and asserted by the suite:
|
|
15
|
+
*
|
|
16
|
+
* 1. **Validate before binding.** `compileHonuaInteractions` runs the whole
|
|
17
|
+
* block through {@link validateHonuaInteractions} plus reference
|
|
18
|
+
* resolution against the components it was handed. A block with issues
|
|
19
|
+
* binds *nothing* — the standard rejects over-cap and malformed documents
|
|
20
|
+
* rather than truncating them.
|
|
21
|
+
* 2. **Actions never emit events.** A verb-driven state change must not
|
|
22
|
+
* re-enter the dispatcher. Two mechanisms enforce it: every compiled
|
|
23
|
+
* handler is skipped while an action is in flight (`#dispatching`), and
|
|
24
|
+
* exploration-backed subscriptions run with the view controller's default
|
|
25
|
+
* `includeSelf: false`, so a change this compiler originated is never
|
|
26
|
+
* delivered back to this compiler. There is no cycle detection because
|
|
27
|
+
* there can be no cycle.
|
|
28
|
+
* 3. **Unsupported pairs are named, never dropped.** When a binding's
|
|
29
|
+
* (`on.event`, `do.verb`) pair — or the component behind a ref — has no
|
|
30
|
+
* primitive to compile onto, it lands in
|
|
31
|
+
* {@link HonuaCompiledInteractions.unsupported} with the pair spelled out,
|
|
32
|
+
* so a host can surface a real "this runtime cannot honor that binding"
|
|
33
|
+
* message instead of silently rendering an inert app.
|
|
34
|
+
*
|
|
35
|
+
* @experimental The compiler surface tracks geospatial-mcp ADR-0030 while
|
|
36
|
+
* that ADR is Proposed; the component-adapter shapes may gain fields.
|
|
37
|
+
*
|
|
38
|
+
* @module
|
|
39
|
+
*/
|
|
40
|
+
import { sourceFeatureSelectionTarget } from "../exploration/selection.js";
|
|
41
|
+
import { subscribeExplorationSelector } from "../exploration/selectors.js";
|
|
42
|
+
import { bindFilterControlsToExploration, bindTableSelectionToExploration } from "./exploration-bindings.js";
|
|
43
|
+
import { createHoverHandler, createSelectionHandler } from "./feature-state.js";
|
|
44
|
+
import { parseHonuaInteractionRef, resolveHonuaInteractionArgs, validateHonuaInteractions, } from "./declarative-contract.js";
|
|
45
|
+
export * from "./declarative-contract.js";
|
|
46
|
+
// ── Compiler ──────────────────────────────────────────────────
|
|
47
|
+
const EMPTY_RESULT_BASE = { bindings: [], disabled: [] };
|
|
48
|
+
/**
|
|
49
|
+
* Compiles an `interactions[]` block onto live components. Returns disposers;
|
|
50
|
+
* never throws for a bad document — a malformed or over-cap block comes back
|
|
51
|
+
* as `{ ok: false, issues }` with nothing bound.
|
|
52
|
+
*/
|
|
53
|
+
export function compileHonuaInteractions(interactions, options) {
|
|
54
|
+
const validation = validateHonuaInteractions(interactions, {
|
|
55
|
+
...(options.fanOutCap !== undefined ? { fanOutCap: options.fanOutCap } : {}),
|
|
56
|
+
});
|
|
57
|
+
const components = options.components ?? {};
|
|
58
|
+
const declared = Array.isArray(interactions) ? interactions : [];
|
|
59
|
+
const refIssues = validation.ok ? resolveReferenceIssues(declared, components) : [];
|
|
60
|
+
const issues = [...validation.issues, ...refIssues];
|
|
61
|
+
if (issues.length > 0) {
|
|
62
|
+
return {
|
|
63
|
+
ok: false,
|
|
64
|
+
issues,
|
|
65
|
+
...EMPTY_RESULT_BASE,
|
|
66
|
+
unsupported: [],
|
|
67
|
+
dispose: () => undefined,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const compiler = new InteractionCompiler(options, components);
|
|
71
|
+
for (const interaction of declared)
|
|
72
|
+
compiler.compile(interaction);
|
|
73
|
+
return compiler.result();
|
|
74
|
+
}
|
|
75
|
+
function resolveReferenceIssues(interactions, components) {
|
|
76
|
+
const issues = [];
|
|
77
|
+
interactions.forEach((interaction, index) => {
|
|
78
|
+
for (const side of ["on", "do"]) {
|
|
79
|
+
const ref = interaction[side].ref;
|
|
80
|
+
if (resolveComponent(ref, components) !== undefined)
|
|
81
|
+
continue;
|
|
82
|
+
issues.push({
|
|
83
|
+
code: "invalid-ref",
|
|
84
|
+
interactionId: interaction.id,
|
|
85
|
+
path: `interactions[${index}].${side}.ref`,
|
|
86
|
+
message: `\`${ref}\` does not resolve to a declared component.`,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return issues;
|
|
91
|
+
}
|
|
92
|
+
function resolveComponent(ref, components) {
|
|
93
|
+
const parsed = parseHonuaInteractionRef(ref);
|
|
94
|
+
if (!parsed)
|
|
95
|
+
return undefined;
|
|
96
|
+
if (parsed.kind === "map") {
|
|
97
|
+
return components.map ? { kind: "map", id: "map", component: components.map } : undefined;
|
|
98
|
+
}
|
|
99
|
+
const id = parsed.id;
|
|
100
|
+
const table = {
|
|
101
|
+
layer: components.layers,
|
|
102
|
+
widget: components.widgets,
|
|
103
|
+
control: components.controls,
|
|
104
|
+
};
|
|
105
|
+
const component = table[parsed.kind]?.[id];
|
|
106
|
+
if (!component)
|
|
107
|
+
return undefined;
|
|
108
|
+
return { kind: parsed.kind, id, component };
|
|
109
|
+
}
|
|
110
|
+
class InteractionCompiler {
|
|
111
|
+
#view;
|
|
112
|
+
#components;
|
|
113
|
+
#onDispatch;
|
|
114
|
+
#bindings = [];
|
|
115
|
+
#unsupported = [];
|
|
116
|
+
#disabled = [];
|
|
117
|
+
/** Re-entrancy guard: an event delivered while an action runs is dropped (actions never emit events). */
|
|
118
|
+
#dispatching = false;
|
|
119
|
+
#disposed = false;
|
|
120
|
+
constructor(options, components) {
|
|
121
|
+
this.#view = options.view;
|
|
122
|
+
this.#components = components;
|
|
123
|
+
this.#onDispatch = options.onDispatch;
|
|
124
|
+
}
|
|
125
|
+
compile(interaction) {
|
|
126
|
+
if (interaction.disabled === true) {
|
|
127
|
+
this.#disabled.push(interaction.id);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const source = resolveComponent(interaction.on.ref, this.#components);
|
|
131
|
+
const target = resolveComponent(interaction.do.ref, this.#components);
|
|
132
|
+
const action = this.#compileAction(interaction, target);
|
|
133
|
+
if (typeof action === "string") {
|
|
134
|
+
this.#reject(interaction, action);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const dispose = this.#compileEvent(interaction, source, action);
|
|
138
|
+
if (typeof dispose === "string") {
|
|
139
|
+
this.#reject(interaction, dispose);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
let released = false;
|
|
143
|
+
this.#bindings.push({
|
|
144
|
+
interactionId: interaction.id,
|
|
145
|
+
on: { ref: interaction.on.ref, event: interaction.on.event },
|
|
146
|
+
do: { ref: interaction.do.ref, verb: interaction.do.verb },
|
|
147
|
+
pair: pairLabel(interaction),
|
|
148
|
+
dispose: () => {
|
|
149
|
+
if (released)
|
|
150
|
+
return;
|
|
151
|
+
released = true;
|
|
152
|
+
dispose();
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
result() {
|
|
157
|
+
const bindings = [...this.#bindings];
|
|
158
|
+
return {
|
|
159
|
+
ok: this.#unsupported.length === 0,
|
|
160
|
+
issues: [],
|
|
161
|
+
bindings,
|
|
162
|
+
unsupported: [...this.#unsupported],
|
|
163
|
+
disabled: [...this.#disabled],
|
|
164
|
+
dispose: () => {
|
|
165
|
+
if (this.#disposed)
|
|
166
|
+
return;
|
|
167
|
+
this.#disposed = true;
|
|
168
|
+
for (const binding of bindings)
|
|
169
|
+
binding.dispose();
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
#reject(interaction, reason) {
|
|
174
|
+
this.#unsupported.push({
|
|
175
|
+
interactionId: interaction.id,
|
|
176
|
+
on: { ref: interaction.on.ref, event: interaction.on.event },
|
|
177
|
+
do: { ref: interaction.do.ref, verb: interaction.do.verb },
|
|
178
|
+
pair: pairLabel(interaction),
|
|
179
|
+
reason,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
// ── Event side ──────────────────────────────────────────────
|
|
183
|
+
/** Returns a disposer, or a string reason the pair is unsupported. */
|
|
184
|
+
#compileEvent(interaction, source, action) {
|
|
185
|
+
const emit = (payload) => {
|
|
186
|
+
if (this.#disposed || this.#dispatching)
|
|
187
|
+
return;
|
|
188
|
+
this.#dispatching = true;
|
|
189
|
+
try {
|
|
190
|
+
action(payload);
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
this.#dispatching = false;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
switch (interaction.on.event) {
|
|
197
|
+
case "featureSelect": {
|
|
198
|
+
if (source.kind !== "layer")
|
|
199
|
+
return `\`featureSelect\` is a layer event; \`${interaction.on.ref}\` is not a layer.`;
|
|
200
|
+
const map = source.component.map;
|
|
201
|
+
if (!map)
|
|
202
|
+
return `Layer "${source.id}" declares no \`map\`, so \`featureSelect\` has no primitive to bind to.`;
|
|
203
|
+
const sourceId = source.component.sourceId ?? source.id;
|
|
204
|
+
const handle = createSelectionHandler(map, {
|
|
205
|
+
source: sourceId,
|
|
206
|
+
layer: source.component.layerId ?? source.id,
|
|
207
|
+
...(source.component.sourceLayer ? { sourceLayer: source.component.sourceLayer } : {}),
|
|
208
|
+
...(source.component.multiSelect !== undefined ? { multiSelect: source.component.multiSelect } : {}),
|
|
209
|
+
onSelectionTargetsChange: (targets) => emit(featureSelectPayload(sourceId, targets)),
|
|
210
|
+
});
|
|
211
|
+
return () => handle.remove();
|
|
212
|
+
}
|
|
213
|
+
case "featureHover": {
|
|
214
|
+
if (source.kind !== "layer")
|
|
215
|
+
return `\`featureHover\` is a layer event; \`${interaction.on.ref}\` is not a layer.`;
|
|
216
|
+
const map = source.component.map;
|
|
217
|
+
if (!map)
|
|
218
|
+
return `Layer "${source.id}" declares no \`map\`, so \`featureHover\` has no primitive to bind to.`;
|
|
219
|
+
const sourceId = source.component.sourceId ?? source.id;
|
|
220
|
+
const handle = createHoverHandler(map, {
|
|
221
|
+
source: sourceId,
|
|
222
|
+
layer: source.component.layerId ?? source.id,
|
|
223
|
+
...(source.component.sourceLayer ? { sourceLayer: source.component.sourceLayer } : {}),
|
|
224
|
+
onHoverTargetChange: (hovered) => emit(featureHoverPayload(sourceId, hovered)),
|
|
225
|
+
});
|
|
226
|
+
return () => handle.remove();
|
|
227
|
+
}
|
|
228
|
+
case "selection": {
|
|
229
|
+
if (source.kind !== "widget")
|
|
230
|
+
return `\`selection\` is a widget event; \`${interaction.on.ref}\` is not a widget.`;
|
|
231
|
+
// Compiled onto the table/grid selection primitive: a widget publishes
|
|
232
|
+
// and observes selection through the shared exploration slice.
|
|
233
|
+
const unsubscribe = bindTableSelectionToExploration(this.#view).subscribe((selection) => emit(selectionPayload(selection)));
|
|
234
|
+
return unsubscribe;
|
|
235
|
+
}
|
|
236
|
+
case "change": {
|
|
237
|
+
if (source.kind !== "control")
|
|
238
|
+
return `\`change\` is a control event; \`${interaction.on.ref}\` is not a control.`;
|
|
239
|
+
// Compiled onto the filter-control primitive, keyed by the control's
|
|
240
|
+
// own id — the same key `bindFilterControlsToExploration().setFilter`
|
|
241
|
+
// writes, so a filter bar built on that primitive needs no adapter.
|
|
242
|
+
const controlId = source.id;
|
|
243
|
+
let previous = this.#view.state.filters[controlId];
|
|
244
|
+
const unsubscribe = bindFilterControlsToExploration(this.#view).subscribe((filters) => {
|
|
245
|
+
const clause = filters[controlId];
|
|
246
|
+
if (clause === previous)
|
|
247
|
+
return;
|
|
248
|
+
previous = clause;
|
|
249
|
+
emit(changePayload(controlId, clause, filters));
|
|
250
|
+
});
|
|
251
|
+
return unsubscribe;
|
|
252
|
+
}
|
|
253
|
+
case "viewportChange": {
|
|
254
|
+
if (source.kind !== "map")
|
|
255
|
+
return "`viewportChange` is a map event; only `map` publishes it.";
|
|
256
|
+
// Compiled onto the shared extent slice — the slice
|
|
257
|
+
// `bindMapExtentToExploration` publishes into.
|
|
258
|
+
const unsubscribe = subscribeExplorationSelector(this.#view, "extent", (state) => state.extent, (extent) => emit(viewportPayload(extent)), { fireImmediately: false });
|
|
259
|
+
return unsubscribe;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// ── Action side ─────────────────────────────────────────────
|
|
264
|
+
/** Returns an action, or a string reason the pair is unsupported. */
|
|
265
|
+
#compileAction(interaction, target) {
|
|
266
|
+
const verb = interaction.do.verb;
|
|
267
|
+
const declaredArgs = interaction.do.args;
|
|
268
|
+
const observe = (args) => {
|
|
269
|
+
this.#onDispatch?.({
|
|
270
|
+
interactionId: interaction.id,
|
|
271
|
+
event: interaction.on.event,
|
|
272
|
+
verb,
|
|
273
|
+
ref: interaction.do.ref,
|
|
274
|
+
args,
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
switch (verb) {
|
|
278
|
+
case "setFilter": {
|
|
279
|
+
const setFilter = componentSetFilter(target);
|
|
280
|
+
const filterId = target.kind === "map" ? "map" : target.id;
|
|
281
|
+
return (payload) => {
|
|
282
|
+
const args = resolveHonuaInteractionArgs(declaredArgs, payload);
|
|
283
|
+
const clause = filterClauseFromArgs(args);
|
|
284
|
+
if (setFilter)
|
|
285
|
+
setFilter(clause);
|
|
286
|
+
else if (clause)
|
|
287
|
+
this.#view.setFilter(filterId, clause);
|
|
288
|
+
else
|
|
289
|
+
this.#view.clearFilter(filterId);
|
|
290
|
+
observe(args);
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
case "setViewport": {
|
|
294
|
+
if (target.kind !== "map")
|
|
295
|
+
return "`setViewport` targets `map`; no other component accepts it.";
|
|
296
|
+
const component = target.component;
|
|
297
|
+
return (payload) => {
|
|
298
|
+
const args = resolveHonuaInteractionArgs(declaredArgs, payload);
|
|
299
|
+
const viewport = viewportFromArgs(args);
|
|
300
|
+
if (component.setViewport)
|
|
301
|
+
component.setViewport(viewport);
|
|
302
|
+
else
|
|
303
|
+
this.#view.setExtent(extentFromBbox(viewport.bbox));
|
|
304
|
+
observe(args);
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
case "selectFeature": {
|
|
308
|
+
if (target.kind === "control")
|
|
309
|
+
return "`selectFeature` has no control-side primitive.";
|
|
310
|
+
const fallbackSourceId = target.kind === "layer" ? (target.component.sourceId ?? target.id) : target.id;
|
|
311
|
+
const selection = bindTableSelectionToExploration(this.#view);
|
|
312
|
+
return (payload) => {
|
|
313
|
+
const args = resolveHonuaInteractionArgs(declaredArgs, payload);
|
|
314
|
+
const featureId = args.featureId ?? args.id;
|
|
315
|
+
if (featureId === undefined || featureId === null) {
|
|
316
|
+
selection.clearSelection();
|
|
317
|
+
observe(args);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
const sourceId = typeof args.sourceId === "string" ? args.sourceId : fallbackSourceId;
|
|
321
|
+
const target_ = sourceFeatureSelectionTarget(sourceId, featureId);
|
|
322
|
+
selection.select([target_], { replace: args.replace !== false });
|
|
323
|
+
observe(args);
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
case "runWidgetQuery": {
|
|
327
|
+
if (target.kind !== "widget")
|
|
328
|
+
return "`runWidgetQuery` targets `widget:{id}`; no other component accepts it.";
|
|
329
|
+
const runQuery = target.component.runQuery;
|
|
330
|
+
if (!runQuery) {
|
|
331
|
+
return `Widget "${target.id}" declares no \`runQuery\`, and there is no exploration-level fallback for \`runWidgetQuery\`.`;
|
|
332
|
+
}
|
|
333
|
+
return (payload) => {
|
|
334
|
+
const args = resolveHonuaInteractionArgs(declaredArgs, payload);
|
|
335
|
+
runQuery(args);
|
|
336
|
+
observe(args);
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
case "setVisibility": {
|
|
340
|
+
if (target.kind === "map")
|
|
341
|
+
return "`setVisibility` targets a layer, widget, or control, never `map`.";
|
|
342
|
+
const setVisibility = target.component.setVisibility;
|
|
343
|
+
if (!setVisibility) {
|
|
344
|
+
return `${target.kind === "layer" ? "Layer" : target.kind === "widget" ? "Widget" : "Control"} "${target.id}" declares no \`setVisibility\`.`;
|
|
345
|
+
}
|
|
346
|
+
return (payload) => {
|
|
347
|
+
const args = resolveHonuaInteractionArgs(declaredArgs, payload);
|
|
348
|
+
setVisibility(args.visible !== false);
|
|
349
|
+
observe(args);
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// ── Payload builders ──────────────────────────────────────────
|
|
356
|
+
function featureSelectPayload(sourceId, targets) {
|
|
357
|
+
const first = targets[0];
|
|
358
|
+
return {
|
|
359
|
+
sourceId: first?.sourceId ?? sourceId,
|
|
360
|
+
...(first ? { featureId: first.id } : {}),
|
|
361
|
+
...(first?.sourceLayer ? { sourceLayer: first.sourceLayer } : {}),
|
|
362
|
+
targets,
|
|
363
|
+
count: targets.length,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function featureHoverPayload(sourceId, hovered) {
|
|
367
|
+
return {
|
|
368
|
+
sourceId: hovered?.sourceId ?? sourceId,
|
|
369
|
+
...(hovered ? { featureId: hovered.id } : {}),
|
|
370
|
+
...(hovered?.sourceLayer ? { sourceLayer: hovered.sourceLayer } : {}),
|
|
371
|
+
...(hovered ? { target: hovered } : {}),
|
|
372
|
+
hovering: hovered !== undefined,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
function selectionPayload(selection) {
|
|
376
|
+
const first = selection[0];
|
|
377
|
+
const qualified = typeof first === "object" && first !== null ? first : undefined;
|
|
378
|
+
return {
|
|
379
|
+
targets: selection,
|
|
380
|
+
count: selection.length,
|
|
381
|
+
...(qualified ? { sourceId: qualified.sourceId, featureId: qualified.id } : {}),
|
|
382
|
+
...(qualified === undefined && first !== undefined ? { featureId: first } : {}),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
function changePayload(id, clause, filters) {
|
|
386
|
+
return {
|
|
387
|
+
id,
|
|
388
|
+
...(clause ? { field: clause.field, operator: clause.operator, value: clause.value, clause } : {}),
|
|
389
|
+
filters,
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
function viewportPayload(extent) {
|
|
393
|
+
return {
|
|
394
|
+
...(extent ? { bbox: [extent.xmin, extent.ymin, extent.xmax, extent.ymax], extent } : {}),
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
// ── Argument projection ───────────────────────────────────────
|
|
398
|
+
function componentSetFilter(target) {
|
|
399
|
+
if (target.kind === "map")
|
|
400
|
+
return undefined;
|
|
401
|
+
const setFilter = target.component.setFilter;
|
|
402
|
+
return setFilter ? (clause) => setFilter(clause) : undefined;
|
|
403
|
+
}
|
|
404
|
+
const FILTER_OPERATORS = new Set([
|
|
405
|
+
"=",
|
|
406
|
+
"!=",
|
|
407
|
+
"<",
|
|
408
|
+
"<=",
|
|
409
|
+
">",
|
|
410
|
+
">=",
|
|
411
|
+
"in",
|
|
412
|
+
"not-in",
|
|
413
|
+
"between",
|
|
414
|
+
"like",
|
|
415
|
+
"is-null",
|
|
416
|
+
"is-not-null",
|
|
417
|
+
]);
|
|
418
|
+
function filterClauseFromArgs(args) {
|
|
419
|
+
const declared = args.clause;
|
|
420
|
+
if (declared && typeof declared === "object" && !Array.isArray(declared)) {
|
|
421
|
+
const clause = declared;
|
|
422
|
+
if (typeof clause.field === "string") {
|
|
423
|
+
return {
|
|
424
|
+
field: clause.field,
|
|
425
|
+
operator: FILTER_OPERATORS.has(clause.operator) ? clause.operator : "=",
|
|
426
|
+
value: clause.value,
|
|
427
|
+
...(Array.isArray(clause.appliesTo) ? { appliesTo: clause.appliesTo } : {}),
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (typeof args.field !== "string")
|
|
432
|
+
return undefined;
|
|
433
|
+
// A `$event.*` path that resolved to nothing clears the filter rather than
|
|
434
|
+
// installing an `= undefined` clause nothing can translate.
|
|
435
|
+
if (args.value === undefined && !isValuelessOperator(args.operator))
|
|
436
|
+
return undefined;
|
|
437
|
+
return {
|
|
438
|
+
field: args.field,
|
|
439
|
+
operator: FILTER_OPERATORS.has(args.operator) ? args.operator : "=",
|
|
440
|
+
value: args.value,
|
|
441
|
+
...(Array.isArray(args.appliesTo) ? { appliesTo: args.appliesTo } : {}),
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
function isValuelessOperator(operator) {
|
|
445
|
+
return operator === "is-null" || operator === "is-not-null";
|
|
446
|
+
}
|
|
447
|
+
function viewportFromArgs(args) {
|
|
448
|
+
const bbox = numberTuple(args.bbox, 4);
|
|
449
|
+
const center = numberTuple(args.center, 2);
|
|
450
|
+
return {
|
|
451
|
+
...(bbox ? { bbox } : {}),
|
|
452
|
+
...(center ? { center } : {}),
|
|
453
|
+
...(typeof args.zoom === "number" ? { zoom: args.zoom } : {}),
|
|
454
|
+
...(typeof args.pitch === "number" ? { pitch: args.pitch } : {}),
|
|
455
|
+
...(typeof args.bearing === "number" ? { bearing: args.bearing } : {}),
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
function numberTuple(value, length) {
|
|
459
|
+
if (!Array.isArray(value) || value.length !== length)
|
|
460
|
+
return undefined;
|
|
461
|
+
return value.every((entry) => typeof entry === "number" && Number.isFinite(entry))
|
|
462
|
+
? value
|
|
463
|
+
: undefined;
|
|
464
|
+
}
|
|
465
|
+
function extentFromBbox(bbox) {
|
|
466
|
+
return bbox ? { xmin: bbox[0], ymin: bbox[1], xmax: bbox[2], ymax: bbox[3] } : undefined;
|
|
467
|
+
}
|
|
468
|
+
function pairLabel(interaction) {
|
|
469
|
+
return `${interaction.on.event} -> ${interaction.do.verb}`;
|
|
470
|
+
}
|
|
@@ -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":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,yBAAyB,CAAC;AAIrF,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,eAAe,CACb,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EACrE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,IAAI,CAAC;IACR,eAAe,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChH,kBAAkB,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/G;AAED,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,EAAE,CACA,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EACvD,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GACrC,IAAI,CAAC;IACR,GAAG,CACD,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EACvD,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GACrC,IAAI,CAAC;CACT;AAED,yDAAyD;AACzD,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,cAAc,CAAC;AAI9D,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,GAAG,MAAM,EACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAEN;AAED,uCAAuC;AACvC,wBAAgB,eAAe,CAC7B,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,GAAG,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,GAAG,MAAM,EACnB,GAAG,CAAC,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAEN;AAID,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IAClC,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"feature-state.d.ts","sourceRoot":"","sources":["../../../src/interactions/feature-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,yBAAyB,CAAC;AAIrF,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,eAAe,CACb,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EACrE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,IAAI,CAAC;IACR,eAAe,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChH,kBAAkB,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/G;AAED,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,EAAE,CACA,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EACvD,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GACrC,IAAI,CAAC;IACR,GAAG,CACD,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EACvD,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GACrC,IAAI,CAAC;CACT;AAED,yDAAyD;AACzD,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,cAAc,CAAC;AAI9D,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,GAAG,MAAM,EACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAEN;AAED,uCAAuC;AACvC,wBAAgB,eAAe,CAC7B,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,GAAG,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,GAAG,MAAM,EACnB,GAAG,CAAC,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAEN;AAID,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IAClC,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,qCAAqC,GAAG,SAAS,KAAK,IAAI,CAAC;CAC5F;AAED,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,MAAM,IAAI,IAAI,CAAC;IACf,wDAAwD;IACxD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACjD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,mBAAmB,GAAG,WAAW,CA2CjG;AAID,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACtC,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAC/D,8DAA8D;IAC9D,wBAAwB,CAAC,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC,qCAAqC,CAAC,KAAK,IAAI,CAAC;CAC5G;AAED,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,MAAM,IAAI,IAAI,CAAC;IACf,iDAAiD;IACjD,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACnD,sDAAsD;IACtD,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC,qCAAqC,CAAC,CAAC;IAC/E,4CAA4C;IAC5C,cAAc,IAAI,IAAI,CAAC;IACvB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,iDAAiD;IACjD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,uBAAuB,GAAG,eAAe,CAkF7G"}
|
|
@@ -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
|
-
|
|
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);
|
package/map/maplibre-target.js
CHANGED
|
@@ -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
|
-
|
|
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/app-platform",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7-beta.0",
|
|
4
4
|
"description": "Honua application-platform surfaces: app-shell, workspace, scene, operator, studio, and hosted-product clients",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gis",
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"proj4": "^2.20.9"
|
|
120
120
|
},
|
|
121
121
|
"peerDependencies": {
|
|
122
|
-
"@honua/sdk": "0.1.
|
|
122
|
+
"@honua/sdk": "0.1.7-beta.0",
|
|
123
123
|
"maplibre-gl": "^5.0.0 || ^6.0.0",
|
|
124
124
|
"cesium": "^1.139.0"
|
|
125
125
|
},
|
package/realtime/sse.d.ts.map
CHANGED
|
@@ -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,
|
|
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) =>
|
|
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,
|
|
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"}
|