@carto/api-client 0.4.6 → 0.4.7-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/build/api-client.cjs +3473 -1556
  2. package/build/api-client.cjs.map +1 -1
  3. package/build/api-client.d.cts +1389 -0
  4. package/build/api-client.d.ts +1389 -0
  5. package/build/api-client.js +3676 -0
  6. package/build/api-client.js.map +1 -0
  7. package/build/worker.d.ts +2 -0
  8. package/build/worker.js +1949 -0
  9. package/build/worker.js.map +1 -0
  10. package/package.json +58 -40
  11. package/src/api/carto-api-error.ts +1 -1
  12. package/src/api/query.ts +5 -5
  13. package/src/api/request-with-parameters.ts +6 -6
  14. package/src/client.ts +3 -3
  15. package/src/constants-internal.ts +5 -11
  16. package/src/constants.ts +28 -3
  17. package/src/deck/get-data-filter-extension-props.ts +146 -0
  18. package/src/deck/index.ts +1 -0
  19. package/src/filters/Filter.ts +179 -0
  20. package/src/filters/FilterTypes.ts +109 -0
  21. package/src/filters/geosjonFeatures.ts +32 -0
  22. package/src/filters/index.ts +6 -0
  23. package/src/filters/tileFeatures.ts +51 -0
  24. package/src/filters/tileFeaturesGeometries.ts +444 -0
  25. package/src/filters/tileFeaturesSpatialIndex.ts +119 -0
  26. package/src/filters.ts +4 -4
  27. package/src/geo.ts +12 -14
  28. package/src/global.d.ts +3 -8
  29. package/src/index.ts +7 -0
  30. package/src/models/common.ts +11 -9
  31. package/src/models/index.ts +1 -1
  32. package/src/models/model.ts +3 -4
  33. package/src/operations/aggregation.ts +154 -0
  34. package/src/operations/applySorting.ts +109 -0
  35. package/src/operations/groupBy.ts +59 -0
  36. package/src/operations/groupByDate.ts +98 -0
  37. package/src/operations/histogram.ts +66 -0
  38. package/src/operations/index.ts +6 -0
  39. package/src/operations/scatterPlot.ts +50 -0
  40. package/src/sources/base-source.ts +8 -8
  41. package/src/sources/boundary-query-source.ts +2 -2
  42. package/src/sources/boundary-table-source.ts +2 -2
  43. package/src/sources/h3-query-source.ts +7 -5
  44. package/src/sources/h3-table-source.ts +7 -5
  45. package/src/sources/h3-tileset-source.ts +20 -8
  46. package/src/sources/index.ts +26 -26
  47. package/src/sources/quadbin-query-source.ts +7 -5
  48. package/src/sources/quadbin-table-source.ts +7 -5
  49. package/src/sources/quadbin-tileset-source.ts +20 -8
  50. package/src/sources/raster-source.ts +3 -2
  51. package/src/sources/types.ts +9 -3
  52. package/src/sources/vector-query-source.ts +7 -5
  53. package/src/sources/vector-table-source.ts +7 -5
  54. package/src/sources/vector-tileset-source.ts +21 -8
  55. package/src/spatial-index.ts +4 -5
  56. package/src/types-internal.ts +11 -5
  57. package/src/types.ts +73 -15
  58. package/src/utils/dateUtils.ts +28 -0
  59. package/src/utils/getTileFormat.ts +9 -0
  60. package/src/utils/makeIntervalComplete.ts +17 -0
  61. package/src/utils/transformTileCoordsToWGS84.ts +77 -0
  62. package/src/utils/transformToTileCoords.ts +85 -0
  63. package/src/utils.ts +3 -3
  64. package/src/widget-sources/index.ts +3 -1
  65. package/src/widget-sources/types.ts +37 -25
  66. package/src/widget-sources/widget-query-source.ts +12 -5
  67. package/src/widget-sources/{widget-base-source.ts → widget-remote-source.ts} +55 -149
  68. package/src/widget-sources/widget-source.ts +145 -0
  69. package/src/widget-sources/widget-table-source.ts +12 -5
  70. package/src/widget-sources/widget-tileset-source-impl.ts +417 -0
  71. package/src/widget-sources/widget-tileset-source.ts +311 -0
  72. package/src/workers/constants.ts +13 -0
  73. package/src/workers/types.ts +19 -0
  74. package/src/workers/widget-tileset-worker.ts +40 -0
  75. package/build/api/carto-api-error.d.ts +0 -26
  76. package/build/api/endpoints.d.ts +0 -24
  77. package/build/api/index.d.ts +0 -5
  78. package/build/api/query.d.ts +0 -3
  79. package/build/api/request-with-parameters.d.ts +0 -10
  80. package/build/api-client.modern.js +0 -1742
  81. package/build/api-client.modern.js.map +0 -1
  82. package/build/client.d.ts +0 -14
  83. package/build/constants-internal.d.ts +0 -26
  84. package/build/constants.d.ts +0 -31
  85. package/build/filters.d.ts +0 -39
  86. package/build/geo.d.ts +0 -19
  87. package/build/index.d.ts +0 -11
  88. package/build/models/common.d.ts +0 -27
  89. package/build/models/index.d.ts +0 -3
  90. package/build/models/model.d.ts +0 -37
  91. package/build/sources/base-source.d.ts +0 -4
  92. package/build/sources/boundary-query-source.d.ts +0 -10
  93. package/build/sources/boundary-table-source.d.ts +0 -8
  94. package/build/sources/h3-query-source.d.ts +0 -5
  95. package/build/sources/h3-table-source.d.ts +0 -5
  96. package/build/sources/h3-tileset-source.d.ts +0 -4
  97. package/build/sources/index.d.ts +0 -26
  98. package/build/sources/quadbin-query-source.d.ts +0 -5
  99. package/build/sources/quadbin-table-source.d.ts +0 -5
  100. package/build/sources/quadbin-tileset-source.d.ts +0 -4
  101. package/build/sources/raster-source.d.ts +0 -4
  102. package/build/sources/types.d.ts +0 -366
  103. package/build/sources/vector-query-source.d.ts +0 -5
  104. package/build/sources/vector-table-source.d.ts +0 -5
  105. package/build/sources/vector-tileset-source.d.ts +0 -4
  106. package/build/spatial-index.d.ts +0 -14
  107. package/build/types-internal.d.ts +0 -52
  108. package/build/types.d.ts +0 -80
  109. package/build/utils.d.ts +0 -32
  110. package/build/widget-sources/index.d.ts +0 -4
  111. package/build/widget-sources/types.d.ts +0 -149
  112. package/build/widget-sources/widget-base-source.d.ts +0 -99
  113. package/build/widget-sources/widget-query-source.d.ts +0 -33
  114. package/build/widget-sources/widget-table-source.d.ts +0 -33
