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

visgl / loaders.gl / 25070233425

28 Apr 2026 06:20PM UTC coverage: 59.434% (+0.01%) from 59.423%
25070233425

push

github

web-flow
website: Add tabs for navigating between format docs (#3407)

11310 of 20887 branches covered (54.15%)

Branch coverage included in aggregate %.

89 of 136 new or added lines in 13 files covered. (65.44%)

1742 existing lines in 132 files now uncovered.

23500 of 37682 relevant lines covered (62.36%)

16296.63 hits per line

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

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

5
import type {Loader, LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
6

7
const loaderImplementationPromises = new Map<Loader, Promise<LoaderWithParser>>();
358✔
8
const loaderImplementations = new Map<Loader, LoaderWithParser>();
358✔
9

10
/** Gets a parser-bearing implementation for a loader, loading it if needed. */
11
export async function getLoaderImplementation(
12
  loader: Loader,
13
  options?: LoaderOptions,
14
  url?: string
15
): Promise<LoaderWithParser> {
16
  if (isLoaderWithParser(loader)) {
2,560✔
17
    return loader;
576✔
18
  }
19

20
  const loaderImplementation = loaderImplementations.get(loader);
1,984✔
21
  if (loaderImplementation) {
1,984✔
22
    return loaderImplementation;
1,634✔
23
  }
24

25
  let loaderImplementationPromise = loaderImplementationPromises.get(loader);
350✔
26
  if (!loaderImplementationPromise) {
350✔
27
    loaderImplementationPromise = resolveLoaderImplementation(loader, options, url)
318✔
28
      .then(implementation => {
29
        loaderImplementations.set(loader, implementation);
312✔
30
        return implementation;
312✔
31
      })
32
      .catch(error => {
33
        loaderImplementationPromises.delete(loader);
6✔
34
        throw error;
6✔
35
      });
36
    loaderImplementationPromises.set(loader, loaderImplementationPromise);
318✔
37
  }
38

39
  return await loaderImplementationPromise;
350✔
40
}
41

42
/** Gets a cached parser-bearing implementation for a loader without loading it. */
43
export function getLoaderImplementationSync(loader: Loader): LoaderWithParser | null {
44
  if (isLoaderWithParser(loader)) {
160,438✔
45
    return loader;
160,402✔
46
  }
47

48
  return loaderImplementations.get(loader) || null;
36✔
49
}
50

51
/** Returns true when a loader object already includes parser methods. */
52
export function isLoaderWithParser(loader: Loader): loader is LoaderWithParser {
53
  const candidate = loader as LoaderWithParser;
163,314✔
54
  return Boolean(
163,314✔
55
    candidate.parse ||
175,514✔
56
      candidate.parseSync ||
57
      candidate.parseInBatches ||
58
      candidate.parseText ||
59
      candidate.parseTextSync ||
60
      candidate.parseFile ||
61
      candidate.parseFileInBatches
62
  );
63
}
64

65
/** Resolves a parser-bearing implementation through loader preload or the test import fallback. */
66
async function resolveLoaderImplementation(
67
  loader: Loader,
68
  options?: LoaderOptions,
69
  url?: string
70
): Promise<LoaderWithParser> {
71
  if (loader.preload) {
318✔
72
    const preloadedLoader = await loader.preload(url || '', options);
315✔
73
    if (isLoaderWithParser(preloadedLoader as Loader)) {
315✔
74
      return preloadedLoader as LoaderWithParser;
311✔
75
    }
76

77
    throw new Error(`${loader.id} loader preload() did not return a parser-bearing loader`);
4✔
78
  }
79

80
  const implementationSpecifier = getLoaderImplementationSpecifier(loader, options);
3✔
81
  return await importLoaderImplementation(implementationSpecifier, loader.id);
3✔
82
}
83

84
/** Gets the dynamic implementation specifier for the test worker fallback path. */
85
function getLoaderImplementationSpecifier(loader: Loader, options?: LoaderOptions): string {
86
  const workerType = options?._workerType || options?.core?._workerType;
3✔
87
  if (workerType === 'test') {
3✔
UNCOV
88
    const sourcePath = `modules/${loader.module}/src/${loader.id}-loader.ts`;
1✔
UNCOV
89
    if (typeof window !== 'undefined') {
1!
UNCOV
90
      return `/${sourcePath}`;
1✔
91
    }
92

93
    if (typeof process !== 'undefined' && process.cwd) {
×
94
      return new URL(sourcePath, `file://${process.cwd()}/`).toString();
×
95
    }
96

97
    return sourcePath;
×
98
  }
99

100
  throw new Error(
2✔
101
    `${loader.id} loader does not provide a parser implementation. Import a parser-bearing loader directly, or use preload() before parse/load.`
102
  );
103
}
104

105
/** Imports a module and finds the parser-bearing loader implementation with the requested id. */
106
async function importLoaderImplementation(
107
  implementationSpecifier: string,
108
  loaderId: string
109
): Promise<LoaderWithParser> {
UNCOV
110
  const moduleExports = await import(
1✔
111
    /* webpackIgnore: true */ /* @vite-ignore */ implementationSpecifier
112
  );
113

UNCOV
114
  for (const exportValue of Object.values(moduleExports)) {
1✔
UNCOV
115
    if (
1!
116
      exportValue &&
4✔
117
      typeof exportValue === 'object' &&
118
      (exportValue as Loader).id === loaderId &&
119
      isLoaderWithParser(exportValue as Loader)
120
    ) {
UNCOV
121
      return exportValue as LoaderWithParser;
1✔
122
    }
123
  }
124

125
  throw new Error(
×
126
    `Could not find parser implementation for ${loaderId} in ${implementationSpecifier}`
127
  );
128
}
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