@emuanalytics/flow-rdf-core 4.0.3 → 4.0.5

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.
Files changed (89) hide show
  1. package/README.md +1 -64
  2. package/dist/index.d.mts +36 -31
  3. package/dist/index.d.ts +36 -31
  4. package/dist/index.mjs +20 -3249
  5. package/dist/lib/context/context-registry.mjs +63 -0
  6. package/dist/lib/context/debugger.mjs +240 -0
  7. package/dist/lib/context/flow-context.mjs +61 -0
  8. package/dist/lib/context/global-state.mjs +70 -0
  9. package/dist/lib/context/map-registry.mjs +59 -0
  10. package/dist/lib/context/query-registry.mjs +53 -0
  11. package/dist/lib/errors/flow-error.mjs +10 -0
  12. package/dist/lib/errors/flow-expression-error.mjs +14 -0
  13. package/dist/lib/errors/flow-map-error.mjs +9 -0
  14. package/dist/lib/expressions/expression-parser.mjs +198 -0
  15. package/dist/lib/expressions/functions/from-palette.mjs +75 -0
  16. package/dist/lib/expressions/functions/regex.mjs +25 -0
  17. package/dist/lib/expressions/functions/state.mjs +25 -0
  18. package/dist/lib/expressions/parser-helpers.mjs +37 -0
  19. package/dist/lib/expressions/reactive-expression.mjs +253 -0
  20. package/dist/lib/map/flow-core-map.mjs +749 -0
  21. package/dist/lib/map/plugins/annotations/annotation-layers.mjs +163 -0
  22. package/dist/lib/map/plugins/annotations/annotation.events.mjs +27 -0
  23. package/dist/lib/map/plugins/annotations/annotation.plugin.mjs +498 -0
  24. package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/modes/DirectModeOverride.mjs +67 -0
  25. package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/modes/DragCircleMode.mjs +65 -0
  26. package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/utils/create_supplementary_points_circle.mjs +15 -0
  27. package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/utils/drag_pan.mjs +20 -0
  28. package/dist/lib/map/plugins/data-join.plugin.mjs +173 -0
  29. package/dist/lib/map/plugins/export/export.plugin.mjs +21 -0
  30. package/dist/lib/map/plugins/export/map-exporter.mjs +177 -0
  31. package/dist/lib/map/plugins/hover-effect.plugin.mjs +58 -0
  32. package/dist/lib/map/plugins/index.d.mts +37 -72
  33. package/dist/lib/map/plugins/index.d.ts +37 -72
  34. package/dist/lib/map/plugins/index.mjs +11 -1811
  35. package/dist/lib/map/plugins/keyboard-shortcut-manager.mjs +120 -0
  36. package/dist/lib/map/plugins/map-plugin-base.mjs +25 -0
  37. package/dist/lib/map/plugins/plugin-manager.mjs +135 -0
  38. package/dist/lib/map/plugins/popup.plugin.mjs +55 -0
  39. package/dist/lib/map/plugins/selection/selection.events.mjs +21 -0
  40. package/dist/lib/map/plugins/selection/selection.plugin.mjs +136 -0
  41. package/dist/lib/map/plugins/selection/source-selection.mjs +156 -0
  42. package/dist/lib/map/plugins/url-sync.plugin.mjs +55 -0
  43. package/dist/lib/map/support/image-registry.mjs +82 -0
  44. package/dist/lib/map/support/map-events.mjs +71 -0
  45. package/dist/lib/map/support/map-feature-stream.mjs +158 -0
  46. package/dist/lib/map/support/map-popup.mjs +159 -0
  47. package/dist/lib/map/types.mjs +7 -0
  48. package/dist/lib/map-style/map-data-source.mjs +192 -0
  49. package/dist/lib/map-style/map-layer-style-builder-generated.mjs +1307 -0
  50. package/dist/lib/map-style/map-layer-style-builder.mjs +86 -0
  51. package/dist/lib/map-style/map-layer.mjs +223 -0
  52. package/dist/lib/map-style/map-style.mjs +178 -0
  53. package/dist/lib/queries/async-committer.mjs +30 -0
  54. package/dist/lib/queries/query.mjs +172 -0
  55. package/dist/lib/state-store/decorators.mjs +83 -0
  56. package/dist/lib/state-store/state-store.mjs +534 -0
  57. package/dist/lib/state-store/utils.mjs +7 -0
  58. package/dist/lib/utils/announce.mjs +12 -0
  59. package/dist/lib/utils/assert.mjs +12 -0
  60. package/dist/{shared/flow-rdf-core.187cb345.mjs → lib/utils/debounce.mjs} +3 -39
  61. package/dist/lib/utils/decorators.mjs +59 -0
  62. package/dist/lib/utils/deferred.mjs +11 -0
  63. package/dist/lib/utils/ensure-array.mjs +16 -0
  64. package/dist/{shared/flow-rdf-core.1f0901c5.mjs → lib/utils/feature-type-checks.mjs} +2 -2
  65. package/dist/lib/utils/functional.mjs +22 -0
  66. package/dist/lib/utils/global.mjs +18 -0
  67. package/dist/lib/utils/index.mjs +8 -5
  68. package/dist/lib/utils/random-id.mjs +9 -0
  69. package/dist/lib/utils/string-utils.mjs +3 -0
  70. package/dist/lib/utils/throttle.mjs +20 -0
  71. package/dist/{shared/flow-rdf-core.25e5f6d7.mjs → lib/utils/type-checks.mjs} +1 -26
  72. package/dist/lib/utils/watchable-promise.mjs +55 -0
  73. package/dist/package.json.mjs +3 -0
  74. package/dist/shared/{flow-rdf-core.4dde996e.d.cts → flow-rdf-core.8b5acf14.d.mts} +1315 -172
  75. package/dist/shared/{flow-rdf-core.4dde996e.d.ts → flow-rdf-core.8b5acf14.d.ts} +1315 -172
  76. package/package.json +4 -8
  77. package/dist/index.cjs +0 -3316
  78. package/dist/index.d.cts +0 -90
  79. package/dist/lib/map/plugins/index.cjs +0 -1851
  80. package/dist/lib/map/plugins/index.d.cts +0 -345
  81. package/dist/lib/utils/index.cjs +0 -48
  82. package/dist/lib/utils/index.d.cts +0 -160
  83. package/dist/shared/flow-rdf-core.06e85a6c.cjs +0 -1394
  84. package/dist/shared/flow-rdf-core.4dde996e.d.mts +0 -1916
  85. package/dist/shared/flow-rdf-core.55c169ca.cjs +0 -150
  86. package/dist/shared/flow-rdf-core.63162669.d.cts +0 -10
  87. package/dist/shared/flow-rdf-core.65045caf.mjs +0 -1360
  88. package/dist/shared/flow-rdf-core.a82b9be4.cjs +0 -34
  89. package/dist/shared/flow-rdf-core.f50908f0.cjs +0 -102
@@ -1,7 +1,8 @@
1
+ import EventEmitter$1, { EventEmitter } from 'eventemitter3';
2
+ import * as lit from 'lit-html';
1
3
  import { Client } from '@emuanalytics/flow-engine-client';
2
4
  import { ISubscription, IObservableStream, IDisposer } from 'mobx-utils';
3
5
  import { MapLibreEvent, MapMouseEvent as MapMouseEvent$1, MapOptions as MapOptions$1, Map } from '@emuanalytics/maplibre-gl';
4
- import EventEmitter$1, { EventEmitter } from 'eventemitter3';
5
6
 
