UNPKG

evnty

Version:

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

628 lines (626 loc) 22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "AsyncIteratorObject", { enumerable: true, get: function() { return AsyncIteratorObject; } }); const _utilscjs = require("./utils.cjs"); class OpState { index; remaining; dropping; value; initialized = false; constructor(index, remaining, dropping, value){ this.index = index; this.remaining = remaining; this.dropping = dropping; this.value = value; } static from(op) { switch(op.kind){ case 5: return new OpState(op.start, 0, false, undefined); case 6: return new OpState(0, op.limit, false, undefined); case 7: return new OpState(0, op.count, false, undefined); case 9: return new OpState(0, 0, true, undefined); case 10: return new OpState(0, 0, false, op.init); default: return new OpState(0, 0, false, undefined); } } } class ProcessResult { value; shouldYield; done; expandIterator; expandOpIndex; flatMapIterator; flatMapOpIndex; constructor(value, shouldYield, done, expandIterator, expandOpIndex, flatMapIterator, flatMapOpIndex){ this.value = value; this.shouldYield = shouldYield; this.done = done; this.expandIterator = expandIterator; this.expandOpIndex = expandOpIndex; this.flatMapIterator = flatMapIterator; this.flatMapOpIndex = flatMapOpIndex; } static continue() { return new ProcessResult(undefined, false, false, null, -1, null, -1); } static yield(value) { return new ProcessResult(value, true, false, null, -1, null, -1); } static done() { return new ProcessResult(undefined, false, true, null, -1, null, -1); } static expand(iterator, opIndex) { return new ProcessResult(undefined, false, false, iterator, opIndex, null, -1); } static flatMap(iterator, opIndex) { return new ProcessResult(undefined, false, false, null, -1, iterator, opIndex); } } function findTakeStates(ops, opStates) { const takeStates = []; for(let i = 0; i < ops.length; i++){ if (ops[i].kind === 6) takeStates.push(opStates[i]); } return takeStates; } function hasExpandingOps(ops) { for(let i = 0; i < ops.length; i++){ const kind = ops[i].kind; if (kind === 11 || kind === 12) return true; } return false; } function checkTakeExhausted(takeStates) { for(let i = 0; i < takeStates.length; i++){ if (takeStates[i].remaining <= 0) return true; } return false; } async function processOps(inputValue, ops, opStates, startIndex) { let value = inputValue; for(let i = startIndex; i < ops.length; i++){ const op = ops[i]; const state = opStates[i]; switch(op.kind){ case 0: value = op.fn(value, state.index++); break; case 1: { const result = op.fn(value, state.index++); const passed = (0, _utilscjs.isThenable)(result) ? await result : result; if (!passed) return ProcessResult.continue(); break; } case 2: { const result = op.fn(value, state.index++); const resolved = (0, _utilscjs.isThenable)(result) ? await result : result; if (resolved === undefined) return ProcessResult.continue(); value = resolved; break; } case 3: value = await value; break; case 4: { const result = op.fn(value, state.index++); if ((0, _utilscjs.isThenable)(result)) await result; break; } case 5: value = [ state.index++, value ]; break; case 6: if (state.remaining <= 0) return ProcessResult.done(); state.remaining--; break; case 8: { const result = op.fn(value, state.index++); const passed = (0, _utilscjs.isThenable)(result) ? await result : result; if (!passed) return ProcessResult.done(); break; } case 7: if (state.remaining > 0) { state.remaining--; return ProcessResult.continue(); } break; case 9: if (state.dropping) { const result = op.fn(value, state.index++); const passed = (0, _utilscjs.isThenable)(result) ? await result : result; if (passed) return ProcessResult.continue(); state.dropping = false; } break; case 10: { if (!state.initialized) { state.initialized = true; if (op.hasInit) { const result = op.fn(state.value, value, state.index++); state.value = (0, _utilscjs.isThenable)(result) ? await result : result; value = state.value; } else { state.value = value; return ProcessResult.continue(); } } else { const result = op.fn(state.value, value, state.index++); state.value = (0, _utilscjs.isThenable)(result) ? await result : result; value = state.value; } break; } case 11: { const iterable = op.fn(value, state.index++); return ProcessResult.flatMap(iterable[Symbol.asyncIterator](), i); } case 12: { const result = op.fn(value, state.index++); const expanded = (0, _utilscjs.isThenable)(result) ? await result : result; return ProcessResult.expand(expanded[Symbol.iterator](), i); } } } return ProcessResult.yield(value); } async function processOpsSimple(inputValue, ops, opStates) { let value = inputValue; for(let i = 0; i < ops.length; i++){ const op = ops[i]; const state = opStates[i]; switch(op.kind){ case 0: value = op.fn(value, state.index++); break; case 1: { const result = op.fn(value, state.index++); const passed = (0, _utilscjs.isThenable)(result) ? await result : result; if (!passed) return { value: undefined, shouldYield: false, done: false }; break; } case 2: { const result = op.fn(value, state.index++); const resolved = (0, _utilscjs.isThenable)(result) ? await result : result; if (resolved === undefined) return { value: undefined, shouldYield: false, done: false }; value = resolved; break; } case 3: value = await value; break; case 4: { const result = op.fn(value, state.index++); if ((0, _utilscjs.isThenable)(result)) await result; break; } case 5: value = [ state.index++, value ]; break; case 6: state.remaining--; break; case 8: { const result = op.fn(value, state.index++); const passed = (0, _utilscjs.isThenable)(result) ? await result : result; if (!passed) return { value: undefined, shouldYield: false, done: true }; break; } case 7: if (state.remaining > 0) { state.remaining--; return { value: undefined, shouldYield: false, done: false }; } break; case 9: if (state.dropping) { const result = op.fn(value, state.index++); const passed = (0, _utilscjs.isThenable)(result) ? await result : result; if (passed) return { value: undefined, shouldYield: false, done: false }; state.dropping = false; } break; case 10: { if (!state.initialized) { state.initialized = true; if (op.hasInit) { const result = op.fn(state.value, value, state.index++); state.value = (0, _utilscjs.isThenable)(result) ? await result : result; value = state.value; } else { state.value = value; return { value: undefined, shouldYield: false, done: false }; } } else { const result = op.fn(state.value, value, state.index++); state.value = (0, _utilscjs.isThenable)(result) ? await result : result; value = state.value; } break; } } } return { value, shouldYield: true, done: false }; } function collectOps(iter) { const ops = []; let current = iter; while(current){ const op = current.op; if (op) ops.push(op); current = current.parent; } ops.reverse(); return ops; } function getSource(iter) { let current = iter; while(current.parent){ current = current.parent; } return current.iterable; } function createSimpleIterable(source, ops) { return { [Symbol.asyncIterator]: ()=>{ const iterator = source[Symbol.asyncIterator](); const opStates = ops.map(OpState.from); const takeStates = findTakeStates(ops, opStates); let done = false; return { async next () { while(!done){ if (checkTakeExhausted(takeStates)) { done = true; await iterator.return?.(); return { value: undefined, done: true }; } const sourceResult = await iterator.next(); if (sourceResult.done) { done = true; return { value: undefined, done: true }; } const result = await processOpsSimple(sourceResult.value, ops, opStates); if (result.done) { done = true; await iterator.return?.(); return { value: undefined, done: true }; } if (result.shouldYield) return { value: result.value, done: false }; } return { value: undefined, done: true }; }, async return (returnValue) { done = true; await iterator.return?.(returnValue); return { value: undefined, done: true }; }, async throw (error) { done = true; if (iterator.throw) { await iterator.throw(error); } throw error; } }; } }; } function createExpandingIterable(source, ops) { return { [Symbol.asyncIterator]: ()=>{ const iterator = source[Symbol.asyncIterator](); const opStates = ops.map(OpState.from); const takeStates = findTakeStates(ops, opStates); let done = false; const innerStack = []; const closeInnerIterators = async ()=>{ for (const frame of innerStack){ if (frame.type === 'flatMap') { await frame.iterator.return?.(); } } innerStack.length = 0; }; const handleResult = async (result)=>{ if (result.done) { done = true; await closeInnerIterators(); await iterator.return?.(); return { value: undefined, done: true }; } if (result.expandIterator) { innerStack.push({ type: 'expand', iterator: result.expandIterator, opIndex: result.expandOpIndex }); return null; } if (result.flatMapIterator) { innerStack.push({ type: 'flatMap', iterator: result.flatMapIterator, opIndex: result.flatMapOpIndex }); return null; } if (result.shouldYield) { return { value: result.value, done: false }; } return null; }; return { async next () { while(!done){ if (innerStack.length > 0) { const frame = innerStack[innerStack.length - 1]; if (frame.type === 'expand') { const expandResult = frame.iterator.next(); if (!expandResult.done) { const result = await processOps(expandResult.value, ops, opStates, frame.opIndex + 1); const handled = await handleResult(result); if (handled) return handled; continue; } innerStack.pop(); continue; } else { const flatMapResult = await frame.iterator.next(); if (!flatMapResult.done) { const result = await processOps(flatMapResult.value, ops, opStates, frame.opIndex + 1); const handled = await handleResult(result); if (handled) return handled; continue; } innerStack.pop(); continue; } } if (checkTakeExhausted(takeStates)) { done = true; await iterator.return?.(); return { value: undefined, done: true }; } const sourceResult = await iterator.next(); if (sourceResult.done) { done = true; return { value: undefined, done: true }; } const result = await processOps(sourceResult.value, ops, opStates, 0); const handled = await handleResult(result); if (handled) return handled; } return { value: undefined, done: true }; }, async return (returnValue) { done = true; await closeInnerIterators(); await iterator.return?.(returnValue); return { value: undefined, done: true }; }, async throw (error) { done = true; await closeInnerIterators(); if (iterator.throw) { await iterator.throw(error); } throw error; } }; } }; } function createFusedIterable(iter) { const source = getSource(iter); const ops = iter.cachedOps ?? (iter.cachedOps = collectOps(iter)); if (ops.length === 0) { return source; } return hasExpandingOps(ops) ? createExpandingIterable(source, ops) : createSimpleIterable(source, ops); } class AsyncIteratorObject { static from(iterable) { const asyncIterable = (0, _utilscjs.toAsyncIterable)(iterable); return new AsyncIteratorObject(asyncIterable); } static merge(...iterables) { return new AsyncIteratorObject((0, _utilscjs.mergeIterables)(...iterables)); } iterable; parent; op; cachedOps = null; [Symbol.toStringTag] = 'AsyncIteratorObject'; constructor(iterable, parent = null, op = null){ this.iterable = iterable; this.parent = parent; this.op = op; } pipe(generatorFactory, signal) { const materialized = createFusedIterable(this); const generator = (0, _utilscjs.pipe)(materialized, generatorFactory, signal); return new AsyncIteratorObject(generator); } awaited() { return new AsyncIteratorObject(this.iterable, this, { kind: 3 }); } map(callbackfn) { return new AsyncIteratorObject(this.iterable, this, { kind: 0, fn: callbackfn }); } filter(predicate) { return new AsyncIteratorObject(this.iterable, this, { kind: 1, fn: predicate }); } filterMap(callbackfn) { return new AsyncIteratorObject(this.iterable, this, { kind: 2, fn: callbackfn }); } inspect(callbackfn) { return new AsyncIteratorObject(this.iterable, this, { kind: 4, fn: callbackfn }); } enumerate(start = 0) { return new AsyncIteratorObject(this.iterable, this, { kind: 5, start }); } take(limit) { return new AsyncIteratorObject(this.iterable, this, { kind: 6, limit }); } takeWhile(predicate) { return new AsyncIteratorObject(this.iterable, this, { kind: 8, fn: predicate }); } drop(count) { return new AsyncIteratorObject(this.iterable, this, { kind: 7, count }); } dropWhile(predicate) { return new AsyncIteratorObject(this.iterable, this, { kind: 9, fn: predicate }); } flatMap(callback) { return new AsyncIteratorObject(this.iterable, this, { kind: 11, fn: callback }); } reduce(callbackfn, ...args) { const hasInit = args.length > 0; return new AsyncIteratorObject(this.iterable, this, { kind: 10, fn: callbackfn, init: args[0], hasInit }); } expand(callbackfn) { return new AsyncIteratorObject(this.iterable, this, { kind: 12, fn: callbackfn }); } [Symbol.asyncIterator]() { return createFusedIterable(this)[Symbol.asyncIterator](); } } //# sourceMappingURL=iterator.cjs.map