@carto/api-client 0.5.0-alpha.7 → 0.5.0-alpha.8

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.
@@ -1,240 +0,0 @@
1
- import {
2
- CategoryRequestOptions,
3
- CategoryResponse,
4
- FeaturesResponse,
5
- FormulaRequestOptions,
6
- FormulaResponse,
7
- HistogramRequestOptions,
8
- HistogramResponse,
9
- RangeRequestOptions,
10
- RangeResponse,
11
- ScatterRequestOptions,
12
- ScatterResponse,
13
- TableRequestOptions,
14
- TableResponse,
15
- TimeSeriesRequestOptions,
16
- TimeSeriesResponse,
17
- } from './types.js';
18
- import {SpatialFilter, Tile} from '../types.js';
19
- import {TileFeatureExtractOptions} from '../filters/index.js';
20
- import {FeatureCollection} from 'geojson';
21
- import {WidgetSource} from './widget-source.js';
22
- import {WidgetTilesetSourceProps} from './widget-tileset-source.js';
23
- import {Method} from '../workers/constants.js';
24
- import {WorkerRequest, WorkerResponse} from '../workers/types.js';
25
-
26
- /**
27
- * Wrapper for {@link WidgetTilesetSource}, moving calculations to Web Workers.
28
- * When supported, use of both classes is identical.
29
- *
30
- * To use this wrapper, the application and environment must support ESM Web
31
- * Workers. For older build systems based on CommonJS, or in environments like
32
- * Node.js, it may be necessary to use {@link WidgetTilesetSource} directly,
33
- * and to (optionally) create workers manually in the application.
34
- */
35
- export class WidgetTilesetWorkerSource extends WidgetSource<WidgetTilesetSourceProps> {
36
- constructor(props: WidgetTilesetSourceProps) {
37
- super(props);
38
- }
39
-
40
- /////////////////////////////////////////////////////////////////////////////
41
- // WEB WORKER MANAGEMENT
42
-
43
- protected _worker: Worker | null = null;
44
- protected _workerNextRequestId = 1;
45
-
46
- /**
47
- * Returns an initialized Worker, to be reused for the lifecycle of this
48
- * source instance.
49
- */
50
- _getWorker() {
51
- if (this._worker) {
52
- return this._worker;
53
- }
54
-
55
- this._worker = new Worker(
56
- new URL('@carto/api-client/worker', import.meta.url),
57
- {
58
- type: 'module',
59
- name: 'cartowidgettileset',
60
- }
61
- );
62
-
63
- this._worker.postMessage({
64
- method: Method.INIT,
65
- params: [this.props],
66
- } as WorkerRequest);
67
-
68
- return this._worker;
69
- }
70
-
71
- /** Executes a given method on the worker. */
72
- _executeWorkerMethod<T>(
73
- method: Method,
74
- params: unknown[],
75
- signal?: AbortSignal
76
- ): Promise<T> {
77
- const worker = this._getWorker();
78
- const requestId = this._workerNextRequestId++;
79
-
80
- // TODO: ViewState may contain non-serializable data, which we do not need.
81
- // Remove this sanitization after sc-469614 is fixed.
82
- const options = params[0] as any;
83
- if (options?.spatialIndexReferenceViewState) {
84
- const {zoom, latitude, longitude} =
85
- options.spatialIndexReferenceViewState;
86
- options.spatialIndexReferenceViewState = {zoom, latitude, longitude};
87
- }
88
-
89
- let resolve: ((value: T) => void) | null = null;
90
- let reject: ((reason: any) => void) | null = null;
91
-
92
- // If worker sends message to main process, check whether it's a response
93
- // to this request, and whether the request can been aborted. Then resolve
94
- // or reject the Promise.
95
- function onMessage(e: MessageEvent) {
96
- const response = e.data as WorkerResponse;
97
- if (response.requestId !== requestId) return;
98
-
99
- if (signal?.aborted) {
100
- reject!(new Error(signal.reason));
101
- } else if (response.ok) {
102
- resolve!(response.result as T);
103
- } else {
104
- reject!(new Error(response.error));
105
- }
106
- }
107
-
108
- // If request is aborted by user, immediately reject the Promise.
109
- function onAbort() {
110
- reject!(new Error(signal!.reason));
111
- }
112
-
113
- worker.addEventListener('message', onMessage);
114
- signal?.addEventListener('abort', onAbort);
115
-
116
- // Send the task to the worker, creating a Promise to resolve/reject later.
117
- const promise = new Promise<T>((_resolve, _reject) => {
118
- resolve = _resolve;
119
- reject = _reject;
120
-
121
- worker.postMessage({
122
- requestId,
123
- method,
124
- params,
125
- } as WorkerRequest);
126
- });
127
-
128
- // Whether the task completes, fails, or aborts: clean up afterward.
129
- void promise.finally(() => {
130
- worker.removeEventListener('message', onMessage);
131
- signal?.removeEventListener('abort', onAbort);
132
- });
133
-
134
- return promise;
135
- }
136
-
137
- /////////////////////////////////////////////////////////////////////////////
138
- // DATA LOADING
139
-
140
- /**
141
- * Loads features as a list of tiles (typically provided by deck.gl).
142
- * After tiles are loaded, {@link extractTileFeatures} must be called
143
- * before computing statistics on the tiles.
144
- */
145
- loadTiles(tiles: unknown[]) {
146
- tiles = (tiles as Tile[]).map(({id, bbox, data}) => ({
147
- id,
148
- bbox,
149
- data,
150
- }));
151
-
152
- this._getWorker().postMessage({
153
- method: Method.LOAD_TILES,
154
- params: [tiles],
155
- } as WorkerRequest);
156
- }
157
-
158
- /** Configures options used to extract features from tiles. */
159
- setTileFeatureExtractOptions(options: TileFeatureExtractOptions) {
160
- this._getWorker().postMessage({
161
- type: Method.SET_TILE_FEATURE_EXTRACT_OPTIONS,
162
- params: [options],
163
- });
164
- }
165
-
166
- /**
167
- * Loads features as GeoJSON (used for testing).
168
- * @experimental
169
- * @internal Not for public use. Spatial filters in other method calls will be ignored.
170
- */
171
- loadGeoJSON({
172
- geojson,
173
- spatialFilter,
174
- }: {
175
- geojson: FeatureCollection;
176
- spatialFilter: SpatialFilter;
177
- }) {
178
- this._getWorker().postMessage({
179
- method: Method.LOAD_GEOJSON,
180
- params: [{geojson, spatialFilter}],
181
- } as WorkerRequest);
182
- }
183
-
184
- /////////////////////////////////////////////////////////////////////////////
185
- // WIDGETS API
186
-
187
- // eslint-disable-next-line @typescript-eslint/require-await
188
- override async getFeatures(): Promise<FeaturesResponse> {
189
- throw new Error('getFeatures not supported for tilesets');
190
- }
191
-
192
- async getFormula({
193
- signal,
194
- ...options
195
- }: FormulaRequestOptions): Promise<FormulaResponse> {
196
- return this._executeWorkerMethod(Method.GET_FORMULA, [options], signal);
197
- }
198
-
199
- override async getHistogram({
200
- signal,
201
- ...options
202
- }: HistogramRequestOptions): Promise<HistogramResponse> {
203
- return this._executeWorkerMethod(Method.GET_HISTOGRAM, [options], signal);
204
- }
205
-
206
- override async getCategories({
207
- signal,
208
- ...options
209
- }: CategoryRequestOptions): Promise<CategoryResponse> {
210
- return this._executeWorkerMethod(Method.GET_CATEGORIES, [options], signal);
211
- }
212
-
213
- override async getScatter({
214
- signal,
215
- ...options
216
- }: ScatterRequestOptions): Promise<ScatterResponse> {
217
- return this._executeWorkerMethod(Method.GET_SCATTER, [options], signal);
218
- }
219
-
220
- override async getTable({
221
- signal,
222
- ...options
223
- }: TableRequestOptions): Promise<TableResponse> {
224
- return this._executeWorkerMethod(Method.GET_TABLE, [options], signal);
225
- }
226
-
227
- override async getTimeSeries({
228
- signal,
229
- ...options
230
- }: TimeSeriesRequestOptions): Promise<TimeSeriesResponse> {
231
- return this._executeWorkerMethod(Method.GET_TIME_SERIES, [options], signal);
232
- }
233
-
234
- override async getRange({
235
- signal,
236
- ...options
237
- }: RangeRequestOptions): Promise<RangeResponse> {
238
- return this._executeWorkerMethod(Method.GET_RANGE, [options], signal);
239
- }
240
- }
@@ -1,33 +0,0 @@
1
- let _isModuleWorkerSupported: boolean | null =
2
- TSUP_FORMAT === 'cjs' ? false : null;
3
-
4
- /**
5
- * Checks whether current environment supports ES Module Workers, by way of a
6
- * two-part check:
7
- * (1) If this is a CJS build, return false.
8
- * (2) If this is an ESM build, return true if the runtime supports ESM Workers.
9
- */
10
- export function isModuleWorkerSupported(): boolean {
11
- if (_isModuleWorkerSupported !== null) {
12
- return _isModuleWorkerSupported;
13
- }
14
-
15
- try {
16
- // https://stackoverflow.com/a/62963963
17
- new Worker('blob://', {
18
- get type() {
19
- _isModuleWorkerSupported = true;
20
- return 'module' as const;
21
- },
22
- });
23
- } catch {
24
- // Do nothing. 'blob://' should always throw an error to prevent the
25
- // browser from creating an (expensive) worker. We care whether the
26
- // 'type' getter was called, not about the error.
27
- } finally {
28
- // If 'type' getter wasn't called, modules are unsupported.
29
- _isModuleWorkerSupported ||= false;
30
- }
31
-
32
- return _isModuleWorkerSupported;
33
- }