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

visgl / loaders.gl / 20352515932

18 Dec 2025 09:56PM UTC coverage: 35.115% (-28.4%) from 63.485%
20352515932

push

github

web-flow
feat(loader-utils): Export is-type helpers (#3258)

1188 of 1998 branches covered (59.46%)

Branch coverage included in aggregate %.

147 of 211 new or added lines in 13 files covered. (69.67%)

30011 existing lines in 424 files now uncovered.

37457 of 108056 relevant lines covered (34.66%)

0.79 hits per line

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

46.2
/modules/core/src/lib/api/parse.ts
1
// loaders.gl
1✔
2
// SPDX-License-Identifier: MIT
1✔
3
// Copyright (c) vis.gl contributors
1✔
4

1✔
5
import type {
1✔
6
  Loader,
1✔
7
  LoaderContext,
1✔
8
  LoaderOptions,
1✔
9
  DataType,
1✔
10
  LoaderWithParser,
1✔
11
  LoaderOptionsType,
1✔
12
  LoaderReturnType,
1✔
13
  LoaderArrayOptionsType,
1✔
14
  LoaderArrayReturnType,
1✔
15
  StrictLoaderOptions
1✔
16
} from '@loaders.gl/loader-utils';
1✔
17
import {
1✔
18
  parseWithWorker,
1✔
19
  canParseWithWorker,
1✔
20
  mergeOptions,
1✔
21
  isResponse
1✔
22
} from '@loaders.gl/loader-utils';
1✔
23
import {assert, validateWorkerVersion} from '@loaders.gl/worker-utils';
1✔
24
import {isLoaderObject} from '../loader-utils/normalize-loader';
1✔
25
import {normalizeOptions} from '../loader-utils/option-utils';
1✔
26
import {getArrayBufferOrStringFromData} from '../loader-utils/get-data';
1✔
27
import {getLoaderContext, getLoadersFromContext} from '../loader-utils/loader-context';
1✔
28
import {getResourceUrl} from '../utils/resource-utils';
1✔
29
import {selectLoader} from './select-loader';
1✔
30

1✔
31
// type LoaderArrayType<T> = T extends (infer Loader)[] ? LoaderOptionsType<Loader> : T
1✔
32

1✔
33
/**
1✔
34
 * Parses `data` asynchronously using the supplied loader
1✔
35
 */
1✔
36
export async function parse<
1✔
37
  LoaderT extends Loader,
1✔
38
  OptionsT extends LoaderOptions = LoaderOptionsType<LoaderT>
1✔
39
>(
1✔
40
  data: DataType | Promise<DataType>,
1✔
41
  loader: LoaderT,
1✔
42
  options?: OptionsT,
1✔
43
  context?: LoaderContext
1✔
44
): Promise<LoaderReturnType<LoaderT>>;
1✔
45

1✔
46
/**
1✔
47
 * Parses `data` asynchronously by matching one of the supplied loader
1✔
48
 */
1✔
49
export async function parse<
1✔
50
  LoaderArrayT extends Loader[],
1✔
51
  OptionsT extends LoaderOptions = LoaderArrayOptionsType<LoaderArrayT>
1✔
52
>(
1✔
53
  data: DataType | Promise<DataType>,
1✔
54
  loaders: LoaderArrayT,
1✔
55
  options?: OptionsT,
1✔
56
  context?: LoaderContext
1✔
57
): Promise<LoaderArrayReturnType<LoaderArrayT>>;
1✔
58

1✔
59
/**
1✔
60
 * Parses data asynchronously by matching a pre-registered loader
1✔
61
 * @deprecated Loader registration is deprecated, use parse(data, loaders, options) instead
1✔
62
 */
1✔
63
export async function parse(
1✔
64
  data: DataType | Promise<DataType>,
1✔
65
  options?: LoaderOptions
1✔
66
): Promise<unknown>;
1✔
67

1✔
68
/**
1✔
69
 * Parses `data` using a specified loader
1✔
70
 * @param data
1✔
71
 * @param loaders
1✔
72
 * @param options
1✔
73
 * @param context
1✔
74
 */
1✔
75
// implementation signature
1✔
UNCOV
76
export async function parse(
×
UNCOV
77
  data: DataType | Promise<DataType>,
×
UNCOV
78
  loaders?: Loader | Loader[] | LoaderOptions,
×
UNCOV
79
  options?: LoaderOptions,
×
UNCOV
80
  context?: LoaderContext
×
UNCOV
81
): Promise<unknown> {
×
UNCOV
82
  // Signature: parse(data, options, context | url)
×
UNCOV
83
  // Uses registered loaders
×
UNCOV
84
  if (loaders && !Array.isArray(loaders) && !isLoaderObject(loaders)) {
×
UNCOV
85
    context = undefined; // context not supported in short signature
×
UNCOV
86
    options = loaders as LoaderOptions;
×
UNCOV
87
    loaders = undefined;
×
UNCOV
88
  }
×
UNCOV
89

×
UNCOV
90
  data = await data; // Resolve any promise
×
UNCOV
91
  options = options || ({} as LoaderOptions); // Could be invalid...
×
UNCOV
92

×
UNCOV
93
  // Extract a url for auto detection
×
UNCOV
94
  const url = getResourceUrl(data);
×
UNCOV
95

×
UNCOV
96
  // Chooses a loader (and normalizes it)
×
UNCOV
97
  // Also use any loaders in the context, new loaders take priority
×
UNCOV
98
  const typedLoaders = loaders as Loader | Loader[] | undefined;
×
UNCOV
99
  const candidateLoaders = getLoadersFromContext(typedLoaders, context);
×
UNCOV
100
  // todo hacky type cast
×
UNCOV
101
  const loader = await selectLoader(data as ArrayBuffer, candidateLoaders, options);
×
UNCOV
102
  // Note: if no loader was found, if so just return null
×
UNCOV
103
  if (!loader) {
×
104
    return null;
×
105
  }
×
UNCOV
106

×
UNCOV
107
  // Normalize options
×
UNCOV
108
  // @ts-expect-error candidateLoaders
×
UNCOV
109
  const strictOptions = normalizeOptions(options, loader, candidateLoaders, url); // Could be invalid...
×
UNCOV
110

×
UNCOV
111
  // Get a context (if already present, will be unchanged)
×
UNCOV
112
  context = getLoaderContext(
×
UNCOV
113
    // @ts-expect-error
×
UNCOV
114
    {url, _parse: parse, loaders: candidateLoaders},
×
UNCOV
115
    strictOptions,
×
UNCOV
116
    context || null
×
UNCOV
117
  );
×
UNCOV
118

×
UNCOV
119
  return await parseWithLoader(loader, data, strictOptions, context);
×
UNCOV
120
}
×
121

1✔
122
// TODO: support progress and abort
1✔
123
// TODO - should accept loader.parseAsyncIterator and concatenate.
1✔
UNCOV
124
async function parseWithLoader(
×
UNCOV
125
  loader: Loader,
×
UNCOV
126
  data,
×
UNCOV
127
  options: StrictLoaderOptions,
×
UNCOV
128
  context: LoaderContext
×
UNCOV
129
): Promise<unknown> {
×
UNCOV
130
  validateWorkerVersion(loader);
×
UNCOV
131

×
UNCOV
132
  options = mergeOptions(loader.options, options);
×
UNCOV
133

×
UNCOV
134
  if (isResponse(data)) {
×
UNCOV
135
    // Serialize to support passing the response to web worker
×
NEW
136
    const {ok, redirected, status, statusText, type, url} = data;
×
NEW
137
    const headers = Object.fromEntries(data.headers.entries());
×
UNCOV
138
    // @ts-expect-error TODO - fix this
×
UNCOV
139
    context.response = {headers, ok, redirected, status, statusText, type, url};
×
UNCOV
140
  }
×
UNCOV
141

×
UNCOV
142
  data = await getArrayBufferOrStringFromData(data, loader, options);
×
UNCOV
143

×
UNCOV
144
  const loaderWithParser = loader as LoaderWithParser;
×
UNCOV
145

×
UNCOV
146
  // First check for synchronous text parser, wrap results in promises
×
UNCOV
147
  if (loaderWithParser.parseTextSync && typeof data === 'string') {
×
UNCOV
148
    return loaderWithParser.parseTextSync(data, options, context);
×
UNCOV
149
  }
×
UNCOV
150

×
UNCOV
151
  // If we have a workerUrl and the loader can parse the given options efficiently in a worker
×
UNCOV
152
  if (canParseWithWorker(loader, options)) {
×
UNCOV
153
    return await parseWithWorker(loader, data, options, context, parse);
×
UNCOV
154
  }
×
UNCOV
155

×
UNCOV
156
  // Check for asynchronous parser
×
UNCOV
157
  if (loaderWithParser.parseText && typeof data === 'string') {
×
UNCOV
158
    return await loaderWithParser.parseText(data, options, context);
×
UNCOV
159
  }
×
UNCOV
160

×
UNCOV
161
  if (loaderWithParser.parse) {
×
UNCOV
162
    return await loaderWithParser.parse(data, options, context);
×
UNCOV
163
  }
×
164

×
165
  // This should not happen, all sync loaders should also offer `parse` function
×
166
  assert(!loaderWithParser.parseSync);
×
167

×
168
  // TBD - If asynchronous parser not available, return null
×
169
  throw new Error(`${loader.id} loader - no parser found and worker is disabled`);
×
170
}
×
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