@reactivex/ix-esnext-esm
Version:
The Interactive Extensions for JavaScript
86 lines (84 loc) • 2.98 kB
JavaScript
import { AsyncIterableX } from '../asynciterablex';
const WAITING_TYPE = 'waiting';
const BATCHING_TYPE = 'batching';
function assertNever(value) {
throw new Error(`Unhandled discriminated union member ${value}`);
}
class BatchAsyncIterable extends AsyncIterableX {
constructor(source) {
super();
this._source = source;
}
[Symbol.asyncIterator]() {
const it = this._source[Symbol.asyncIterator]();
let state = { type: BATCHING_TYPE, values: [] };
let ended = null;
function consumeNext() {
it.next().then(res => {
if (res.done) {
ended = Promise.resolve({ done: true });
if (state.type === WAITING_TYPE) {
state.resolver.resolve(ended);
}
}
else {
if (state.type === WAITING_TYPE) {
const { resolve } = state.resolver;
state = { type: BATCHING_TYPE, values: [] };
resolve({ done: res.done, value: [res.value] });
}
else if (state.type === BATCHING_TYPE) {
state.values.push(res.value);
}
else {
assertNever(state);
}
consumeNext();
}
}, err => {
ended = Promise.reject(err);
if (state.type === WAITING_TYPE) {
const { reject } = state.resolver;
reject(err);
}
});
}
consumeNext();
return {
next() {
if (state.type === BATCHING_TYPE && state.values.length > 0) {
const { values } = state;
state.values = [];
return Promise.resolve({ done: false, value: values });
}
if (ended) {
return ended;
}
if (state.type === WAITING_TYPE) {
throw new Error('Previous `next()` is still in progress');
}
return new Promise((resolve, reject) => {
state = {
type: WAITING_TYPE,
resolver: { resolve, reject }
};
});
},
return(value) {
return it.return
? it.return(value).then(() => ({ done: true }))
: Promise.resolve({ done: true });
}
};
}
}
/**
* Returns an async iterable sequence of batches that are collected from the source sequence between
* subsequent `next()` calls.
*/
export function batch() {
return function batchOperator(source) {
return new BatchAsyncIterable(source);
};
}
//# sourceMappingURL=batch.mjs.map