• 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

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

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

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

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

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

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

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

UNCOV
47
  try {
147✔
48
    // eslint-disable-next-line no-constant-condition
UNCOV
49
    while (true) {
147✔
UNCOV
50
      const currentBatchPromise = nextBatchPromise || reader.read();
338✔
51
      // Issue a read for an additional batch, while we await the next batch
52
      // Idea is to make fetching happen in parallel with processing / parsing
UNCOV
53
      if (options?._streamReadAhead) {
338!
54
        nextBatchPromise = reader.read();
×
55
      }
56
      // Read from the stream
57
      // value is a Uint8Array
UNCOV
58
      const {done, value} = await currentBatchPromise;
338✔
59
      // Exit if we're done
UNCOV
60
      if (done) {
338✔
UNCOV
61
        return;
133✔
62
      }
63
      // Else yield the chunk
UNCOV
64
      yield toArrayBuffer(value);
205✔
65
    }
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
  }
71
}
72

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

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

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