// loaders.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors import type {LoaderOptions} from '@loaders.gl/loader-utils'; /** Common properties for all data sources */ export type DataSourceProps = { url?: string | Blob; /** LoaderOptions provide an option to override `fetch`. Will also be passed to any sub loaders */ loadOptions?: LoaderOptions; }; /** base class of all data sources */ export abstract class DataSource { abstract data: unknown; /** A resolved fetch function extracted from loadOptions prop */ fetch: (url: string, options?: RequestInit) => Promise; /** The actual load options, if calling a loaders.gl loader */ loadOptions: LoaderOptions; _needsRefresh: boolean = true; props: PropsT; constructor(props: PropsT) { this.props = {...props}; this.loadOptions = {...props.loadOptions}; this.fetch = getFetchFunction(this.loadOptions); } setProps(props: PropsT) { this.props = Object.assign(this.props, props); // TODO - add a shallow compare to avoid setting refresh if no change? this.setNeedsRefresh(); } /** Mark this data source as needing a refresh (redraw) */ setNeedsRefresh(): void { this._needsRefresh = true; } /** * Does this data source need refreshing? * @note The specifics of the refresh mechanism depends on type of data source */ getNeedsRefresh(clear: boolean = true) { const needsRefresh = this._needsRefresh; if (clear) { this._needsRefresh = false; } return needsRefresh; } } /** * Gets the current fetch function from options * @todo - move to loader-utils module * @todo - use in core module counterpart * @param options * @param context */ export function getFetchFunction(options?: LoaderOptions) { const fetchFunction = options?.fetch; // options.fetch can be a function if (fetchFunction && typeof fetchFunction === 'function') { return (url: string, fetchOptions?: RequestInit) => fetchFunction(url, fetchOptions); } // options.fetch can be an options object, use global fetch with those options const fetchOptions = options?.fetch; if (fetchOptions && typeof fetchOptions !== 'function') { return (url) => fetch(url, fetchOptions); } // else return the global fetch function return (url) => fetch(url); }