@@ -0,0 +1,311 @@
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, WidgetSourceProps} from './widget-source.js';
22
+ import {Method} from '../workers/constants.js';
23
+ import {WorkerRequest, WorkerResponse} from '../workers/types.js';
24
+ import {SpatialDataType, TilesetSourceOptions} from '../sources/types.js';
25
+ import {TileFormat} from '../constants.js';
26
+ import {WidgetTilesetSourceImpl} from './widget-tileset-source-impl.js';
27
+
28
+ export type WidgetTilesetSourceProps = WidgetSourceProps &
29
+ Omit<TilesetSourceOptions, 'filters'> & {
30
+ tileFormat: TileFormat;
31
+ spatialDataType: SpatialDataType;
32
+ };
33
+
34
+ export type WidgetTilesetSourceResult = {widgetSource: WidgetTilesetSource};
35
+
36
+ /**
37
+ * Source for Widget API requests on a data source defined by a tileset.
38
+ *
39
+ * Generally not intended to be constructed directly. Instead, call
40
+ * {@link vectorTilesetSource}, {@link h3TilesetSource}, or {@link quadbinTilesetSource},
41
+ * which can be shared with map layers. Sources contain a `widgetSource`
42
+ * property, for use by widget implementations.
43
+ *
44
+ * Example:
45
+ *
46
+ * ```javascript
47
+ * import { vectorTilesetSource } from '@carto/api-client';
48
+ *
49
+ * const data = vectorTilesetSource({
50
+ * accessToken: '••••',
51
+ * connectionName: 'carto_dw',
52
+ * tableName: 'carto-demo-data.demo_rasters.my_tileset_source'
53
+ * });
54
+ *
55
+ * const { widgetSource } = await data;
56
+ * ```
57
+ */
58
+ export class WidgetTilesetSource extends WidgetSource<WidgetTilesetSourceProps> {
59
+ protected _localImpl: WidgetTilesetSourceImpl | null = null;
60
+
61
+ protected _workerImpl: Worker | null = null;
62
+ protected _workerEnabled: boolean;
63
+ protected _workerNextRequestId = 1;
64
+
65
+ constructor(props: WidgetTilesetSourceProps) {
66
+ super(props);
67
+
68
+ this._workerEnabled =
69
+ (props.widgetWorker ?? true) &&
70
+ TSUP_FORMAT !== 'cjs' &&
71
+ typeof Worker !== 'undefined';
72
+
73
+ if (!this._workerEnabled) {
74
+ this._localImpl = new WidgetTilesetSourceImpl(this.props);
75
+ }
76
+ }
77
+
78
+ destroy() {
79
+ this._localImpl?.destroy();
80
+ this._localImpl = null;
81
+
82
+ this._workerImpl?.terminate();
83
+ this._workerImpl = null;
84
+
85
+ super.destroy();
86
+ }
87
+
88
+ /////////////////////////////////////////////////////////////////////////////
89
+ // WEB WORKER MANAGEMENT
90
+
91
+ /**
92
+ * Returns an initialized Worker, to be reused for the lifecycle of this
93
+ * source instance.
94
+ */
95
+ protected _getWorker(): Worker {
96
+ if (this._workerImpl) {
97
+ return this._workerImpl;
98
+ }
99
+
100
+ this._workerImpl = new Worker(
101
+ new URL('@carto/api-client/worker', import.meta.url),
102
+ {
103
+ type: 'module',
104
+ name: 'cartowidgettileset',
105
+ }
106
+ );
107
+
108
+ this._workerImpl.postMessage({
109
+ method: Method.INIT,
110
+ params: [this.props],
111
+ } as WorkerRequest);
112
+
113
+ return this._workerImpl;
114
+ }
115
+
116
+ /** Executes a given method on the worker. */
117
+ protected _executeWorkerMethod<T>(
118
+ method: Method,
119
+ params: unknown[],
120
+ signal?: AbortSignal
121
+ ): Promise<T> {
122
+ if (!this._workerEnabled) {
123
+ // @ts-expect-error No type-checking dynamic method name.
124
+ return this._localImpl[method](...params);
125
+ }
126
+
127
+ const worker = this._getWorker();
128
+ const requestId = this._workerNextRequestId++;
129
+
130
+ // TODO: ViewState may contain non-serializable data, which we do not need.
131
+ // Remove this sanitization after sc-469614 is fixed.
132
+ const options = params[0] as any;
133
+ if (options?.spatialIndexReferenceViewState) {
134
+ const {zoom, latitude, longitude} =
135
+ options.spatialIndexReferenceViewState;
136
+ options.spatialIndexReferenceViewState = {zoom, latitude, longitude};
137
+ }
138
+
139
+ let resolve: ((value: T) => void) | null = null;
140
+ let reject: ((reason: any) => void) | null = null;
141
+
142
+ // If worker sends message to main process, check whether it's a response
143
+ // to this request, and whether the request can been aborted. Then resolve
144
+ // or reject the Promise.
145
+ function onMessage(e: MessageEvent) {
146
+ const response = e.data as WorkerResponse;
147
+ if (response.requestId !== requestId) return;
148
+
149
+ if (signal?.aborted) {
150
+ onAbort();
151
+ } else if (response.ok) {
152
+ resolve!(response.result as T);
153
+ } else {
154
+ reject!(new Error(response.error));
155
+ }
156
+ }
157
+
158
+ // If request is aborted by user, immediately reject the Promise.
159
+ function onAbort() {
160
+ // https://developer.mozilla.org/en-US/docs/Web/API/DOMException#aborterror
161
+ const abortError = new Error(signal!.reason);
162
+ abortError.name = 'AbortError';
163
+ reject!(abortError);
164
+ }
165
+
166
+ worker.addEventListener('message', onMessage);
167
+ signal?.addEventListener('abort', onAbort);
168
+
169
+ // Send the task to the worker, creating a Promise to resolve/reject later.
170
+ const promise = new Promise<T>((_resolve, _reject) => {
171
+ resolve = _resolve;
172
+ reject = _reject;
173
+
174
+ worker.postMessage({
175
+ requestId,
176
+ method,
177
+ params,
178
+ } as WorkerRequest);
179
+ });
180
+
181
+ // Whether the task completes, fails, or aborts: clean up afterward.
182
+ void promise.finally(() => {
183
+ worker.removeEventListener('message', onMessage);
184
+ signal?.removeEventListener('abort', onAbort);
185
+ });
186
+
187
+ return promise;
188
+ }
189
+
190
+ /////////////////////////////////////////////////////////////////////////////
191
+ // DATA LOADING
192
+
193
+ /**
194
+ * Loads features as a list of tiles (typically provided by deck.gl).
195
+ * After tiles are loaded, {@link extractTileFeatures} must be called
196
+ * before computing statistics on the tiles.
197
+ */
198
+ loadTiles(tiles: unknown[]) {
199
+ if (!this._workerEnabled) {
200
+ return this._localImpl!.loadTiles(tiles);
201
+ }
202
+
203
+ const worker = this._getWorker();
204
+
205
+ tiles = (tiles as Tile[]).map(({id, bbox, data}) => ({
206
+ id,
207
+ bbox,
208
+ data,
209
+ }));
210
+
211
+ worker.postMessage({
212
+ method: Method.LOAD_TILES,
213
+ params: [tiles],
214
+ } as WorkerRequest);
215
+ }
216
+
217
+ /** Configures options used to extract features from tiles. */
218
+ setTileFeatureExtractOptions(options: TileFeatureExtractOptions) {
219
+ if (!this._workerEnabled) {
220
+ return this._localImpl?.setTileFeatureExtractOptions(options);
221
+ }
222
+
223
+ const worker = this._getWorker();
224
+
225
+ worker.postMessage({
226
+ type: Method.SET_TILE_FEATURE_EXTRACT_OPTIONS,
227
+ params: [options],
228
+ });
229
+ }
230
+
231
+ /**
232
+ * Loads features as GeoJSON (used for testing).
233
+ * @experimental
234
+ * @internal Not for public use. Spatial filters in other method calls will be ignored.
235
+ */
236
+ loadGeoJSON({
237
+ geojson,
238
+ spatialFilter,
239
+ }: {
240
+ geojson: FeatureCollection;
241
+ spatialFilter: SpatialFilter;
242
+ }) {
243
+ if (!this._workerEnabled) {
244
+ return this._localImpl!.loadGeoJSON({geojson, spatialFilter});
245
+ }
246
+
247
+ const worker = this._getWorker();
248
+
249
+ worker.postMessage({
250
+ method: Method.LOAD_GEOJSON,
251
+ params: [{geojson, spatialFilter}],
252
+ } as WorkerRequest);
253
+ }
254
+
255
+ /////////////////////////////////////////////////////////////////////////////
256
+ // WIDGETS API
257
+
258
+ // eslint-disable-next-line @typescript-eslint/require-await
259
+ override async getFeatures(): Promise<FeaturesResponse> {
260
+ throw new Error('getFeatures not supported for tilesets');
261
+ }
262
+
263
+ async getFormula({
264
+ signal,
265
+ ...options
266
+ }: FormulaRequestOptions): Promise<FormulaResponse> {
267
+ return this._executeWorkerMethod(Method.GET_FORMULA, [options], signal);
268
+ }
269
+
270
+ override async getHistogram({
271
+ signal,
272
+ ...options
273
+ }: HistogramRequestOptions): Promise<HistogramResponse> {
274
+ return this._executeWorkerMethod(Method.GET_HISTOGRAM, [options], signal);
275
+ }
276
+
277
+ override async getCategories({
278
+ signal,
279
+ ...options
280
+ }: CategoryRequestOptions): Promise<CategoryResponse> {
281
+ return this._executeWorkerMethod(Method.GET_CATEGORIES, [options], signal);
282
+ }
283
+
284
+ override async getScatter({
285
+ signal,
286
+ ...options
287
+ }: ScatterRequestOptions): Promise<ScatterResponse> {
288
+ return this._executeWorkerMethod(Method.GET_SCATTER, [options], signal);
289
+ }
290
+
291
+ override async getTable({
292
+ signal,
293
+ ...options
294
+ }: TableRequestOptions): Promise<TableResponse> {
295
+ return this._executeWorkerMethod(Method.GET_TABLE, [options], signal);
296
+ }
297
+
298
+ override async getTimeSeries({
299
+ signal,
300
+ ...options
301
+ }: TimeSeriesRequestOptions): Promise<TimeSeriesResponse> {
302
+ return this._executeWorkerMethod(Method.GET_TIME_SERIES, [options], signal);
303
+ }
304
+
305
+ override async getRange({
306
+ signal,
307
+ ...options
308
+ }: RangeRequestOptions): Promise<RangeResponse> {
309
+ return this._executeWorkerMethod(Method.GET_RANGE, [options], signal);
310
+ }
311
+ }
@@ -0,0 +1,13 @@
1
+ export enum Method {
2
+ INIT = 'init',
3
+ LOAD_TILES = 'loadTiles',
4
+ SET_TILE_FEATURE_EXTRACT_OPTIONS = 'setTileFeatureExtractOptions',
5
+ LOAD_GEOJSON = 'loadGeoJSON',
6
+ GET_FORMULA = 'getFormula',
7
+ GET_HISTOGRAM = 'getHistogram',
8
+ GET_CATEGORIES = 'getCategories',
9
+ GET_SCATTER = 'getScatter',
10
+ GET_TABLE = 'getTable',
11
+ GET_TIME_SERIES = 'getTimeSeries',
12
+ GET_RANGE = 'getRange',
13
+ }
@@ -0,0 +1,19 @@
1
+ import type {Method} from './constants.js';
2
+
3
+ export type WorkerRequest = {
4
+ requestId?: number;
5
+ method: Method;
6
+ params: unknown[];
7
+ };
8
+
9
+ export type WorkerResponse =
10
+ | {
11
+ requestId: number;
12
+ ok: true;
13
+ result: unknown;
14
+ }
15
+ | {
16
+ requestId: number;
17
+ ok: false;
18
+ error: string;
19
+ };
@@ -0,0 +1,40 @@
1
+ import {WidgetTilesetSourceImpl} from '../widget-sources/widget-tileset-source-impl.js';
2
+ import {type WidgetTilesetSourceProps} from '../widget-sources/widget-tileset-source.js';
3
+ import {Method} from './constants.js';
4
+ import type {WorkerRequest, WorkerResponse} from './types.js';
5
+
6
+ /*
7
+ * Web Worker, compiled as a separate `@carto/api-client/worker` entrypoint.
8
+ *
9
+ * Workers are scoped to the lifecycle of a single WidgetTilesetSource instance,
10
+ * representing and executing calculations on a single datasource.
11
+ */
12
+
13
+ let source: WidgetTilesetSourceImpl;
14
+
15
+ addEventListener('message', (e) => {
16
+ const {method, params, requestId} = e.data as WorkerRequest;
17
+
18
+ if (method === Method.INIT) {
19
+ source = new WidgetTilesetSourceImpl({
20
+ ...(params[0] as WidgetTilesetSourceProps),
21
+ widgetWorker: false,
22
+ });
23
+ return;
24
+ }
25
+
26
+ if (!source) {
27
+ const error = `Cannot execute "${method}" on uninitialized source.`;
28
+ postMessage({ok: false, error, requestId} as WorkerResponse);
29
+ return;
30
+ }
31
+
32
+ // @ts-expect-error No type-checking dynamic method name.
33
+ Promise.resolve(source[method](...params))
34
+ .then((result) => {
35
+ postMessage({ok: true, result, requestId} as WorkerResponse);
36
+ })
37
+ .catch((error) => {
38
+ postMessage({ok: false, error, requestId} as WorkerResponse);
39
+ });
40
+ });
@@ -1,26 +0,0 @@
1
- import { MapType } from '../types';
2
- export type APIRequestType = 'Map data' | 'Map instantiation' | 'Public map' | 'Tile stats' | 'SQL' | 'Basemap style';
3
- export type APIErrorContext = {
4
- requestType: APIRequestType;
5
- mapId?: string;
6
- connection?: string;
7
- source?: string;
8
- type?: MapType;
9
- };
10
- /**
11
- *
12
- * Custom error for reported errors in CARTO Maps API.
13
- * Provides useful debugging information in console and context for applications.
14
- *
15
- */
16
- export declare class CartoAPIError extends Error {
17
- /** Source error from server */
18
- error: Error;
19
- /** Context (API call & parameters) in which error occured */
20
- errorContext: APIErrorContext;
21
- /** Response from server */
22
- response?: Response;
23
- /** JSON Response from server */
24
- responseJson?: any;
25
- constructor(error: Error, errorContext: APIErrorContext, response?: Response, responseJson?: any);
26
- }
@@ -1,24 +0,0 @@
1
- import { MapType } from '../types.js';
2
- export type V3Endpoint = 'maps' | 'stats' | 'sql';
3
- /** @internal Required by fetchMap(). */
4
- export declare function buildPublicMapUrl({ apiBaseUrl, cartoMapId, }: {
5
- apiBaseUrl: string;
6
- cartoMapId: string;
7
- }): string;
8
- /** @internal Required by fetchMap(). */
9
- export declare function buildStatsUrl({ attribute, apiBaseUrl, connectionName, source, type, }: {
10
- attribute: string;
11
- apiBaseUrl: string;
12
- connectionName: string;
13
- source: string;
14
- type: MapType;
15
- }): string;
16
- export declare function buildSourceUrl({ apiBaseUrl, connectionName, endpoint, }: {
17
- apiBaseUrl: string;
18
- connectionName: string;
19
- endpoint: MapType;
20
- }): string;
21
- export declare function buildQueryUrl({ apiBaseUrl, connectionName, }: {
22
- apiBaseUrl: string;
23
- connectionName: string;
24
- }): string;
@@ -1,5 +0,0 @@
1
- export { CartoAPIError, APIErrorContext, APIRequestType, } from './carto-api-error.js';
2
- export { buildPublicMapUrl, buildStatsUrl } from './endpoints.js';
3
- export { query } from './query.js';
4
- export type { QueryOptions } from './query.js';
5
- export { requestWithParameters } from './request-with-parameters.js';
@@ -1,3 +0,0 @@
1
- import type { SourceOptions, QuerySourceOptions, QueryResult } from '../sources/types';
2
- export type QueryOptions = SourceOptions & QuerySourceOptions;
3
- export declare const query: (options: QueryOptions) => Promise<QueryResult>;
@@ -1,10 +0,0 @@
1
- import { APIErrorContext } from './carto-api-error';
2
- import { LocalCacheOptions } from '../sources/types';
3
- export declare function requestWithParameters<T = any>({ baseUrl, parameters, headers: customHeaders, errorContext, maxLengthURL, localCache, }: {
4
- baseUrl: string;
5
- parameters?: Record<string, unknown>;
6
- headers?: Record<string, string>;
7
- errorContext: APIErrorContext;
8
- maxLengthURL?: number;
9
- localCache?: LocalCacheOptions;
10
- }): Promise<T>;