"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { Callable: function() { return Callable; }, Event: function() { return Event; }, Unsubscribe: function() { return Unsubscribe; }, createEvent: function() { return createEvent; }, createInterval: function() { return createInterval; }, default: function() { return _default; }, merge: function() { return merge; }, removeListener: function() { return removeListener; }, setTimeoutAsync: function() { return setTimeoutAsync; } }); const removeListener = (listeners, listener)=>{ let index = listeners.indexOf(listener); const wasRemoved = index !== -1; while(~index){ listeners.splice(index, 1); index = listeners.indexOf(listener); } return wasRemoved; }; const setTimeoutAsync = (timeout, signal)=>new Promise((resolve)=>{ const timerId = setTimeout(resolve, timeout, true); signal?.addEventListener('abort', ()=>{ clearTimeout(timerId); resolve(false); }); }); class Callable extends Function { constructor(func){ super(); return Object.setPrototypeOf(func, new.target.prototype); } } class Unsubscribe extends Callable { _done = false; constructor(callback){ super(async ()=>{ this._done = true; await callback(); }); } get done() { return this._done; } pre(callback) { return new Unsubscribe(async ()=>{ await callback(); await this(); }); } post(callback) { return new Unsubscribe(async ()=>{ await this(); await callback(); }); } countdown(count) { return new Unsubscribe(async ()=>{ if (!--count) { await this(); } }); } } var SpyType; (function(SpyType) { SpyType[SpyType["Add"] = 0] = "Add"; SpyType[SpyType["Remove"] = 1] = "Remove"; })(SpyType || (SpyType = {})); class Event extends Callable { listeners; spies = []; _disposed = false; dispose; constructor(dispose){ const listeners = []; super((value)=>Promise.all(listeners.map(async (listener)=>listener(await value)))); this.listeners = listeners; this.dispose = async ()=>{ this._disposed = true; void this.clear(); await this._error?.dispose(); await dispose?.(); }; } _error; get error() { return this._error ??= new Event(); } get size() { return this.listeners.length; } get disposed() { return this._disposed; } lacks(listener) { return this.listeners.indexOf(listener) === -1; } has(listener) { return this.listeners.indexOf(listener) !== -1; } off(listener) { if (removeListener(this.listeners, listener) && this.spies.length) { [ ...this.spies ].forEach((spy)=>spy(listener, 1)); } return this; } on(listener) { this.listeners.push(listener); if (this.spies.length) { [ ...this.spies ].forEach((spy)=>spy(listener, 0)); } return new Unsubscribe(()=>{ void this.off(listener); }); } once(listener) { const oneTimeListener = (event)=>{ void this.off(oneTimeListener); return listener(event); }; return this.on(oneTimeListener); } clear() { this.listeners.splice(0); if (this.spies.length) { [ ...this.spies ].forEach((spy)=>spy(undefined, 1)); } return this; } then(onfulfilled, onrejected) { const unsubscribe = []; const promise = new Promise((resolve, reject)=>{ unsubscribe.push(this.once(resolve)); unsubscribe.push(this.error.once(reject)); }); return promise.then(onfulfilled, onrejected).finally(async ()=>{ await Promise.all(unsubscribe.map((u)=>u())); }); } async settle() { return await Promise.allSettled([ this.promise ]).then(([settled])=>settled); } get promise() { return this.then(); } [Symbol.asyncIterator]() { const queue = []; const doneEvent = new Event(); const emitEvent = async (value)=>{ queue.push(value); await doneEvent(false); }; const unsubscribe = this.on(emitEvent).pre(async ()=>{ removeListener(this.spies, spy); queue.splice(0); await doneEvent.dispose(); }); const spy = (target = emitEvent, action)=>{ if (target === emitEvent && action === 1) { void doneEvent(true); void unsubscribe(); } }; this.spies.push(spy); return { async next () { if (queue.length) { return { value: queue.shift(), done: false }; } if (!await doneEvent) { return { value: queue.shift(), done: false }; } return { value: undefined, done: true }; }, async return (value) { await unsubscribe(); return { done: true, value }; } }; } pipe(generator) { const emitEvent = async (value)=>{ try { for await (const generatedValue of generator(value)){ await result(generatedValue).catch(result.error); } } catch (e) { await result.error(e); } }; const unsubscribe = this.on(emitEvent).pre(()=>{ removeListener(this.spies, spy); }); const spy = (target = emitEvent, action)=>{ if (target === emitEvent && action === 1) { void unsubscribe(); } }; this.spies.push(spy); const result = new Event(unsubscribe); return result; } async *generator(generator) { for await (const value of this.pipe(generator)){ yield value; } } filter(filter) { return this.pipe(async function*(value) { if (await filter(value)) { yield value; } }); } first(filter) { const filteredEvent = this.pipe(async function*(value) { if (await filter(value)) { yield value; await filteredEvent.dispose(); } }); return filteredEvent; } map(mapper) { return this.pipe(async function*(value) { yield await mapper(value); }); } reduce(reducer, ...init) { let hasInit = init.length === 1; let result = init[0]; return this.pipe(async function*(value) { if (hasInit) { result = await reducer(result, value); yield result; } else { result = value; hasInit = true; } }); } expand(expander) { return this.pipe(async function*(value) { const values = await expander(value); for (const value of values){ yield value; } }); } orchestrate(conductor) { let initialized = false; let lastValue; const unsubscribe = this.on(async (event)=>{ initialized = true; lastValue = event; }); const unsubscribeConductor = conductor.on(async ()=>{ if (initialized) { await orchestratedEvent(lastValue); initialized = false; } }); const orchestratedEvent = new Event(unsubscribe.post(unsubscribeConductor)); return orchestratedEvent; } debounce(interval) { let controller = new AbortController(); return this.pipe(async function*(value) { controller.abort(); controller = new AbortController(); const complete = await setTimeoutAsync(interval, controller.signal); if (complete) { yield value; } }); } throttle(interval) { let timeout = 0; let pendingValue; let hasPendingValue = false; return this.pipe(async function*(value) { const now = Date.now(); if (timeout <= now) { timeout = now + interval; yield value; } else { pendingValue = value; if (!hasPendingValue) { hasPendingValue = true; await setTimeoutAsync(timeout - now); timeout = now + interval; hasPendingValue = false; yield pendingValue; } } }); } batch(interval, size) { let controller = new AbortController(); const batch = []; return this.pipe(async function*(value) { batch.push(value); if (size !== undefined && batch.length >= size) { controller.abort(); yield batch.splice(0); } if (batch.length === 1) { controller = new AbortController(); const complete = await setTimeoutAsync(interval, controller.signal); if (complete) { yield batch.splice(0); } } }); } queue() { const queue = []; let done = false; const valueEvent = new Event(); const unsubscribe = this.on(async (value)=>{ queue.push(value); await valueEvent(); }); const pop = async ()=>{ if (!queue.length) { await valueEvent; } return queue.shift(); }; const stop = async ()=>{ await unsubscribe(); done = true; await valueEvent(); }; return { pop, stop, get stopped () { return done; }, then (onfulfilled, onrejected) { return this.pop().then(onfulfilled, onrejected); }, [Symbol.asyncIterator] () { return { next: async ()=>{ return { value: await pop(), done }; } }; } }; } } const merge = (...events)=>{ const mergedEvent = new Event(); events.forEach((event)=>event.on(mergedEvent)); return mergedEvent; }; const createInterval = (interval)=>{ let counter = 0; const intervalEvent = new Event(()=>clearInterval(timerId)); const timerId = setInterval(()=>intervalEvent(counter++), interval); return intervalEvent; }; const createEvent = ()=>new Event(); const _default = createEvent; //# sourceMappingURL=index.cjs.map