Last active
January 27, 2020 02:16
-
-
Save Zemnmez/3e85347fe8bf56b8674bf6c2a4358c15 to your computer and use it in GitHub Desktop.
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
type Eventually<T> = | |
T | Promise<T>; | |
type EventuallyIterable<T> = Iterable<T> | AsyncIterable<T> | |
const map: | |
<T,O>(f: Eventually<(v: T, i: number) => O>, v: EventuallyIterable<T>) => EventuallyIterable<O> | |
= | |
async function*(f, iter) { | |
let n = 0; | |
for await (let value of iter) yield (await f)(value, n++); | |
} | |
; | |
type RepeatTupleMap<T> = { | |
0: [], | |
1: [T], | |
2: [T,T], | |
3: [T,T,T], | |
4: [T,T,T,T], | |
5: [T,T,T,T,T], | |
6: [T,T,T,T,T,T], | |
7: [T,T,T,T,T,T,T], | |
8: [T,T,T,T,T,T,T,T] | |
} | |
type RepeatTuple<N extends number, T> = | |
N extends keyof RepeatTupleMap<T>? RepeatTupleMap<T>[N]: readonly T[] | |
const chunk: | |
<N extends number>(size: Eventually<N>) => <T>(v: EventuallyIterable<T>) => EventuallyIterable<RepeatTuple<N,T>> | |
= | |
<N extends number>(size: Eventually<N>) => <T>(iter: EventuallyIterable<T>) => (async function*() { | |
let bucket: T[] = []; | |
for await (let value of iter) { | |
bucket.push(value); | |
if (bucket.length == await size) { | |
yield bucket as RepeatTuple<N,T>; | |
bucket = []; | |
} | |
} | |
})() | |
; | |
const EventuallyIterable: | |
<T>(I: EventuallyIterable<Eventually<T>>) => EventuallyIterable<T> | |
= | |
async function*<T>(I: EventuallyIterable<Eventually<T>>): EventuallyIterable<T> { | |
for await (let value of I) yield await value | |
} | |
; | |
/** perform a promise iterator lazily in chunks */ | |
const chunkedPromise: | |
<N extends number>(N: Eventually<N>) => | |
<T>(I: EventuallyIterable<T>) => EventuallyIterable<Promise<RepeatTuple<N,T>>> | |
= | |
<N extends number>(N: Eventually<N>) => | |
<T>(I: EventuallyIterable<T>) => | |
map(v => Promise.all(v) as Promise<RepeatTuple<N,T>>, chunk(N)(I)); | |
; | |
const flat: | |
<T>(I: EventuallyIterable<EventuallyIterable<T>>) => EventuallyIterable<T> | |
= | |
async function*(I) { | |
for await (let chunk of I) for await (let member of chunk) yield member | |
} | |
; | |
const throttledPromise: | |
<N extends number>(N:N) => | |
<T>(I: EventuallyIterable<T>) => EventuallyIterable<T> | |
= | |
N => I => flat(EventuallyIterable(chunkedPromise(N)(I))) | |
; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment