@loaders.gl/core 5.0.0-alpha.6 → 5.0.0-alpha.8

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 (47) hide show
  1. package/dist/dist.dev.js +313 -51
  2. package/dist/dist.min.js +3 -3
  3. package/dist/index.cjs +297 -58
  4. package/dist/index.cjs.map +3 -3
  5. package/dist/lib/api/create-data-source.d.ts +1 -1
  6. package/dist/lib/api/create-data-source.d.ts.map +1 -1
  7. package/dist/lib/api/create-data-source.js +23 -2
  8. package/dist/lib/api/create-data-source.js.map +1 -1
  9. package/dist/lib/api/load-in-batches.d.ts.map +1 -1
  10. package/dist/lib/api/load-in-batches.js +17 -6
  11. package/dist/lib/api/load-in-batches.js.map +1 -1
  12. package/dist/lib/api/load.d.ts +3 -3
  13. package/dist/lib/api/load.d.ts.map +1 -1
  14. package/dist/lib/api/load.js +14 -5
  15. package/dist/lib/api/load.js.map +1 -1
  16. package/dist/lib/api/parse-file.d.ts.map +1 -1
  17. package/dist/lib/api/parse-file.js +6 -2
  18. package/dist/lib/api/parse-file.js.map +1 -1
  19. package/dist/lib/api/parse-in-batches.d.ts.map +1 -1
  20. package/dist/lib/api/parse-in-batches.js +6 -1
  21. package/dist/lib/api/parse-in-batches.js.map +1 -1
  22. package/dist/lib/api/parse.d.ts.map +1 -1
  23. package/dist/lib/api/parse.js +6 -1
  24. package/dist/lib/api/parse.js.map +1 -1
  25. package/dist/lib/init.js +1 -1
  26. package/dist/lib/loader-utils/get-fetch-function.js +4 -13
  27. package/dist/lib/loader-utils/get-fetch-function.js.map +1 -1
  28. package/dist/lib/loader-utils/option-defaults.d.ts.map +1 -1
  29. package/dist/lib/loader-utils/option-defaults.js +1 -0
  30. package/dist/lib/loader-utils/option-defaults.js.map +1 -1
  31. package/dist/lib/loader-utils/option-utils.d.ts +7 -0
  32. package/dist/lib/loader-utils/option-utils.d.ts.map +1 -1
  33. package/dist/lib/loader-utils/option-utils.js +29 -0
  34. package/dist/lib/loader-utils/option-utils.js.map +1 -1
  35. package/dist/null-loader.js +1 -1
  36. package/dist/null-worker-node.js +1 -1
  37. package/dist/null-worker.js +1 -1
  38. package/package.json +6 -6
  39. package/src/lib/api/create-data-source.ts +31 -2
  40. package/src/lib/api/load-in-batches.ts +18 -11
  41. package/src/lib/api/load.ts +44 -6
  42. package/src/lib/api/parse-file.ts +15 -2
  43. package/src/lib/api/parse-in-batches.ts +11 -1
  44. package/src/lib/api/parse.ts +11 -1
  45. package/src/lib/loader-utils/get-fetch-function.ts +4 -15
  46. package/src/lib/loader-utils/option-defaults.ts +1 -0
  47. package/src/lib/loader-utils/option-utils.ts +34 -0
@@ -14,12 +14,24 @@ import type {
14
14
  LoaderArrayOptionsType,
15
15
  LoaderArrayReturnType,
16
16
  SourceLoader,
17
+ SourcePropsType,
18
+ SourceArrayOptionsType,
19
+ DataSourceOptions,
17
20
  LoaderWithParser
18
21
  } from '@loaders.gl/loader-utils';
19
- import {isBlob, isSourceLoader} from '@loaders.gl/loader-utils';
22
+ import {
23
+ isBlob,
24
+ isSourceLoader,
25
+ resolveAuthenticationOptions,
26
+ resolveLoaderAuthenticationOptions
27
+ } from '@loaders.gl/loader-utils';
20
28
  import {isLoaderObject} from '../loader-utils/normalize-loader';
21
29
  import {getFetchFunction} from '../loader-utils/get-fetch-function';
22
- import {normalizeLoaderOptions} from '../loader-utils/option-utils';
30
+ import {
31
+ applySearchParamsToUrl,
32
+ normalizeLoaderOptions,
33
+ getGlobalLoaderOptions
34
+ } from '../loader-utils/option-utils';
23
35
  import {fetchFile} from '../fetch/fetch-file';
