-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix!: return iterators from synchronous sources (#55)
Crossing async boundaries is not free. If a synchronous iterator is passed to a function, it should not force the caller to await on the result. This PR updates some of the basic `it-*` modules to not create unecessary async when they don't have to. The return types of these functions are now derived from the input types so if you have linting rules that forbid awaiting on non-thenables those awaits will need to be removed. BREAKING CHANGE: if you pass a synchronous iterator to a function it will return a synchronous generator in response
- Loading branch information
1 parent
9029b9a
commit b6d8422
Showing
58 changed files
with
1,379 additions
and
293 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,32 @@ | ||
function isAsyncIterable <T> (thing: any): thing is AsyncIterable<T> { | ||
return thing[Symbol.asyncIterator] != null | ||
} | ||
|
||
/** | ||
* Collects all values from an (async) iterable and returns them as an array | ||
*/ | ||
export default async function all <T> (source: AsyncIterable<T> | Iterable<T>): Promise<T[]> { | ||
function all <T> (source: Iterable<T>): T[] | ||
function all <T> (source: AsyncIterable<T>): Promise<T[]> | ||
function all <T> (source: AsyncIterable<T> | Iterable<T>): Promise<T[]> | T[] { | ||
if (isAsyncIterable(source)) { | ||
return (async () => { | ||
const arr = [] | ||
|
||
for await (const entry of source) { | ||
arr.push(entry) | ||
} | ||
|
||
return arr | ||
})() | ||
} | ||
|
||
const arr = [] | ||
|
||
for await (const entry of source) { | ||
for (const entry of source) { | ||
arr.push(entry) | ||
} | ||
|
||
return arr | ||
} | ||
|
||
export default all |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,73 @@ | ||
function isAsyncIterable <T> (thing: any): thing is AsyncIterable<T> { | ||
return thing[Symbol.asyncIterator] != null | ||
} | ||
|
||
/** | ||
* Takes an (async) iterable that emits things and returns an async iterable that | ||
* emits those things in fixed-sized batches | ||
*/ | ||
export default async function * batch <T> (source: AsyncIterable<T> | Iterable<T>, size: number = 1): AsyncGenerator<T[], void, undefined> { | ||
let things: T[] = [] | ||
function batch <T> (source: Iterable<T>, size?: number): Generator<T[], void, undefined> | ||
function batch <T> (source: AsyncIterable<T> | Iterable<T>, size?: number): AsyncGenerator<T[], void, undefined> | ||
function batch <T> (source: AsyncIterable<T> | Iterable<T>, size: number = 1): Generator<T[], void, undefined> | AsyncGenerator<T[], void, undefined> { | ||
size = Number(size) | ||
|
||
if (isAsyncIterable(source)) { | ||
return (async function * () { | ||
let things: T[] = [] | ||
|
||
if (size < 1) { | ||
size = 1 | ||
} | ||
|
||
if (size !== Math.round(size)) { | ||
throw new Error('Batch size must be an integer') | ||
} | ||
|
||
for await (const thing of source) { | ||
things.push(thing) | ||
|
||
if (size < 1) { | ||
size = 1 | ||
while (things.length >= size) { | ||
yield things.slice(0, size) | ||
|
||
things = things.slice(size) | ||
} | ||
} | ||
|
||
while (things.length > 0) { | ||
yield things.slice(0, size) | ||
|
||
things = things.slice(size) | ||
} | ||
}()) | ||
} | ||
|
||
for await (const thing of source) { | ||
things.push(thing) | ||
return (function * () { | ||
let things: T[] = [] | ||
|
||
while (things.length >= size) { | ||
yield things.slice(0, size) | ||
if (size < 1) { | ||
size = 1 | ||
} | ||
|
||
things = things.slice(size) | ||
if (size !== Math.round(size)) { | ||
throw new Error('Batch size must be an integer') | ||
} | ||
} | ||
|
||
while (things.length > 0) { | ||
yield things.slice(0, size) | ||
for (const thing of source) { | ||
things.push(thing) | ||
|
||
things = things.slice(size) | ||
} | ||
while (things.length >= size) { | ||
yield things.slice(0, size) | ||
|
||
things = things.slice(size) | ||
} | ||
} | ||
|
||
while (things.length > 0) { | ||
yield things.slice(0, size) | ||
|
||
things = things.slice(size) | ||
} | ||
}()) | ||
} | ||
|
||
export default batch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.