• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visgl / loaders.gl / 24139120841

08 Apr 2026 01:53PM UTC coverage: 65.319% (+30.2%) from 35.137%
24139120841

push

github

web-flow
chore: Replace puppeteer with playwright (#3350)

14216 of 18890 branches covered (75.26%)

Branch coverage included in aggregate %.

3 of 3 new or added lines in 1 file covered. (100.0%)

3248 existing lines in 369 files now uncovered.

73509 of 115413 relevant lines covered (63.69%)

5763.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.57
/modules/loader-utils/src/lib/sources/data-source.ts
1
// loaders.gl
1✔
2
// SPDX-License-Identifier: MIT
1✔
3
// Copyright (c) vis.gl contributors
1✔
4

1✔
5
import type {Loader, StrictLoaderOptions} from '../../loader-types';
1✔
6
import type {RequiredOptions} from '../option-utils/merge-options';
1✔
7
import {mergeOptions} from '../option-utils/merge-options';
1✔
8
import {resolvePath} from '../path-utils/file-aliases';
1✔
9

1✔
10
/** Common properties for all data sources */
1✔
11
export type DataSourceOptions = Partial<{
1✔
12
  core: {
1✔
13
    /** Allows application to specify which source should be selected. Matches `Source.type`. Defaults to 'auto' */
1✔
14
    type?: string;
1✔
15
    /** Any dataset attributions (in case underlying metadata does not include attributions) */
1✔
16
    attributions?: string[];
1✔
17
    /** LoaderOptions provide an option to override `fetch`. Will also be passed to any sub loaders */
1✔
18
    loadOptions?: StrictLoaderOptions;
1✔
19
    /** Make additional loaders available to the data source */
1✔
20
    loaders?: Loader[];
1✔
21
  };
1✔
22
  [key: string]: Record<string, unknown>;
1✔
23
}>;
1✔
24

1✔
25
/** base class of all data sources */
1✔
26
export abstract class DataSource<DataT, OptionsT extends DataSourceOptions> {
1✔
27
  static defaultOptions: Required<DataSourceOptions> = {
1✔
28
    core: {
17✔
29
      type: 'auto',
17✔
30
      attributions: [],
17✔
31
      loadOptions: {},
26✔
32
      loaders: []
26✔
33
    }
26✔
34
  };
26✔
35

26✔
36
  optionsType?: OptionsT & DataSourceOptions;
26✔
37
  options: Required<OptionsT & DataSourceOptions>;
21✔
38
  readonly data: DataT;
21✔
39
  readonly url: string;
21✔
40

21✔
41
  /** The actual load options, if calling a loaders.gl loader */
21✔
42
  loadOptions: StrictLoaderOptions;
21✔
43
  /** A resolved fetch function extracted from loadOptions prop */
26✔
44
  fetch: (url: string, options?: RequestInit) => Promise<Response>;
23✔
45
  _needsRefresh: boolean = true;
23✔
46

23✔
47
  constructor(
23✔
48
    data: DataT,
21✔
49
    options: OptionsT,
21✔
50
    defaultOptions?: Omit<RequiredOptions<OptionsT>, 'core'>
21✔
51
  ) {
21✔
52
    if (defaultOptions) {
21✔
53
      // @ts-expect-error Typescript gets confused
18✔
54
      this.options = mergeOptions({...defaultOptions, core: DataSource.defaultOptions}, options);
18✔
55
    } else {
21✔
56
      // @ts-expect-error
3✔
57
      this.options = {...options};
3✔
58
    }
3✔
59
    this.data = data;
×
60
    this.url = typeof data === 'string' ? resolvePath(data) : '';
✔
61
    this.loadOptions = normalizeDirectLoaderOptions(this.options.core?.loadOptions);
21✔
62
    this.fetch = getFetchFunction(this.loadOptions);
21✔
63
  }
21✔
64

1✔
65
  setProps(options: OptionsT) {
1✔
66
    this.options = Object.assign(this.options, options);
×
67
    // TODO - add a shallow compare to avoid setting refresh if no change?
×
68
    this.setNeedsRefresh();
×
69
  }
×
UNCOV
70

×
UNCOV
71
  /** Mark this data source as needing a refresh (redraw) */
×
72
  setNeedsRefresh(): void {
1✔
73
    this._needsRefresh = true;
×
74
  }
×
75

1✔
76
  /**
1✔
77
   * Does this data source need refreshing?
1✔
78
   * @note The specifics of the refresh mechanism depends on type of data source
1✔
79
   */
1✔
80
  getNeedsRefresh(clear: boolean = true) {
1✔
81
    const needsRefresh = this._needsRefresh;
×
82
    if (clear) {
✔
83
      this._needsRefresh = false;
✔
84
    }
1✔
85
    return needsRefresh;
×
86
  }
×
87
}
1✔
88

1✔
89
/**
1✔
90
 * Gets the current fetch function from options
1✔
91
 * @todo - move to loader-utils module
1✔
92
 * @todo - use in core module counterpart
1✔
93
 * @param options
1✔
94
 * @param context
1✔
95
 */
1✔
96
export function getFetchFunction(options?: StrictLoaderOptions) {
1✔
97
  const fetchFunction = options?.core?.fetch;
21✔
98

21✔
99
  // options.fetch can be a function
21✔
100
  if (fetchFunction && typeof fetchFunction === 'function') {
21!
101
    return (url: string, fetchOptions?: RequestInit) => fetchFunction(url, fetchOptions);
✔
102
  }
×
103

21✔
104
  // options.fetch can be an options object, use global fetch with those options
21✔
105
  const fetchOptions = options?.fetch;
21✔
106
  if (fetchOptions && typeof fetchOptions !== 'function') {
21✔
107
    return url => fetch(url, fetchOptions);
1✔
108
  }
1✔
109

20✔
110
  // else return the global fetch function
20✔
111
  return url => fetch(url);
20✔
112
}
20✔
113

1✔
114
function normalizeDirectLoaderOptions(options?: StrictLoaderOptions): StrictLoaderOptions {
21✔
115
  const loadOptions = {...options};
21✔
116
  if (options?.core) {
21!
117
    loadOptions.core = {...options.core};
×
118
  }
×
119

21✔
120
  const topLevelBaseUri = typeof loadOptions.baseUri === 'string' ? loadOptions.baseUri : undefined;
21✔
121
  const topLevelBaseUrl = typeof loadOptions.baseUrl === 'string' ? loadOptions.baseUrl : undefined;
21✔
122

21✔
123
  if (topLevelBaseUri !== undefined || topLevelBaseUrl !== undefined) {
21✔
124
    loadOptions.core ||= {};
2✔
125
    if (loadOptions.core.baseUrl === undefined) {
2✔
126
      loadOptions.core.baseUrl = topLevelBaseUrl ?? topLevelBaseUri;
2✔
127
    }
2✔
128
    delete loadOptions.baseUri;
2✔
129
    delete loadOptions.baseUrl;
2✔
130
  }
2✔
131

21✔
132
  return loadOptions;
21✔
133
}
21✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc