• 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

64.52
/modules/core/src/iterators/make-iterator/make-stream-iterator.ts
1
// loaders.gl
1✔
2
// SPDX-License-Identifier: MIT
1✔
3
// Copyright (c) vis.gl contributors
1✔
4

1✔
5
import type {Readable} from 'stream';
1✔
6
import {isBrowser, toArrayBuffer} from '@loaders.gl/loader-utils';
1✔
7

1✔
8
export type StreamIteratorOptions = {
1✔
9
  _streamReadAhead?: boolean;
1✔
10
};
1✔
11

1✔
12
/**
1✔
13
 * Returns an async iterable that reads from a stream (works in both Node.js and browsers)
1✔
14
 * @param stream stream to iterator over
1✔
15
 */
1✔
16
export function makeStreamIterator(
1✔
17
  stream: ReadableStream | Readable,
126✔
18
  options?: StreamIteratorOptions
126✔
19
): AsyncIterable<ArrayBuffer> {
126✔
20
  return isBrowser
126✔
21
    ? makeBrowserStreamIterator(stream as ReadableStream, options)
126!
22
    : makeNodeStreamIterator(stream as Readable, options);
126✔
23
}
126✔
24

265✔
25
/**
265✔
26
 * Returns an async iterable that reads from a DOM (browser) stream
265✔
27
 * @param stream stream to iterate from
265✔
28
 * @see https://jakearchibald.com/2017/async-iterators-and-generators/#making-streams-iterate
265✔
29
 */
265✔
UNCOV
30
async function* makeBrowserStreamIterator(
×
UNCOV
31
  stream: ReadableStream,
×
UNCOV
32
  options?: StreamIteratorOptions
×
UNCOV
33
): AsyncIterable<ArrayBuffer> {
×
UNCOV
34
  // WhatWG: stream is supposed to have a `getIterator` method
×
UNCOV
35
  // if (typeof stream.getIterator === 'function') {
×
UNCOV
36
  //   return stream.getIterator();
×
UNCOV
37
  // }
×
UNCOV
38
  // if (typeof stream[Symbol.asyncIterator] === 'function') {
×
UNCOV
39
  //   return makeToArrayBufferIterator(stream);
×
UNCOV
40
  // }
×
UNCOV
41

×
UNCOV
42
  // In the browser, we first need to get a lock on the stream
×
UNCOV
43
  const reader = stream.getReader();
×
UNCOV
44

×
UNCOV
45
  let nextBatchPromise: Promise<{done?: boolean; value?: Uint8Array}> | undefined;
×
UNCOV
46

×
UNCOV
47
  try {
×
UNCOV
48
    // eslint-disable-next-line no-constant-condition
×
UNCOV
49
    while (true) {
×
UNCOV
50
      const currentBatchPromise = nextBatchPromise || reader.read();
×
UNCOV
51
      // Issue a read for an additional batch, while we await the next batch
×
UNCOV
52
      // Idea is to make fetching happen in parallel with processing / parsing
×
UNCOV
53
      if (options?._streamReadAhead) {
×
54
        nextBatchPromise = reader.read();
×
55
      }
×
UNCOV
56
      // Read from the stream
×
UNCOV
57
      // value is a Uint8Array
×
UNCOV
58
      const {done, value} = await currentBatchPromise;
×
UNCOV
59
      // Exit if we're done
×
UNCOV
60
      if (done) {
×
UNCOV
61
        return;
×
UNCOV
62
      }
×
UNCOV
63
      // Else yield the chunk
×
UNCOV
64
      yield toArrayBuffer(value);
×
UNCOV
65
    }
×
UNCOV
66
  } catch (_error) {
×
67
    // TODO - examples makes it look like this should always be called,
×
68
    // but that generates exceptions so only call it if we do not reach the end
×
69
    reader.releaseLock();
×
70
  }
×
UNCOV
71
}
×
72

1✔
73
/**
1✔
74
 * Returns an async iterable that reads from a DOM (browser) stream
1✔
75
 * @param stream stream to iterate from
1✔
76
 * @note Requires Node.js >= 10
1✔
77
 */
1✔
78
async function* makeNodeStreamIterator(
126✔
79
  stream: Readable,
126✔
80
  options?: StreamIteratorOptions
126✔
81
): AsyncIterable<ArrayBuffer> {
126✔
82
  // Hacky test for node version to ensure we don't call bad polyfills
126✔
83
  // NODE 10+: stream is an asyncIterator
126✔
84
  for await (const chunk of stream) {
126✔
85
    yield toArrayBuffer(chunk); // Coerce each chunk to ArrayBuffer
275✔
86
  }
273✔
87
}
124✔
88
/* TODO - remove NODE < 10
1✔
89
 * @see https://github.com/bustle/streaming-iterables, MIT license
1✔
90
 *
1✔
91
  if (typeof stream[Symbol.asyncIterator] === 'function') {
1✔
92
    return;
1✔
93
  }
1✔
94

1✔
95
  // TODO - check if is this ever used in Node 10+?
1✔
96
  // eslint-disable-next-line no-constant-condition
1✔
97
  while (true) {
1✔
98
    const data = stream.read();
1✔
99
    if (data !== null) {
1✔
100
      yield toArrayBuffer(data);
1✔
101
      // eslint-disable-next-line no-continue
1✔
102
      continue;
1✔
103
    }
1✔
104
    if (stream._readableState?.ended) {
1✔
105
      return;
1✔
106
    }
1✔
107
    await onceReadable(stream);
1✔
108
  }
1✔
109

1✔
110
async function onceReadable(stream: Readable): Promise<any> {
1✔
111
  return new Promise((resolve) => {
1✔
112
    stream.once('readable', resolve);
1✔
113
  });
1✔
114
}
1✔
115
  */
1✔
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