24
36
 
25
37
  import {parse} from './parse';
@@ -49,7 +61,7 @@ export async function load<
49
61
  >(
50
62
  url: string | DataType,
51
63
  loader: LoaderT,
52
- options?: OptionsT,
64
+ options?: LoaderT extends SourceLoader ? SourcePropsType<LoaderT> & DataSourceOptions : OptionsT,
53
65
  context?: LoaderContext
54
66
  ): Promise<LoaderReturnType<LoaderT>>;
55
67
 
@@ -59,7 +71,7 @@ export async function load<
59
71
  >(
60
72
  url: string | DataType,
61
73
  loaders: LoaderArrayT,
62
- options?: OptionsT,
74
+ options?: LoaderArrayT extends SourceLoader[] ? SourceArrayOptionsType<LoaderArrayT> : OptionsT,
63
75
  context?: LoaderContext
64
76
  ): Promise<LoaderArrayReturnType<LoaderArrayT>>;
65
77
 
@@ -95,8 +107,15 @@ export async function load(
95
107
  resolvedOptions = options as LoaderOptions;
96
108
  }
97
109
 
110
+ resolvedOptions ||= getGlobalLoaderOptions();
111
+
98
112
  if (!Array.isArray(resolvedLoaders) && isSourceLoader(resolvedLoaders)) {
99
113
  const sourceLoader = await resolveSourceLoader(resolvedLoaders, url, resolvedOptions);
114
+ resolvedOptions = await resolveLoaderAuthenticationOptions(
115
+ resolvedLoaders.getAuthentications ? resolvedLoaders : sourceLoader,
116
+ typeof url === 'string' ? url : '',
117
+ resolvedOptions || {}
118
+ );
100
119
  const runtimeCoreApi = {
101
120
  fetchFile,
102
121
  parse,
@@ -119,6 +138,11 @@ export async function load(
119
138
  isSourceLoader(resolvedLoaders[0])
120
139
  ) {
121
140
  const sourceLoader = await resolveSourceLoader(resolvedLoaders[0], url, resolvedOptions);
141
+ resolvedOptions = await resolveLoaderAuthenticationOptions(
142
+ resolvedLoaders[0].getAuthentications ? resolvedLoaders[0] : sourceLoader,
143
+ typeof url === 'string' ? url : '',
144
+ resolvedOptions || {}
145
+ );
122
146
  const runtimeCoreApi = {
123
147
  fetchFile,
124
148
  parse,
@@ -143,6 +167,11 @@ export async function load(
143
167
 
144
168
  if (selectedLoader && isSourceLoader(selectedLoader)) {
145
169
  const sourceLoader = await resolveSourceLoader(selectedLoader, url, resolvedOptions);
170
+ resolvedOptions = await resolveLoaderAuthenticationOptions(
171
+ selectedLoader.getAuthentications ? selectedLoader : sourceLoader,
172
+ typeof url === 'string' ? url : '',
173
+ resolvedOptions || {}
174
+ );
146
175
  return sourceLoader.createDataSource(
147
176
  url,
148
177
  (resolvedOptions || {}) as LoaderOptionsType<SourceLoader>,
@@ -164,6 +193,11 @@ export async function load(
164
193
  resolvedOptions,
165
194
  url
166
195
  );
196
+ resolvedOptions = await resolveLoaderAuthenticationOptions(
197
+ selectedLoader.getAuthentications ? selectedLoader : loaderImplementation,
198
+ url,
199
+ resolvedOptions || {}
200
+ );
167
201
  const parseUrl = (
168
202
  loaderImplementation as LoaderWithParser & {
169
203
  parseUrl?: (
@@ -173,18 +207,22 @@ export async function load(
173
207
  ) => Promise<unknown>;
174
208
  }
175
209
  ).parseUrl;
176
- if (parseUrl) return await parseUrl(url, resolvedOptions, context);
210
+ if (parseUrl) {
211
+ const requestUrl = applySearchParamsToUrl(url, resolvedOptions);
212
+ return await parseUrl(requestUrl, resolvedOptions, context);
213
+ }
177
214
  }
178
215
  }
179
216
 
180
217
  // Select fetch function
218
+ if (resolvedOptions) resolvedOptions = resolveAuthenticationOptions(resolvedOptions);
181
219
  const fetch = getFetchFunction(resolvedOptions);
182
220
 
183
221
  // at this point, `url` could be already loaded binary data
184
222
  let data = url;
185
223
  // url is a string, fetch the url
186
224
  if (typeof url === 'string') {
187
- data = await fetch(url);
225
+ data = await fetch(applySearchParamsToUrl(url, resolvedOptions));
188
226
  // URL is Blob or File, fetchFile handles it (alt: we could generate ObjectURL here)
189
227
  }
190
228
 
@@ -16,7 +16,11 @@ import type {
16
16
  ReadableFile,
17
17
  StrictLoaderOptions
18
18
  } from '@loaders.gl/loader-utils';
19
- import {isSourceLoader, mergeOptions} from '@loaders.gl/loader-utils';
19
+ import {
20
+ isSourceLoader,
21
+ mergeOptions,
22
+ resolveLoaderAuthenticationOptions
23
+ } from '@loaders.gl/loader-utils';
20
24
  import {validateWorkerVersion} from '@loaders.gl/worker-utils';
21
25
  import {isLoaderObject} from '../loader-utils/normalize-loader';
22
26
  import {normalizeOptions} from '../loader-utils/option-utils';
@@ -96,7 +100,16 @@ export async function parseFile(
96
100
  }
97
101
 
98
102
  // @ts-expect-error candidateLoaders may be a single forced loader
99
- const strictOptions = normalizeOptions(options, loader, candidateLoaders, url);
103
+ const normalizedOptions = normalizeOptions(options, loader, candidateLoaders, url);
104
+ const authenticationLoader =
105
+ !loader.getAuthentications && normalizedOptions.core?.credentials?.length
106
+ ? await getLoaderImplementation(loader, normalizedOptions, url || context?.url)
107
+ : loader;
108
+ const strictOptions = await resolveLoaderAuthenticationOptions(
109
+ authenticationLoader,
110
+ url,
111
+ normalizedOptions
112
+ );
100
113
  context = getLoaderContext(
101
114
  // @ts-expect-error candidateLoaders may be a single forced loader
102
115
  {url, _parse: parse, loaders: candidateLoaders},
@@ -4,6 +4,7 @@
4
4
 
5
5
  import type {Batch} from '@loaders.gl/schema';
6
6
  import {isTable, makeBatchFromTable} from '@loaders.gl/schema-utils';
7
+ import {resolveLoaderAuthenticationOptions} from '@loaders.gl/loader-utils';
7
8
  import type {
8
9
  Loader,
9
10
  LoaderWithParser,
@@ -112,7 +113,16 @@ export async function parseInBatches(
112
113
  }
113
114
 
114
115
  // Normalize options
115
- const strictOptions = normalizeOptions(options, loader, loaderArray, url);
116
+ const normalizedOptions = normalizeOptions(options, loader, loaderArray, url);
117
+ const authenticationLoader =
118
+ !loader.getAuthentications && normalizedOptions.core?.credentials?.length
119
+ ? await getLoaderImplementation(loader, normalizedOptions, url || context?.url)
120
+ : loader;
121
+ const strictOptions = await resolveLoaderAuthenticationOptions(
122
+ authenticationLoader,
123
+ url || '',
124
+ normalizedOptions
125
+ );
116
126
  context = getLoaderContext(
117
127
  {url, _parseInBatches: parseInBatches, _parse: parse, loaders: loaderArray},
118
128
  strictOptions,
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
+ import {resolveLoaderAuthenticationOptions} from '@loaders.gl/loader-utils';
5
6
  import type {
6
7
  Loader,
7
8
  LoaderContext,
@@ -121,7 +122,16 @@ export async function parse(
121
122
 
122
123
  // Normalize options
123
124
  // @ts-expect-error candidateLoaders
124
- const strictOptions = normalizeOptions(options, loader, candidateLoaders, url); // Could be invalid...
125
+ const normalizedOptions = normalizeOptions(options, loader, candidateLoaders, url); // Could be invalid...
126
+ const authenticationLoader =
127
+ !loader.getAuthentications && normalizedOptions.core?.credentials?.length
128
+ ? await getLoaderImplementation(loader, normalizedOptions, url || context?.url)
129
+ : loader;
130
+ const strictOptions = await resolveLoaderAuthenticationOptions(
131
+ authenticationLoader,
132
+ url || '',
133
+ normalizedOptions
134
+ );
125
135
 
126
136
  // Get a context (if already present, will be unchanged)
127
137
  context = getLoaderContext(
@@ -27,9 +27,7 @@ export function getFetchFunction(
27
27
  if (typeof fetchOption === 'function') {
28
28
  fetchFunction = fetchOption;
29
29
  } else if (isObject(fetchOption)) {
30
- const baseFetch = context?.fetch || fetchFile;
31
- fetchFunction = (url, requestOptions) =>
32
- baseFetch(url, mergeFetchOptions(fetchOption as RequestInit, requestOptions));
30
+ fetchFunction = context?.fetch || fetchFile;
33
31
  } else if (context?.fetch) {
34
32
  fetchFunction = context.fetch;
35
33
  } else {
@@ -38,17 +36,8 @@ export function getFetchFunction(
38
36
 
39
37
  return createAuthenticatedFetch({
40
38
  fetch: fetchFunction,
41
- credentials: loaderOptions.core?.credentials || []
39
+ credentials: loaderOptions.core?.credentials || [],
40
+ authentications: loaderOptions.core?.authentications,
41
+ fetchOptions: isObject(fetchOption) ? (fetchOption as RequestInit) : undefined
42
42
  });
43
43
  }
44
-
45
- /** Combines static and per-request fetch options without replacing either header collection. */
46
- function mergeFetchOptions(defaultOptions: RequestInit, requestOptions?: RequestInit): RequestInit {
47
- const options = {...defaultOptions, ...requestOptions};
48
- if (defaultOptions.headers || requestOptions?.headers) {
49
- const headers = new Headers(defaultOptions.headers);
50
- new Headers(requestOptions?.headers).forEach((value, key) => headers.set(key, value));
51
- options.headers = headers;
52
- }
53
- return options;
54
- }
@@ -7,6 +7,7 @@ import {isBrowser} from '@loaders.gl/loader-utils';
7
7
  import {ConsoleLog} from './loggers';
8
8
 
9
9
  export const DEFAULT_LOADER_OPTIONS: LoaderOptions = {
10
+ searchParams: undefined,
10
11
  core: {
11
12
  baseUrl: undefined,
12
13
  // baseUrl
@@ -42,6 +42,40 @@ const CORE_LOADER_OPTION_KEYS = [
42
42
  'transforms'
43
43
  ] as const;
44
44
 
45
+ /**
46
+ * Appends loader search parameters to a URL while preserving existing parameters and fragments.
47
+ * @param url URL to update
48
+ * @param options Loader options containing optional search parameters
49
+ * @returns URL with the configured parameters appended
50
+ */
51
+ export function applySearchParamsToUrl(url: string, options?: LoaderOptions): string {
52
+ const searchParams = options?.searchParams;
53
+ if (!searchParams || Object.keys(searchParams).length === 0 || /^(?:data|blob):/i.test(url)) {
54
+ return url;
55
+ }
56
+
57
+ const hashIndex = url.indexOf('#');
58
+ const hash = hashIndex >= 0 ? url.slice(hashIndex) : '';
59
+ const urlWithoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
60
+ const queryIndex = urlWithoutHash.indexOf('?');
61
+ const path = queryIndex >= 0 ? urlWithoutHash.slice(0, queryIndex) : urlWithoutHash;
62
+ const query = queryIndex >= 0 ? urlWithoutHash.slice(queryIndex + 1) : '';
63
+ const existingSearchParams = new URLSearchParams(query);
64
+ const appendedSearchParams = new URLSearchParams();
65
+ for (const [key, value] of Object.entries(searchParams)) {
66
+ if (!existingSearchParams.has(key)) {
67
+ appendedSearchParams.set(key, String(value));
68
+ }
69
+ }
70
+
71
+ const serializedAppendedSearchParams = appendedSearchParams.toString();
72
+ return `${path}${queryIndex >= 0 ? `?${query}` : ''}${
73
+ serializedAppendedSearchParams
74
+ ? `${queryIndex >= 0 ? '&' : '?'}${serializedAppendedSearchParams}`
75
+ : ''
76
+ }${hash}`;
77
+ }
78
+
45
79
  /**
46
80
  * Global state for loaders.gl. Stored on `globalThis.loaders._state`
47
81
  */