• 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

69.13
/modules/loader-utils/src/lib/iterators/async-iteration.ts
1
import {concatenateArrayBuffers} from '../binary-utils/array-buffer-utils';
1✔
2

1✔
3
// GENERAL UTILITIES
1✔
4

1✔
5
/**
1✔
6
 * Iterates over an {@link AsyncIterable} or {@link Iterable}, invoking `visitor` for each yielded
1✔
7
 * value without rewinding the iterator when exiting early. This enables the caller to continue
1✔
8
 * iterating in another loop after `visitor` signals cancellation.
1✔
9
 */
1✔
10
export async function forEach<TValue>(
1✔
11
  iterable: AsyncIterable<TValue> | Iterable<TValue> | AsyncIterator<TValue>,
1✔
12
  visitor: (value: TValue) => any
1✔
13
) {
1✔
14
  const iterator = toAsyncIterator(iterable);
1✔
15
  // eslint-disable-next-line
1✔
16
  while (true) {
1✔
17
    const {done, value} = await iterator.next();
4✔
18
    if (done) {
4✔
19
      if (iterator.return) {
1✔
20
        iterator.return();
1✔
21
      }
1✔
22
      return;
1✔
23
    }
1✔
24
    const cancel = visitor(value);
3✔
25
    if (cancel) {
4!
UNCOV
26
      return;
×
UNCOV
27
    }
×
28
  }
4✔
29
}
1✔
30

1✔
31
/**
1✔
32
 * Concatenates all binary chunks yielded by an async or sync iterator.
1✔
33
 * Supports `ArrayBuffer`, typed array views, and `ArrayBufferLike` sources (e.g. `SharedArrayBuffer`).
1✔
34
 * This allows atomic parsers to operate on iterator inputs by materializing them into a single buffer.
1✔
35
 */
1✔
36
export async function concatenateArrayBuffersAsync(
3✔
37
  asyncIterator:
3✔
38
    | AsyncIterable<ArrayBufferLike | ArrayBufferView>
3✔
39
    | Iterable<ArrayBufferLike | ArrayBufferView>
3✔
40
): Promise<ArrayBuffer> {
3✔
41
  const arrayBuffers: ArrayBuffer[] = [];
3✔
42
  for await (const chunk of asyncIterator) {
3✔
43
    arrayBuffers.push(copyToArrayBuffer(chunk));
8✔
44
  }
8✔
45
  return concatenateArrayBuffers(...arrayBuffers);
3✔
46
}
3✔
47

1✔
48
export async function concatenateStringsAsync(
×
49
  asyncIterator: AsyncIterable<string> | Iterable<string>
×
50
): Promise<string> {
×
51
  const strings: string[] = [];
×
52
  for await (const chunk of asyncIterator) {
×
53
    strings.push(chunk);
×
54
  }
×
55
  return strings.join('');
×
56
}
×
57

1✔
58
/**
1✔
59
 * Normalizes binary chunk iterators to yield `ArrayBuffer` instances.
1✔
60
 * Accepts `ArrayBuffer`, `ArrayBufferView`, and `ArrayBufferLike` sources
1✔
61
 * (e.g. `SharedArrayBuffer`) and returns a copied `ArrayBuffer` for each chunk.
1✔
62
 */
1✔
63
export async function* toArrayBufferIterator(
3✔
64
  asyncIterator:
3✔
65
    | AsyncIterable<ArrayBufferLike | ArrayBufferView>
3✔
66
    | Iterable<ArrayBufferLike | ArrayBufferView>
3✔
67
): AsyncIterable<ArrayBuffer> {
3✔
68
  for await (const chunk of asyncIterator) {
3✔
69
    yield copyToArrayBuffer(chunk);
5✔
70
  }
5✔
71
}
3✔
72

1✔
73
function copyToArrayBuffer(chunk: ArrayBufferLike | ArrayBufferView | ArrayBuffer): ArrayBuffer {
13✔
74
  if (chunk instanceof ArrayBuffer) {
13✔
75
    return chunk;
3✔
76
  }
3✔
77

10✔
78
  if (ArrayBuffer.isView(chunk)) {
10✔
79
    const {buffer, byteOffset, byteLength} = chunk;
10✔
80
    return copyFromBuffer(buffer, byteOffset, byteLength);
10✔
81
  }
10!
82

×
83
  return copyFromBuffer(chunk as ArrayBufferLike);
×
84
}
×
85

1✔
86
function copyFromBuffer(
10✔
87
  buffer: ArrayBufferLike,
10✔
88
  byteOffset = 0,
10✔
89
  byteLength = buffer.byteLength - byteOffset
10✔
90
): ArrayBuffer {
10✔
91
  const view = new Uint8Array(buffer, byteOffset, byteLength);
10✔
92
  const copy = new Uint8Array(view.length);
10✔
93
  copy.set(view);
10✔
94
  return copy.buffer;
10✔
95
}
10✔
96

1✔
97
function toAsyncIterator<TValue>(
1✔
98
  iterable: AsyncIterable<TValue> | Iterable<TValue> | AsyncIterator<TValue>
1✔
99
): AsyncIterator<TValue> {
1✔
100
  if (typeof iterable[Symbol.asyncIterator] === 'function') {
1✔
101
    return iterable[Symbol.asyncIterator]();
1✔
102
  }
1!
103

×
104
  if (typeof iterable[Symbol.iterator] === 'function') {
×
105
    const iterator = iterable[Symbol.iterator]();
×
106
    return iteratorToAsyncIterator(iterator);
×
107
  }
×
108

×
109
  return iterable as AsyncIterator<TValue>;
×
110
}
×
111

1✔
112
function iteratorToAsyncIterator<T>(iterator: Iterator<T>): AsyncIterator<T> {
×
113
  return {
×
114
    next(value?: any) {
×
115
      return Promise.resolve(iterator.next(value));
×
116
    },
×
117

×
118
    return(value?: any) {
×
119
      if (typeof iterator.return === 'function') {
×
120
        return Promise.resolve(iterator.return(value));
×
121
      }
×
122
      return Promise.resolve({done: true, value});
×
123
    },
×
124

×
125
    throw(error?: any) {
×
126
      if (typeof iterator.throw === 'function') {
×
127
        return Promise.resolve(iterator.throw(error));
×
128
      }
×
129
      return Promise.reject(error);
×
130
    }
×
131
  };
×
132
}
×
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