6
7
  type Annotation = {
7
8
  annotationType: string;
@@ -18,43 +19,497 @@ type Path<T, TBase = Record<string, unknown>> = PathImpl<T, TBase, StoreKey<T, T
18
19
  type PathValue<T, P extends Path<T, TBase>, TBase = Record<string, unknown>> = P extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? Rest extends Path<T[Key], TBase> ? PathValue<T[Key], Rest, TBase> : never : never : P extends keyof T ? T[P] : never;
19
20
 
20
21
  type StoreConstructor<T extends StateStore> = new () => T;
22
+ /**
23
+ * Store annotations are used when extending the {@link StateStore} class to mark state properties
24
+ * as observable, computed, and/or serializable.
25
+ *
26
+ * Annotations can be applied as decorators when using TypeScript or by passing an object to
27
+ * the {@link StateStore.initialize} method.
28
+ *
29
+ * Available annotations:
30
+ *
31
+ * | Annotation | Remarks |
32
+ * | ------------------- | -------------------------- |
33
+ * | `observable` | alias for `observable.deep` |
34
+ * | `obervable.deep` | Mark property as deeply observable. Child properties of objects and array elements will be recursively marked as observable. |
35
+ * | `obervable.ref` | Mark property as observable. Track changes using strict `===` equality. Use this as an optimization for immutable object properties and arrays. The _value_ of the property is ignored, only its strict identity is considered. |
36
+ * | `obervable.shallow` | Mark collection as observable. The collection itself is observable (reacting to inserts, deletions etc.), but the contents of the collection are not marked as observable. |
37
+ * | `obervable.struct` | Mark object or array as observable. Assigning a new value that is _structurally_ equal to the old value will not trigger a reactive update. |
38
+ * | `computed` | Mark a getter as a computed property. Computed properties are lazily evaluated and memoized. |
39
+ * | `serialize` | Mark a property as serializable. The property will be included in the serialized output of {@link StateStore.serialize}. |
40
+ * | `action` | Mark a method as an _action_. Use this annotation for helper methods you declare on your derived {@link StateStore} class that modify state. The method will automatically be run in a transaction and can reduce the number of reactive updates triggered when modifying multiple observable properties. |
41
+ *
42
+ * @example
43
+ * Using annotations in JavaScript:
44
+ *```js
45
+ * import {
46
+ * observable,
47
+ * serialize,
48
+ * computed,
49
+ * StateStore
50
+ * } from '@emuanalytics/flow-rdf-core';
51
+ *
52
+ * // Declare a state store using annotations
53
+ * class AppState extends StateStore {
54
+ * constructor() {
55
+ * super();
56
+ * this.initialize({
57
+ * a: [observable, serialize],
58
+ * b: [observable],
59
+ * c: [computed],
60
+ * d: [observable.ref],
61
+ * helperMethod: [action]
62
+ * });
63
+ * }
64
+ *
65
+ * a = 'a value';
66
+ * b = 2;
67
+ *
68
+ * get c() {
69
+ * return `${this.a} - ${this.b}`;
70
+ * }
71
+ *
72
+ * d = { a: 1, b: 2 };
73
+ *
74
+ * // This method will be run in a transaction
75
+ * helperMethod(val) {
76
+ * this.a = val;
77
+ * this.increment('b');
78
+ * }
79
+ * }
80
+ * ```
81
+ *
82
+ * @example
83
+ * Using TypeScript decorators:
84
+ *```js
85
+ * import {
86
+ * observable,
87
+ * serialize,
88
+ * computed,
89
+ * StateStore
90
+ * } from '@emuanalytics/flow-rdf-core';
91
+ *
92
+ * // Declare a state store using annotations
93
+ * class AppState extends StateStore {
94
+ * constructor() {
95
+ * super();
96
+ * this.initialize();
97
+ * }
98
+ *
99
+ * @serialize
100
+ * @observable
101
+ * a = 'a value';
102
+ *
103
+ * @observable
104
+ * b = 2;
105
+ *
106
+ * @computed
107
+ * get c() {
108
+ * return `${this.a} - ${this.b}`;
109
+ * }
110
+ *
111
+ * @observable.ref
112
+ * d = { a: 1, b: 2 };
113
+ *
114
+ * // This method will be run in a transaction
115
+ * @action
116
+ * helperMethod(val) {
117
+ * this.a = val;
118
+ * this.increment('b');
119
+ * }
120
+ * }
121
+ * ```
122
+ */
21
123
  type StoreAnnotations<T extends StateStore> = {
22
124
  [P in StoreKey<T, StateStore>]?: Annotation | Annotation[];
23
125
  };
24
126
  type SerializationFormat = 'raw' | 'json' | 'lz';
127
+ /**
128
+ * State stores define reactive application state and are the basis of Flo.w RDF's reactive functionality.
129
+ *
130
+ * In typical usage, the {@link StateStore} class is extended to define an application-specific
131
+ * state store and a singleton instance is created to manage application state. The application-specific
132
+ * class defines which state properties are available, their initial values, their types (when using TypeScript), and
133
+ * whether they are serialized.
134
+ *
135
+ * Properties of the application-specific state store can be marked as `observable` using decorators or annotations.
136
+ * Reads and writes to these properties are tracked within reactive contexts and will trigger updates to any
137
+ * dependent computations or side-effects.
138
+ *
139
+ * Getters can be marked as `computed` to define derived properties that are automatically updated when
140
+ * their dependencies change. Computed properties are lazy and memoized, meaning that they are only evaluated
141
+ * when an entity is observing their value and are only re-evaluated when their dependencies change.
142
+ *
143
+ * Observable state properties can also be marked as serializable using decorators or annotations. This allows the state store
144
+ * to be serialized to a string or object and deserialized. Serialization is can be used tp persist
145
+ * application state to local storage or for supporting shareable URLs with embedded state. Call {@link StateStore.serialize}
146
+ * to serialize the state store and {@link StateStore.deserialize} to update its properties from a previously serialized state.
147
+ *
148
+ * Because application state store instances are designed to be globally-available singletons, they can be a convenient
149
+ * way to expose state-related helper methods. These can be marked with the `action` annotation to automatically run
150
+ * within a transaction.
151
+ *
152
+ * ##TODO Describe state paths
153
+ *
154
+ * @example
155
+ * Define an application state store using TypeScript with decorators:
156
+ * ```ts
157
+ * import {
158
+ * observable,
159
+ * serialize,
160
+ * computed,
161
+ * StateStore
162
+ * } from '@emuanalytics/flow-rdf-core';
163
+ *
164
+ * class AppState extends StateStore {
165
+ * constructor() {
166
+ * super();
167
+ * this.initialize();
168
+ * }
169
+ *
170
+ * // Observable and serializable property
171
+ * @serialize
172
+ * @observable
173
+ * a = 'a value';
174
+ *
175
+ * // Observable property - not serialized
176
+ * @observable b = 2;
177
+ *
178
+ * // Computed property
179
+ * @computed
180
+ * get c() {
181
+ * return `${this.a} - ${this.b}`;
182
+ * }
183
+ * }
184
+ *
185
+ * // Application-wide singleton instance
186
+ * export const appState = new AppState();
187
+ * ```
188
+ *
189
+ * @example
190
+ * Define an application state store using JavaScript with annotations:
191
+ * ```js
192
+ * import {
193
+ * observable,
194
+ * serialize,
195
+ * computed,
196
+ * StateStore
197
+ * } from '@emuanalytics/flow-rdf-core';
198
+ *
199
+ * // Declare a state store using annotations
200
+ * class AppState extends StateStore {
201
+ * constructor() {
202
+ * super();
203
+ * this.initialize({
204
+ * a: [observable, serialize],
205
+ * b: [observable],
206
+ * c: [computed]
207
+ * });
208
+ * }
209
+ *
210
+ * a = 'a value';
211
+ * b = 2;
212
+ *
213
+ * get c() {
214
+ * return `${this.a} - ${this.b}`;
215
+ * }
216
+ * }
217
+ *
218
+ * // Application-wide singleton instance
219
+ * export const appState = new AppState();
220
+ * ```
221
+ */
25
222
  declare class StateStore {
26
223
  private get formattedName();
27
224
  private serializationAnnotations;
225
+ /**
226
+ * Returns `true` if the store has been initialized.
227
+ *
228
+ * Derived state stores **must** be initialized before use by calling {@link StateStore.initialize}
229
+ * in the constructor.
230
+ *
231
+ * @returns `true` if the store has been initialized.
232
+ */
28
233
  get initialized(): boolean;
29
234
  id: string;
30
- constructor();
31
- get<P extends Path<this, StateStore>>(path: P): PathValue<this, P, StateStore>;
32
- set<P extends Path<this, StateStore>>(path: P, val: PathValue<this, P, StateStore>): void;
235
+ /**
236
+ * Constructs a new `StateStore`.
237
+ *
238
+ * In derived classes, call `super()` in the constructor followed by `this.initialize(...)`.
239
+ *
240
+ * @example
241
+ * ```js
242
+ * constructor() {
243
+ * super();
244
+ *
245
+ * // Required!
246
+ * this.initialize();
247
+ * }
248
+ * ```
249
+ * @param id - Optional unique identifier for debugging purposes. If not supplied, a random identifier will be generated.
250
+ */
251
+ constructor(id?: string);
252
+ /**
253
+ * Returns the value at the specified path in the state store.
254
+ *
255
+ * @param path - State store path to retrieve.
256
+ * @typeParam TPath - Type defining possible state store paths.
257
+ * @returns The value of the state store property at the specified path.
258
+ */
259
+ get<TPath extends Path<this, StateStore>>(path: TPath): PathValue<this, TPath, StateStore>;
260
+ /**
261
+ * Sets the value at the specified path in the state store.
262
+ *
263
+ * @param path - State store path to set
264
+ * @param val - Value to set at the specified path
265
+ */
266
+ set<TPath extends Path<this, StateStore>>(path: TPath, val: PathValue<this, TPath, StateStore>): void;
267
+ /**
268
+ * Use this method to batch multiple state updates into a single transaction.
269
+ * This can improve performance by reducing the number of reactive updates triggered by
270
+ * state updates.
271
+ *
272
+ * @example
273
+ * Set multiple state properties within a transaction:
274
+ * ```js
275
+ * store.transaction(() => {
276
+ * store.set('a', 1);
277
+ * store.set('b', 2);
278
+ * store.set('c', 3);
279
+ * });
280
+ * ```
281
+ *
282
+ * @param fn - The function to run within the transaction.
283
+ */
33
284
  transaction(fn: (state: this) => void): void;
285
+ /**
286
+ * Toggles the value at the specified path in the state store.
287
+ * This method assumes that the value at the specified path is a boolean.
288
+ *
289
+ * @param path - The path to the boolean value to toggle.
290
+ * @returns The new value at the specified path.
291
+ */
34
292
  toggle<P extends Path<this, StateStore>>(path: P): boolean;
293
+ /**
294
+ * Increments the value at the specified path in the state store.
295
+ * This method assumes that the value at the specified path is a number.
296
+ *
297
+ * @param path - The path to the number value to increment.
298
+ * @returns The new value at the specified path.
299
+ */
35
300
  increment<P extends Path<this, StateStore>>(path: P): number;
301
+ /**
302
+ * Decrements the value at the specified path in the state store.
303
+ * This method assumes that the value at the specified path is a number.
304
+ *
305
+ * @param path The path to the number value to decrement.
306
+ * @returns The new value at the specified path.
307
+ */
36
308
  decrement<P extends Path<this, StateStore>>(path: P): number;
309
+ /**
310
+ * Bind an HTML control element to a state store property. Two-way binding
311
+ * is established between the control and the state store property. When the
312
+ * control value changes, the state store property is updated. When the state
313
+ * store property changes, the control value is updated.
314
+ *
315
+ * Supports:
316
+ * - Native elements that emit an `input` event and have a `value` property.
317
+ * - Flo.w RDF UI custom elements that emit `flow-ui-input` or `flow-ui-change` events and have
318
+ * a value property.
319
+ *
320
+ * :::warning
321
+ * Bindings should be disposed of when no longer needed by calling `unsubscribe()` on the returned subscription.
322
+ * :::
323
+ *
324
+ * :::warning
325
+ * This method is provided to support reactive binding for vanilla JS and TS applications. When using
326
+ * other supported frameworks (e.g. Angular) use the preferred binding method for that framework.
327
+ * :::
328
+ *
329
+ * @example
330
+ * ```js
331
+ * const subscription = store.bindControl(document.getElementById('my-input'), 'myStateProperty');
332
+ * ...
333
+ * subscription.unsubscribe();
334
+ * ```
335
+ *
336
+ * @param el - The HTML element to bind
337
+ * @param statePath - The path to the state store property to bind
338
+ * @param options - Binding options
339
+ * @param options.toState - A function to convert the control value to the state store value
340
+ * @param options.fromState - A function to convert the state store value to the control value
341
+ * @param options.updateOn - The event type that will trigger an update of the state store property. Default is `input`.
342
+ * @returns A subscription that can be used to `unsubscribe()` the binding.
343
+ */
37
344
  bindControl<TStatePath extends Path<this, StateStore>, TStateValue extends PathValue<this, TStatePath, StateStore>, TElementValue, TElement extends HTMLElement & {
38
345
  value: TElementValue;
39
346
  }>(el: TElement, statePath: TStatePath, options?: {
40
347
  toState?: (value: TElementValue) => TStateValue;
41
348
  fromState?: (value: TStateValue) => TElementValue;
349
+ updateOn: 'input' | 'change';
42
350
  }): ISubscription;
43
- bindElementProp<TElementProp extends keyof TElement, TElement extends HTMLElement, TStatePath extends Path<this, StateStore>, TStateValue extends PathValue<this, TStatePath, StateStore>>(el: TElement, prop: TElementProp, statePath: TStatePath, options?: {
351
+ /**
352
+ * Bind an HTML element property to a state store property. One-way binding
353
+ * is established between the element property and the state store property.
354
+ * When the state store property changes, the element property is updated.
355
+ *
356
+ * :::warning
357
+ * Bindings should be disposed of when no longer needed by calling `unsubscribe()` on the returned subscription.
358
+ * :::
359
+ *
360
+ * :::warning
361
+ * This method is provided to support reactive binding for vanilla JS and TS applications. When using
362
+ * other supported frameworks (e.g. Angular) use the preferred binding method for that framework.
363
+ * :::
364
+ *
365
+ * @example
366
+ * ```js
367
+ * const el = document.getElementById('my-span');
368
+ * const subscription = store.bindElementProp(el, 'textContent', 'myStateProperty');
369
+ * ...
370
+ * subscription.unsubscribe();
371
+ * ```
372
+ *
373
+ * @param el - The HTML element to bind
374
+ * @param prop - The property of the element to bind
375
+ * @param path - The path to the state store property to bind
376
+ * @param options - Binding options
377
+ * @param options.fromState - A function to convert the state store value to the element property value
378
+ * @returns A subscription that can be used to `unsubscribe()` the binding.
379
+ */
380
+ bindElementProp<TElementProp extends keyof TElement, TElement extends HTMLElement, TStatePath extends Path<this, StateStore>, TStateValue extends PathValue<this, TStatePath, StateStore>>(el: TElement, prop: TElementProp, path: TStatePath, options?: {
44
381
  fromState?: (value: TStateValue) => TElement[TElementProp];
45
382
  }): ISubscription;
46
- bindElementAttr<TElement extends HTMLElement, P extends Path<this, StateStore>>(el: TElement, attr: string, statePath: P): ISubscription;
383
+ /**
384
+ * Bind an HTML element attribute to a state store property. One-way binding
385
+ * is established between the element attribute and the state store property.
386
+ * When the state store property changes, the element attribute is updated
387
+ * (using `el.setAttribute(...)`).
388
+ *
389
+ * :::warning
390
+ * Bindings should be disposed of when no longer needed by calling `unsubscribe()` on the returned subscription.
391
+ * :::
392
+ *
393
+ * :::warning
394
+ * This method is provided to support reactive binding for vanilla JS and TS applications. When using
395
+ * other supported frameworks (e.g. Angular) use the preferred binding method for that framework.
396
+ * :::
397
+ *
398
+ * @param el - The HTML element to bind
399
+ * @param attr - The attribute of the element to bind
400
+ * @param path - The path to the state store property to bind
401
+ * @returns
402
+ */
403
+ bindElementAttr<TElement extends HTMLElement, TStatePath extends Path<this, StateStore>, TStateValue extends PathValue<this, TStatePath, StateStore>>(el: TElement, attr: string, path: TStatePath, options?: {
404
+ fromState?: (value: TStateValue) => string;
405
+ }): ISubscription;
406
+ /**
407
+ * Create an observable stream that emits the value of the specified state store property
408
+ * when it changes. The stream can be subscribed to using its `subscribe()` method.
409
+ *
410
+ * :::warning
411
+ * Subscriptions should be disposed of when no longer required by calling their `unsubscribe()` method.
412
+ * :::
413
+ *
414
+ * :::danger
415
+ * It is an anti-pattern to modify state store properties directly from within a stream subscription.
416
+ * Use a `computed` property instead. Limit use of `toStream` to running imperative side-effects
417
+ * in response to a reactive update of a state property.
418
+ * :::
419
+ *
420
+ * @example
421
+ * ```js
422
+ * const subscription = store.toStream('myStateProperty').subscribe((value) => {
423
+ * console.log('myStateProperty changed:', value);
424
+ * });
425
+ * ...
426
+ * subscription.unsubscribe();
427
+ * ```
428
+ *
429
+ * @param path - The path to the state store property to bind
430
+ * @param fireImmediately - If `true`, the stream will emit the current value immediately
431
+ * If `false`, the stream will only emit values when the state store property changes.
432
+ *
433
+ * @returns An observable stream that emits the value of the specified state property.
434
+ */
47
435
  toStream<P extends Path<this, StateStore>>(path: P, fireImmediately?: boolean): IObservableStream<PathValue<this, P, StateStore>>;
436
+ /**
437
+ * Creates a reactive context that will automatically re-run the specified function
438
+ * whenever referenced reactive state changes. The supplied function is run immediately
439
+ * and referenced state properties are tracked. The function will be re-run when tracked
440
+ * state properties change.
441
+ *
442
+ * Note that referenced state properties are determined dynamically
443
+ * by access. If a code branch is not taken, the referenced state properties in that branch
444
+ * will not be tracked. If, on a subsequent run, the code branch is taken, the tracking
445
+ * will be updated to include the newly accessed state properties.
446
+ *
447
+ * This method is similar to `toStream` but allows access to the complete state object rather
448
+ * than a single property.
449
+ *
450
+ * :::warning
451
+ * Autoruns should be disposed of when no longer needed by invoking the `disposer` function
452
+ * returned when creating an autorun.
453
+ * :::
454
+ *
455
+ * :::danger
456
+ * It is an anti-pattern to modify state store properties directly from within an autorun.
457
+ * Use a `computed` property instead. Limit use of autoruns to running imperative side-effects
458
+ * in response to a reactive update.
459
+ * :::
460
+ *
461
+ * @example
462
+ * ```js
463
+ * const disposer = store.autorun((state) => {
464
+ * // Set map properties as a side effect whenever any of `state.zoom`, `state.bearing`, or `state.pitch` change
465
+ * map.setCenter({zoom: state.zoom, bearing: state.bearing, pitch: state.pitch});
466
+ * });
467
+ * ...
468
+ * disposer();
469
+ * ```
470
+ *
471
+ * @param autorunFn - The function to run within a reactive context
472
+ * @param name - Optional name for debugging purposes
473
+ * @returns - A disposer function. Invoke this function to dispose of the autorun.
474
+ */
48
475
  autorun(autorunFn: (state: this) => void, name?: string): IDisposer;
476
+ /**
477
+ * This method **must**
478
+ * be called in the constructor of derived classes to initialize the state store.
479
+ * An exception will be thrown if this method is not called before using the state store.
480
+ *
481
+ * If using decorators to configure reactive properties, this method should be called without arguments.
482
+ * If not using decorators, supply reactive annotations to configure reactive properties.
483
+ *
484
+ * See {@link StoreAnnotations} for a list of available annotations.
485
+ *
486
+ * :::info
487
+ * If this method is called without using decorators and without supplying reactive annotations,
488
+ * the state store will be configured automatically:
489
+ *
490
+ * - All properties will be made observable.
491
+ * - All getters will converted to computed properties.
492
+ *
493
+ * This is only recommended for simple state stores in demos.
494
+ * :::
495
+ *
496
+ * @param annotations Optional annotations for configuring reactive properties.
497
+ */
49
498
  initialize(annotations?: StoreAnnotations<this>): void;
50
- private makeObservable;
51
- private makeAutoObservable;
499
+ /** Serialize to `raw` format */
52
500
  serialize(): Record<string, string>;
53
- serialize(format: 'raw'): Record<string, string>;
54
- serialize(format: 'lz' | 'json'): string;
501
+ /** Serialize to `raw` format */
502
+ serialize(format: 'raw', group?: string): Record<string, string>;
503
+ /** Serialize to `json` or `lz` format */
504
+ serialize(format: 'json' | 'lz', group?: string): string;
505
+ /** Deserialize `raw` format */
55
506
  deserialize(value: Record<string, string>): void;
507
+ /** Deserialize `raw` format */
56
508
  deserialize(value: Record<string, string>, format: 'raw'): void;
509
+ /** Deserialize `json` or `lz` format */
57
510
  deserialize(value: string, format: 'json' | 'lz'): void;
511
+ private makeObservable;
512
+ private makeAutoObservable;
58
513
  private checkInitialized;
59
514
  }
60
515
 
@@ -123,164 +578,161 @@ declare class Debugger<TState extends StateStore = StateStore> {
123
578
  private logStateValue;
124
579
  }
125
580
 
126
- /** Result format of a [[Query]]. */
127
- type QueryResultFormat = 'json' | 'geojson' | 'csv';
128
- /** [[FlowQueryDefinition]] 'attributes' entry. */
129
- type QueryAttribute = string | [any, string];
130
- /**
131
- * [[FlowQueryDefinition]] 'where' clauses.
132
- */
133
- interface QueryWhereClauses {
134
- [attribute: string]: any;
135
- }
136
- /**
137
- * [[FlowQueryDefinition]] extra parameters.
138
- */
139
- interface QueryExtraParams {
140
- [key: string]: string | number;
141
- }
142
- /**
143
- * [[FlowQueryDefinition]] 'order' clause.
144
- *
145
- * A field name or [field, asc/desc] tuple.
146
- */
147
- type QueryOrderClause = string | number | [string | number, 'asc' | 'desc'];
148
- interface QuerySampleOptions {
149
- percentage: number;
150
- method?: 'system' | 'bernoulli';
151
- seed?: number;
152
- }
153
- /**
154
- * Definition of a Flo.w reactive dataset query.
155
- */
156
- interface QueryDefinition {
157
- /** ID of dataset to query. */
158
- datasetId: string;
159
- /** Attributes to return in results. */
160
- attributes?: QueryAttribute[];
161
- /** DISTINCT ON attributes */
162
- distinct?: string | string[];
163
- /** Filter results using 'where' clauses. */
164
- where?: QueryWhereClauses;
165
- /** Sort results by attributes. */
166
- order?: QueryOrderClause[];
167
- /** Group results by attributes. */
168
- group?: (string | number)[];
169
- /** Start offset of returned results */
170
- offset?: number;
171
- /** Limit number of returned results */
172
- limit?: number;
173
- /** Format of returned data. */
174
- format?: QueryResultFormat;
175
- /** Additional query parameters. */
176
- params?: QueryExtraParams;
177
- /** Sampling options. */
178
- sample?: QuerySampleOptions;
179
- }
180
- interface QueryOptions {
181
- id?: string;
182
- fireImmediately?: boolean;
183
- delay?: number;
184
- contextId?: string;
185
- }
186
- /**
187
- * [[FlowQuery]] query definition function.
188
- *
189
- * @typeParam TState Type of application state.
190
- */
191
- type QueryDefinitionFn<TState> = (this: TState, store: TState) => QueryDefinition | Promise<QueryDefinition> | null;
192
- /**
193
- * [[FlowQuery]] result transform function.
194
- *
195
- * @typeParam T Type of transformed query results.
196
- */
197
- type QueryResultTransformFn<T = any> = (results: any) => T | null;
198
-
199
- declare class Query<TResults, TState extends StateStore = any> {
200
- private queryFn;
201
- private static _defaultOptions;
202
- static setDefaultOptions(options: QueryOptions): void;
203
- private _options;
204
- private _committer;
205
- private _disposer;
206
- private _transformFn;
207
- private get formattedName();
208
- get id(): string;
209
- results: TResults | null;
210
- busy: boolean;
211
- error: Error | null;
212
- constructor(queryFn: QueryDefinitionFn<TState | null>, transformFn?: QueryResultTransformFn<TResults>, options?: QueryOptions);
213
- destroy(): void;
214
- runImmediately(): Promise<TResults | null>;
215
- private wake;
216
- private sleep;
217
- private runQuery;
218
- }
219
- declare function query<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, options: QueryOptions): Query<TResult, TState>;
220
- declare function query<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, transformFn?: QueryResultTransformFn<TResult>, options?: QueryOptions): Query<TResult, TState>;
221
- declare function queryMany<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, options: QueryOptions): Query<TResult[], TState>;
222
- declare function queryMany<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, transformFn?: QueryResultTransformFn<TResult[]>, options?: QueryOptions): Query<TResult[], TState>;
223
- declare function queryOne<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, options: QueryOptions): Query<TResult, TState>;
224
- declare function queryOne<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, transformFn?: QueryResultTransformFn<TResult>, options?: QueryOptions): Query<TResult, TState>;
225
-
226
- /**
227
- * The `QueryRegistry` is a container for [[Query]] instances.
228
- *
229
- * Queries can be registered and retrieved by ID.
230
- */
231
- declare class QueryRegistry {
232
- private _queries;
233
- /**
234
- * Register a Flo.w reactive query.
235
- *
236
- * @param query Query to register.
237
- */
238
- registerQuery(query: Query<any>): void;
239
- /**
240
- * Un-register a Flo.w reactive query.
241
- *
242
- * @param query Query to unregister.
243
- */
244
- unregisterQuery(query: Query<any>): void;
245
- /**
246
- * Retrieve the specified query.
247
- *
248
- * This method returns a promise that resolves when the query has been initialized.
249
- *
250
- * @param id Map ID.
251
- */
252
- getQuery<TResults = any, TState extends StateStore = any>(id: string): Promise<Query<TResults, TState>>;
253
- }
254
-
255
- declare class FlowError extends Error {
581
+ declare class FlowCoreError extends Error {
256
582
  cause?: Error | undefined;
257
583
  constructor(message: string, cause?: Error | undefined);
258
584
  }
259
585
 
260
- declare class FlowExpressionError extends FlowError {
586
+ declare class FlowCoreExpressionError extends FlowCoreError {
261
587
  readonly reason: 'parseError' | 'evaluationError';
262
588
  readonly errors: string[];
263
589
  constructor(expression: string, reason: 'parseError' | 'evaluationError', errors: string[]);
264
590
  }
265
591
 
592
+ /**
593
+ * A Flo.w RDF reactive expression - used internally to parse and evaluate {@link MapLayer}
594
+ * style [expressions](/flow-rdf-core/expression-reference/). An expression can be evaluated
595
+ * and its MapLibre-compatible representation can be generated.
596
+ *
597
+ * @example
598
+ * ```js
599
+ * const ex = new ReactiveExpression('1 + 2');
600
+ * console.log(ex.value); // 3
601
+ * console.log(ex.maplibreExpression); // ['+', 1, 2]
602
+ * ```
603
+ *
604
+ *
605
+ */
266
606
  declare class ReactiveExpression<TState extends StateStore = StateStore, R = any> {
267
607
  private static parser;
268
608
  private static customFunctions;
609
+ /**
610
+ * Returns `true` if the specified custom function has been registered.
611
+ *
612
+ * @param fn - The custom function name
613
+ */
269
614
  static hasCustomFunction(fn: string): boolean;
615
+ /**
616
+ * Register a custom function to be used in reactive expressions.
617
+ *
618
+ * @param fn - The custom function to register
619
+ */
270
620
  static registerCustomFunction(fn: FlowCoreExpressionCustomFunction): void;
271
621
  private _expression;
272
622
  private parsedResult;
273
623
  private _store;
624
+ /**
625
+ * Parses a program string into a map of properties and their associated {@link ReactiveExpression}.
626
+ *
627
+ * The program string should be a series of property/expression pairs separated by semicolons as follows:
628
+ *
629
+ * ```js
630
+ * const program = `
631
+ * prop1: 1 + 2;
632
+ * prop2: 'a string';
633
+ * prop3: $stateProp * 3;
634
+ * `;
635
+ *
636
+ * const parsedProgram = ReactiveExpression.parseProgram(program);
637
+ * // {
638
+ * // prop1: ReactiveExpression,
639
+ * // prop2: ReactiveExpression,
640
+ * // prop3: ReactiveExpression
641
+ * // }
642
+ *
643
+ * ```
644
+ *
645
+ * @param program - The program to parse
646
+ * @returns A map of property names and their associated expressions.
647
+ */
274
648
  static parseProgram(program: string): {
275
649
  [key: string]: ReactiveExpression;
276
650
  };
651
+ /**
652
+ * Generates the MapLibre-compatible representation of this expression.
653
+ *
654
+ * This is used internally when creating MapLibre style specifications
655
+ * from Flo.w RDF {@link MapLayer} styles.
656
+ *
657
+ * This getter is a reactive `computed` and will re-evaluate within a
658
+ * reactive context when the expression value changes.
659
+ *
660
+ * @computed
661
+ *
662
+ * @returns The MapLibre-compatible representation of this expression
663
+ */
277
664
  get maplibreExpression(): ParserExpression | undefined;
665
+ /**
666
+ * Evaluates the expression and returns the result.
667
+ *
668
+ * This getter is a reactive `computed` and will re-evaluate within a
669
+ * reactive context when the expression value changes.
670
+ *
671
+ * @example
672
+ * ```js
673
+ * const ex = new ReactiveExpression('1 + 2');
674
+ * console.log(ex.value); // 3
675
+ * ```
676
+ *
677
+ * @computed
678
+ *
679
+ * @returns - The result of evaluating the expression
680
+ */
278
681
  get value(): R;
279
- get parseError(): FlowExpressionError | null;
682
+ /**
683
+ * Returns details of parsing errors if the expression could not be parsed.
684
+ */
685
+ get parseError(): FlowCoreExpressionError | null;
686
+ /**
687
+ * Returns the original expression string passed to the constructor.
688
+ */
280
689
  get expression(): string;
690
+ /**
691
+ * Returns the state store bound to the expression.
692
+ */
281
693
  get store(): TState | null;
694
+ /**
695
+ * Constructs a new `ReactiveExpression`.
696
+ *
697
+ * @example
698
+ * ```js
699
+ * const ex = new ReactiveExpression('1 + 2');
700
+ * console.log(ex.value); // 3
701
+ * ```
702
+ *
703
+ * @param expression - the string representation of the expression
704
+ * @param parsedExpression - Used internally to bypass parsing when evaluating a program.
705
+ */
282
706
  constructor(expression: string, parsedExpression?: ParserExpression);
707
+ /**
708
+ * Binds a {@link StateStore} to the expression. The state store is used to resolve
709
+ * state variables in the expression.
710
+ *
711
+ * Note: If no state store is bound, the expression will not be able to resolve
712
+ * state variables and will return `null` when evaluated. A console warning will
713
+ * be logged.
714
+ *
715
+ * @param store {@link StateStore} to bind to the expression
716
+ * @returns
717
+ */
283
718
  bindState(store: TState | null): this;
719
+ /**
720
+ * Returns a subscribable stream, which produces the value of the expression
721
+ * whenever a reactive update causes the expression to re-evaluate.
722
+ *
723
+ * @example
724
+ * ```js
725
+ * const ex = new ReactiveExpression('$val * 2');
726
+ * const subscription = ex.toStream().subscribe((value) => console.log(value));
727
+ * ...
728
+ * subscription.unsubscribe();
729
+ * ```
730
+ *
731
+ * @param fireImmediately - If `true`, the stream will fire immediately with the current value.
732
+ * If `false` the stream will only fire when the value changes.
733
+ *
734
+ * @returns A subscribable stream of the expression value
735
+ */
284
736
  toStream(fireImmediately?: boolean): IObservableStream<R>;
285
737
  private evaluateExpression;
286
738
  private expandCustomFunctions;
@@ -295,8 +747,24 @@ interface FlowCoreExpressionCustomFunction {
295
747
  fn: FlowCoreExpressionCustomFunctionSignature;
296
748
  }
297
749
  type FlowCoreExpressionCustomFunctionSignature = <TState extends StateStore = any>(expr: ParserFunctionExpression, parentExpression: ReactiveExpression) => ParserExpression;
750
+ interface FlowCoreExpressionCustomFunctions {
751
+ [name: string]: FlowCoreExpressionCustomFunction;
752
+ }
298
753
  type ParserExpression = number | string | boolean | null | ParserFunctionExpression;
299
754
  type ParserFunctionExpression = [string, ...any[]];
755
+ interface ParserProgram {
756
+ [key: string]: ParserExpressionWithIndex;
757
+ }
758
+ interface ParserExpressionWithIndex {
759
+ expr: ParserExpression;
760
+ start: ParserIndex;
761
+ end: ParserIndex;
762
+ }
763
+ interface ParserIndex {
764
+ offset: number;
765
+ line: number;
766
+ column: number;
767
+ }
300
768
 
301
769
  declare class MapLayerStyleBuilder {
302
770
  private static _styleBuilders;
@@ -1474,7 +1942,7 @@ declare class MapDataSource {
1474
1942
 
1475
1943
  type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
1476
1944
 
1477
- declare class FlowMapError extends FlowError {
1945
+ declare class FlowMapError extends FlowCoreError {
1478
1946
  constructor(message: string, originalError?: Error);
1479
1947
  }
1480
1948
 
@@ -1501,16 +1969,34 @@ interface MapFeature {
1501
1969
  [key: string]: any;
1502
1970
  };
1503
1971
  }
1972
+ /**
1973
+ * Map parameters for use with the {@link FlowCoreMap.setCenter} and {@link FlowCoreMap.getCenter} methods.
1974
+ */
1504
1975
  interface MapCenterOptions {
1976
+ /** Longitude of map center */
1505
1977
  lng: number;
1978
+ /** Latitude of map center */
1506
1979
  lat: number;
1980
+ /** Map zoom level */
1507
1981
  zoom: number;
1982
+ /** Map bearing in degrees */
1508
1983
  bearing: number;
1984
+ /** Map pitch in degrees */
1509
1985
  pitch: number;
1510
1986
  }
1987
+ /**
1988
+ * Animation options for use with the {@link FlowCoreMap.setCenter} and {@link FlowCoreMap.setBounds} methods.
1989
+ */
1511
1990
  interface MapAnimationOptions {
1991
+ /** Animation mode */
1512
1992
  mode?: 'jump' | 'ease' | 'fly';
1993
+ /** Animation duration in milliseconds */
1513
1994
  duration?: number;
1995
+ /** Animation easing function.
1996
+ *
1997
+ * A function taking a time in the range 0..1 and returning a number where 0 is
1998
+ * the initial state and 1 is the final state.
1999
+ */
1514
2000
  easing?: (time: number) => number;
1515
2001
  }
1516
2002
  interface MapPaddingOptions {
@@ -1532,38 +2018,103 @@ interface MapPaddingOptions {
1532
2018
  left: number;
1533
2019
  }
1534
2020
 
2021
+ /**
2022
+ * This interface defines all event types emitted {@link FlowCoreMap} and
2023
+ * the type of the corresponding event handler.
2024
+ *
2025
+ * {@link FlowCoreMap} extends [EventEmitter](https://github.com/dashed/EventEmitter3) to provide
2026
+ * event handling capabilities. The {@link FlowCoreMap.on} method is used to subscribe to events.
2027
+ *
2028
+ * @example
2029
+ * ```js
2030
+ * map.on('click', (event) => {
2031
+ * console.log('Map clicked at:', event.lngLat);
2032
+ * });
2033
+ * ```
2034
+ */
1535
2035
  interface MapEventTypes {
2036
+ /**
2037
+ * Emitted when the map is clicked.
2038
+ * @group Mouse Events
2039
+ */
1536
2040
  click: (event: MapMouseEvent) => void;
2041
+ /**
2042
+ * Emitted when the map is double-clicked.
2043
+ * @group Mouse Events
2044
+ */
1537
2045
  dblClick: (event: MapMouseEvent) => void;
2046
+ /**
2047
+ * Emitted when the mouse is moved. Note that this event is throttled to 100ms.
2048
+ *
2049
+ * @group Mouse Events
2050
+ */
1538
2051
  mouseMove: (event: MapMouseEvent) => void;
2052
+ /**
2053
+ * Emitted when the mouse leaves the map bounds.
2054
+ * @group Mouse Events
2055
+ */
1539
2056
  mouseOut: (event: MapMouseEvent) => void;
2057
+ /**
2058
+ * Emitted when the map finishes panning or zooming.
2059
+ *
2060
+ * Note that this event is emitted following user interaction **and**
2061
+ * programmatic changes to the map.
2062
+ * @group Map Events
2063
+ */
1540
2064
  moveEnd: (event: MapEvent) => void;
1541
- sourceAdded: (event: MapSourceEvent) => void;
1542
- sourceRemoved: (event: MapSourceEvent) => void;
1543
- beforeSourceAdded: (event: MapSourceEvent) => void;
1544
- beforeSourceRemoved: (event: MapSourceEvent) => void;
1545
- sourceFeatureState: (event: MapSourceEvent) => void;
2065
+ /**
2066
+ * Emitted when the map is destroyed.
2067
+ * @group Map Events
2068
+ */
1546
2069
  destroyed: (event: MapEvent) => void;
2070
+ /**
2071
+ * Emitted when the map has started or finished loading data.
2072
+ * @group Loading Events
2073
+ */
1547
2074
  loading: (event: MapLoadingEvent) => void;
1548
- beforeStyleChanged: (event: MapStyleChangeEvent) => void;
1549
- styleChanged: (event: MapStyleChangeEvent) => void;
1550
- error: (event: FlowMapError) => void;
1551
- }
1552
- interface MapEventTypes {
1553
- click: (event: MapMouseEvent) => void;
1554
- dblClick: (event: MapMouseEvent) => void;
1555
- mouseMove: (event: MapMouseEvent) => void;
1556
- mouseOut: (event: MapMouseEvent) => void;
1557
- moveEnd: (event: MapEvent) => void;
2075
+ /**
2076
+ * Emitted after a {@link MapDataSource} has been added to the map.
2077
+ * @group Source Events
2078
+ */
1558
2079
  sourceAdded: (event: MapSourceEvent) => void;
2080
+ /**
2081
+ * Emitted after a {@link MapDataSource} has been removed from the map.
2082
+ * @group Source Events
2083
+ */
1559
2084
  sourceRemoved: (event: MapSourceEvent) => void;
2085
+ /**
2086
+ * Emitted before a {@link MapDataSource} is added to the map.
2087
+ * @group Source Events
2088
+ */
1560
2089
  beforeSourceAdded: (event: MapSourceEvent) => void;
2090
+ /**
2091
+ * Emitted before a {@link MapDataSource} is removed from the map.
2092
+ * @group Source Events
2093
+ */
1561
2094
  beforeSourceRemoved: (event: MapSourceEvent) => void;
2095
+ /**
2096
+ * Emitted when map feature state changes following a call to {@link FlowCoreMap.setFeatureState},
2097
+ * {@link FlowCoreMap.setFeatureStateBulk}, or {@link FlowCoreMap.removeFeatureState}.
2098
+ * @group Source Events
2099
+ */
1562
2100
  sourceFeatureState: (event: MapSourceEvent) => void;
1563
- destroyed: (event: MapEvent) => void;
1564
- loading: (event: MapLoadingEvent) => void;
2101
+ /**
2102
+ * Emitted before the map style changes.
2103
+ * @group Style Events
2104
+ */
1565
2105
  beforeStyleChanged: (event: MapStyleChangeEvent) => void;
2106
+ /**
2107
+ * Emitted after the map style has changed.
2108
+ * @group Style Events
2109
+ */
1566
2110
  styleChanged: (event: MapStyleChangeEvent) => void;
2111
+ /**
2112
+ * Emitted when an error has occurred.
2113
+ *
2114
+ * If no error handler is registered, the error will be logged to the console.
2115
+ *
2116
+ * @group Error Events
2117
+ */
1567
2118
  error: (event: FlowMapError) => void;
1568
2119
  }
1569
2120
  type MapEventType = keyof MapEventTypes;
@@ -1723,13 +2274,36 @@ declare class ImageRegistry {
1723
2274
  private loadImage;
1724
2275
  }
1725
2276
 
2277
+ /**
2278
+ * Options for creating a {@link MapFeatureStream}.
2279
+ *
2280
+ * See {@link FlowCoreMap.featureStream } for more information.
2281
+ */
1726
2282
  interface FeatureStreamOptions {
2283
+ /** An array of feature IDs to track. Note that {@link MapDataSourceOptions.featureId}
2284
+ * must be set on the map data source to specify which feature property to use as the feature ID.
2285
+ */
1727
2286
  featureIds: Array<string | number>;
2287
+ /** Set to `true` to fire the stream immediately when subscribed. If `false`, the stream will only
2288
+ * emit when feature data changes.
2289
+ */
1728
2290
  fireImmediately?: boolean;
2291
+ /** The map instance. */
1729
2292
  map: FlowCoreMap;
2293
+ /** The map data source ID to track. */
1730
2294
  source: string;
2295
+ /**
2296
+ * The map data source layer to track. This only applies to vector data sources and can be
2297
+ * omitted for Flo.w vector tiles. Defaults to `'geometry'`.
2298
+ */
1731
2299
  sourceLayer?: string;
1732
2300
  }
2301
+ /**
2302
+ * A observable stream of map feature data. Subscribe to an instance of this class to receive
2303
+ * updates when map feature data changes.
2304
+ *
2305
+ * See {@link FlowCoreMap.featureStream } for usage information.
2306
+ */
1733
2307
  declare class MapFeatureStream {
1734
2308
  private _boundHandleLoading;
1735
2309
  private _boundHandleSourceFeatureState;
@@ -1737,9 +2311,43 @@ declare class MapFeatureStream {
1737
2311
  private _sourceLoadCount;
1738
2312
  private _sourceLoaded;
1739
2313
  constructor(options: FeatureStreamOptions);
2314
+ /**
2315
+ * Returns feature data corresponding to the requested feature IDs. This is a computed property that will
2316
+ * automatically update when the feature data changes. Accessing this property within a reactive
2317
+ * context will automatically trigger a reactive update.
2318
+ *
2319
+ * :::info
2320
+ * This method provides an alternative to {@link subscribe} for responding to feature data upates.
2321
+ * :::
2322
+ *
2323
+ * @example
2324
+ * ```js
2325
+ * const featureStream = myMap.featureStream({
2326
+ * featureIds: ['feature1', 'feature2'],
2327
+ * source: 'my-source'
2328
+ * });
2329
+ *
2330
+ * const disposer = appState.autoRun(() => {
2331
+ * const featureData = featureStream.featureData;
2332
+ * console.log('Feature data changed:', featureData);
2333
+ * });
2334
+ * ...
2335
+ * disposer();
2336
+ * ```
2337
+ *
2338
+ */
1740
2339
  get featureData(): Record<string | number, MapFeature>;
2340
+ /** Returns the feature IDs being tracked. */
1741
2341
  get featureIds(): Array<string | number>;
2342
+ /** Update the feature IDs being tracked. */
1742
2343
  set featureIds(featureIds: Array<string | number>);
2344
+ /**
2345
+ * Subscribe to the feature stream. The supplied handler will be called whenever the feature data changes.
2346
+ *
2347
+ * :::warning
2348
+ * Subscriptions should be disposed of when no longer required by calling their `unsubscribe()` method.
2349
+ * :::
2350
+ */
1743
2351
  subscribe(handler: (featureData: Record<string | number, MapFeature>) => void): ISubscription;
1744
2352
  private featureFromMaplibreFeature;
1745
2353
  private handleLoading;
@@ -1749,13 +2357,32 @@ declare class MapFeatureStream {
1749
2357
  private suspend;
1750
2358
  }
1751
2359
 
2360
+ /**
2361
+ * Map options supplied when creating a new {@link FlowCoreMap} instance.
2362
+ */
1752
2363
  interface MapOptions<TState extends StateStore = StateStore> extends Omit<MapOptions$1, 'style'> {
2364
+ /** Unique map identifier. */
1753
2365
  id?: string;
2366
+ /** Base map style */
1754
2367
  baseStyle?: string | MapStyleSpecification;
2368
+ /** Map container selector or element. This specifies where in the DOM the map will be inserted. */
1755
2369
  container: string | HTMLElement;
2370
+ /**
2371
+ * Click tolerance in pixels. This defines a radius around the mouse position when selecting map features.
2372
+ * Increase this value to make clicking on line features easier. (Default: 0)
2373
+ */
1756
2374
  featureClickTolerance?: number;
2375
+ /**
2376
+ * Flow context identifier. This defines the {@link FlowContext} to use for data requests and reactive
2377
+ * state. If not specified, the default context will be used. Note that the map initialization will
2378
+ * pause until the context is initialized and ready to be used.
2379
+ */
1757
2380
  contextId?: string;
1758
2381
  }
2382
+ /**
2383
+ *
2384
+ *
2385
+ */
1759
2386
  declare class FlowCoreMap<TState extends StateStore = StateStore> extends EventEmitter$1<MapEventTypes> {
1760
2387
  private static _defaultOptions;
1761
2388
  private _context;
@@ -1769,12 +2396,78 @@ declare class FlowCoreMap<TState extends StateStore = StateStore> extends EventE
1769
2396
  private _style;
1770
2397
  private _styleUpdateSubscription;
1771
2398
  private _throttledMouseMove;
1772
- maplibreMap: Map;
2399
+ private _maplibreMap;
2400
+ /**
2401
+ * Return the underlying [Maplibre GL JS](https://maplibre.org/maplibre-gl-js/docs/) map instance. This can be used to
2402
+ * access the full Maplibre API for advanced use cases.
2403
+ *
2404
+ * :::danger
2405
+ * Use with caution. Directly modifying the Maplibre map instance can cause unexpected behavior particularly if
2406
+ * the changes conflict with the {@link FlowCoreMap} state. Do not call any Maplibre methods that add or
2407
+ * remove map layers or data sources, or modify the map style directly.
2408
+ * :::
2409
+ */
2410
+ get maplibreMap(): Map;
2411
+ /**
2412
+ * Constructs a new `FlowCoreMap` instance.
2413
+ *
2414
+ * The map will be initialized with the specified options and base style.
2415
+ * When the map API is ready for use, the {@link initialized} promise will resolve.
2416
+ *
2417
+ * @example
2418
+ * ```js
2419
+ * const map = new FlowCoreMap({
2420
+ * id: 'my-map',
2421
+ * container: '#map-container',
2422
+ * baseStyle: 'fjord',
2423
+ * });
2424
+ *
2425
+ * map.initialized.then(() => {
2426
+ * console.log('Map initialized');
2427
+ * // Configure map data sources and layers
2428
+ * ...
2429
+ * });
2430
+ * ```
2431
+ *
2432
+ */
1773
2433
  constructor(options: MapOptions<TState>);
2434
+ /**
2435
+ * Returns the {@link FlowContext} associated with this map.
2436
+ */
1774
2437
  get context(): FlowContext<TState>;
2438
+ /**
2439
+ * Returns the map's container element.
2440
+ */
1775
2441
  get container(): HTMLElement;
2442
+ /**
2443
+ * Returns the map identifier.
2444
+ */
1776
2445
  get id(): string;
2446
+ /**
2447
+ * Returns a promise that resolves when the map is fully initialized and ready for use.
2448
+ *
2449
+ * @example
2450
+ * ```js
2451
+ * map.initialized.then(() => {
2452
+ * console.log('Map ready fo use');
2453
+ * // Configure map data sources and layers
2454
+ * ...
2455
+ * });
2456
+ * ```
2457
+ */
1777
2458
  get initialized(): Promise<void>;
2459
+ /**
2460
+ * Returns the full Maplibre style specification for this map. This is a `computed` property and will trigger
2461
+ * reactive updates when accessed in a reactive context.
2462
+ *
2463
+ * @example
2464
+ * ```js
2465
+ * stateStore.autorun(() => {
2466
+ * const style = map.styleSpecification;
2467
+ * console.log('Map style was updated', style);
2468
+ * });
2469
+ * ```
2470
+ */
1778
2471
  get styleSpecification(): MapStyleSpecification;
1779
2472
  /**
1780
2473
  * @internal
@@ -1782,24 +2475,160 @@ declare class FlowCoreMap<TState extends StateStore = StateStore> extends EventE
1782
2475
  * Used by map export to get images added to map.
1783
2476
  */
1784
2477
  get imageRegistry(): ImageRegistry;
2478
+ /**
2479
+ * Adds a {@link MapLayer} to the map.
2480
+ *
2481
+ * @example
2482
+ * Create a new circle layer and add it to the map:
2483
+ * ```js
2484
+ * const circleLayer = new MapLayer({
2485
+ * id: "circle-layer",
2486
+ * type: "circle",
2487
+ * source: "airquality",
2488
+ * style: layerStyle("circle")
2489
+ * .circleColor('red')
2490
+ * .build()
2491
+ * });
2492
+ *
2493
+ * map.addLayer(layer);
2494
+ * ```
2495
+ */
1785
2496
  addLayer(layer: MapLayer): MapLayer;
2497
+ /**
2498
+ * Creates a new {@link MapLayer} instance using the provided options
2499
+ * and adds it to the map.
2500
+ *
2501
+ * @example
2502
+ * Create a new circle layer and add it to the map in a single step:
2503
+ * ```js
2504
+ * map.addLayer({
2505
+ * id: "circle-layer",
2506
+ * type: "circle",
2507
+ * source: "airquality",
2508
+ * style: layerStyle("circle")
2509
+ * .circleColor('red')
2510
+ * .build()
2511
+ * });
2512
+ * ```
2513
+ */
1786
2514
  addLayer(layerOptions: MapLayerOptions): MapLayer;
2515
+ /**
2516
+ * Adds a {@link MapDataSource} to the map.
2517
+ */
1787
2518
  addSource(source: MapDataSource): MapDataSource;
2519
+ /**
2520
+ * Creates a new {@link MapDataSource} instance using the provided options
2521
+ * and adds it to the map.
2522
+ */
1788
2523
  addSource(sourceOptions: MapDataSourceOptions): MapDataSource;
2524
+ /**
2525
+ * Destroys the map instance and removes it from the DOM.
2526
+ */
1789
2527
  destroy(): void;
2528
+ /**
2529
+ * Called internally and by map plugins to notify an error.
2530
+ *
2531
+ * To handle errors, attach an error event listener to the map instance as follows:
2532
+ *
2533
+ * ```js
2534
+ * map.on('error', (error) => {
2535
+ * // Handle error
2536
+ * console.error(`A map error occurred: ${error.message}`);
2537
+ * });
2538
+ * ```
2539
+ *
2540
+ * If no error event listener is attached, the error will be logged to the console.
2541
+ */
1790
2542
  emitError(message: string, originalError?: Error): void;
2543
+ /** Used internally and by plugins to emit a map event. */
1791
2544
  emitEvent<T extends MapEvent<keyof MapEventTypes, any>>(event: T): void;
2545
+ /**
2546
+ * Returns an observable {@link MapFeatureStream} for the specified feature identifiers. The feature stream
2547
+ * will emit feature data for the specified features as their properties updated.
2548
+ * Call the {@link MapFeatureStream.subscribe} method to receive feature data updates.
2549
+ *
2550
+ * :::warning
2551
+ * All subscriptions should be disposed of when no longer needed.
2552
+ * :::
2553
+ *
2554
+ * This method is used internally by the map popup plugin to receive feature properties for rendering
2555
+ * popup content but can be used whenever you want to track feature data changes for a set of features.
2556
+ *
2557
+ * :::warning
2558
+ * The feature stream will only emit feature data for features that are currently visible on the map. If the
2559
+ * user pans the map away from the requested features, the map will eventually unload the features and will
2560
+ * stop providing updates.
2561
+ * :::
2562
+ *
2563
+ * @example
2564
+ * ```js
2565
+ * const subscription = map.featureStream({
2566
+ * source: 'my-data-source',
2567
+ * featureIds: ['feature-1', 'feature-2']
2568
+ * }).subscribe((featureData) => {
2569
+ * console.log('Feature data updated', featureData);
2570
+ * });
2571
+ * ...
2572
+ * subscription.unsubscribe();
2573
+ * ```
2574
+ *
2575
+ * @param options
2576
+ * @returns
2577
+ */
1792
2578
  featureStream(options: Omit<FeatureStreamOptions, 'map'>): MapFeatureStream;
1793
- private get formattedName();
2579
+ /**
2580
+ * Returns the feature state for the specified map feature.
2581
+ *
2582
+ * See ##TODO for more information about map feature state.
2583
+ *
2584
+ * @param feature - Map feature identifier
2585
+ */
1794
2586
  getFeatureState(feature: MapFeatureIdentifier): Record<string, any>;
2587
+ /**
2588
+ * Returns the {@link MapLayer} with the specified ID.
2589
+ *
2590
+ * @param id - Map layer ID
2591
+ */
1795
2592
  getLayer(id: string): MapLayer;
2593
+ /**
2594
+ * Returns all map layers that match the specified filter function.
2595
+ * If no filter is specified, all layers are returned.
2596
+ *
2597
+ * @param filter - Filter function. Return `true` to include the map layer in the result.
2598
+ */
1796
2599
  getLayers(filter?: (layer: MapLayer) => boolean): MapLayer[];
2600
+ /**
2601
+ * Returns a registered map plugin.
2602
+ *
2603
+ * @example
2604
+ * Retrieve the popup plugin from a map:
2605
+ * ```js
2606
+ * const popupPlugin = map.getPlugin(PopupPlugin);
2607
+ * popupPlugin.registerPopup('my-popup', {...});
2608
+ * ```
2609
+ *
2610
+ * @param pluginOrName - Plugin constructor or name as a string.
2611
+ */
1797
2612
  getPlugin<T extends MapPluginBase = MapPluginBase>(pluginOrName: PluginConstructor<T> | string): T;
2613
+ /**
2614
+ * Returns the {@link MapDataSource} with the specified ID.
2615
+ *
2616
+ * @param id - Data source ID
2617
+ */
1798
2618
  getSource(id: string): MapDataSource;
2619
+ /**
2620
+ * Returns all {@link MapDataSource} instance that match the specified filter function.
2621
+ * If no filter is specified, all data sources are returned.
2622
+ *
2623
+ * @param filter - Filter function. Return `true` to include the map data source in the result.
2624
+ */
1799
2625
  getSources(filter?: (source: MapDataSource) => boolean): MapDataSource[];
1800
2626
  /**
1801
2627
  * Register a map icon image.
1802
2628
  *
2629
+ * The image can be used on [symbol-type map layers](/flow-rdf-core/layer-reference/symbol) by specifying the image ID
2630
+ * as the [`icon-image`](/flow-rdf-core/layer-reference/symbol#icon-image) property.
2631
+ *
1803
2632
  * @param id Image ID.
1804
2633
  * @param src Image source URL.
1805
2634
  * @param width Image display width.
@@ -1809,35 +2638,151 @@ declare class FlowCoreMap<TState extends StateStore = StateStore> extends EventE
1809
2638
  */
1810
2639
  registerImage(id: string, src: string, width?: number, height?: number, pixelDensity?: number, recolor?: boolean): void;
1811
2640
  /**
1812
- * Programmatically remove feature state properties from a map feature.
2641
+ * Remove feature state properties from a map feature.
1813
2642
  *
1814
2643
  * @param feature Feature to modify. Specify `null` to modify all map features.
1815
2644
  * @param key Feature state key to remove. Specify `null` to remove all feature state for specified feature(s).
1816
2645
  */
1817
2646
  removeFeatureState(feature: PartialBy<MapFeatureIdentifier, 'id'>, key?: string, fireEvent?: boolean): void;
2647
+ /**
2648
+ * Remove the specified {@link MapLayer} from the map.
2649
+ * @param id - Map layer ID
2650
+ */
1818
2651
  removeLayer(id: string): this;
2652
+ /**
2653
+ * Remove the specified {@link MapDataSource} from the map.
2654
+ * @param id - Map data source ID
2655
+ */
1819
2656
  removeSource(id: string, removeLayers?: boolean): this;
2657
+ /**
2658
+ * Set the map's base style.
2659
+ *
2660
+ * ##TODO list of available base styles
2661
+ *
2662
+ * @param style - A style identifier or a Maplibre style specification.
2663
+ */
1820
2664
  setBaseStyle(style: string | MapStyleSpecification): Promise<void>;
2665
+ /**
2666
+ * Returns the map's current center, bearing, pitch, and zoom level.
2667
+ */
1821
2668
  getCenter(): MapCenterOptions;
1822
- setCenter(center: Partial<MapCenterOptions>, animationOptions?: MapAnimationOptions): this;
2669
+ /**
2670
+ * Sets one or more of the map's center, bearing, pitch, and/or zoom level.
2671
+ * Animation options can be specified to animate the transition. If animation options are not specified,
2672
+ * the map will jump to the new view immediately.
2673
+ *
2674
+ * A promise is returned that resolves when the map has finished moving.
2675
+ *
2676
+ * @example
2677
+ * Zoom the map and log to console when finished:
2678
+ * ```js
2679
+ * const { zoom } = map.getCenter();
2680
+ * map.setCenter({zoom: zoom + 2}, {mode: 'ease', duration: 2000}).then(() => {
2681
+ * console.log('Map zoomed ');
2682
+ * });
2683
+ * ```
2684
+ *
2685
+ * @param center
2686
+ * @param animationOptions
2687
+ * @returns A promise that resolves when the map has finished moving.
2688
+ */
2689
+ setCenter(center: Partial<MapCenterOptions>, animationOptions?: MapAnimationOptions): Promise<void>;
2690
+ /**
2691
+ * Returns the map's current bounds in degrees as an array of `[west, south, east, north]`.
2692
+ *
2693
+ * See also {@link getVisibleBounds}.
2694
+ */
1823
2695
  getBounds(): [number, number, number, number];
2696
+ /**
2697
+ * Set the map's bounds to the specified bounding box.
2698
+ *
2699
+ * Animation options can be specified to animate the transition. If animation options are not specified,
2700
+ * the map will jump to the new view immediately.
2701
+ *
2702
+ * Specify the `padding` option to add padding around the bounding box in pixels.
2703
+ *
2704
+ * @param bounds - Bounding box in degrees as an array of `[west, south, east, north]`.
2705
+ * @param options - Animation and padding options.
2706
+ */
1824
2707
  setBounds(bounds: [number, number, number, number], options?: MapAnimationOptions & {
1825
2708
  padding?: number;
1826
2709
  }): void;
2710
+ /**
2711
+ * Returns the map's current visible bounds in degrees as an array of `[west, south, east, north]`.
2712
+ *
2713
+ * The visible bounds may differ from the map's full bounds if fixed positioning is used. With fixed positioning,
2714
+ * the map's canvas extends outside its container underneath other elements like side-bars. This allows side-bars
2715
+ * to be opened and closed without re-rendering the map. The visible bounds represent the region of the map that
2716
+ * is currently visible within the map's container.
2717
+ *
2718
+ * See also {@link getBounds}.
2719
+ */
1827
2720
  getVisibleBounds(): [number, number, number, number];
1828
2721
  /**
1829
- * Programmatically set feature state properties for a map feature.
2722
+ * Set feature state properties for a map feature.
2723
+ *
2724
+ * ##TODO more info on feature state
1830
2725
  *
1831
2726
  * @param feature Feature to modify.
1832
2727
  * @param state Feature state properties to set.
1833
2728
  */
1834
2729
  setFeatureState(feature: MapFeatureIdentifier, state: Record<string, any>, fireEvent?: boolean): void;
2730
+ /**
2731
+ * Set feature state properties in bulk for multiple map features.
2732
+ *
2733
+ * ##TODO more info on feature state
2734
+ *
2735
+ * @param feature Feature to modify.
2736
+ * @param state Feature state properties to set.
2737
+ */
1835
2738
  setFeatureStateBulk(sourceId: MapSourceIdentifier, featureState: {
1836
2739
  [featureId: MapFeatureId]: Record<string, any>;
1837
2740
  }): void;
2741
+ /**
2742
+ * Run a series of map updates as a single transaction. This can be used to batch multiple updates
2743
+ * while only triggering a single re-render of the map.
2744
+ *
2745
+ * @example
2746
+ * ```js
2747
+ * map.transaction(() => {
2748
+ * map.addSource({ ... });
2749
+ * map.addLayer({ ... });
2750
+ * map.addLayer({ ... });
2751
+ * });
2752
+ * ```
2753
+ *
2754
+ * @param fn - Function containing map updates to run as a transaction.
2755
+ */
1838
2756
  transaction(fn: () => void): void;
2757
+ /**
2758
+ * Register a map plugin with the map instance.
2759
+ *
2760
+ * Some plugins may require additional options to be passed when registering the plugin.
2761
+ *
2762
+ * @example
2763
+ * Register the HoverEffectPlugin with the map:
2764
+ * ```js
2765
+ * map.usePlugin(HoverEffectPlugin);
2766
+ * ```
2767
+ *
2768
+ * @param plugin - Plugin constructor or name
2769
+ * @param options - Plugin-specific options
2770
+ * @returns The plugin instance
2771
+ */
1839
2772
  usePlugin<T extends MapPluginBase>(plugin: PluginConstructor<T>, options?: PluginOptionsType<T>): T;
2773
+ /**
2774
+ * Register multiple map plugins with the map instance.
2775
+ *
2776
+ * @example
2777
+ * Register multiple plugins with the map:
2778
+ * ```js
2779
+ * map.usePlugins([HoverEffectPlugin, PopupPlugin]);
2780
+ * ```
2781
+ *
2782
+ * @param plugins - Array of plugin constructors to register
2783
+ */
1840
2784
  usePlugins(plugins: PluginConstructor[]): void;
2785
+ private get formattedName();
1841
2786
  private bindMapEvents;
1842
2787
  private featureFromMaplibreFeature;
1843
2788
  private featureQueryBox;
@@ -1851,6 +2796,74 @@ declare class FlowCoreMap<TState extends StateStore = StateStore> extends EventE
1851
2796
  private updateMapStyle;
1852
2797
  }
1853
2798
 
2799
+ type MapPopupTemplateFn<TState extends StateStore = StateStore> = (feature: MapFeature | null, state: TState) => string | Node | lit.TemplateResult;
2800
+ interface MapPopupEvents {
2801
+ closed: (popup: MapPopup) => void;
2802
+ }
2803
+ /**
2804
+ * [[MapPopup]] options.
2805
+ */
2806
+ interface MapPopupOptions {
2807
+ /** Specify a CSS class to add to the popup. */
2808
+ class?: string;
2809
+ /** Enable 'close' button. */
2810
+ closeButton?: boolean;
2811
+ /** Enable closing popup on click on map. */
2812
+ closeOnClick?: boolean;
2813
+ /** Enable closing pop when map is moved. */
2814
+ closeOnMove?: boolean;
2815
+ /** Specify popup content as HTML string or HTML node. */
2816
+ content: string | Node | MapPopupTemplateFn;
2817
+ /** Maximum width of popup in CSS units. */
2818
+ maxWidth?: string;
2819
+ trackFeature?: boolean;
2820
+ }
2821
+ /**
2822
+ * Core functionality for Flo.w map popups.
2823
+ *
2824
+ *
2825
+ */
2826
+ declare class MapPopup extends EventEmitter$1<MapPopupEvents> {
2827
+ readonly map: FlowCoreMap;
2828
+ readonly options: MapPopupOptions;
2829
+ private _feature?;
2830
+ private _contentContainer;
2831
+ private _featureStream;
2832
+ private _maplibrePopup;
2833
+ private _featureStreamDisposer?;
2834
+ /**
2835
+ * Constructs a new `MapPopup` instance.
2836
+ *
2837
+ * This is called by the `FlowMap::openPopup` method.
2838
+ *
2839
+ * @param map Parent Flo.w map.
2840
+ * @param options Popup options.
2841
+ */
2842
+ constructor(map: FlowCoreMap, options: MapPopupOptions);
2843
+ get feature(): MapFeatureIdentifier | undefined;
2844
+ /**
2845
+ * Close the popup.
2846
+ */
2847
+ close(): void;
2848
+ /**
2849
+ * Move the popup to a new location.
2850
+ *
2851
+ * @param lngLat New location.
2852
+ */
2853
+ moveTo(lngLat: [number, number]): void;
2854
+ /**
2855
+ * Open the popup at the specified location.
2856
+ *
2857
+ * @param lngLat Popup location.
2858
+ */
2859
+ open(event: MapMouseEvent): void;
2860
+ open(lngLat: [number, number], feature?: MapFeatureIdentifier): void;
2861
+ private cssClasses;
2862
+ private handleFeatureUpdate;
2863
+ private popupCloseHandler;
2864
+ private renderContent;
2865
+ }
2866
+
1854
2867
  /**
1855
2868
  * The `MapRegistry` is a container for [[FlowCoreMap]] instances.
1856
2869
  *
@@ -1861,14 +2874,18 @@ declare class MapRegistry {
1861
2874
  /**
1862
2875
  * Register a Flo.w map.
1863
2876
  *
1864
- * @param id Map ID.
1865
2877
  * @param map Map to register.
1866
2878
  */
1867
2879
  registerMap(map: FlowCoreMap): FlowCoreMap;
1868
2880
  /**
1869
2881
  * Un-register a Flo.w map.
1870
2882
  *
1871
- * @param id Map ID.
2883
+ * ```mermaid
2884
+ * graph TB
2885
+ * mermaid.js --> TypeDoc;
2886
+ * ```
2887
+ *
2888
+ * @param map - the map to unregister.
1872
2889
  */
1873
2890
  unregisterMap(map: FlowCoreMap): void;
1874
2891
  /**
@@ -1881,6 +2898,135 @@ declare class MapRegistry {
1881
2898
  getMap(id: string): Promise<FlowCoreMap>;
1882
2899
  }
1883
2900
 
2901
+ /** Result format of a [[Query]]. */
2902
+ type QueryResultFormat = 'json' | 'geojson' | 'csv';
2903
+ /** [[FlowQueryDefinition]] 'attributes' entry. */
2904
+ type QueryAttribute = string | [any, string];
2905
+ /**
2906
+ * [[FlowQueryDefinition]] 'where' clauses.
2907
+ */
2908
+ interface QueryWhereClauses {
2909
+ [attribute: string]: any;
2910
+ }
2911
+ /**
2912
+ * [[FlowQueryDefinition]] extra parameters.
2913
+ */
2914
+ interface QueryExtraParams {
2915
+ [key: string]: string | number;
2916
+ }
2917
+ /**
2918
+ * [[FlowQueryDefinition]] 'order' clause.
2919
+ *
2920
+ * A field name or [field, asc/desc] tuple.
2921
+ */
2922
+ type QueryOrderClause = string | number | [string | number, 'asc' | 'desc'];
2923
+ interface QuerySampleOptions {
2924
+ percentage: number;
2925
+ method?: 'system' | 'bernoulli';
2926
+ seed?: number;
2927
+ }
2928
+ /**
2929
+ * Definition of a Flo.w reactive dataset query.
2930
+ */
2931
+ interface QueryDefinition {
2932
+ /** ID of dataset to query. */
2933
+ datasetId: string;
2934
+ /** Attributes to return in results. */
2935
+ attributes?: QueryAttribute[];
2936
+ /** DISTINCT ON attributes */
2937
+ distinct?: string | string[];
2938
+ /** Filter results using 'where' clauses. */
2939
+ where?: QueryWhereClauses;
2940
+ /** Sort results by attributes. */
2941
+ order?: QueryOrderClause[];
2942
+ /** Group results by attributes. */
2943
+ group?: (string | number)[];
2944
+ /** Start offset of returned results */
2945
+ offset?: number;
2946
+ /** Limit number of returned results */
2947
+ limit?: number;
2948
+ /** Format of returned data. */
2949
+ format?: QueryResultFormat;
2950
+ /** Additional query parameters. */
2951
+ params?: QueryExtraParams;
2952
+ /** Sampling options. */
2953
+ sample?: QuerySampleOptions;
2954
+ }
2955
+ interface QueryOptions {
2956
+ id?: string;
2957
+ fireImmediately?: boolean;
2958
+ delay?: number;
2959
+ contextId?: string;
2960
+ }
2961
+ /**
2962
+ * [[FlowQuery]] query definition function.
2963
+ *
2964
+ * @typeParam TState Type of application state.
2965
+ */
2966
+ type QueryDefinitionFn<TState> = (this: TState, store: TState) => QueryDefinition | Promise<QueryDefinition> | null;
2967
+ /**
2968
+ * [[FlowQuery]] result transform function.
2969
+ *
2970
+ * @typeParam T Type of transformed query results.
2971
+ */
2972
+ type QueryResultTransformFn<T = any> = (results: any) => T | null;
2973
+
2974
+ declare class Query<TResults, TState extends StateStore = any> {
2975
+ private queryFn;
2976
+ private static _defaultOptions;
2977
+ static setDefaultOptions(options: QueryOptions): void;
2978
+ private _options;
2979
+ private _committer;
2980
+ private _disposer;
2981
+ private _transformFn;
2982
+ private get formattedName();
2983
+ get id(): string;
2984
+ results: TResults | null;
2985
+ busy: boolean;
2986
+ error: Error | null;
2987
+ constructor(queryFn: QueryDefinitionFn<TState | null>, transformFn?: QueryResultTransformFn<TResults>, options?: QueryOptions);
2988
+ destroy(): void;
2989
+ runImmediately(): Promise<TResults | null>;
2990
+ private wake;
2991
+ private sleep;
2992
+ private runQuery;
2993
+ }
2994
+ declare function query<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, options: QueryOptions): Query<TResult, TState>;
2995
+ declare function query<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, transformFn?: QueryResultTransformFn<TResult>, options?: QueryOptions): Query<TResult, TState>;
2996
+ declare function queryMany<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, options: QueryOptions): Query<TResult[], TState>;
2997
+ declare function queryMany<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, transformFn?: QueryResultTransformFn<TResult[]>, options?: QueryOptions): Query<TResult[], TState>;
2998
+ declare function queryOne<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, options: QueryOptions): Query<TResult, TState>;
2999
+ declare function queryOne<TResult = any, TState extends StateStore = any>(queryFn: QueryDefinitionFn<TState>, transformFn?: QueryResultTransformFn<TResult>, options?: QueryOptions): Query<TResult, TState>;
3000
+
3001
+ /**
3002
+ * The `QueryRegistry` is a container for [[Query]] instances.
3003
+ *
3004
+ * Queries can be registered and retrieved by ID.
3005
+ */
3006
+ declare class QueryRegistry {
3007
+ private _queries;
3008
+ /**
3009
+ * Register a Flo.w reactive query.
3010
+ *
3011
+ * @param query Query to register.
3012
+ */
3013
+ registerQuery(query: Query<any>): void;
3014
+ /**
3015
+ * Un-register a Flo.w reactive query.
3016
+ *
3017
+ * @param query Query to unregister.
3018
+ */
3019
+ unregisterQuery(query: Query<any>): void;
3020
+ /**
3021
+ * Retrieve the specified query.
3022
+ *
3023
+ * This method returns a promise that resolves when the query has been initialized.
3024
+ *
3025
+ * @param id Map ID.
3026
+ */
3027
+ getQuery<TResults = any, TState extends StateStore = any>(id: string): Promise<Query<TResults, TState>>;
3028
+ }
3029
+
1884
3030
  declare const DEFAULT_CONTEXT_ID = "default";
1885
3031
  interface FlowContextOptions<TState extends StateStore = StateStore> {
1886
3032
  id?: string;
@@ -1904,13 +3050,10 @@ declare class FlowContext<TState extends StateStore = StateStore> {
1904
3050
  *
1905
3051
  * Use [[ContextRegistry.initializeContext]] to create an instance of `FlowCoreContext`.
1906
3052
  *
1907
- * @param id The ID of the context.
1908
- * @param host The Flo.w Engine host URL.
1909
- * @param apiKey The Flo.w Engine API key.
1910
- * @param enableDebug Set to `true` to enable the debugger.
3053
+ * @param options - The context options.
1911
3054
  */
1912
3055
  constructor(options: FlowContextOptions<TState>);
1913
3056
  evaluateExpression(expr: string): any;
1914
3057
  }
1915
3058
 
1916
- export { type QueryOptions as $, type Annotation as A, BackgroundLayerStyleBuilder as B, CircleLayerStyleBuilder as C, DEFAULT_CONTEXT_ID as D, type MapFeatureIdentifier as E, type FlowContextOptions as F, type MapPaddingOptions as G, HeatmapLayerStyleBuilder as H, type MapSourceIdentifier as I, type MapOptions as J, FlowCoreMap as K, LineLayerStyleBuilder as L, type MapStyleSpecification as M, Query as N, query as O, queryMany as P, QueryRegistry as Q, ReactiveExpression as R, StateStore as S, queryOne as T, type QueryResultFormat as U, type QueryAttribute as V, type QueryWhereClauses as W, type QueryExtraParams as X, type QueryOrderClause as Y, type QuerySampleOptions as Z, type QueryDefinition as _, FlowContext as a, type QueryDefinitionFn as a0, type QueryResultTransformFn as a1, traceReaction as a2, type Path as a3, type PathValue as a4, type StoreConstructor as a5, type StoreAnnotations as a6, type SerializationFormat as a7, MapEvent as a8, type MapFeatureId as a9, MapPluginBase as aa, PluginManager as ab, MapSourceEvent as ac, MapMouseEvent as ad, MapFeatureStream as ae, type PartialBy as af, MapStyleChangeEvent as ag, type PluginOptionsType as ah, type PluginEventsType as ai, type PluginConstructor as aj, type EventHandlers as ak, MapDataSource as b, MapLayer as c, MapRegistry as d, type FlowEngineEndpoint as e, type MapLayerType as f, FillLayerStyleBuilder as g, SymbolLayerStyleBuilder as h, FillExtrusionLayerStyleBuilder as i, RasterLayerStyleBuilder as j, HillshadeLayerStyleBuilder as k, layerStyle as l, MapLayerStyleBuilder as m, StyleExpression as n, expr as o, type MapLayerOptions as p, type MapLayerExpression as q, type MapLayerSpecification as r, type MapLayerPropertyMetadataIndex as s, type MapDataSourceType as t, type MapDataSourceOptions as u, type MapDataSourceSpecification as v, type MapGeojsonData as w, type MapAnimationOptions as x, type MapCenterOptions as y, type MapFeature as z };
3059
+ export { type MapOptions as $, type Annotation as A, BackgroundLayerStyleBuilder as B, CircleLayerStyleBuilder as C, DEFAULT_CONTEXT_ID as D, type MapLayerExpression as E, type FlowContextOptions as F, type MapLayerSpecification as G, HeatmapLayerStyleBuilder as H, type MapLayerPropertyMetadataIndex as I, type MapDataSourceType as J, type MapDataSourceOptions as K, LineLayerStyleBuilder as L, type MapStyleSpecification as M, type MapDataSourceSpecification as N, type MapGeojsonData as O, type ParserExpression as P, QueryRegistry as Q, ReactiveExpression as R, StateStore as S, type MapAnimationOptions as T, type MapCenterOptions as U, type MapFeature as V, type MapFeatureIdentifier as W, type MapPaddingOptions as X, type MapSourceIdentifier as Y, MapFeatureStream as Z, type FeatureStreamOptions as _, MapDataSource as a, FlowCoreMap as a0, type MapEventTypes as a1, type MapEventType as a2, MapEvent as a3, MapMouseEvent as a4, MapSourceEvent as a5, MapLoadingEvent as a6, MapStyleChangeEvent as a7, type MapPopupTemplateFn as a8, type MapPopupOptions as a9, type PluginEventsType as aA, type PluginConstructor as aB, type EventHandlers as aC, MapPopup as aa, Query as ab, query as ac, queryMany as ad, queryOne as ae, type QueryResultFormat as af, type QueryAttribute as ag, type QueryWhereClauses as ah, type QueryExtraParams as ai, type QueryOrderClause as aj, type QuerySampleOptions as ak, type QueryDefinition as al, type QueryOptions as am, type QueryDefinitionFn as an, type QueryResultTransformFn as ao, traceReaction as ap, type Path as aq, type PathValue as ar, type StoreConstructor as as, type StoreAnnotations as at, type SerializationFormat as au, type MapFeatureId as av, MapPluginBase as aw, PluginManager as ax, type PartialBy as ay, type PluginOptionsType as az, MapLayer as b, FlowContext as c, FlowCoreError as d, FlowCoreExpressionError as e, FlowMapError as f, MapRegistry as g, type FlowCoreExpressionCustomFunction as h, type FlowCoreExpressionCustomFunctionSignature as i, type FlowCoreExpressionCustomFunctions as j, type ParserExpressionWithIndex as k, type ParserFunctionExpression as l, type ParserIndex as m, type ParserProgram as n, type FlowEngineEndpoint as o, type MapLayerType as p, FillLayerStyleBuilder as q, SymbolLayerStyleBuilder as r, FillExtrusionLayerStyleBuilder as s, RasterLayerStyleBuilder as t, HillshadeLayerStyleBuilder as u, layerStyle as v, MapLayerStyleBuilder as w, StyleExpression as x, expr as y, type MapLayerOptions as z };