UNPKG

evnty

Version:

Async-first, reactive event handling library for complex event flows in browser and Node.js

310 lines (308 loc) 9.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: Object.getOwnPropertyDescriptor(all, name).get }); } _export(exports, { get MapIteratorType () { return MapIteratorType; }, get abortableIterable () { return abortableIterable; }, get isThenable () { return isThenable; }, get iterate () { return iterate; }, get mapIterator () { return mapIterator; }, get mergeIterables () { return mergeIterables; }, get min () { return min; }, get noop () { return noop; }, get pipe () { return pipe; }, get setTimeoutAsync () { return setTimeoutAsync; }, get toAsyncIterable () { return toAsyncIterable; } }); const _sequencecjs = require("./sequence.cjs"); function isThenable(value) { return value !== null && typeof value === 'object' && typeof value.then === 'function'; } const noop = ()=>{}; function min(values, fallback) { let result = Infinity; for (const value of values){ if (value < result) result = value; } return result === Infinity ? fallback : result; } var MapIteratorType = /*#__PURE__*/ function(MapIteratorType) { MapIteratorType[MapIteratorType["NEXT"] = 0] = "NEXT"; MapIteratorType[MapIteratorType["RETURN"] = 1] = "RETURN"; MapIteratorType[MapIteratorType["THROW"] = 2] = "THROW"; return MapIteratorType; }({}); const mapIterator = (iterator, map)=>{ const subIterator = { next: async (...args)=>{ const result = await iterator.next(...args); return map(result, 0); } }; if (iterator.return) { subIterator.return = async (...args)=>{ const result = await iterator.return(...args); return map(result, 1); }; } else { subIterator.return = async (value)=>{ return map({ done: true, value }, 1); }; } if (iterator.throw) { subIterator.throw = async (...args)=>{ const result = await iterator.throw(...args); return map(result, 2); }; } return subIterator; }; function abortableIterable(iterable, signal) { return { [Symbol.asyncIterator] () { const iterator = iterable[Symbol.asyncIterator](); const { promise, resolve } = Promise.withResolvers(); const onAbort = ()=>resolve(); let closed = false; const finish = (value)=>{ if (closed) { return Promise.resolve({ done: true, value: value }); } closed = true; signal.removeEventListener('abort', onAbort); return iterator.return?.(value) ?? Promise.resolve({ done: true, value: value }); }; if (signal.aborted) { onAbort(); } else { signal.addEventListener('abort', onAbort); } const race = [ promise, undefined ]; return { async next (...args) { race[1] = iterator.next(...args); const result = await Promise.race(race); if (result === undefined) { void finish(); return { done: true, value: undefined }; } if (result.done) { closed = true; signal.removeEventListener('abort', onAbort); } return result; }, async return (value) { return finish(value); } }; } }; } const iterate = (startOrCount, countWhenTwoArgs, step = 1)=>{ const hasStartArg = countWhenTwoArgs !== undefined; const start = hasStartArg ? startOrCount : 0; const count = startOrCount === undefined ? Infinity : hasStartArg ? countWhenTwoArgs : startOrCount; return { [Symbol.iterator] () { let idx = 0; let current = start; return { next () { if (idx < count) { const value = current; current += step; idx++; return { value, done: false }; } return { value: undefined, done: true }; }, return (value) { idx = count; return { value, done: true }; }, throw (error) { idx = count; throw error; } }; } }; }; const setTimeoutAsync = async (timeout, signal)=>{ if (signal?.aborted) { return false; } const { promise, resolve } = Promise.withResolvers(); const timerId = setTimeout(resolve, timeout, true); const onAbort = ()=>{ clearTimeout(timerId); resolve(false); }; signal?.addEventListener('abort', onAbort); return promise.finally(()=>signal?.removeEventListener('abort', onAbort)); }; const toAsyncIterable = (iterable)=>{ return { [Symbol.asyncIterator] () { const iterator = iterable[Symbol.iterator](); return { async next (...args) { return iterator.next(...args); }, async return (maybeValue) { const value = await maybeValue; return iterator.return?.(value) ?? { value, done: true }; }, async throw (error) { if (iterator.throw) { return iterator.throw(error); } throw error; } }; } }; }; const isAsyncIterable = (value)=>{ return typeof value[Symbol.asyncIterator] === 'function'; }; async function* pipe(iterable, generatorFactory, signal) { const source = signal ? abortableIterable(iterable, signal) : iterable; const generator = generatorFactory(); for await (const value of source){ const produced = generator(value); const subIterable = isAsyncIterable(produced) ? produced : toAsyncIterable(produced); const abortableSub = signal ? abortableIterable(subIterable, signal) : subIterable; for await (const subValue of abortableSub){ yield subValue; } } } const mergeIterables = (...iterables)=>{ return { [Symbol.asyncIterator] () { if (iterables.length === 0) { return { next: async ()=>({ value: undefined, done: true }) }; } const exit = Symbol('mergeIterables.exit'); const ctrl = new AbortController(); const sequence = new _sequencecjs.Sequence(ctrl.signal); let remaining = iterables.length; const pump = async (iterable)=>{ try { for await (const value of abortableIterable(iterable, ctrl.signal)){ if (!sequence.emit(value)) { break; } } } catch (error) { ctrl.abort(error); } finally{ remaining -= 1; if (remaining === 0 && !ctrl.signal.aborted) { ctrl.abort(exit); } } }; for (const iterable of iterables){ void pump(iterable); } return { next: async ()=>{ try { const value = await sequence.receive(); return { value, done: false }; } catch { if (ctrl.signal.aborted && ctrl.signal.reason === exit) { return { value: undefined, done: true }; } throw ctrl.signal.reason; } }, return: async ()=>{ ctrl.abort(exit); return { value: undefined, done: true }; }, throw: async (error)=>{ ctrl.abort(error); return { value: undefined, done: true }; } }; } }; }; //# sourceMappingURL=utils.cjs.map