Skip to content

Commit

Permalink
refactor(carto): Refactor fetchMap() for deck.gl v9.1 (#9232)
Browse files Browse the repository at this point in the history
  • Loading branch information
donmccurdy authored Dec 5, 2024
1 parent b01b47e commit 442108a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 60 deletions.
2 changes: 1 addition & 1 deletion modules/carto/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"prepublishOnly": "npm run build-bundle && npm run build-bundle -- --env=dev"
},
"dependencies": {
"@carto/api-client": "^0.4.0-alpha.4",
"@carto/api-client": "^0.4.0",
"@loaders.gl/gis": "^4.2.0",
"@loaders.gl/loader-utils": "^4.2.0",
"@loaders.gl/mvt": "^4.2.0",
Expand Down
97 changes: 42 additions & 55 deletions modules/carto/src/api/fetch-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Copyright (c) vis.gl contributors

import {
SOURCE_DEFAULTS,
DEFAULT_API_BASE_URL,
APIErrorContext,
CartoAPIError,
GeojsonResult,
Expand All @@ -12,6 +12,7 @@ import {
Format,
MapType,
QueryParameters,
SourceOptions,
buildPublicMapUrl,
buildStatsUrl,
h3QuerySource,
Expand Down Expand Up @@ -45,14 +46,7 @@ type Dataset = {

/* global clearInterval, setInterval, URL */
/* eslint-disable complexity, max-statements, max-params */
async function _fetchMapDataset(
dataset: Dataset,
accessToken: string,
apiBaseUrl: string,
clientId?: string,
headers?: Record<string, string>,
maxLengthURL = SOURCE_DEFAULTS.maxLengthURL
) {
async function _fetchMapDataset(dataset: Dataset, context: _FetchMapContext) {
const {
aggregationExp,
aggregationResLevel,
Expand All @@ -66,16 +60,12 @@ async function _fetchMapDataset(
} = dataset;

const cache: {value?: number} = {};
const globalOptions: any = {
accessToken,
apiBaseUrl,
const globalOptions = {
...context,
cache,
clientId,
connectionName,
format,
headers,
maxLengthURL
};
format
} as SourceOptions;

if (type === 'tileset') {
// TODO do we want a generic tilesetSource?
Expand Down Expand Up @@ -120,14 +110,9 @@ async function _fetchMapDataset(
return cacheChanged;
}

async function _fetchTilestats(
attribute: string,
dataset: Dataset,
accessToken: string,
apiBaseUrl: string,
maxLengthURL = SOURCE_DEFAULTS.maxLengthURL
) {
async function _fetchTilestats(attribute: string, dataset: Dataset, context: _FetchMapContext) {
const {connectionName, data, id, source, type, queryParameters} = dataset;
const {apiBaseUrl} = context;
const errorContext: APIErrorContext = {
requestType: 'Tile stats',
connection: connectionName,
Expand All @@ -140,7 +125,7 @@ async function _fetchTilestats(

const baseUrl = buildStatsUrl({attribute, apiBaseUrl, ...dataset});
const client = new URLSearchParams(data.tiles[0]).get('client');
const headers = {Authorization: `Bearer ${accessToken}`};
const headers = {Authorization: `Bearer ${context.accessToken}`};
const parameters: Record<string, string> = {};
if (client) {
parameters.client = client;
Expand All @@ -156,7 +141,7 @@ async function _fetchTilestats(
headers,
parameters,
errorContext,
maxLengthURL
maxLengthURL: context.maxLengthURL
});

// Replace tilestats for attribute with value from API
Expand All @@ -166,23 +151,14 @@ async function _fetchTilestats(
return true;
}

async function fillInMapDatasets(
{datasets, token}: {datasets: Dataset[]; token: string},
clientId: string,
apiBaseUrl: string,
headers?: Record<string, string>,
maxLengthURL = SOURCE_DEFAULTS.maxLengthURL
) {
const promises = datasets.map(dataset =>
_fetchMapDataset(dataset, token, apiBaseUrl, clientId, headers, maxLengthURL)
);
async function fillInMapDatasets({datasets}: {datasets: Dataset[]}, context: _FetchMapContext) {
const promises = datasets.map(dataset => _fetchMapDataset(dataset, context));
return await Promise.all(promises);
}

async function fillInTileStats(
{datasets, keplerMapConfig, token}: {datasets: Dataset[]; keplerMapConfig: any; token: string},
apiBaseUrl: string,
maxLengthURL = SOURCE_DEFAULTS.maxLengthURL
{datasets, keplerMapConfig}: {datasets: Dataset[]; keplerMapConfig: any},
context: _FetchMapContext
) {
const attributes: {attribute: string; dataset: any}[] = [];
const {layers} = keplerMapConfig.config.visState;
Expand Down Expand Up @@ -211,7 +187,7 @@ async function fillInTileStats(
}

const promises = filteredAttributes.map(({attribute, dataset}) =>
_fetchTilestats(attribute, dataset, token, apiBaseUrl, maxLengthURL)
_fetchTilestats(attribute, dataset, context)
);
return await Promise.all(promises);
}
Expand Down Expand Up @@ -260,6 +236,14 @@ export type FetchMapOptions = {
maxLengthURL?: number;
};

/**
* Context reused while fetching and updating a map with fetchMap().
*/
type _FetchMapContext = {apiBaseUrl: string} & Pick<
FetchMapOptions,
'accessToken' | 'clientId' | 'headers' | 'maxLengthURL'
>;

export type FetchMapResult = ParseMapResult & {
/**
* Basemap properties.
Expand All @@ -271,16 +255,15 @@ export type FetchMapResult = ParseMapResult & {
/* eslint-disable max-statements */
export async function fetchMap({
accessToken,
apiBaseUrl = SOURCE_DEFAULTS.apiBaseUrl,
apiBaseUrl = DEFAULT_API_BASE_URL,
cartoMapId,
clientId = SOURCE_DEFAULTS.clientId,
headers = {},
clientId,
headers,
autoRefresh,
onNewData,
maxLengthURL = SOURCE_DEFAULTS.maxLengthURL
maxLengthURL
}: FetchMapOptions): Promise<FetchMapResult> {
assert(cartoMapId, 'Must define CARTO map id: fetchMap({cartoMapId: "XXXX-XXXX-XXXX"})');
assert(apiBaseUrl, 'Must define apiBaseUrl');

if (accessToken) {
headers = {Authorization: `Bearer ${accessToken}`, ...headers};
Expand All @@ -298,23 +281,27 @@ export async function fetchMap({
const baseUrl = buildPublicMapUrl({apiBaseUrl, cartoMapId});
const errorContext: APIErrorContext = {requestType: 'Public map', mapId: cartoMapId};
const map = await requestWithParameters({baseUrl, headers, errorContext, maxLengthURL});
const context: _FetchMapContext = {
accessToken: map.token || accessToken,
apiBaseUrl,
clientId,
headers,
maxLengthURL
};

// Periodically check if the data has changed. Note that this
// will not update when a map is published.
let stopAutoRefresh: (() => void) | undefined;
if (autoRefresh) {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
const intervalId = setInterval(async () => {
const changed = await fillInMapDatasets(
map,
clientId,
apiBaseUrl,
{
const changed = await fillInMapDatasets(map, {
...context,
headers: {
...headers,
'If-Modified-Since': new Date().toUTCString()
},
maxLengthURL
);
}
});
if (onNewData && changed.some(v => v === true)) {
onNewData(parseMap(map));
}
Expand Down Expand Up @@ -343,11 +330,11 @@ export async function fetchMap({
fetchBasemapProps({config: map.keplerMapConfig.config, errorContext}),

// Mutates map.datasets so that dataset.data contains data
fillInMapDatasets(map, clientId, apiBaseUrl, headers, maxLengthURL)
fillInMapDatasets(map, context)
]);

// Mutates attributes in visualChannels to contain tile stats
await fillInTileStats(map, apiBaseUrl, maxLengthURL);
await fillInTileStats(map, context);

const out = {...parseMap(map), basemap, ...{stopAutoRefresh}};

Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1083,10 +1083,10 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==

"@carto/api-client@^0.4.0-alpha.4":
version "0.4.0-alpha.4"
resolved "https://registry.yarnpkg.com/@carto/api-client/-/api-client-0.4.0-alpha.4.tgz#32af6a903624a1cf1c930002a6640116d756750d"
integrity sha512-Bm+hoKfMwzruFMvbowypB/CoBQUOl8zqE3XmBHodU0akE341xdSLx8B9w7f4jtqYylXh0wk1irz2sFfW37N2HQ==
"@carto/api-client@^0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@carto/api-client/-/api-client-0.4.0.tgz#853469e70dcfa5ce14083f6ad9348911d08046fa"
integrity sha512-zFn4/cBBVNvpSqS9di72XuRUl5qrWHEW2KsuWK3fzR5Sng8jXoTFESf6poY0nyhxlAutkMNZIAhpHm+wdc7y/w==
dependencies:
"@turf/bbox-clip" "^7.1.0"
"@turf/bbox-polygon" "^7.1.0"
Expand Down

0 comments on commit 442108a

Please sign in to comment.