evnty
Version:
Async-first, reactive event handling library for complex event flows in browser and Node.js
310 lines (308 loc) • 9.74 kB
JavaScript
"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