Skip to content

Commit 0902067

Browse files
achingbrainhugomrdias
authored andcommitted
feat: accept browser readable streams as input (#21)
N.b you can't read from a browser reaable stream repeatedly as the first call to `stream.getReader` locks the reader to the first invocation so I had to change all the test data to be functions that reutrn a new instance of the data.
1 parent fd3bfc5 commit 0902067

File tree

2 files changed

+52
-22
lines changed

2 files changed

+52
-22
lines changed

src/files/normalise-input.js

+17-3
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ module.exports = function normaliseInput (input) {
9999
})()
100100
}
101101

102+
// window.ReadableStream
103+
if (typeof input.getReader === 'function') {
104+
return (async function * () {
105+
for await (const obj of browserStreamToIt(input)) {
106+
yield toFileObject(obj)
107+
}
108+
})()
109+
}
110+
102111
// AsyncIterable<?>
103112
if (input[Symbol.asyncIterator]) {
104113
return (async function * () {
@@ -171,6 +180,11 @@ function toAsyncIterable (input) {
171180
return blobToAsyncGenerator(input)
172181
}
173182

183+
// Browser stream
184+
if (typeof input.getReader === 'function') {
185+
return browserStreamToIt(input)
186+
}
187+
174188
// Iterator<?>
175189
if (input[Symbol.iterator]) {
176190
return (async function * () { // eslint-disable-line require-await
@@ -232,14 +246,14 @@ function isFileObject (obj) {
232246
function blobToAsyncGenerator (blob) {
233247
if (typeof blob.stream === 'function') {
234248
// firefox < 69 does not support blob.stream()
235-
return streamBlob(blob)
249+
return browserStreamToIt(blob.stream())
236250
}
237251

238252
return readBlob(blob)
239253
}
240254

241-
async function * streamBlob (blob) {
242-
const reader = blob.stream().getReader()
255+
async function * browserStreamToIt (stream) {
256+
const reader = stream.getReader()
243257

244258
while (true) {
245259
const result = await reader.read()

test/files/normalise-input.spec.js

+35-19
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,24 @@ const globalThis = require('../../src/globalthis')
1212
chai.use(dirtyChai)
1313
const expect = chai.expect
1414

15-
const STRING = 'hello world'
16-
const BUFFER = Buffer.from(STRING)
17-
const ARRAY = Array.from(BUFFER)
18-
const TYPEDARRAY = Uint8Array.from(ARRAY)
15+
const STRING = () => 'hello world'
16+
const BUFFER = () => Buffer.from(STRING())
17+
const ARRAY = () => Array.from(BUFFER())
18+
const TYPEDARRAY = () => Uint8Array.from(ARRAY())
1919
let BLOB
20+
let WINDOW_READABLE_STREAM
2021

2122
if (supportsFileReader) {
22-
BLOB = new globalThis.Blob([
23-
STRING
23+
BLOB = () => new globalThis.Blob([
24+
STRING()
2425
])
26+
27+
WINDOW_READABLE_STREAM = () => new globalThis.ReadableStream({
28+
start (controller) {
29+
controller.enqueue(BUFFER())
30+
controller.close()
31+
}
32+
})
2533
}
2634

2735
async function verifyNormalisation (input) {
@@ -31,7 +39,7 @@ async function verifyNormalisation (input) {
3139
chai.assert.fail('Content should have been an iterable or an async iterable')
3240
}
3341

34-
expect(await all(input[0].content)).to.deep.equal([BUFFER])
42+
expect(await all(input[0].content)).to.deep.equal([BUFFER()])
3543
expect(input[0].path).to.equal('')
3644
}
3745

@@ -54,56 +62,56 @@ function asyncIterableOf (thing) {
5462
describe('normalise-input', function () {
5563
function testInputType (content, name, isBytes) {
5664
it(name, async function () {
57-
await testContent(content)
65+
await testContent(content())
5866
})
5967

6068
if (isBytes) {
6169
it(`Iterable<${name}>`, async function () {
62-
await testContent(iterableOf(content))
70+
await testContent(iterableOf(content()))
6371
})
6472

6573
it(`AsyncIterable<${name}>`, async function () {
66-
await testContent(asyncIterableOf(content))
74+
await testContent(asyncIterableOf(content()))
6775
})
6876
}
6977

7078
it(`{ path: '', content: ${name} }`, async function () {
71-
await testContent({ path: '', content })
79+
await testContent({ path: '', content: content() })
7280
})
7381

7482
if (isBytes) {
7583
it(`{ path: '', content: Iterable<${name}> }`, async function () {
76-
await testContent({ path: '', content: iterableOf(content) })
84+
await testContent({ path: '', content: iterableOf(content()) })
7785
})
7886

7987
it(`{ path: '', content: AsyncIterable<${name}> }`, async function () {
80-
await testContent({ path: '', content: asyncIterableOf(content) })
88+
await testContent({ path: '', content: asyncIterableOf(content()) })
8189
})
8290
}
8391

8492
it(`Iterable<{ path: '', content: ${name} }`, async function () {
85-
await testContent(iterableOf({ path: '', content }))
93+
await testContent(iterableOf({ path: '', content: content() }))
8694
})
8795

8896
it(`AsyncIterable<{ path: '', content: ${name} }`, async function () {
89-
await testContent(asyncIterableOf({ path: '', content }))
97+
await testContent(asyncIterableOf({ path: '', content: content() }))
9098
})
9199

92100
if (isBytes) {
93101
it(`Iterable<{ path: '', content: Iterable<${name}> }>`, async function () {
94-
await testContent(iterableOf({ path: '', content: iterableOf(content) }))
102+
await testContent(iterableOf({ path: '', content: iterableOf(content()) }))
95103
})
96104

97105
it(`Iterable<{ path: '', content: AsyncIterable<${name}> }>`, async function () {
98-
await testContent(iterableOf({ path: '', content: asyncIterableOf(content) }))
106+
await testContent(iterableOf({ path: '', content: asyncIterableOf(content()) }))
99107
})
100108

101109
it(`AsyncIterable<{ path: '', content: Iterable<${name}> }>`, async function () {
102-
await testContent(asyncIterableOf({ path: '', content: iterableOf(content) }))
110+
await testContent(asyncIterableOf({ path: '', content: iterableOf(content()) }))
103111
})
104112

105113
it(`AsyncIterable<{ path: '', content: AsyncIterable<${name}> }>`, async function () {
106-
await testContent(asyncIterableOf({ path: '', content: asyncIterableOf(content) }))
114+
await testContent(asyncIterableOf({ path: '', content: asyncIterableOf(content()) }))
107115
})
108116
}
109117
}
@@ -124,6 +132,14 @@ describe('normalise-input', function () {
124132
testInputType(BLOB, 'Blob', false)
125133
})
126134

135+
describe('window.ReadableStream', () => {
136+
if (!supportsFileReader) {
137+
return
138+
}
139+
140+
testInputType(WINDOW_READABLE_STREAM, 'window.ReadableStream', false)
141+
})
142+
127143
describe('Iterable<Number>', () => {
128144
testInputType(ARRAY, 'Iterable<Number>', false)
129145
})

0 commit comments

Comments
 (0)