Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(carto): Refactor fetchMap() for deck.gl v9.1 #9232

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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-alpha.5",
"@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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a change of behavior?

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 = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const context: _FetchMapContext = {
const context: FetchMapContext = {

Why the underscore?

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-alpha.5":
version "0.4.0-alpha.5"
resolved "https://registry.yarnpkg.com/@carto/api-client/-/api-client-0.4.0-alpha.5.tgz#2250591a11a3877422746f021cba32d37900e941"
integrity sha512-jH2EsgH9TSzb0wFrN26DYeNC3vN6Y24PiXOQcGwrCWDGuEx5CHmVbdWFz9wPztGPbpHE39tjqij5JuFfBy9Rfw==
dependencies:
"@turf/bbox-clip" "^7.1.0"
"@turf/bbox-polygon" "^7.1.0"
Expand Down
Loading