'use strict'; /** * These are for code abbreviation + smaller bundles: */ const $S = Symbol.iterator; const $A = Symbol.asyncIterator; /** * Determines if the value is a non-null object. */ function isObject(value) { return value !== null && typeof value === 'object'; } /** * Determines if the given object has the given set property. */ function has(object, key) { return key in Object(object); } function hasOfType(object, key, type) { return has(object, key) && typeof object[key] === type; } /** * Determines if the value is Promise-like. */ function isPromiseLike(value) { return hasOfType(value, 'then', 'function'); } /** * Determines if the value is array-like. */ function isArrayLike(value) { return (hasOfType(value, 'length', 'number') && Number.isInteger(value.length)); } /** * Determines if the value is an iterable. */ function isSyncIterable(value) { return hasOfType(value, $S, 'function'); } /** * Determines if the value is an async iterable. */ function isAsyncIterable(value) { return hasOfType(value, $A, 'function'); } /** * Determines if the value is an iterator. * * Note: This function cannot distinguish between sync and async iterators. */ function isUnknownIterator(value) { return hasOfType(value, 'next', 'function'); } /** * Determines if the value is an iterator result. */ function isIteratorResult(value) { return has(value, 'value') || (has(value, 'done') && value.done === true); } /** * Determines if the value is an indexed type. */ function isIndexed(value) { return (Array.isArray(value) || isTypedArray(value) || typeof value === 'string' || value instanceof String); } /** * Determines if the value is a typed array. */ function isTypedArray(value) { return (has(value, 'BYTES_PER_ELEMENT') && has(value, 'buffer') && isArrayBufferLike(value.buffer)); } /** * Determines if the value is a buffer-like array. */ function isArrayBufferLike(value) { return hasOfType(value, 'byteLength', 'number'); } /** * Wraps operator signature. */ function createOperation(syncFunc, asyncFunc, args) { return (i) => { const func = i[$S] ? syncFunc : asyncFunc; return args ? func.apply(null, [i, ...args]) : func(i); }; } /** * Creates a generic synchronous operator that throws an error during iteration. */ function throwOnSync(operatorName) { return () => ({ [$S]() { return iterateOnce(true, () => { throw new Error(`Operator "${operatorName}" requires asynchronous pipeline`); }); } }); } /** * Creates a once-off iterator with a callback. * It is to help to throw errors when the iteration starts. */ function iterateOnce(sync, cb) { const value = undefined; let done = false; return { next() { if (!done) { done = true; cb(); } return sync ? { value, done } : Promise.resolve({ value, done }); } }; } /** * Type-dependent performance optimizer. * * Tests show that for indexed types, JavaScript performs way better * when accessed via index, rather than iterable interface. */ function optimizeIterable(input) { return isIndexed(input) ? indexedIterable(input) : input; } /** * Wraps an indexed iterable into an Iterable object */ function indexedIterable(input) { return { [$S]() { const len = input.length; let i = 0; return { next() { return i < len ? { value: input[i++], done: false } : { value: undefined, done: true }; } }; } }; } /** * Wraps an indexed iterable into an AsyncIterable object */ function indexedAsyncIterable(input) { return { [$A]() { const len = input.length; let i = 0; return { next() { return Promise.resolve(i < len ? { value: input[i++], done: false } : { value: undefined, done: true }); } }; } }; } /** * Converts any synchronous iterable into asynchronous one. * * It makes possible to use asynchronous-only operators downstream, * while also correctly casting all types in the pipeline, avoiding * any ambiguity between synchronous and asynchronous iterables. * * ```ts * const i = pipe( * toAsync(source), // make iterable asynchronous * delay(500) // now can use asynchronous operators * ); * ``` * * - Passing it an already asynchronous iterable will just reuse it. * - All indexed types are optimized for performance. * * @throws `TypeError: 'Cannot convert to AsyncIterable'` when conversion is not possible. * * @see * - {@link toIterable} * - {@link pipe} * @category Core */ function toAsync(i) { // Already an async iterable? if (isAsyncIterable(i)) { return i; } if (!isSyncIterable(i)) { throw new TypeError('Cannot convert to AsyncIterable'); } if (isIndexed(i)) { return indexedAsyncIterable(i); } return { [$A]() { const it = i[$S](); return { next() { return Promise.resolve(it.next()); } }; } }; } function toIterable(i) { if (isObject(i)) { // Already an iterable? if (isSyncIterable(i) || isAsyncIterable(i)) { return i; } // An iterator. if (isUnknownIterator(i)) { const value = i.next(); // this line may throw (outside the pipeline) if (isObject(value)) { const s = isPromiseLike(value) ? $A : $S; if (s === $A || isIteratorResult(value)) { return { [s]() { let started; return { next() { if (started) { return i.next(); } started = true; return value; } }; } }; } } } // An async value. if (isPromiseLike(i)) { return toSingleAsyncIterable(i); } if (isArrayLike(i)) { return { [$S]() { let k = 0; return { next() { return k < i.length ? { value: i[k++], done: false } : { value: undefined, done: true }; } }; } }; } } // A sync value. return toSyncIterable(i); } /** * Converts an indexed (array-like) value into a reversed iterable. * * This is to produce a maximum-performance reversed iterable, by wrapping data into * iterable and applying logical reversal (without any processing) at the same time. * * ```ts * import {reverse} from 'iter-ops'; * * const i = reverse('word'); //=> Iterable * * console.log([...i]); //=> ['d', 'r', 'o', 'w'] * ``` * * @throws `TypeError: 'An array-like value was expected: ...'` when the input is not array-like. * * @category Core */ function reverse(input) { if (typeof (input === null || input === void 0 ? void 0 : input.length) !== 'number') { throw new TypeError(`An array-like value was expected: ${JSON.stringify(input)}`); } return { [$S]() { let i = input.length; return { next() { return i ? { value: input[--i], done: false } : { value: undefined, done: true }; } }; } }; } /** * Create an iterable that has the given value as its only element. */ function toSyncIterable(value) { return [value]; } /** * Create an async iterable that has the awaited given value as its only element. */ function toSingleAsyncIterable(asyncValue) { return { [$A]() { let finished; return { next() { if (finished) { return Promise.resolve({ value: undefined, done: true }); } finished = true; return asyncValue.then((value) => ({ value, done: false })); } }; } }; } function catchError(...args) { return createOperation(catchErrorSync, catchErrorAsync, args); } function catchErrorSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0, repeats, last, lastError; return { next() { do { try { last = i.next(); index++; if (!last.done) { return last; } } catch (e) { repeats = sameError(e, lastError) ? repeats + 1 : 0; lastError = e; let value, emitted; cb(e, { index: index++, lastValue: last === null || last === void 0 ? void 0 : last.value, repeats, state, emit(v) { value = v; emitted = true; } }); if (emitted) { return { value, done: false }; } } } while (!(last === null || last === void 0 ? void 0 : last.done)); return { value: undefined, done: true }; } }; } }; } function catchErrorAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0, repeats, last, lastError; return { next() { return i.next().then((a) => { last = a; index++; return a; }, (e) => { repeats = sameError(e, lastError) ? repeats + 1 : 0; lastError = e; let value, emitted; cb(e, { index: index++, lastValue: last === null || last === void 0 ? void 0 : last.value, repeats, state, emit(v) { value = v; emitted = true; } }); return emitted ? { value, done: false } : this.next(); }); } }; } }; } /** * Helper for determining when we are looking at the same error. */ function sameError(a, b) { return a === b || ((a === null || a === void 0 ? void 0 : a.message) && a.message === (b === null || b === void 0 ? void 0 : b.message)); } /** * Pipes an `Iterable` or `AsyncIterable` through the list of operators, and returns either {@link IterableExt} or {@link AsyncIterableExt}. * * @throws `TypeError: 'An iterable object was expected: ...'` when the input is not iterable. * * @see * - {@link pipeSync} * - {@link pipeAsync} * - {@link toIterable} * - {@link toAsync} * * @category Core */ const pipe = ((...[i, ...p]) => { if (isSyncIterable(i)) { return pipeSync(i, ...p); } if (isAsyncIterable(i)) { return pipeAsync(i, ...p); } throw new TypeError(`An iterable object was expected: ${JSON.stringify(i)}`); }); /** * Pipes a synchronous `Iterable` through the list of synchronous operators, and returns {@link IterableExt}. * * @see * - {@link pipe} * - {@link pipeAsync} * - {@link toIterable} * - {@link toAsync} * * @throws `TypeError: 'Cannot run the sync pipeline from an AsyncIterable'` when the iterable is asynchronous. * * @category Core */ const pipeSync = ((i, ...p) => { if (isAsyncIterable(i)) { throw new TypeError('Cannot run the sync pipeline from an AsyncIterable'); } return extendIterable(p.reduce((c, a) => a(c), optimizeIterable(i))); }); /** * Pipes an `Iterable` or `AsyncIterable` through the list of asynchronous operators, and returns {@link AsyncIterableExt}. * * It applies automatic conversion when a synchronous iterable is passed in. * * ```ts * import {pipeAsync, delay} from 'iter-ops'; * * const i = pipeAsync([1, 2, 3], delay(1000)); * * (async function() { * for await (const a of i) { * console.log(a); // 1, 2, 3 (with 1s delay) * } * })(); * ``` * * @see * - {@link pipe} * - {@link pipeSync} * - {@link toIterable} * - {@link toAsync} * * @category Core */ const pipeAsync = ((i, ...p) => extendAsyncIterable(p.reduce((c, a) => a(c), toAsync(i)))); /** * Extends an UnknownIterable object into IterableExt type. */ function extendIterable(i) { Object.defineProperty(i, 'first', { get: () => i[$S]().next().value }); i.catch = (cb) => extendIterable(catchError(cb)(i)); return i; } /** * Extends an AsyncIterable object into AsyncIterableExt type. */ function extendAsyncIterable(i) { Object.defineProperty(i, 'first', { get: () => i[$A]() .next() .then((a) => a.value) }); i.catch = (cb) => extendAsyncIterable(catchError(cb)(i)); return i; } function aggregate(...args) { return createOperation(aggregateSync, aggregateAsync, args); } function aggregateSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); let finished = false; return { next() { if (finished) { return { value: undefined, done: true }; } const arr = []; let a; while (!(a = i.next()).done) { arr.push(a.value); } finished = true; return { value: cb(arr), done: false }; } }; } }; } function aggregateAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const arr = []; let finished = false; return { next() { return i.next().then((a) => { if (a.done) { if (finished) { return a; } finished = true; const r = cb(arr); if (isPromiseLike(r)) { return r.then((value) => ({ value, done: false })); } return { value: r, done: false }; } arr.push(a.value); return this.next(); }); } }; } }; } function concat(...args) { return createOperation(concatSync, concatAsync, args); } function concatSync(iterable, ...values) { if (!values.length) { // reuse the source when nothing to merge with; return iterable; } return { [$S]() { const i = iterable[$S](); let index = -1, k, v, start = true; return { next() { var _a; if (index < 0) { const a = i.next(); if (!a.done) { return a; } index = 0; } while (index < values.length) { if (start) { v = values[index]; k = typeof (v === null || v === void 0 ? void 0 : v.next) === 'function' ? v : (_a = v === null || v === void 0 ? void 0 : v[$S]) === null || _a === void 0 ? void 0 : _a.call(v); start = false; } if (k) { const b = k.next(); if (!b.done) { return b; } } start = true; index++; if (!k) { return { value: v, done: false }; } } return { value: undefined, done: true }; } }; } }; } function concatAsync(iterable, ...values) { if (!values.length) { // reuse the source when nothing to merge with; return iterable; } return { [$A]() { let v = iterable[$A](); // current value or iterator let index = -1, // current "values" index start = false; // set when need to step forward return { next() { var _a, _b; if (start) { if (++index === values.length) { return Promise.resolve({ value: undefined, done: true }); } v = values[index]; const k = typeof (v === null || v === void 0 ? void 0 : v.next) === 'function' ? v : ((_a = v === null || v === void 0 ? void 0 : v[Symbol.iterator]) === null || _a === void 0 ? void 0 : _a.call(v)) || ((_b = v === null || v === void 0 ? void 0 : v[Symbol.asyncIterator]) === null || _b === void 0 ? void 0 : _b.call(v)); start = !k; if (start) { return Promise.resolve({ value: v, done: false }); } v = k; } const a = v.next(); const out = (b) => { if (b.done) { start = true; return this.next(); } return b; }; return isPromiseLike(a) ? a.then(out) : Promise.resolve(out(a)); } }; } }; } function concurrencyFork(...args) { return createOperation(concurrencyForkSync, concurrencyForkAsync, args); } function concurrencyForkSync(iterable, work) { try { const i = typeof work.onSync === 'function' && work.onSync(iterable); return i || iterable; } catch (err) { return { [$S]() { let done = false; return { next() { if (done) { return { value: undefined, done }; } done = true; throw err; // now catchError operator can handle the error } }; } }; } } function concurrencyForkAsync(iterable, work) { try { const i = typeof work.onAsync === 'function' && work.onAsync(iterable); return i || iterable; } catch (err) { return { [$A]() { let done = false; return { next() { if (done) { return Promise.resolve({ value: undefined, done }); } done = true; // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors return Promise.reject(err); // now catchError operator can handle the error } }; } }; } } function consume(...args) { return createOperation(consumeSync, consumeAsync, args); } function consumeSync(iterable, consumer) { return { [$S]() { let done = false; return { next() { if (!done) { done = true; return { value: consumer(iterable, true), done: false }; } return { value: undefined, done }; } }; } }; } function consumeAsync(iterable, consumer) { return { [$A]() { let done = false; return { next() { if (!done) { done = true; const a = consumer(iterable, false); if (isPromiseLike(a)) { return a.then((value) => ({ value, done: false })); } return Promise.resolve({ value: a, done: false }); } return Promise.resolve({ value: undefined, done }); } }; } }; } function count(...args) { return createOperation(countSync, countAsync, args); } function countSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const test = typeof cb === 'function' && cb; const state = {}; let value = 0, index = 0, finished = false, a; return { next() { while (!finished) { a = i.next(); if (a.done) { finished = true; return { value, done: false }; } if (!test || test(a.value, index++, state)) { value++; } } return a; } }; } }; } function countAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const test = typeof cb === 'function' && cb; const state = {}; let value = 0, index = 0, finished = false; return { next() { return i.next().then((a) => { if (a.done) { if (finished) { return a; } finished = true; return { value, done: false }; } const r = !test || test(a.value, index++, state); const out = (flag) => { value += flag ? 1 : 0; return this.next(); }; return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } function defaultEmpty(...args) { return createOperation(defaultEmptySync, defaultEmptyAsync, args); } function defaultEmptySync(iterable, value) { return { [$S]() { const i = iterable[$S](); let k, v, start = true, empty = true, done = false; return { next() { var _a; if (!done) { const a = i.next(); if (!a.done) { empty = false; return a; } if (empty) { if (start) { v = value; k = typeof (v === null || v === void 0 ? void 0 : v.next) === 'function' ? v : (_a = v === null || v === void 0 ? void 0 : v[$S]) === null || _a === void 0 ? void 0 : _a.call(v); start = false; } if (k) { const b = k.next(); done = !!b.done; return b; } done = true; return { value: v, done: false }; } } return { value: undefined, done: true }; } }; } }; } function defaultEmptyAsync(iterable, value) { return { [$A]() { const i = iterable[$A](); let k, started = false, // set once default iteration started done = false, // set when we are finished (with a simple value) skip = false; // set when default data not needed return { next() { if (skip) { return i.next(); } if (done) { return Promise.resolve({ value: undefined, done }); } if (started) { if (k) { const b = k.next(); return isPromiseLike(b) ? b : Promise.resolve(b); } done = true; // we are done with our simple value; return Promise.resolve({ value: value, done: false }); } return i.next().then((a) => { var _a, _b; if (a.done) { const x = value; k = typeof (x === null || x === void 0 ? void 0 : x.next) === 'function' ? x : ((_a = x === null || x === void 0 ? void 0 : x[$S]) === null || _a === void 0 ? void 0 : _a.call(x)) || ((_b = x === null || x === void 0 ? void 0 : x[$A]) === null || _b === void 0 ? void 0 : _b.call(x)); started = true; return this.next(); } skip = true; return a; }); } }; } }; } function delay(...args) { return createOperation(throwOnSync('delay'), delayAsync, args); } function delayAsync(iterable, timeout) { if (typeof timeout === 'number' && timeout < 0) { return iterable; // just reuse the source iterable } return { [$A]() { const i = iterable[$A](); const cb = typeof timeout === 'function' && timeout; const state = {}; let index = 0; return { next() { return i.next().then((a) => { if (a.done) { return a; } const delay = cb ? cb(a.value, index++, state) : timeout; return delay < 0 ? a : new Promise((resolve) => setTimeout(() => resolve(a), delay)); }); } }; } }; } function distinct(...args) { return createOperation(distinctSync, distinctAsync, args); } function distinctSync(iterable, keySelector) { return { [$S]() { const i = iterable[$S](); const ks = typeof keySelector === 'function' && keySelector; const keySet = new Set(); let index = 0; return { next() { let a; do { a = i.next(); if (!a.done) { const key = ks ? ks(a.value, index++) : a.value; if (!keySet.has(key)) { keySet.add(key); return a; } } } while (!a.done); keySet.clear(); // for better memory management return a; } }; } }; } function distinctAsync(iterable, keySelector) { return { [$A]() { const i = iterable[$A](); const ks = typeof keySelector === 'function' && keySelector; const keySet = new Set(); let index = 0; return { next() { return i.next().then((a) => { if (a.done) { keySet.clear(); // for better memory management return a; } const key = ks ? ks(a.value, index++) : a.value; if (!keySet.has(key)) { keySet.add(key); return a; } return this.next(); }); } }; } }; } function drain(...args) { return createOperation(drainSync, drainAsync, args); } function drainSync(iterable) { return { [$S]() { const i = iterable[$S](); return { next() { while (!i.next().done) ; return { value: undefined, done: true }; } }; } }; } function drainAsync(iterable) { return { [$A]() { const i = iterable[$A](); return { next() { return i.next().then((a) => (a.done ? a : this.next())); } }; } }; } function empty(...args) { return createOperation(emptySync, emptyAsync, args); } function emptySync() { return { [$S]: () => ({ next: () => ({ value: undefined, done: true }) }) }; } function emptyAsync() { return { [$A]: () => ({ next() { return Promise.resolve({ value: undefined, done: true }); } }) }; } function every(...args) { return createOperation(everySync, everyAsync, args); } function everySync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0, finished; return { next() { if (!finished) { let a; while (!(a = i.next()).done && cb(a.value, index++, state)) ; finished = true; return { value: !!a.done, done: false }; } return { value: undefined, done: true }; } }; } }; } function everyAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0, finished; return { next() { if (finished) { return Promise.resolve({ value: undefined, done: true }); } return i.next().then((a) => { const r = (a.done || cb(a.value, index++, state)); const out = (flag) => { finished = a.done || !flag; return finished ? { value: !!a.done, done: false } : this.next(); }; return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } function filter(...args) { return createOperation(filterSync, filterAsync, args); } function filterSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0; return { next() { let a; while (!(a = i.next()).done && !cb(a.value, index++, state)) ; return a; } }; } }; } function filterAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0; return { next() { return i.next().then((a) => { if (a.done) { return a; } const r = cb(a.value, index++, state); const out = (flag) => (flag ? a : this.next()); return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } function first(...args) { return createOperation(firstSync, firstAsync, args); } function firstSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; const test = typeof cb === 'function' && cb; let index = 0, finished; return { next() { if (finished) { return { value: undefined, done: true }; } let a; while (!(a = i.next()).done && test && !test(a.value, index++, state)) ; finished = true; return a; } }; } }; } function firstAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; const test = typeof cb === 'function' && cb; let index = 0, finished = false; return { next() { if (finished) { return Promise.resolve({ value: undefined, done: true }); } return i.next().then((a) => { const r = (a.done || !test || test(a.value, index++, state)); const out = (flag) => { finished = flag; return finished ? a : this.next(); }; return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } function flat(...args) { return createOperation(flatSync, flatAsync, args); } function flatSync(iterable, depth = 1, skip) { return { [$S]() { const d = new Array(depth + 1); d[0] = iterable[$S](); let level = 0; return { next() { var _a, _b; do { const v = d[level].next(); // next value if (v.done) { if (!level) { return v; // we are finished } level--; // back to upper level continue; } if (level === depth) { return v; // maximum depth reached } const i = (_b = (_a = v.value) === null || _a === void 0 ? void 0 : _a[$S]) === null || _b === void 0 ? void 0 : _b.call(_a); if (!i || (typeof skip === 'function' && skip(v.value, level))) { return v; // non-iterable value or to be skipped } d[++level] = i; // save next iterable } while (true); } }; } }; } function flatAsync(iterable, depth = 1, skip) { return { [$A]() { const d = new Array(depth + 1); d[0] = { i: iterable[$A](), sync: false }; let level = 0; return { next() { var _a, _b, _c, _d; const v = d[level].i.next(); // next value if (d[level].sync) { if (v.done) { level--; // back to upper level return this.next(); } if (level === depth) { return Promise.resolve(v); // maximum depth reached } let i = (_b = (_a = v.value) === null || _a === void 0 ? void 0 : _a[$S]) === null || _b === void 0 ? void 0 : _b.call(_a); // first try with sync let sync = true; if (!i) { i = (_d = (_c = v.value) === null || _c === void 0 ? void 0 : _c[$A]) === null || _d === void 0 ? void 0 : _d.call(_c); // then try with async if (!i || (typeof skip === 'function' && skip(v.value, level))) { return Promise.resolve(v); // non-iterable value } sync = false; } d[++level] = { i, sync }; // save next iterable return this.next(); } return v.then((a) => { var _a, _b, _c, _d; if (a.done) { if (!level) { return a; // we are finished } level--; // back to upper level return this.next(); } if (level === depth) { return a; // maximum depth reached } let i = (_b = (_a = a.value) === null || _a === void 0 ? void 0 : _a[$A]) === null || _b === void 0 ? void 0 : _b.call(_a); // first, try with async let sync = false; if (!i) { i = (_d = (_c = a.value) === null || _c === void 0 ? void 0 : _c[$S]) === null || _d === void 0 ? void 0 : _d.call(_c); // then try with sync if (!i || (typeof skip === 'function' && skip(a.value, level))) { return a; // non-iterable value } sync = true; } d[++level] = { i, sync }; // save next iterable return this.next(); }); } }; } }; } function flatMap(...args) { return createOperation(flatMapSync, flatMapAsync, args); } function flatMapSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let spread; // spread sub-iterator let index = 0; return { next() { var _a; do { if (spread) { const a = spread.next(); if (a.done) { spread = null; continue; } return a; } const v = i.next(); if (v.done) { return v; } const value = cb(v.value, index++, state); spread = (_a = value === null || value === void 0 ? void 0 : value[$S]) === null || _a === void 0 ? void 0 : _a.call(value); if (!spread) { return { value, done: false }; } } while (true); } }; } }; } function flatMapAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let spread; // sync or async sub-iterator to be spread let sync; // set when 'spread' is synchronous let index = 0; return { next() { if (spread) { const a = spread.next(); if (sync) { if (a.done) { spread = null; // finished spreading return this.next(); } return Promise.resolve(a); } return a.then((b) => { if (b.done) { spread = null; // finished spreading return this.next(); } return b; }); } return i.next().then((c) => { if (c.done) { return c; } const out = (value) => { var _a, _b; spread = (_a = value === null || value === void 0 ? void 0 : value[$S]) === null || _a === void 0 ? void 0 : _a.call(value); sync = !!spread; if (!spread) { spread = (_b = value === null || value === void 0 ? void 0 : value[$A]) === null || _b === void 0 ? void 0 : _b.call(value); if (!spread) { return { value, done: false }; // return value as is } } return this.next(); }; const v = cb(c.value, index++, state); return isPromiseLike(v) ? v.then(out) : out(v); }); } }; } }; } function indexBy(...args) { return createOperation(indexBySync, indexByAsync, args); } function indexBySync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = -1; return { next() { let a; while (!(a = i.next()).done && !cb(a.value, ++index, state)) ; return a.done ? a : { value: { index, value: a.value }, done: false }; } }; } }; } function indexByAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = -1; return { next() { return i.next().then((a) => { if (a.done) { return a; } const r = cb(a.value, ++index, state); const out = (flag) => flag ? { value: { index, value: a.value }, done: false } : this.next(); return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } function isEmpty(...args) { return createOperation(isEmptySync, isEmptyAsync, args); } function isEmptySync(iterable) { return { [$S]() { const i = iterable[$S](); let finished = false; return { next() { if (!finished) { const a = i.next(); finished = true; return { value: !!a.done, done: false }; } return { value: undefined, done: true }; } }; } }; } function isEmptyAsync(iterable) { return { [$A]() { const i = iterable[$A](); let finished = false; return { next() { if (finished) { return Promise.resolve({ value: undefined, done: true }); } finished = true; return i .next() .then((a) => ({ value: !!a.done, done: false })); } }; } }; } function last(...args) { return createOperation(lastSync, lastAsync, args); } function lastSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; const test = typeof cb === 'function' && cb; let index = 0; return { next() { let a, r; while (!(a = i.next()).done) { if (!test || test(a.value, index++, state)) { r = a; } } return r ? { value: r.value, done: false } : a; } }; } }; } function lastAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; const test = typeof cb === 'function' && cb; let finished = false, index = 0, value; return { next() { return i.next().then((a) => { if (finished) { return { value: undefined, done: true }; } const r = (a.done || !test || test(a.value, index++, state)); const out = (flag) => { finished = !!a.done; value = flag && !a.done ? a : value || a; return finished ? value : this.next(); }; return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } function map(...args) { return createOperation(mapSync, mapAsync, args); } function mapSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0; return { next() { let a; while (!(a = i.next()).done) { return { value: cb(a.value, index++, state), done: false }; } return a; } }; } }; } function mapAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0; return { next() { return i.next().then((a) => a.done ? a : { value: cb(a.value, index++, state), done: false }); } }; } }; } function onEnd(...args) { return createOperation(onEndSync, onEndAsync, args); } function onEndSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); let start, finished, lastValue, count = 0, max, min; return { next() { const now = Date.now(); start = start || now; const a = i.next(); if (a.done) { if (!finished) { finished = true; const total = Date.now() - start; const average = count > 0 ? total / count : 0; cb({ count, duration: { average, min, max, total }, lastValue, sync: true }); } } else { lastValue = a.value; const delay = Date.now() - now; if (!count) { max = { delay, index: 0, value: lastValue }; min = { delay, index: 0, value: lastValue }; } // istanbul ignore next (test requires significant sync payload) if (delay > max.delay) { max.delay = delay; max.index = count; max.value = lastValue; } // istanbul ignore next (test requires significant sync payload) if (delay < min.delay) { min.delay = delay; min.index = count; min.value = lastValue; } count++; } return a; } }; } }; } function onEndAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); let start, finished, lastValue, count = 0, max, min; return { next() { const now = Date.now(); start = start || now; return i.next().then((a) => { if (a.done) { if (!finished) { finished = true; const total = Date.now() - start; const average = count > 0 ? total / count : 0; cb({ count, duration: { average, min, max, total }, lastValue, sync: false }); } } else { lastValue = a.value; const delay = Date.now() - now; if (!count) { max = { delay, index: 0, value: lastValue }; min = { delay, index: 0, value: lastValue }; } if (delay > max.delay) { max.delay = delay; max.index = count; max.value = lastValue; } if (delay < min.delay) { min.delay = delay; min.index = count; min.value = lastValue; } count++; } return a; }); } }; } }; } function page(...args) { return createOperation(pageSync, pageAsync, args); } function pageSync(iterable, size) { return { [$S]() { if (typeof size !== 'number' || size < 1) { return iterateOnce(true, () => { throw new TypeError(`Page size >= 1 is required: ${JSON.stringify(size)}`); }); } const i = iterable[$S](); return { next() { const value = []; let a, c = 0; while (c++ < size && !(a = i.next()).done) { value.push(a.value); } if (value.length) { return { value, done: false }; } return { value: undefined, done: true }; } }; } }; } function pageAsync(iterable, size) { return { [$A]() { if (typeof size !== 'number' || size < 1) { return iterateOnce(false, () => { throw new TypeError(`Page size >= 1 is required: ${JSON.stringify(size)}`); }); } const i = iterable[$A](); return { next() { const value = []; let c = 0; const nextValue = () => i.next().then((a) => { if (a.done) { return value.length ? { value, done: false } : a; } value.push(a.value); return ++c < size ? nextValue() : { value, done: false }; }); return nextValue(); } }; } }; } function reduce(...args) { return createOperation(reduceSync, reduceAsync, args); } function reduceSync(iterable, cb, initialValue) { return { [$S]() { const i = iterable[$S](); const state = {}; let done = false, index = 0; return { next() { let value; if (done) { return { value, done }; } value = initialValue; let a; while (!(a = i.next()).done) { if (!index && value === undefined) { value = a.value; index++; } else { value = cb(value, a.value, index++, state); } } done = true; return { value, done: false }; } }; } }; } function reduceAsync(iterable, cb, initialValue) { return { [$A]() { const i = iterable[$A](); const state = {}; let finished = false, index = 0, value; const next = () => { return i.next().then((a) => { if (a.done) { if (finished) { return a; } finished = true; return { value, done: false }; } if (!index && value === undefined) { value = a.value; index++; return next(); } const v = cb(value, a.value, index++, state); if (isPromiseLike(v)) { return v.then((val) => { value = val; return next(); }); } value = v; return next(); }); }; if (isPromiseLike(initialValue)) { return { next: () => initialValue.then((iv) => { value = iv; return next(); }) }; } value = initialValue; return { next }; } }; } function repeat(...args) { return createOperation(repeatSync, repeatAsync, args); } function repeatSync(iterable, count) { if (typeof count === 'number' && count < 1) { return iterable; } return { [$S]() { const i = iterable[$S](); const state = {}; const cb = typeof count === 'function' && count; const initialCount = !cb && count; let copyCount = initialCount; let index = -1, copied = 0, start = true, a; return { next() { if (start) { a = i.next(); start = false; index++; copied = 0; copyCount = initialCount; } if (a.done) { return a; } if (cb) { start = !cb(a.value, index, copied++, state); return a; } if (copyCount) { copyCount--; } else { start = true; } return a; } }; } }; } function repeatAsync(iterable, count) { if (typeof count === 'number' && count < 1) { return iterable; } return { [$A]() { const i = iterable[$A](); const state = {}; const cb = typeof count === 'function' && count; const initialCount = !cb && count; let copyCount = initialCount; let index = -1, copied = 0, start = true, a; return { async next() { if (start) { a = await i.next(); start = false; index++; copied = 0; copyCount = initialCount; } if (a.done) { return a; } if (cb) { start = !(await cb(a.value, index, copied++, state)); return a; } if (copyCount) { copyCount--; } else { start = true; } return a; } }; } }; } function retry(...args) { return createOperation(retrySync, retryAsync, args); } function retrySync(iterable, retry) { if (typeof retry === 'number' && retry < 1) { // reuse the source when repeat is not needed; return iterable; } return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0; const cb = typeof retry === 'function' && retry; let attempt = 0; const retriesNumber = !cb && retry > 0 ? retry : 0; let leftTries = retriesNumber; return { next() { do { try { const a = i.next(); index++; attempt = 0; leftTries = retriesNumber; return a; } catch (error) { const r = cb && cb({ attempt, index, error, state }); attempt++; index++; if (!r && !leftTries--) { throw error; } } } while (true); } }; } }; } function retryAsync(iterable, retry) { if (typeof retry === 'number' && retry < 1) { // reuse the source when repeat is not needed; return iterable; } return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0; const cb = typeof retry === 'function' && retry; let attempt = 0; const retriesNumber = !cb && retry > 0 ? retry : 0; let leftTries = retriesNumber; return { next() { return i.next().then((a) => { index++; attempt = 0; leftTries = retriesNumber; return a; }, (error) => { if (cb) { const b = (f) => f ? this.next() : // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors Promise.reject(error); const r = cb({ attempt, index, error, state }); attempt++; index++; return isPromiseLike(r) ? r.then(b) : b(r); } if (leftTries) { leftTries--; return this.next(); } // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors return Promise.reject(error); }); } }; } }; } function skip(...args) { return createOperation(skipSync, skipAsync, args); } function skipSync(iterable, count) { return { [$S]() { const i = iterable[$S](); let index = 0, finished = false; return { next() { let a = i.next(); if (!finished) { while (!a.done && index++ < count) { a = i.next(); } finished = true; } return a; } }; } }; } function skipAsync(iterable, count) { return { [$A]() { const i = iterable[$A](); let index = 0, finished = false; return { next() { return i.next().then((a) => { if (!finished) { finished = a.done || index++ >= count; } return finished ? a : this.next(); }); } }; } }; } function skipUntil(...args) { return createOperation(skipUntilSync, skipUntilAsync, args); } function skipUntilSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0, started; return { next() { let a = i.next(); if (!started) { while (!a.done && !cb(a.value, index++, state)) { a = i.next(); } started = !a.done; } return a; } }; } }; } function skipUntilAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0, started; return { next() { return i.next().then((a) => { if (started || a.done) { return a; } const r = cb(a.value, index++, state); const out = (flag) => { started = flag; return started ? a : this.next(); }; return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } function skipWhile(...args) { return createOperation(skipWhileSync, skipWhileAsync, args); } function skipWhileSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0, started; return { next() { let a = i.next(); if (!started) { while (!a.done && cb(a.value, index++, state)) { a = i.next(); } started = true; } return a; } }; } }; } function skipWhileAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0, started; return { next() { return i.next().then((a) => { if (started || a.done) { return a; } const r = cb(a.value, index++, state); const out = (flag) => { started = !flag; return started ? a : this.next(); }; return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } function some(...args) { return createOperation(someSync, someAsync, args); } function someSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0, finished; return { next() { if (!finished) { let a; while (!(a = i.next()).done && !cb(a.value, index++, state)) ; finished = true; return { value: !a.done, done: false }; } return { value: undefined, done: true }; } }; } }; } function someAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0, finished; return { next() { if (finished) { return Promise.resolve({ value: undefined, done: true }); } return i.next().then((a) => { const r = (a.done || cb(a.value, index++, state)); const out = (flag) => { finished = flag; return finished ? { value: !a.done, done: false } : this.next(); }; return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } /** * Strategy for carrying over split/toggle values. * It defines what to do with each value that triggers the split/toggle. * * Note that {@link split} operator treats this enum in non-strict manner: * - any negative number is treated as `back` * - any positive number is treated as `forward` * - everything else is treated as `none` */ exports.SplitValueCarry = void 0; (function (SplitValueCarry) { /** * Split/toggle value is carried back, to be the last value in the current list. */ SplitValueCarry[SplitValueCarry["back"] = -1] = "back"; /** * Split/toggle value is just a placeholder/gap, to be skipped. * This is the default. */ SplitValueCarry[SplitValueCarry["none"] = 0] = "none"; /** * Split/toggle value is carried forward, to make the first value in the next list. */ SplitValueCarry[SplitValueCarry["forward"] = 1] = "forward"; })(exports.SplitValueCarry || (exports.SplitValueCarry = {})); function split(...args) { return createOperation(splitSync, splitAsync, args); } function splitSync(iterable, cb, options) { return { [$S]() { const i = iterable[$S](); const state = {}; // quick access to the options: const carryStart = (options === null || options === void 0 ? void 0 : options.carryStart) ? (options === null || options === void 0 ? void 0 : options.carryStart) < 0 ? -1 : (options === null || options === void 0 ? void 0 : options.carryStart) > 0 ? 1 : 0 : 0; const carryEnd = (options === null || options === void 0 ? void 0 : options.carryEnd) ? (options === null || options === void 0 ? void 0 : options.carryEnd) < 0 ? -1 : (options === null || options === void 0 ? void 0 : options.carryEnd) > 0 ? 1 : 0 : 0; const toggle = !!(options === null || options === void 0 ? void 0 : options.toggle); // all indexes: let startIndex = 0; let listIndex = 0; let splitIndex = 0; let collecting = !toggle; // indicates when we are collecting values let finished = false; // indicates when we are all done let prev; // previous value when carrying forward return { next() { const list = []; let v; // next value object do { if (prev) { // previous trigger value is being moved forward; list.push(prev.value); prev = null; } v = i.next(); if (!v.done) { const index = { start: startIndex++, list: listIndex, split: splitIndex }; if (cb(v.value, index, state)) { // split/toggle has been triggered; const carry = collecting ? carryEnd : carryStart; if (carry) { if (carry < 0) { list.push(v.value); } else { prev = v; // carry "forward", save for the next list } } if (toggle) { collecting = !collecting; listIndex = collecting && carry > 0 ? 1 : 0; if (collecting) { splitIndex++; continue; } return { value: list, done: false }; } listIndex = carry > 0 ? 1 : 0; splitIndex++; break; } if (collecting) { listIndex++; list.push(v.value); } } } while (!v.done); if (!finished) { finished = !!v.done; if (collecting) { return { value: list, done: false }; } } return { value: undefined, done: true }; } }; } }; } function splitAsync(iterable, cb, options) { return { [$A]() { const i = iterable[$A](); const state = {}; // quick access to the options: const carryStart = (options === null || options === void 0 ? void 0 : options.carryStart) ? (options === null || options === void 0 ? void 0 : options.carryStart) < 0 ? -1 : (options === null || options === void 0 ? void 0 : options.carryStart) > 0 ? 1 : 0 : 0; const carryEnd = (options === null || options === void 0 ? void 0 : options.carryEnd) ? (options === null || options === void 0 ? void 0 : options.carryEnd) < 0 ? -1 : (options === null || options === void 0 ? void 0 : options.carryEnd) > 0 ? 1 : 0 : 0; const toggle = !!(options === null || options === void 0 ? void 0 : options.toggle); // all indexes: let startIndex = 0; let listIndex = 0; let splitIndex = 0; let collecting = !toggle; // indicates when we are collecting values let finished = false; // indicates when we are all done let prev; // previous value when carrying forward return { async next() { const list = []; let v; // next value object do { if (prev) { // previous trigger value is being moved forward; list.push(prev.value); prev = null; } v = await i.next(); if (!v.done) { const index = { start: startIndex++, list: listIndex, split: splitIndex }; if (await cb(v.value, index, state)) { // split/toggle has been triggered; const carry = collecting ? carryEnd : carryStart; if (carry) { if (carry < 0) { list.push(v.value); } else { prev = v; // carry "forward", save for the next list } } if (toggle) { collecting = !collecting; listIndex = collecting && carry > 0 ? 1 : 0; if (collecting) { splitIndex++; continue; } return { value: list, done: false }; } listIndex = carry > 0 ? 1 : 0; splitIndex++; break; } if (collecting) { listIndex++; list.push(v.value); } } } while (!v.done); if (!finished) { finished = !!v.done; if (collecting) { return { value: list, done: false }; } } return { value: undefined, done: true }; } }; } }; } function spread(...args) { return createOperation(spreadSync, spreadAsync, args); } function spreadSync(iterable) { return { [$S]() { const i = iterable[$S](); let a, k, v, start = true, index = 0; return { next() { var _a, _b; do { if (start) { a = i.next(); start = false; if (!a.done) { k = (_b = (_a = a.value) === null || _a === void 0 ? void 0 : _a[$S]) === null || _b === void 0 ? void 0 : _b.call(_a); if (!k) { throw new TypeError(`Value at index ${index} is not iterable: ${JSON.stringify(a.value)}`); } } index++; } if (!a.done) { v = k.next(); if (!v.done) { return v; } start = true; } } while (!a.done); return a; } }; } }; } function spreadAsync(iterable) { return { [$A]() { const i = iterable[$A](); let k, start = true, index = 0, sync; return { next() { const nextValue = (wrap) => { const out = (v) => { if (!v.done) { return sync && wrap ? Promise.resolve(v) : v; } start = true; return this.next(); }; const r = k.next(); return sync ? out(r) : r.then(out); }; if (start) { start = false; return i.next().then((a) => { var _a, _b, _c, _d; if (a.done) { return a; } sync = true; k = (_b = (_a = a.value) === null || _a === void 0 ? void 0 : _a[$S]) === null || _b === void 0 ? void 0 : _b.call(_a); if (!k) { sync = false; k = (_d = (_c = a.value) === null || _c === void 0 ? void 0 : _c[$A]) === null || _d === void 0 ? void 0 : _d.call(_c); } if (!k) { throw new TypeError(`Value at index ${index} is not iterable: ${JSON.stringify(a.value)}`); } index++; return nextValue(false); }); } return nextValue(true); } }; } }; } function take(...args) { return createOperation(takeSync, takeAsync, args); } function takeSync(iterable, count) { return { [$S]() { const i = iterable[$S](); let index = 0, finished; return { next() { finished = finished || index++ >= count; if (!finished) { const a = i.next(); finished = !!a.done; if (!finished) { return a; } } return { value: undefined, done: true }; } }; } }; } function takeAsync(iterable, count) { return { [$A]() { const i = iterable[$A](); let index = 0, finished; return { next() { finished = finished || index++ >= count; if (finished) { return Promise.resolve({ value: undefined, done: true }); } return i.next().then((a) => { finished = !!a.done; return finished ? { value: undefined, done: true } : a; }); } }; } }; } function takeLast(...args) { return createOperation(takeLastSync, takeLastAsync, args); } function takeLastSync(iterable, count) { return { [$S]() { const i = iterable[$S](); const buffer = []; let ready = false, done = false, index = 0; return { next() { if (!done && count > 0) { if (!ready) { let a; while (!(a = i.next()).done) { buffer.push(a); if (count < buffer.length) { buffer.shift(); } } ready = true; } if (index < buffer.length) { return buffer[index++]; } done = true; } return { value: undefined, done: true }; } }; } }; } function takeLastAsync(iterable, count) { return { [$A]() { const i = iterable[$A](); const buffer = []; let done = false, index = 0; return { next() { return i.next().then((a) => { if (!done && count > 0) { if (!a.done) { buffer.push(a); if (count < buffer.length) { buffer.shift(); } return this.next(); } if (index < buffer.length) { return buffer[index++]; } done = true; } return { value: undefined, done: true }; }); } }; } }; } function takeUntil(...args) { return createOperation(takeUntilSync, takeUntilAsync, args); } function takeUntilSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0, stopped; return { next() { if (!stopped) { const a = i.next(); stopped = a.done || cb(a.value, index++, state); if (!stopped) { return a; } } return { value: undefined, done: true }; } }; } }; } function takeUntilAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0, stopped; return { next() { return i.next().then((a) => { if (stopped || a.done) { return { value: undefined, done: true }; } const r = cb(a.value, index++, state); const out = (flag) => { stopped = flag; return stopped ? { value: undefined, done: true } : a; }; return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } function takeWhile(...args) { return createOperation(takeWhileSync, takeWhileAsync, args); } function takeWhileSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0, stopped; return { next() { if (!stopped) { const a = i.next(); stopped = a.done || !cb(a.value, index++, state); if (!stopped) { return a; } } return { value: undefined, done: true }; } }; } }; } function takeWhileAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0, stopped; return { next() { return i.next().then((a) => { if (stopped || a.done) { return { value: undefined, done: true }; } const r = cb(a.value, index++, state); const out = (flag) => { stopped = !flag; return stopped ? { value: undefined, done: true } : a; }; return isPromiseLike(r) ? r.then(out) : out(r); }); } }; } }; } function tap(...args) { return createOperation(tapSync, tapAsync, args); } function tapSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0; return { next() { const a = i.next(); if (!a.done) { cb(a.value, index++, state); } return a; } }; } }; } function tapAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0; return { next() { return i.next().then((a) => { if (!a.done) { cb(a.value, index++, state); } return a; }); } }; } }; } function throttle(...args) { return createOperation(throwOnSync('throttle'), throttleAsync, args); } function throttleAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0; return { next() { return i .next() .then((a) => a.done ? a : cb(a.value, index++, state).then(() => a)); } }; } }; } function timeout(...args) { return createOperation(timeoutSync, timeoutAsync, args); } function timeoutSync(iterable, ms, cb) { if (ms < 0) { // timeout is inactive, reuse the source iterable instead: return iterable; } return { [$S]() { const i = iterable[$S](); let count = 0; // number of items processed let start; let done = false; return { next() { if (done) { return { value: undefined, done }; } const now = Date.now(); start = start || now; if (now - start > ms) { done = true; if (typeof cb === 'function') { cb(count); // notify of the timeout } return { value: undefined, done }; } count++; return i.next(); } }; } }; } function timeoutAsync(iterable, ms, cb) { if (ms < 0) { // timeout is inactive, reuse the source iterable instead: return iterable; } return { [$A]() { const i = iterable[$A](); let count = 0; // number of items processed let done = false; const resolutions = []; const rejections = []; const timeoutId = setTimeout(() => { done = true; if (typeof cb === 'function') { try { cb(count); // notify of the timeout } catch (err) { rejections.forEach((r) => r(err)); return; } } resolutions.forEach((r) => r({ value: undefined, done })); }, ms); return { next() { if (done) { return Promise.resolve({ value: undefined, done }); } return new Promise((resolve, reject) => { resolutions.push(resolve); rejections.push(reject); i.next() .then((data) => { if (done) { return; // we have timed out } if (data.done) { clearTimeout(timeoutId); done = true; } count++; resolve(data); }) .catch((err) => { clearTimeout(timeoutId); done = true; // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors reject(err); }); }); } }; } }; } function timing(...args) { return createOperation(timingSync, timingAsync, args); } function timingSync(iterable, cb) { return { [$S]() { const i = iterable[$S](); const state = {}; let index = 0; return { next() { const start = Date.now(); const a = i.next(); if (!a.done) { const duration = Date.now() - start; cb({ duration, index: index++, value: a.value, state, sync: true }); } return a; } }; } }; } function timingAsync(iterable, cb) { return { [$A]() { const i = iterable[$A](); const state = {}; let index = 0; return { next() { const start = Date.now(); return i.next().then((a) => { if (!a.done) { const duration = Date.now() - start; cb({ duration, index: index++, value: a.value, state, sync: false }); } return a; }); } }; } }; } function toArray(...args) { return createOperation(toArraySync, toArrayAsync, args); } function toArraySync(iterable) { return { [$S]() { const i = iterable[$S](); let done = false; return { next() { if (done) { return { value: undefined, done }; } const arr = []; let a; while (!(a = i.next()).done) { arr.push(a.value); } done = true; return { value: arr, done: false }; } }; } }; } function toArrayAsync(iterable) { return { [$A]() { const i = iterable[$A](); const value = []; let finished = false; return { next() { return i.next().then((a) => { if (a.done) { if (finished) { return a; } finished = true; return { value, done: false }; } value.push(a.value); return this.next(); }); } }; } }; } function wait() { return createOperation(throwOnSync('wait'), waitAsync); } function waitAsync(iterable) { return { [$A]() { const i = iterable[$A](); return { next() { return i.next().then((a) => { if (a.done) { return a; } const p = a.value; return isPromiseLike(p) ? p.then((value) => ({ value, done: false })) : a; }); } }; } }; } function waitRace(...args) { return createOperation(throwOnSync('waitRace'), waitRaceAsync, args); } // implemented by: https://stackoverflow.com/users/1048572/bergi function waitRaceAsync(iterable, cacheSize) { cacheSize = cacheSize >= 2 ? cacheSize : 1; return { [$A]() { const i = iterable[$A](); let finished = false; // resolvers for currently active tasks, that are racing to remove and call the first one: const resolvers = []; // cache of promises to be resolved or to be returned by `.next()` to the destination: const promises = []; function kickOffNext() { promises.push(new Promise((resolve) => { resolvers.push(resolve); // `new Promise` executor handles synchronous exceptions i.next().then((a) => { var _a, _b; if (a.done) { finished = true; (_a = resolvers.pop()) === null || _a === void 0 ? void 0 : _a(a); } else if (isPromiseLike(a.value)) { const promise = a.value; promise.then((value) => { var _a; (_a = resolvers.shift()) === null || _a === void 0 ? void 0 : _a({ done: false, value }); kickOffMore(); }, () => { var _a; (_a = resolvers.shift()) === null || _a === void 0 ? void 0 : _a(promise); kickOffMore(); }); } else { (_b = resolvers.shift()) === null || _b === void 0 ? void 0 : _b(a); } kickOffMore(); // advance source iterator as far as possible within limit }, (err) => { var _a; // handle rejections from calling `i.next()` // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors (_a = resolvers.shift()) === null || _a === void 0 ? void 0 : _a(Promise.reject(err)); finished = true; }); })); } function kickOffMore() { if (!finished && // stop when source is done promises.length < cacheSize && // backpressure: don't put too many promises in the cache if destination doesn't poll `.next()` fast enough resolvers.length < cacheSize // limit: don't let more tasks than the maximum race to resolve the next promises ) { kickOffNext(); } } if (cacheSize < 2) { // cache + racing will have no effect, so deactivating them, // by using the same logic as operator wait(): return { next() { return i.next().then((a) => { if (a.done) { return a; } const p = a.value; return isPromiseLike(p) ? p.then((value) => ({ value, done: false })) : a; }); } }; } return { next() { if (!promises.length) { kickOffNext(); } return promises.shift(); } }; } }; } function zip(...args) { return createOperation(zipSync, zipAsync, args); } function zipSync(iterable, ...values) { return { [$S]() { const list = [ iterable[$S](), ...values.map((v) => typeof v[$S] === 'function' ? v[$S]() : v) ]; const errIterator = validateZipIterators(true, list); let finished; return (errIterator || { next() { if (!finished) { const value = []; for (let i = 0; i < list.length; i++) { const v = list[i].next(); if (v.done) { finished = true; return v; } value.push(v.value); } return { value, done: false }; } return { value: undefined, done: true }; } }); } }; } function zipAsync(iterable, ...values) { return { [$A]() { const list = [ iterable[$A](), ...values.map((v) => typeof v[$S] === 'function' ? v[$S]() : typeof v[$A] === 'function' ? v[$A]() : v) ]; const errIterator = validateZipIterators(false, list); let finished; return (errIterator || { next() { if (!finished) { return Promise.all(list.map((i) => i.next())).then((a) => { const value = []; for (let i = 0; i < a.length; i++) { if (a[i].done) { finished = true; return a[i]; } value.push(a[i].value); } return { value, done: false }; }); } return Promise.resolve({ value: undefined, done: true }); } }); } }; } function validateZipIterators(sync, inputs) { for (let i = 1; i < inputs.length; i++) { const a = inputs[i]; if (!a || typeof a.next !== 'function') { return iterateOnce(sync, () => { // either not iterable, or async iterable passed inside synchronous pipeline; throw new TypeError(`Value at index ${i - 1} is not iterable: ${JSON.stringify(a)}`); }); } } } exports.aggregate = aggregate; exports.catchError = catchError; exports.concat = concat; exports.concurrencyFork = concurrencyFork; exports.consume = consume; exports.count = count; exports.defaultEmpty = defaultEmpty; exports.delay = delay; exports.distinct = distinct; exports.drain = drain; exports.empty = empty; exports.every = every; exports.filter = filter; exports.first = first; exports.flat = flat; exports.flatMap = flatMap; exports.indexBy = indexBy; exports.isEmpty = isEmpty; exports.last = last; exports.map = map; exports.onEnd = onEnd; exports.page = page; exports.pipe = pipe; exports.pipeAsync = pipeAsync; exports.pipeSync = pipeSync; exports.reduce = reduce; exports.repeat = repeat; exports.retry = retry; exports.reverse = reverse; exports.skip = skip; exports.skipUntil = skipUntil; exports.skipWhile = skipWhile; exports.some = some; exports.split = split; exports.spread = spread; exports.take = take; exports.takeLast = takeLast; exports.takeUntil = takeUntil; exports.takeWhile = takeWhile; exports.tap = tap; exports.throttle = throttle; exports.timeout = timeout; exports.timing = timing; exports.toArray = toArray; exports.toAsync = toAsync; exports.toIterable = toIterable; exports.wait = wait; exports.waitRace = waitRace; exports.zip = zip;