@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.
- package/README.md +1 -64
- package/dist/index.d.mts +36 -31
- package/dist/index.d.ts +36 -31
- package/dist/index.mjs +20 -3249
- package/dist/lib/context/context-registry.mjs +63 -0
- package/dist/lib/context/debugger.mjs +240 -0
- package/dist/lib/context/flow-context.mjs +61 -0
- package/dist/lib/context/global-state.mjs +70 -0
- package/dist/lib/context/map-registry.mjs +59 -0
- package/dist/lib/context/query-registry.mjs +53 -0
- package/dist/lib/errors/flow-error.mjs +10 -0
- package/dist/lib/errors/flow-expression-error.mjs +14 -0
- package/dist/lib/errors/flow-map-error.mjs +9 -0
- package/dist/lib/expressions/expression-parser.mjs +198 -0
- package/dist/lib/expressions/functions/from-palette.mjs +75 -0
- package/dist/lib/expressions/functions/regex.mjs +25 -0
- package/dist/lib/expressions/functions/state.mjs +25 -0
- package/dist/lib/expressions/parser-helpers.mjs +37 -0
- package/dist/lib/expressions/reactive-expression.mjs +253 -0
- package/dist/lib/map/flow-core-map.mjs +749 -0
- package/dist/lib/map/plugins/annotations/annotation-layers.mjs +163 -0
- package/dist/lib/map/plugins/annotations/annotation.events.mjs +27 -0
- package/dist/lib/map/plugins/annotations/annotation.plugin.mjs +498 -0
- package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/modes/DirectModeOverride.mjs +67 -0
- package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/modes/DragCircleMode.mjs +65 -0
- package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/utils/create_supplementary_points_circle.mjs +15 -0
- package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/utils/drag_pan.mjs +20 -0
- package/dist/lib/map/plugins/data-join.plugin.mjs +173 -0
- package/dist/lib/map/plugins/export/export.plugin.mjs +21 -0
- package/dist/lib/map/plugins/export/map-exporter.mjs +177 -0
- package/dist/lib/map/plugins/hover-effect.plugin.mjs +58 -0
- package/dist/lib/map/plugins/index.d.mts +37 -72
- package/dist/lib/map/plugins/index.d.ts +37 -72
- package/dist/lib/map/plugins/index.mjs +11 -1811
- package/dist/lib/map/plugins/keyboard-shortcut-manager.mjs +120 -0
- package/dist/lib/map/plugins/map-plugin-base.mjs +25 -0
- package/dist/lib/map/plugins/plugin-manager.mjs +135 -0
- package/dist/lib/map/plugins/popup.plugin.mjs +55 -0
- package/dist/lib/map/plugins/selection/selection.events.mjs +21 -0
- package/dist/lib/map/plugins/selection/selection.plugin.mjs +136 -0
- package/dist/lib/map/plugins/selection/source-selection.mjs +156 -0
- package/dist/lib/map/plugins/url-sync.plugin.mjs +55 -0
- package/dist/lib/map/support/image-registry.mjs +82 -0
- package/dist/lib/map/support/map-events.mjs +71 -0
- package/dist/lib/map/support/map-feature-stream.mjs +158 -0
- package/dist/lib/map/support/map-popup.mjs +159 -0
- package/dist/lib/map/types.mjs +7 -0
- package/dist/lib/map-style/map-data-source.mjs +192 -0
- package/dist/lib/map-style/map-layer-style-builder-generated.mjs +1307 -0
- package/dist/lib/map-style/map-layer-style-builder.mjs +86 -0
- package/dist/lib/map-style/map-layer.mjs +223 -0
- package/dist/lib/map-style/map-style.mjs +178 -0
- package/dist/lib/queries/async-committer.mjs +30 -0
- package/dist/lib/queries/query.mjs +172 -0
- package/dist/lib/state-store/decorators.mjs +83 -0
- package/dist/lib/state-store/state-store.mjs +534 -0
- package/dist/lib/state-store/utils.mjs +7 -0
- package/dist/lib/utils/announce.mjs +12 -0
- package/dist/lib/utils/assert.mjs +12 -0
- package/dist/{shared/flow-rdf-core.187cb345.mjs → lib/utils/debounce.mjs} +3 -39
- package/dist/lib/utils/decorators.mjs +59 -0
- package/dist/lib/utils/deferred.mjs +11 -0
- package/dist/lib/utils/ensure-array.mjs +16 -0
- package/dist/{shared/flow-rdf-core.1f0901c5.mjs → lib/utils/feature-type-checks.mjs} +2 -2
- package/dist/lib/utils/functional.mjs +22 -0
- package/dist/lib/utils/global.mjs +18 -0
- package/dist/lib/utils/index.mjs +8 -5
- package/dist/lib/utils/random-id.mjs +9 -0
- package/dist/lib/utils/string-utils.mjs +3 -0
- package/dist/lib/utils/throttle.mjs +20 -0
- package/dist/{shared/flow-rdf-core.25e5f6d7.mjs → lib/utils/type-checks.mjs} +1 -26
- package/dist/lib/utils/watchable-promise.mjs +55 -0
- package/dist/package.json.mjs +3 -0
- package/dist/shared/{flow-rdf-core.4dde996e.d.cts → flow-rdf-core.8b5acf14.d.mts} +1315 -172
- package/dist/shared/{flow-rdf-core.4dde996e.d.ts → flow-rdf-core.8b5acf14.d.ts} +1315 -172
- package/package.json +4 -8
- package/dist/index.cjs +0 -3316
- package/dist/index.d.cts +0 -90
- package/dist/lib/map/plugins/index.cjs +0 -1851
- package/dist/lib/map/plugins/index.d.cts +0 -345
- package/dist/lib/utils/index.cjs +0 -48
- package/dist/lib/utils/index.d.cts +0 -160
- package/dist/shared/flow-rdf-core.06e85a6c.cjs +0 -1394
- package/dist/shared/flow-rdf-core.4dde996e.d.mts +0 -1916
- package/dist/shared/flow-rdf-core.55c169ca.cjs +0 -150
- package/dist/shared/flow-rdf-core.63162669.d.cts +0 -10
- package/dist/shared/flow-rdf-core.65045caf.mjs +0 -1360
- package/dist/shared/flow-rdf-core.a82b9be4.cjs +0 -34
- package/dist/shared/flow-rdf-core.f50908f0.cjs +0 -102
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { isString, isNumber, isBoolean, isArray } from '../utils/type-checks.mjs';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __publicField = (obj, key, value) => {
|
|
6
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
7
|
+
return value;
|
|
8
|
+
};
|
|
9
|
+
class MapLayerStyleBuilder {
|
|
10
|
+
constructor() {
|
|
11
|
+
__publicField(this, "_styles", /* @__PURE__ */ new Map());
|
|
12
|
+
}
|
|
13
|
+
static registerStyleBuilder(layerType, builder) {
|
|
14
|
+
this._styleBuilders.set(layerType, builder);
|
|
15
|
+
}
|
|
16
|
+
static createStyleBuilder(layerType) {
|
|
17
|
+
const builder = this._styleBuilders.get(layerType);
|
|
18
|
+
if (!builder) {
|
|
19
|
+
throw new Error(`MapLayerStyleBuilder: Unknown layer type '${layerType}'`);
|
|
20
|
+
}
|
|
21
|
+
return new builder();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Whether this layer is displayed.
|
|
25
|
+
*
|
|
26
|
+
* @param value - visible value (default `true`)
|
|
27
|
+
*/
|
|
28
|
+
visibility(value) {
|
|
29
|
+
this.addStyle("visibility", value);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a style specification string.
|
|
34
|
+
*
|
|
35
|
+
* Call this method after setting all style properties
|
|
36
|
+
* on the style builder.
|
|
37
|
+
*
|
|
38
|
+
* @returns Layer style specification string
|
|
39
|
+
*/
|
|
40
|
+
build() {
|
|
41
|
+
const styles = [];
|
|
42
|
+
for (const [prop, value] of this._styles.entries()) {
|
|
43
|
+
styles.push(`${prop}: ${value};`);
|
|
44
|
+
}
|
|
45
|
+
return styles.join("\n");
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Format and add style property to the style builder.
|
|
49
|
+
*/
|
|
50
|
+
addStyle(property, value) {
|
|
51
|
+
this._styles.set(property, this.formatValue(value));
|
|
52
|
+
}
|
|
53
|
+
formatValue(value) {
|
|
54
|
+
if (isStyleExpression(value)) {
|
|
55
|
+
return value.toString();
|
|
56
|
+
} else if (isString(value)) {
|
|
57
|
+
return `'${value.toString()}'`;
|
|
58
|
+
} else if (isNumber(value)) {
|
|
59
|
+
return value.toString();
|
|
60
|
+
} else if (isBoolean(value)) {
|
|
61
|
+
return (!!value).toString();
|
|
62
|
+
} else if (isArray(value)) {
|
|
63
|
+
return `[${value.map((v) => this.formatValue(v)).join(", ")}]`;
|
|
64
|
+
} else {
|
|
65
|
+
return value.toString();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
__publicField(MapLayerStyleBuilder, "_styleBuilders", /* @__PURE__ */ new Map());
|
|
70
|
+
class StyleExpression {
|
|
71
|
+
constructor(_expr) {
|
|
72
|
+
this._expr = _expr;
|
|
73
|
+
__publicField(this, "__styleExpression", "styleexpression");
|
|
74
|
+
}
|
|
75
|
+
toString() {
|
|
76
|
+
return this._expr;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function isStyleExpression(val) {
|
|
80
|
+
return val && val.__styleExpression;
|
|
81
|
+
}
|
|
82
|
+
function expr(expr2) {
|
|
83
|
+
return new StyleExpression(expr2);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { MapLayerStyleBuilder, StyleExpression, expr };
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import * as maplibreSpec from '@emuanalytics/maplibre-gl-style-spec';
|
|
2
|
+
import { makeObservable, observable, computed, action } from 'mobx';
|
|
3
|
+
import { isDefined, isObjectFull, isNil } from '../utils/type-checks.mjs';
|
|
4
|
+
import { ReactiveExpression } from '../expressions/reactive-expression.mjs';
|
|
5
|
+
import { FlowCoreError } from '../errors/flow-error.mjs';
|
|
6
|
+
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __publicField = (obj, key, value) => {
|
|
10
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
11
|
+
return value;
|
|
12
|
+
};
|
|
13
|
+
const _MapLayer = class _MapLayer {
|
|
14
|
+
constructor(options) {
|
|
15
|
+
__publicField(this, "_options");
|
|
16
|
+
__publicField(this, "_state", null);
|
|
17
|
+
__publicField(this, "_filter", null);
|
|
18
|
+
__publicField(this, "_paintProps", {});
|
|
19
|
+
__publicField(this, "_layoutProps", {});
|
|
20
|
+
this._options = {
|
|
21
|
+
..._MapLayer._defaultOptions,
|
|
22
|
+
...options
|
|
23
|
+
};
|
|
24
|
+
this.getPropertyMetadata("visibility", options.type);
|
|
25
|
+
makeObservable(
|
|
26
|
+
this,
|
|
27
|
+
{
|
|
28
|
+
//observable
|
|
29
|
+
_paintProps: observable,
|
|
30
|
+
_layoutProps: observable,
|
|
31
|
+
_filter: observable,
|
|
32
|
+
_options: observable,
|
|
33
|
+
//computed
|
|
34
|
+
layerSpecification: computed,
|
|
35
|
+
// actions
|
|
36
|
+
bindState: action,
|
|
37
|
+
setMinZoom: action,
|
|
38
|
+
setMaxZoom: action,
|
|
39
|
+
setInteractive: action,
|
|
40
|
+
setAbove: action,
|
|
41
|
+
setBelow: action,
|
|
42
|
+
setStyle: action,
|
|
43
|
+
setStyleProperty: action,
|
|
44
|
+
setFilter: action
|
|
45
|
+
},
|
|
46
|
+
{ name: this.formattedName(options.id) }
|
|
47
|
+
);
|
|
48
|
+
if (options.filter) {
|
|
49
|
+
this.setFilter(options.filter);
|
|
50
|
+
}
|
|
51
|
+
if (options.style) {
|
|
52
|
+
this.setStyle(options.style);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
get layerSpecification() {
|
|
56
|
+
this._options.above;
|
|
57
|
+
this._options.below;
|
|
58
|
+
const layer = {
|
|
59
|
+
id: this._options.id,
|
|
60
|
+
type: this._options.type,
|
|
61
|
+
source: this._options.source
|
|
62
|
+
};
|
|
63
|
+
if (isDefined(this._options.minZoom)) {
|
|
64
|
+
layer.minzoom = this._options.minZoom;
|
|
65
|
+
}
|
|
66
|
+
if (isDefined(this._options.maxZoom)) {
|
|
67
|
+
layer.maxzoom = this._options.maxZoom;
|
|
68
|
+
}
|
|
69
|
+
if (isDefined(this._options.sourceLayer)) {
|
|
70
|
+
layer["source-layer"] = this._options.sourceLayer;
|
|
71
|
+
}
|
|
72
|
+
if (isDefined(this._filter)) {
|
|
73
|
+
layer.filter = this._filter.maplibreExpression;
|
|
74
|
+
}
|
|
75
|
+
if (isObjectFull(this._paintProps)) {
|
|
76
|
+
layer.paint = Object.keys(this._paintProps).reduce((accum, key) => {
|
|
77
|
+
accum[key] = this._paintProps[key].maplibreExpression;
|
|
78
|
+
return accum;
|
|
79
|
+
}, {});
|
|
80
|
+
}
|
|
81
|
+
if (isObjectFull(this._layoutProps)) {
|
|
82
|
+
layer.layout = Object.keys(this._layoutProps).reduce((accum, key) => {
|
|
83
|
+
let expr = this._layoutProps[key].maplibreExpression;
|
|
84
|
+
if (key === "visibility") {
|
|
85
|
+
expr = this._layoutProps[key].value ? "visible" : "none";
|
|
86
|
+
}
|
|
87
|
+
accum[key] = expr;
|
|
88
|
+
return accum;
|
|
89
|
+
}, {});
|
|
90
|
+
}
|
|
91
|
+
return layer;
|
|
92
|
+
}
|
|
93
|
+
get id() {
|
|
94
|
+
return this._options.id;
|
|
95
|
+
}
|
|
96
|
+
get type() {
|
|
97
|
+
return this._options.type;
|
|
98
|
+
}
|
|
99
|
+
get source() {
|
|
100
|
+
return this._options.source;
|
|
101
|
+
}
|
|
102
|
+
get interactive() {
|
|
103
|
+
return !!this._options.interactive;
|
|
104
|
+
}
|
|
105
|
+
get above() {
|
|
106
|
+
return this._options.above;
|
|
107
|
+
}
|
|
108
|
+
get below() {
|
|
109
|
+
return this._options.below;
|
|
110
|
+
}
|
|
111
|
+
bindState(state) {
|
|
112
|
+
this._state = state;
|
|
113
|
+
if (this._filter) {
|
|
114
|
+
this._filter.bindState(state);
|
|
115
|
+
}
|
|
116
|
+
Object.values(this._paintProps).forEach((prop) => prop.bindState(state));
|
|
117
|
+
Object.values(this._layoutProps).forEach((prop) => prop.bindState(state));
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
setMinZoom(zoom) {
|
|
121
|
+
this._options.minZoom = zoom;
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
setMaxZoom(zoom) {
|
|
125
|
+
this._options.maxZoom = zoom;
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
setInteractive(interactive) {
|
|
129
|
+
this._options.interactive = interactive;
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
setAbove(layerId) {
|
|
133
|
+
this._options.above = layerId;
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
setBelow(layerId) {
|
|
137
|
+
this._options.below = layerId;
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
setStyle(styleProgram) {
|
|
141
|
+
const parsedProgram = ReactiveExpression.parseProgram(styleProgram);
|
|
142
|
+
const props = Object.keys(parsedProgram);
|
|
143
|
+
props.forEach((prop) => {
|
|
144
|
+
const metadata = this.getPropertyMetadata(prop, this._options.type);
|
|
145
|
+
const layerProps = metadata.type === "paint" ? this._paintProps : this._layoutProps;
|
|
146
|
+
layerProps[prop] = parsedProgram[prop].bindState(this._state);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Set an individual style property.
|
|
151
|
+
*
|
|
152
|
+
* @param property Property name.
|
|
153
|
+
* @param expression Property style expression.
|
|
154
|
+
*/
|
|
155
|
+
setStyleProperty(property, expression) {
|
|
156
|
+
const metadata = this.getPropertyMetadata(property, this._options.type);
|
|
157
|
+
const props = metadata.type === "paint" ? this._paintProps : this._layoutProps;
|
|
158
|
+
if (isNil(expression)) {
|
|
159
|
+
delete props[property];
|
|
160
|
+
} else {
|
|
161
|
+
const expr = new ReactiveExpression(expression).bindState(this._state);
|
|
162
|
+
if (expr.parseError) {
|
|
163
|
+
throw expr.parseError;
|
|
164
|
+
}
|
|
165
|
+
props[property] = expr;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
setFilter(expression) {
|
|
169
|
+
this._filter = null;
|
|
170
|
+
if (isDefined(expression)) {
|
|
171
|
+
let expr = new ReactiveExpression(expression).bindState(this._state);
|
|
172
|
+
if (expr.parseError) {
|
|
173
|
+
throw expr.parseError;
|
|
174
|
+
}
|
|
175
|
+
if (!maplibreSpec.expression.isExpressionFilter(expr.maplibreExpression)) {
|
|
176
|
+
expr = new ReactiveExpression(expr.expression, ["to-boolean", expr.maplibreExpression]);
|
|
177
|
+
}
|
|
178
|
+
this._filter = expr;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
formattedName(id) {
|
|
182
|
+
return `MapLayer<${id || this._options.id}>`;
|
|
183
|
+
}
|
|
184
|
+
getPropertyMetadata(property, layerType) {
|
|
185
|
+
if (!_MapLayer._propertyMetadataIndex) {
|
|
186
|
+
_MapLayer.initializePropertyMetadataIndex();
|
|
187
|
+
}
|
|
188
|
+
const layerMetadata = _MapLayer._propertyMetadataIndex[layerType];
|
|
189
|
+
if (!layerMetadata) {
|
|
190
|
+
throw new FlowCoreError(`${this.formattedName()}: unknown layer type '${layerType}'`);
|
|
191
|
+
}
|
|
192
|
+
const propertyMetadata = layerMetadata[property];
|
|
193
|
+
if (!propertyMetadata) {
|
|
194
|
+
throw new FlowCoreError(`${this.formattedName()}: unknown layer property '${property}'`);
|
|
195
|
+
}
|
|
196
|
+
return propertyMetadata;
|
|
197
|
+
}
|
|
198
|
+
static initializePropertyMetadataIndex() {
|
|
199
|
+
const layerTypes = Object.keys(maplibreSpec.latest.layer.type.values);
|
|
200
|
+
this._propertyMetadataIndex = layerTypes.reduce((acc, layerType) => {
|
|
201
|
+
acc[layerType] = {};
|
|
202
|
+
["layout", "paint"].forEach((propType) => {
|
|
203
|
+
Object.keys(maplibreSpec.latest[`${propType}_${layerType}`]).forEach((prop) => {
|
|
204
|
+
acc[layerType][prop] = {
|
|
205
|
+
property: prop,
|
|
206
|
+
type: propType,
|
|
207
|
+
definition: maplibreSpec.latest[`${propType}_${layerType}`][prop]
|
|
208
|
+
};
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
return acc;
|
|
212
|
+
}, {});
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
__publicField(_MapLayer, "_propertyMetadataIndex");
|
|
216
|
+
__publicField(_MapLayer, "_defaultOptions", {
|
|
217
|
+
interactive: true,
|
|
218
|
+
minZoom: 0,
|
|
219
|
+
maxZoom: 18
|
|
220
|
+
});
|
|
221
|
+
let MapLayer = _MapLayer;
|
|
222
|
+
|
|
223
|
+
export { MapLayer };
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { makeObservable, observable, computed, action } from 'mobx';
|
|
2
|
+
import { isNil } from '../utils/type-checks.mjs';
|
|
3
|
+
import { FlowCoreError } from '../errors/flow-error.mjs';
|
|
4
|
+
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __publicField = (obj, key, value) => {
|
|
8
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
9
|
+
return value;
|
|
10
|
+
};
|
|
11
|
+
const _MapStyle = class _MapStyle {
|
|
12
|
+
constructor() {
|
|
13
|
+
__publicField(this, "_state", null);
|
|
14
|
+
__publicField(this, "_baseStyle");
|
|
15
|
+
__publicField(this, "_sources", {});
|
|
16
|
+
__publicField(this, "_layers", {});
|
|
17
|
+
__publicField(this, "_layerOrder", []);
|
|
18
|
+
this._baseStyle = _MapStyle._defaultBaseStyle;
|
|
19
|
+
makeObservable(
|
|
20
|
+
this,
|
|
21
|
+
{
|
|
22
|
+
//observable
|
|
23
|
+
_sources: observable,
|
|
24
|
+
_layers: observable,
|
|
25
|
+
_layerOrder: observable,
|
|
26
|
+
_baseStyle: observable.ref,
|
|
27
|
+
//computed
|
|
28
|
+
styleSpecification: computed,
|
|
29
|
+
// actions
|
|
30
|
+
bindState: action,
|
|
31
|
+
setBaseStyle: action,
|
|
32
|
+
addSource: action,
|
|
33
|
+
removeSource: action,
|
|
34
|
+
addLayer: action,
|
|
35
|
+
removeLayer: action
|
|
36
|
+
},
|
|
37
|
+
{ name: this.formattedName }
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
get styleSpecification() {
|
|
41
|
+
const spec = {
|
|
42
|
+
...this._baseStyle,
|
|
43
|
+
sources: { ...this._baseStyle.sources },
|
|
44
|
+
layers: [...this._baseStyle.layers]
|
|
45
|
+
};
|
|
46
|
+
Object.values(this._sources).forEach((source) => {
|
|
47
|
+
spec.sources[source.id] = source.dataSourceSpecification;
|
|
48
|
+
});
|
|
49
|
+
this._layerOrder.forEach((id) => {
|
|
50
|
+
const layer = this._layers[id];
|
|
51
|
+
const layerSpec = layer.layerSpecification;
|
|
52
|
+
const baseLayerIndex = spec.layers.findIndex((l) => l.id === id);
|
|
53
|
+
if (baseLayerIndex >= 0) {
|
|
54
|
+
const baseLayer = spec.layers[baseLayerIndex];
|
|
55
|
+
const mergedBaseLayer = {
|
|
56
|
+
...baseLayer,
|
|
57
|
+
paint: {
|
|
58
|
+
...baseLayer.paint,
|
|
59
|
+
...layerSpec.paint
|
|
60
|
+
},
|
|
61
|
+
layout: {
|
|
62
|
+
...baseLayer.layout,
|
|
63
|
+
...layerSpec.layout
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
spec.layers.splice(baseLayerIndex, 1, mergedBaseLayer);
|
|
67
|
+
} else {
|
|
68
|
+
const source = spec.sources[layer.source];
|
|
69
|
+
if (source.type === "vector" && isNil(layerSpec["source-layer"])) {
|
|
70
|
+
layerSpec["source-layer"] = "geometry";
|
|
71
|
+
}
|
|
72
|
+
const layerIndex = this.layerInsertionPoint(layer, spec);
|
|
73
|
+
spec.layers.splice(layerIndex, 0, layer.layerSpecification);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return spec;
|
|
77
|
+
}
|
|
78
|
+
get formattedName() {
|
|
79
|
+
return `MapStyle<${this._baseStyle.id}>`;
|
|
80
|
+
}
|
|
81
|
+
bindState(state) {
|
|
82
|
+
this._state = state;
|
|
83
|
+
state.transaction(() => {
|
|
84
|
+
Object.values(this._sources).forEach((source) => source.bindState(state));
|
|
85
|
+
Object.values(this._layers).forEach((layer) => layer.bindState(state));
|
|
86
|
+
});
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
setBaseStyle(style) {
|
|
90
|
+
this._baseStyle = style ? Object.freeze({ ...style }) : _MapStyle._defaultBaseStyle;
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
addSource(source) {
|
|
94
|
+
this._sources[source.id] = source;
|
|
95
|
+
source.bindState(this._state);
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
removeSource(id, removeLayers = false) {
|
|
99
|
+
if (!this._sources[id]) {
|
|
100
|
+
throw new FlowCoreError(`${this.formattedName}: no source with id '${id}'`);
|
|
101
|
+
}
|
|
102
|
+
const linkedLayers = Object.values(this._layers).filter((layer) => layer.source === id).map((layer) => layer.id);
|
|
103
|
+
if (removeLayers) {
|
|
104
|
+
linkedLayers.forEach((id2) => this.removeLayer(id2));
|
|
105
|
+
} else if (linkedLayers.length) {
|
|
106
|
+
throw new FlowCoreError(
|
|
107
|
+
`${this.formattedName}: cannot remove source with id '${id}' when in use by layers ${linkedLayers.join(", ")}`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
delete this._sources[id];
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
getSource(id) {
|
|
114
|
+
const source = this._sources[id];
|
|
115
|
+
if (!source) {
|
|
116
|
+
throw new FlowCoreError(`${this.formattedName}: no source with id '${id}'`);
|
|
117
|
+
}
|
|
118
|
+
return source;
|
|
119
|
+
}
|
|
120
|
+
getSources(filter) {
|
|
121
|
+
return Object.values(this._sources).filter((source) => filter ? filter(source) : true);
|
|
122
|
+
}
|
|
123
|
+
addLayer(layer) {
|
|
124
|
+
if (!this._sources[layer.source] && !this._baseStyle.sources[layer.source]) {
|
|
125
|
+
throw new FlowCoreError(`${this.formattedName}: no source with id '${layer.source}'`);
|
|
126
|
+
}
|
|
127
|
+
this._layers[layer.id] = layer;
|
|
128
|
+
this._layerOrder.push(layer.id);
|
|
129
|
+
layer.bindState(this._state);
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
removeLayer(id) {
|
|
133
|
+
if (!this._layers[id]) {
|
|
134
|
+
throw new FlowCoreError(`${this.formattedName}: no layer with id '${id}'`);
|
|
135
|
+
}
|
|
136
|
+
delete this._layers[id];
|
|
137
|
+
const index = this._layerOrder.indexOf(id);
|
|
138
|
+
this._layerOrder.splice(index, 1);
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
getLayer(id) {
|
|
142
|
+
const layer = this._layers[id];
|
|
143
|
+
if (!layer) {
|
|
144
|
+
throw new FlowCoreError(`${this.formattedName}: no layer with id '${id}'`);
|
|
145
|
+
}
|
|
146
|
+
return layer;
|
|
147
|
+
}
|
|
148
|
+
getLayers(filter) {
|
|
149
|
+
return this._layerOrder.map((layerId) => this._layers[layerId]).filter((layer) => filter ? filter(layer) : true);
|
|
150
|
+
}
|
|
151
|
+
layerInsertionPoint(layer, spec) {
|
|
152
|
+
let insertionIndex = -1;
|
|
153
|
+
if (layer.above) {
|
|
154
|
+
insertionIndex = spec.layers.findIndex((l) => l.id === layer.above);
|
|
155
|
+
if (insertionIndex >= 0)
|
|
156
|
+
insertionIndex++;
|
|
157
|
+
} else if (layer.below) {
|
|
158
|
+
insertionIndex = spec.layers.findIndex((l) => l.id === layer.below);
|
|
159
|
+
} else {
|
|
160
|
+
const below = spec.metadata?.insertionPoints?.[layer.type];
|
|
161
|
+
insertionIndex = spec.layers.findIndex((l) => l.id === below);
|
|
162
|
+
}
|
|
163
|
+
if (insertionIndex === -1) {
|
|
164
|
+
insertionIndex = spec.layers.length;
|
|
165
|
+
}
|
|
166
|
+
return insertionIndex;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
__publicField(_MapStyle, "_defaultBaseStyle", Object.freeze({
|
|
170
|
+
version: 8,
|
|
171
|
+
id: "default",
|
|
172
|
+
name: "Default base style",
|
|
173
|
+
sources: {},
|
|
174
|
+
layers: []
|
|
175
|
+
}));
|
|
176
|
+
let MapStyle = _MapStyle;
|
|
177
|
+
|
|
178
|
+
export { MapStyle };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => {
|
|
4
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
return value;
|
|
6
|
+
};
|
|
7
|
+
class AsyncCommitter {
|
|
8
|
+
constructor() {
|
|
9
|
+
__publicField(this, "_requestId", 0);
|
|
10
|
+
__publicField(this, "_commitId", 0);
|
|
11
|
+
}
|
|
12
|
+
async resolve(promise) {
|
|
13
|
+
this._requestId += 1;
|
|
14
|
+
const currentRequestId = this._requestId;
|
|
15
|
+
const value = await promise;
|
|
16
|
+
if (currentRequestId <= this._commitId) {
|
|
17
|
+
return { succeeded: false };
|
|
18
|
+
}
|
|
19
|
+
this._commitId = currentRequestId;
|
|
20
|
+
return { succeeded: true, value };
|
|
21
|
+
}
|
|
22
|
+
async run(asyncFunction) {
|
|
23
|
+
return this.resolve(asyncFunction());
|
|
24
|
+
}
|
|
25
|
+
abandon() {
|
|
26
|
+
this._commitId = this._requestId;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { AsyncCommitter };
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import Debug from 'debug';
|
|
2
|
+
import { makeObservable, observable, onBecomeObserved, onBecomeUnobserved, reaction, runInAction } from 'mobx';
|
|
3
|
+
import { randomId } from '../utils/random-id.mjs';
|
|
4
|
+
import { AsyncCommitter } from './async-committer.mjs';
|
|
5
|
+
import { getGlobalState } from '../context/global-state.mjs';
|
|
6
|
+
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __publicField = (obj, key, value) => {
|
|
10
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
11
|
+
return value;
|
|
12
|
+
};
|
|
13
|
+
const debug = Debug("flow:query");
|
|
14
|
+
const DEFAULT_DELAY = 100;
|
|
15
|
+
const _Query = class _Query {
|
|
16
|
+
constructor(queryFn, transformFn, options) {
|
|
17
|
+
this.queryFn = queryFn;
|
|
18
|
+
__publicField(this, "_options");
|
|
19
|
+
__publicField(this, "_committer", new AsyncCommitter());
|
|
20
|
+
__publicField(this, "_disposer", null);
|
|
21
|
+
__publicField(this, "_transformFn", (results) => results);
|
|
22
|
+
__publicField(this, "results", null);
|
|
23
|
+
__publicField(this, "busy", false);
|
|
24
|
+
__publicField(this, "error", null);
|
|
25
|
+
this._options = {
|
|
26
|
+
..._Query._defaultOptions,
|
|
27
|
+
...options
|
|
28
|
+
};
|
|
29
|
+
this._options.id = this._options.id ?? randomId("query");
|
|
30
|
+
makeObservable(
|
|
31
|
+
this,
|
|
32
|
+
{
|
|
33
|
+
results: observable.ref,
|
|
34
|
+
busy: observable,
|
|
35
|
+
error: observable.ref
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "flowQuery"
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
onBecomeObserved(this, "results", this.wake.bind(this));
|
|
42
|
+
onBecomeUnobserved(this, "results", this.sleep.bind(this));
|
|
43
|
+
if (transformFn) {
|
|
44
|
+
this._transformFn = transformFn;
|
|
45
|
+
}
|
|
46
|
+
getGlobalState().globalContextRegistry.getContext(this._options?.contextId).then((context) => {
|
|
47
|
+
context.queries.registerQuery(this);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
static setDefaultOptions(options) {
|
|
51
|
+
this._defaultOptions = { ...this._defaultOptions, ...options };
|
|
52
|
+
}
|
|
53
|
+
get formattedName() {
|
|
54
|
+
return `Query<${this._options.id}>`;
|
|
55
|
+
}
|
|
56
|
+
get id() {
|
|
57
|
+
return this._options.id;
|
|
58
|
+
}
|
|
59
|
+
destroy() {
|
|
60
|
+
getGlobalState().globalContextRegistry.getContext(this._options?.contextId).then((context) => {
|
|
61
|
+
context.queries.unregisterQuery(this);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async runImmediately() {
|
|
65
|
+
const context = await getGlobalState().globalContextRegistry.getContext(this._options.contextId);
|
|
66
|
+
const queryDefinition = this.queryFn.call(context.state, context.state);
|
|
67
|
+
await this.runQuery(queryDefinition);
|
|
68
|
+
if (this.error) {
|
|
69
|
+
throw this.error;
|
|
70
|
+
}
|
|
71
|
+
return this.results;
|
|
72
|
+
}
|
|
73
|
+
async wake() {
|
|
74
|
+
this.sleep();
|
|
75
|
+
const context = await getGlobalState().globalContextRegistry.getContext(this._options.contextId);
|
|
76
|
+
this._disposer = reaction(
|
|
77
|
+
(r) => {
|
|
78
|
+
return this.queryFn.call(context.state, context.state);
|
|
79
|
+
},
|
|
80
|
+
(queryDefinition, prev, r) => {
|
|
81
|
+
this.runQuery(queryDefinition);
|
|
82
|
+
},
|
|
83
|
+
{ name: this.formattedName, fireImmediately: this._options.fireImmediately, delay: this._options.delay }
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
sleep() {
|
|
87
|
+
if (this._disposer) {
|
|
88
|
+
runInAction(() => {
|
|
89
|
+
this.results = null;
|
|
90
|
+
this.error = null;
|
|
91
|
+
this.busy = false;
|
|
92
|
+
this._committer.abandon();
|
|
93
|
+
});
|
|
94
|
+
const disposer = this._disposer;
|
|
95
|
+
this._disposer = null;
|
|
96
|
+
disposer();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async runQuery(queryDefinition) {
|
|
100
|
+
debug(`${this.formattedName}: running query`, queryDefinition);
|
|
101
|
+
const context = await getGlobalState().globalContextRegistry.getContext(this._options.contextId);
|
|
102
|
+
try {
|
|
103
|
+
if (queryDefinition === null) {
|
|
104
|
+
runInAction(() => {
|
|
105
|
+
this.results = null;
|
|
106
|
+
this.error = null;
|
|
107
|
+
this.busy = false;
|
|
108
|
+
});
|
|
109
|
+
} else {
|
|
110
|
+
runInAction(() => {
|
|
111
|
+
this.busy = true;
|
|
112
|
+
this.error = null;
|
|
113
|
+
});
|
|
114
|
+
const response = await this._committer.run(() => {
|
|
115
|
+
return context.flowClient.datasets.query(queryDefinition);
|
|
116
|
+
});
|
|
117
|
+
if (response.succeeded) {
|
|
118
|
+
runInAction(() => {
|
|
119
|
+
this.results = this._transformFn(response.value);
|
|
120
|
+
this.busy = false;
|
|
121
|
+
});
|
|
122
|
+
} else {
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
} catch (e) {
|
|
126
|
+
console.error(`${this.formattedName}: ${e.message}`);
|
|
127
|
+
runInAction(() => {
|
|
128
|
+
this.results = null;
|
|
129
|
+
this.error = e;
|
|
130
|
+
this.busy = false;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
__publicField(_Query, "_defaultOptions", {
|
|
136
|
+
fireImmediately: true,
|
|
137
|
+
delay: DEFAULT_DELAY
|
|
138
|
+
});
|
|
139
|
+
let Query = _Query;
|
|
140
|
+
function query(queryFn, transformFnOrOptions, options) {
|
|
141
|
+
if (typeof transformFnOrOptions === "object") {
|
|
142
|
+
options = transformFnOrOptions;
|
|
143
|
+
transformFnOrOptions = void 0;
|
|
144
|
+
}
|
|
145
|
+
return new Query(queryFn, transformFnOrOptions, options);
|
|
146
|
+
}
|
|
147
|
+
function queryMany(queryFn, transformFnOrOptions, options) {
|
|
148
|
+
if (typeof transformFnOrOptions === "object") {
|
|
149
|
+
options = transformFnOrOptions;
|
|
150
|
+
transformFnOrOptions = void 0;
|
|
151
|
+
}
|
|
152
|
+
return query(queryFn, transformFnOrOptions, options);
|
|
153
|
+
}
|
|
154
|
+
function queryOne(queryFn, transformFnOrOptions, options) {
|
|
155
|
+
if (typeof transformFnOrOptions === "object") {
|
|
156
|
+
options = transformFnOrOptions;
|
|
157
|
+
transformFnOrOptions = void 0;
|
|
158
|
+
}
|
|
159
|
+
const oneTransform = (results) => {
|
|
160
|
+
let oneResult = null;
|
|
161
|
+
if (results?.length) {
|
|
162
|
+
oneResult = results[0];
|
|
163
|
+
}
|
|
164
|
+
if (transformFnOrOptions && typeof transformFnOrOptions === "function") {
|
|
165
|
+
oneResult = transformFnOrOptions(oneResult);
|
|
166
|
+
}
|
|
167
|
+
return oneResult;
|
|
168
|
+
};
|
|
169
|
+
return query(queryFn, oneTransform, options);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export { Query, query, queryMany, queryOne };
|