feat: init

This commit is contained in:
Nick 2024-08-10 02:59:22 -05:00
parent 8379d09058
commit 2cfa016090
2929 changed files with 299087 additions and 3 deletions

View file

@ -0,0 +1,69 @@
# Changelog
All notable changes to this project will be documented in this file.
# [2.2.4](https://github.com/vladfrangu/async_event_emitter/compare/v2.2.4...v2.2.4) - (2023-12-03)
## 🐛 Bug Fixes
- Correct import of CJS version in package.json (#3) ([8dc308c](https://github.com/vladfrangu/async_event_emitter/commit/8dc308c43fdf9a024a7d48e7219d75e4c9f597dd))
# [2.2.2](https://github.com/vladfrangu/async_event_emitter/compare/v2.2.1...v2.2.2) - (2023-05-11)
## 🐛 Bug Fixes
- Listener count was always 0 for one listener ([9b78e19](https://github.com/vladfrangu/async_event_emitter/commit/9b78e1992db649004dee852359240b3d0baaac2d))
# [2.2.1](https://github.com/vladfrangu/async_event_emitter/compare/v2.2.0...v2.2.1) - (2023-04-08)
## 🐛 Bug Fixes
- Include comment for throwing error on emit ([19de045](https://github.com/vladfrangu/async_event_emitter/commit/19de0452702a0d9e35e9241259d100ca6d6f5447))
# [2.2.0](https://github.com/vladfrangu/async_event_emitter/compare/v2.1.4...v2.2.0) - (2023-04-07)
## 🚀 Features
- Speed 🚀 ([23eb908](https://github.com/vladfrangu/async_event_emitter/commit/23eb90852ff8a6ceb4d6105c6df44c646642efae))
# [2.1.4](https://github.com/vladfrangu/async_event_emitter/compare/v2.1.3...v2.1.4) - (2023-02-18)
## 🐛 Bug Fixes
- Remove predefined error event to allow extensions ([4224bbe](https://github.com/vladfrangu/async_event_emitter/commit/4224bbeae5c25cb94d4073600a9dff7ae3abcceb))
# [2.1.2](https://github.com/vladfrangu/async_event_emitter/compare/v2.1.1...v2.1.2) - (2022-09-19)
## 🐛 Bug Fixes
- Don't use any `@types/node` types ([e4babce](https://github.com/vladfrangu/async_event_emitter/commit/e4babce88c17befdb6f84c73c0de2e0602260681))
# [2.1.1](https://github.com/vladfrangu/async_event_emitter/compare/v2.1.0...v2.1.1) - (2022-09-19)
## 🐛 Bug Fixes
- Correct type errors when building with other types too ([72a03ae](https://github.com/vladfrangu/async_event_emitter/commit/72a03ae1ac30456241b4003a7c2ea93d27e8de5e))
# [2.1.0](https://github.com/vladfrangu/async_event_emitter/compare/v2.0.1...v2.1.0) - (2022-09-18)
## 🚀 Features
- Bring in line with nodejs EventEmitters ([5a14ed0](https://github.com/vladfrangu/async_event_emitter/commit/5a14ed04bf87ec6a34cd33e26e3f25f101f87bcd))
# [2.0.1](https://github.com/vladfrangu/async_event_emitter/compare/v2.0.0...v2.0.1) - (2022-07-09)
## 🐛 Bug Fixes
- Error event not properly emitting ([b849b38](https://github.com/vladfrangu/async_event_emitter/commit/b849b387c36515c60234c06681bfd4ec32ee5336))
# [2.0.0](https://github.com/vladfrangu/async_event_emitter/compare/v1.0.1...v2.0.0) - (2022-06-29)
## 🚀 Features
- Use stringified bigints instead of uuids for promise map ([8c69419](https://github.com/vladfrangu/async_event_emitter/commit/8c694199da1a0a231feb1be3b0d7cfdb18cefd0b))
### 💥 Breaking Changes:
# Changelog
All notable changes to this project will be documented in this file.

View file

@ -0,0 +1,24 @@
# The MIT License (MIT)
Copyright © `2022` `Vlad Frangu`
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the “Software”), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

51
node_modules/@vladfrangu/async_event_emitter/README.md generated vendored Normal file
View file

@ -0,0 +1,51 @@
<div align="center">
# @vladfrangu/async_event_emitter
**Simple to use event emitter implementation with async support in mind.**
[![GitHub](https://img.shields.io/github/license/vladfrangu/async_event_emitter)](https://github.com/vladfrangu/async_event_emitter/blob/main/LICENSE.md)
[![codecov](https://codecov.io/gh/vladfrangu/async_event_emitter/branch/main/graph/badge.svg?token=0MSAyoZNxz)](https://codecov.io/gh/vladfrangu/async_event_emitter)
[![npm](https://img.shields.io/npm/v/@vladfrangu/async_event_emitter?color=crimson&logo=npm&style=flat-square)](https://www.npmjs.com/package/@vladfrangu/async_event_emitter)
</div>
## Description
A very small, lightweight and simple re-implementation of event emitters, with support for async event handlers in mind.
> **Note**: `@vladfrangu/async_event_emitter` requires Node.js v14 or higher to work, or a browser that has async/await support.
## Features
- TypeScript friendly
- Offers CJS, ESM and UMD builds
- Consistent interface with what is expected from an event emitter
- Simple handling of asynchronous event handlers to allow waiting for their execution to finish if you want to exit the process
## Buy me some doughnuts
Most of my projects are and always will be open source, even if I don't get donations. That being said, I know there are amazing people who may still want to donate just to show their appreciation. Thank you very much in advance!
I accept donations through Ko-fi, PayPal, Patreon and GitHub Sponsorships. You can use the buttons below to donate through your method of choice.
| Donate With | Address |
| :-------------: | :------------------------------------------------------: |
| GitHub Sponsors | [Click Here](https://github.com/sponsors/vladfrangu) |
| Ko-fi | [Click Here](https://ko-fi.com/wolfgalvlad) |
| Patreon | [Click Here](https://patreon.com/vladfrangu) |
| PayPal | [Click Here](https://www.paypal.com/paypalme/franguvlad) |
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

View file

@ -0,0 +1,23 @@
# Most parts of this code are from node.js, specifically from https://github.com/nodejs/node/blob/main/lib/events.js
As such, a lot of the code is licensed under the following license:
Copyright Node.js contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

View file

@ -0,0 +1,568 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
AbortError: () => AbortError,
AsyncEventEmitter: () => AsyncEventEmitter
});
module.exports = __toCommonJS(src_exports);
function validateListener(input) {
if (typeof input !== "function") {
throw new TypeError(`The listener argument must be a function. Received ${typeof input}`);
}
}
__name(validateListener, "validateListener");
function validateAbortSignal(input) {
if (input && !(input instanceof AbortSignal)) {
throw new TypeError(`The signal option must be an AbortSignal. Received ${input}`);
}
}
__name(validateAbortSignal, "validateAbortSignal");
function spliceOne(list, index) {
for (; index + 1 < list.length; index++) {
list[index] = list[index + 1];
}
list.pop();
}
__name(spliceOne, "spliceOne");
function arrayClone(arr) {
switch (arr.length) {
case 2:
return [arr[0], arr[1]];
case 3:
return [arr[0], arr[1], arr[2]];
case 4:
return [arr[0], arr[1], arr[2], arr[3]];
case 5:
return [arr[0], arr[1], arr[2], arr[3], arr[4]];
case 6:
return [arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]];
}
return arr.slice();
}
__name(arrayClone, "arrayClone");
function identicalSequenceRange(a, b) {
for (let i = 0; i < a.length - 3; i++) {
const pos = b.indexOf(a[i]);
if (pos !== -1) {
const rest = b.length - pos;
if (rest > 3) {
let len = 1;
const maxLen = Math.min(a.length - i, rest);
while (maxLen > len && a[i + len] === b[pos + len]) {
len++;
}
if (len > 3) {
return [len, i];
}
}
}
}
return [0, 0];
}
__name(identicalSequenceRange, "identicalSequenceRange");
function enhanceStackTrace(err, own) {
let ctorInfo = "";
try {
const { name } = this.constructor;
if (name !== "AsyncEventEmitter")
ctorInfo = ` on ${name} instance`;
} catch {
}
const sep = `
Emitted 'error' event${ctorInfo} at:
`;
const errStack = err.stack.split("\n").slice(1);
const ownStack = own.stack.split("\n").slice(1);
const { 0: len, 1: off } = identicalSequenceRange(ownStack, errStack);
if (len > 0) {
ownStack.splice(off + 1, len - 2, " [... lines matching original stack trace ...]");
}
return err.stack + sep + ownStack.join("\n");
}
__name(enhanceStackTrace, "enhanceStackTrace");
var _AsyncEventEmitter = class _AsyncEventEmitter {
constructor() {
this._events = {
__proto__: null
};
this._eventCount = 0;
this._maxListeners = 10;
this._internalPromiseMap = /* @__PURE__ */ new Map();
this._wrapperId = 0n;
}
addListener(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, false);
this._addListener(eventName, wrapped, false);
return this;
}
on(eventName, listener) {
return this.addListener(eventName, listener);
}
once(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, true);
this._addListener(eventName, wrapped, false);
return this;
}
removeListener(eventName, listener) {
validateListener(listener);
const events = this._events;
const eventList = events[eventName];
if (eventList === void 0) {
return this;
}
if (eventList === listener || eventList.listener === listener) {
if (--this._eventCount === 0) {
this._events = { __proto__: null };
} else {
delete events[eventName];
if (events.removeListener) {
this.emit("removeListener", eventName, eventList.listener ?? eventList);
}
}
} else if (typeof eventList !== "function") {
let position = -1;
for (let i = eventList.length - 1; i >= 0; i--) {
if (eventList[i] === listener || eventList[i].listener === listener) {
position = i;
break;
}
}
if (position < 0) {
return this;
}
if (position === 0) {
eventList.shift();
} else {
spliceOne(eventList, position);
}
if (eventList.length === 0) {
delete events[eventName];
--this._eventCount;
}
if (events.removeListener !== void 0) {
this.emit("removeListener", eventName, listener);
}
}
return this;
}
off(eventName, listener) {
return this.removeListener(eventName, listener);
}
removeAllListeners(event) {
const events = this._events;
if (events.removeListener === void 0) {
if (!event) {
this._events = { __proto__: null };
this._eventCount = 0;
} else if (events[event] !== void 0) {
if (--this._eventCount === 0) {
this._events = { __proto__: null };
} else {
delete events[event];
}
}
return this;
}
if (!event) {
for (const key of Reflect.ownKeys(events)) {
if (key === "removeListener") {
continue;
}
this.removeAllListeners(key);
}
this.removeAllListeners("removeListener");
this._events = { __proto__: null };
this._eventCount = 0;
return this;
}
const listeners = events[event];
if (typeof listeners === "function") {
this.removeListener(event, listeners);
} else if (listeners !== void 0) {
for (let i = listeners.length - 1; i >= 0; i--) {
this.removeListener(event, listeners[i]);
}
}
return this;
}
setMaxListeners(n) {
if (typeof n !== "number" || n < 0 || Number.isNaN(n)) {
throw new RangeError(`Expected to get a non-negative number for "setMaxListeners", got ${n} instead`);
}
this._maxListeners = n;
return this;
}
getMaxListeners() {
return this._maxListeners;
}
listeners(eventName) {
const eventList = this._events[eventName];
if (eventList === void 0) {
return [];
}
if (typeof eventList === "function") {
return [eventList.listener ?? eventList];
}
const ret = arrayClone(eventList);
for (let i = 0; i < ret.length; ++i) {
const orig = ret[i].listener;
if (typeof orig === "function") {
ret[i] = orig;
}
}
return ret;
}
rawListeners(eventName) {
const eventList = this._events[eventName];
if (eventList === void 0) {
return [];
}
if (typeof eventList === "function") {
return [eventList];
}
return arrayClone(eventList);
}
emit(eventName, ...args) {
let doError = eventName === "error";
const events = this._events;
if (events !== void 0) {
doError = doError && events.error === void 0;
} else if (!doError) {
return false;
}
if (doError) {
let er;
if (args.length > 0) {
er = args[0];
}
if (er instanceof Error) {
try {
const capture = {};
Error.captureStackTrace(capture, _AsyncEventEmitter.prototype.emit);
Object.defineProperty(er, "stack", {
value: enhanceStackTrace.call(this, er, capture),
configurable: true
});
} catch {
}
throw er;
}
const stringifiedError = String(er);
const err = new Error(`Unhandled 'error' event emitted, received ${stringifiedError}`);
err.context = er;
throw err;
}
const handlers = events[eventName];
if (handlers === void 0) {
return false;
}
if (typeof handlers === "function") {
const result = handlers.apply(this, args);
if (result !== void 0 && result !== null) {
handleMaybeAsync(this, result);
}
} else {
const len = handlers.length;
const listeners = arrayClone(handlers);
for (let i = 0; i < len; ++i) {
const result = listeners[i].apply(this, args);
if (result !== void 0 && result !== null) {
handleMaybeAsync(this, result);
}
}
}
return true;
}
listenerCount(eventName) {
const events = this._events;
if (events === void 0) {
return 0;
}
const eventListeners = events[eventName];
if (typeof eventListeners === "function") {
return 1;
}
return eventListeners?.length ?? 0;
}
prependListener(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, false);
this._addListener(eventName, wrapped, true);
return this;
}
prependOnceListener(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, true);
this._addListener(eventName, wrapped, true);
return this;
}
eventNames() {
return this._eventCount > 0 ? Reflect.ownKeys(this._events) : [];
}
async waitForAllListenersToComplete() {
const promises = [...this._internalPromiseMap.values()];
if (promises.length === 0) {
return false;
}
await Promise.all(promises);
return true;
}
_addListener(eventName, wrappedListener, prepend) {
if (this._events.newListener !== void 0) {
this.emit("newListener", eventName, wrappedListener.listener ?? wrappedListener);
}
let existing = this._events[eventName];
if (existing === void 0) {
existing = this._events[eventName] = wrappedListener;
++this._eventCount;
} else if (typeof existing === "function") {
existing = this._events[eventName] = prepend ? [wrappedListener, existing] : [existing, wrappedListener];
} else if (prepend) {
existing.unshift(wrappedListener);
} else {
existing.push(wrappedListener);
}
if (this._maxListeners > 0 && existing.length > this._maxListeners && !existing._hasWarnedAboutMaxListeners) {
existing._hasWarnedAboutMaxListeners = true;
const warningMessage = [
`Possible AsyncEventEmitter memory leak detected. ${existing.length} ${String(eventName)} listeners added to ${this.constructor.name}.`,
`Use emitter.setMaxListeners() to increase the limit.`
].join(" ");
console.warn(warningMessage);
}
}
_wrapListener(eventName, listener, once) {
if (!once) {
return listener;
}
const state = {
fired: false,
wrapFn: void 0,
eventEmitter: this,
eventName,
listener
};
const aliased = onceWrapper;
const wrapped = aliased.bind(state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
static listenerCount(emitter, eventName) {
return emitter.listenerCount(eventName);
}
static async once(emitter, eventName, options = {}) {
const signal = options?.signal;
validateAbortSignal(signal);
if (signal?.aborted) {
throw new AbortError(void 0, { cause: getReason(signal) });
}
return new Promise((resolve, reject) => {
const errorListener = /* @__PURE__ */ __name((err) => {
emitter.removeListener(eventName, resolver);
if (signal) {
eventTargetAgnosticRemoveListener(emitter, eventName, abortListener);
}
reject(err);
}, "errorListener");
const resolver = /* @__PURE__ */ __name((...args) => {
emitter.removeListener("error", errorListener);
if (signal) {
eventTargetAgnosticRemoveListener(signal, "abort", abortListener);
}
resolve(args);
}, "resolver");
emitter.once(eventName, resolver);
if (eventName !== "error") {
emitter.once("error", errorListener);
}
const abortListener = /* @__PURE__ */ __name(() => {
eventTargetAgnosticRemoveListener(emitter, eventName, resolver);
eventTargetAgnosticRemoveListener(emitter, "error", errorListener);
reject(new AbortError(void 0, { cause: getReason(signal) }));
}, "abortListener");
if (signal) {
eventTargetAgnosticAddListener(signal, "abort", abortListener, { once: true });
}
});
}
static on(emitter, eventName, options = {}) {
const signal = options?.signal;
validateAbortSignal(signal);
if (signal?.aborted) {
throw new AbortError(void 0, { cause: getReason(signal) });
}
const unconsumedEvents = [];
const unconsumedPromises = [];
let error = null;
let finished = false;
const abortListener = /* @__PURE__ */ __name(() => {
errorHandler(new AbortError(void 0, { cause: getReason(signal) }));
}, "abortListener");
const eventHandler = /* @__PURE__ */ __name((...args) => {
const promise = unconsumedPromises.shift();
if (promise) {
promise.resolve(createIterResult(args, false));
} else {
unconsumedEvents.push(args);
}
}, "eventHandler");
const errorHandler = /* @__PURE__ */ __name((err) => {
finished = true;
const toError = unconsumedPromises.shift();
if (toError) {
toError.reject(err);
} else {
error = err;
}
void iterator.return();
}, "errorHandler");
const iterator = Object.setPrototypeOf(
{
next() {
const value = unconsumedEvents.shift();
if (value) {
return Promise.resolve(createIterResult(value, false));
}
if (error) {
const p = Promise.reject(error);
error = null;
return p;
}
if (finished) {
return Promise.resolve(createIterResult(void 0, true));
}
return new Promise((resolve, reject) => {
unconsumedPromises.push({ resolve, reject });
});
},
return() {
emitter.off(eventName, eventHandler);
emitter.off("error", errorHandler);
if (signal) {
eventTargetAgnosticRemoveListener(signal, "abort", abortListener);
}
finished = true;
const doneResult = createIterResult(void 0, true);
for (const promise of unconsumedPromises) {
promise.resolve(doneResult);
}
return Promise.resolve(doneResult);
},
throw(err) {
if (!err || !(err instanceof Error)) {
throw new TypeError(`Expected Error instance to be thrown in AsyncEventEmitter.AsyncIterator. Got ${err}`);
}
error = err;
emitter.off(eventName, eventHandler);
emitter.off("error", errorHandler);
},
[Symbol.asyncIterator]() {
return this;
}
},
AsyncIteratorPrototype
);
emitter.on(eventName, eventHandler);
if (eventName !== "error") {
emitter.on("error", errorHandler);
}
if (signal) {
eventTargetAgnosticAddListener(signal, "abort", abortListener);
}
return iterator;
}
};
__name(_AsyncEventEmitter, "AsyncEventEmitter");
var AsyncEventEmitter = _AsyncEventEmitter;
function onceWrapper() {
if (!this.fired) {
this.eventEmitter.removeListener(this.eventName, this.wrapFn);
this.fired = true;
if (arguments.length === 0) {
return this.listener.call(this.eventEmitter);
}
return this.listener.apply(this.eventEmitter, arguments);
}
}
__name(onceWrapper, "onceWrapper");
function getReason(signal) {
return signal?.reason;
}
__name(getReason, "getReason");
function eventTargetAgnosticRemoveListener(emitter, name, listener, flags) {
if (typeof emitter.off === "function") {
emitter.off(name, listener);
} else if (typeof emitter.removeEventListener === "function") {
emitter.removeEventListener(name, listener, flags);
}
}
__name(eventTargetAgnosticRemoveListener, "eventTargetAgnosticRemoveListener");
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
if (typeof emitter.on === "function") {
if (flags?.once) {
emitter.once(name, listener);
} else {
emitter.on(name, listener);
}
} else if (typeof emitter.addEventListener === "function") {
emitter.addEventListener(name, listener, flags);
}
}
__name(eventTargetAgnosticAddListener, "eventTargetAgnosticAddListener");
var AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(async function* () {
}).prototype);
function createIterResult(value, done) {
return { value, done };
}
__name(createIterResult, "createIterResult");
var _AbortError = class _AbortError extends Error {
constructor(message = "The operation was aborted", options = void 0) {
if (options !== void 0 && typeof options !== "object") {
throw new TypeError(`Failed to create AbortError: options is not an object or undefined`);
}
super(message, options);
this.code = "ABORT_ERR";
this.name = "AbortError";
}
};
__name(_AbortError, "AbortError");
var AbortError = _AbortError;
function handleMaybeAsync(emitter, result) {
try {
const fin = result.finally;
if (typeof fin === "function") {
const promiseId = String(++emitter["_wrapperId"]);
emitter["_internalPromiseMap"].set(promiseId, result);
fin.call(result, /* @__PURE__ */ __name(function final() {
emitter["_internalPromiseMap"].delete(promiseId);
}, "final"));
}
} catch (err) {
emitter.emit("error", err);
}
}
__name(handleMaybeAsync, "handleMaybeAsync");
//# sourceMappingURL=index.cjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,58 @@
declare class AsyncEventEmitter<Events extends {} = Record<PropertyKey, unknown[]> & AsyncEventEmitterPredefinedEvents, _Events extends Record<PropertyKey, unknown[]> = Events> {
private _events;
private _eventCount;
private _maxListeners;
private _internalPromiseMap;
private _wrapperId;
addListener<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
on<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
once<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
removeListener<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
off<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
removeAllListeners<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(event?: K | undefined): this;
setMaxListeners(n: number): this;
getMaxListeners(): number;
listeners<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K): Listener<_Events[keyof Events]>['listener'][];
rawListeners<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K): Listener<_Events[keyof Events]>[];
emit<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, ...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]): boolean;
listenerCount<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K): number;
prependListener<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
prependOnceListener<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
eventNames(): (keyof _Events | keyof AsyncEventEmitterPredefinedEvents)[];
waitForAllListenersToComplete(): Promise<boolean>;
private _addListener;
private _wrapListener;
static listenerCount<Emitter extends AsyncEventEmitter<any>, EventNames = Emitter extends AsyncEventEmitter<infer Events> ? Events : never, EventName extends PropertyKey = EventNames extends never ? string | symbol : keyof EventNames>(emitter: Emitter, eventName: EventName | keyof AsyncEventEmitterPredefinedEvents): number;
// @ts-ignore
static once<Emitter extends AsyncEventEmitter<any, any>, EventNames extends {} = Emitter extends AsyncEventEmitter<infer Events, any> ? Events : Record<PropertyKey, unknown[]>, EventName extends PropertyKey = keyof EventNames | keyof AsyncEventEmitterPredefinedEvents, EventResult extends unknown[] = EventNames extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[EventName] : EventNames[EventName]>(emitter: Emitter, eventName: EventName, options?: AbortableMethods): Promise<EventResult>;
// @ts-ignore
static on<Emitter extends AsyncEventEmitter<any, any>, EventNames extends {} = Emitter extends AsyncEventEmitter<infer Events, any> ? Events : Record<PropertyKey, unknown[]>, EventName extends PropertyKey = keyof EventNames | keyof AsyncEventEmitterPredefinedEvents, EventResult extends unknown[] = EventNames extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[EventName] : EventNames[EventName]>(emitter: Emitter, eventName: EventName, options?: AbortableMethods): AsyncGenerator<EventResult, void>;
}
interface AsyncEventEmitterPredefinedEvents {
newListener: [eventName: string | symbol, listener: (...args: any[]) => Awaitable<void>];
removeListener: [eventName: string | symbol, listener: (...args: any[]) => Awaitable<void>];
}
interface WrappedOnce<Args extends any[] = any[]> {
(...args: Args): Awaitable<void>;
listener: (...args: Args) => Awaitable<void>;
_hasWarnedAboutMaxListeners?: boolean;
}
interface Listener<Args extends any[] = any[]> {
(...args: Args): Awaitable<void>;
listener: (...args: Args) => Awaitable<void>;
_hasWarnedAboutMaxListeners?: boolean;
}
type Awaitable<T> = T | Promise<T>;
interface AbortableMethods {
signal?: AbortSignal;
}
interface AbortErrorOptions {
cause?: unknown;
}
declare class AbortError extends Error {
readonly code = "ABORT_ERR";
readonly name = "AbortError";
constructor(message?: string, options?: AbortErrorOptions | undefined);
}
export { AbortError, type AbortErrorOptions, type AbortableMethods, AsyncEventEmitter, type AsyncEventEmitterPredefinedEvents, type Awaitable, type Listener, type WrappedOnce };

View file

@ -0,0 +1,58 @@
declare class AsyncEventEmitter<Events extends {} = Record<PropertyKey, unknown[]> & AsyncEventEmitterPredefinedEvents, _Events extends Record<PropertyKey, unknown[]> = Events> {
private _events;
private _eventCount;
private _maxListeners;
private _internalPromiseMap;
private _wrapperId;
addListener<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
on<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
once<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
removeListener<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
off<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
removeAllListeners<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(event?: K | undefined): this;
setMaxListeners(n: number): this;
getMaxListeners(): number;
listeners<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K): Listener<_Events[keyof Events]>['listener'][];
rawListeners<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K): Listener<_Events[keyof Events]>[];
emit<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, ...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]): boolean;
listenerCount<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K): number;
prependListener<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
prependOnceListener<K extends keyof _Events | keyof AsyncEventEmitterPredefinedEvents>(eventName: K, listener: (...args: K extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[K] : _Events[K]) => void): this;
eventNames(): (keyof _Events | keyof AsyncEventEmitterPredefinedEvents)[];
waitForAllListenersToComplete(): Promise<boolean>;
private _addListener;
private _wrapListener;
static listenerCount<Emitter extends AsyncEventEmitter<any>, EventNames = Emitter extends AsyncEventEmitter<infer Events> ? Events : never, EventName extends PropertyKey = EventNames extends never ? string | symbol : keyof EventNames>(emitter: Emitter, eventName: EventName | keyof AsyncEventEmitterPredefinedEvents): number;
// @ts-ignore
static once<Emitter extends AsyncEventEmitter<any, any>, EventNames extends {} = Emitter extends AsyncEventEmitter<infer Events, any> ? Events : Record<PropertyKey, unknown[]>, EventName extends PropertyKey = keyof EventNames | keyof AsyncEventEmitterPredefinedEvents, EventResult extends unknown[] = EventNames extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[EventName] : EventNames[EventName]>(emitter: Emitter, eventName: EventName, options?: AbortableMethods): Promise<EventResult>;
// @ts-ignore
static on<Emitter extends AsyncEventEmitter<any, any>, EventNames extends {} = Emitter extends AsyncEventEmitter<infer Events, any> ? Events : Record<PropertyKey, unknown[]>, EventName extends PropertyKey = keyof EventNames | keyof AsyncEventEmitterPredefinedEvents, EventResult extends unknown[] = EventNames extends keyof AsyncEventEmitterPredefinedEvents ? AsyncEventEmitterPredefinedEvents[EventName] : EventNames[EventName]>(emitter: Emitter, eventName: EventName, options?: AbortableMethods): AsyncGenerator<EventResult, void>;
}
interface AsyncEventEmitterPredefinedEvents {
newListener: [eventName: string | symbol, listener: (...args: any[]) => Awaitable<void>];
removeListener: [eventName: string | symbol, listener: (...args: any[]) => Awaitable<void>];
}
interface WrappedOnce<Args extends any[] = any[]> {
(...args: Args): Awaitable<void>;
listener: (...args: Args) => Awaitable<void>;
_hasWarnedAboutMaxListeners?: boolean;
}
interface Listener<Args extends any[] = any[]> {
(...args: Args): Awaitable<void>;
listener: (...args: Args) => Awaitable<void>;
_hasWarnedAboutMaxListeners?: boolean;
}
type Awaitable<T> = T | Promise<T>;
interface AbortableMethods {
signal?: AbortSignal;
}
interface AbortErrorOptions {
cause?: unknown;
}
declare class AbortError extends Error {
readonly code = "ABORT_ERR";
readonly name = "AbortError";
constructor(message?: string, options?: AbortErrorOptions | undefined);
}
export { AbortError, type AbortErrorOptions, type AbortableMethods, AsyncEventEmitter, type AsyncEventEmitterPredefinedEvents, type Awaitable, type Listener, type WrappedOnce };

View file

@ -0,0 +1,570 @@
"use strict";
var AsyncEventEmitter = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
AbortError: () => AbortError,
AsyncEventEmitter: () => AsyncEventEmitter
});
function validateListener(input) {
if (typeof input !== "function") {
throw new TypeError(`The listener argument must be a function. Received ${typeof input}`);
}
}
__name(validateListener, "validateListener");
function validateAbortSignal(input) {
if (input && !(input instanceof AbortSignal)) {
throw new TypeError(`The signal option must be an AbortSignal. Received ${input}`);
}
}
__name(validateAbortSignal, "validateAbortSignal");
function spliceOne(list, index) {
for (; index + 1 < list.length; index++) {
list[index] = list[index + 1];
}
list.pop();
}
__name(spliceOne, "spliceOne");
function arrayClone(arr) {
switch (arr.length) {
case 2:
return [arr[0], arr[1]];
case 3:
return [arr[0], arr[1], arr[2]];
case 4:
return [arr[0], arr[1], arr[2], arr[3]];
case 5:
return [arr[0], arr[1], arr[2], arr[3], arr[4]];
case 6:
return [arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]];
}
return arr.slice();
}
__name(arrayClone, "arrayClone");
function identicalSequenceRange(a, b) {
for (let i = 0; i < a.length - 3; i++) {
const pos = b.indexOf(a[i]);
if (pos !== -1) {
const rest = b.length - pos;
if (rest > 3) {
let len = 1;
const maxLen = Math.min(a.length - i, rest);
while (maxLen > len && a[i + len] === b[pos + len]) {
len++;
}
if (len > 3) {
return [len, i];
}
}
}
}
return [0, 0];
}
__name(identicalSequenceRange, "identicalSequenceRange");
function enhanceStackTrace(err, own) {
let ctorInfo = "";
try {
const { name } = this.constructor;
if (name !== "AsyncEventEmitter")
ctorInfo = ` on ${name} instance`;
} catch {
}
const sep = `
Emitted 'error' event${ctorInfo} at:
`;
const errStack = err.stack.split("\n").slice(1);
const ownStack = own.stack.split("\n").slice(1);
const { 0: len, 1: off } = identicalSequenceRange(ownStack, errStack);
if (len > 0) {
ownStack.splice(off + 1, len - 2, " [... lines matching original stack trace ...]");
}
return err.stack + sep + ownStack.join("\n");
}
__name(enhanceStackTrace, "enhanceStackTrace");
var _AsyncEventEmitter = class _AsyncEventEmitter {
constructor() {
this._events = {
__proto__: null
};
this._eventCount = 0;
this._maxListeners = 10;
this._internalPromiseMap = /* @__PURE__ */ new Map();
this._wrapperId = 0n;
}
addListener(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, false);
this._addListener(eventName, wrapped, false);
return this;
}
on(eventName, listener) {
return this.addListener(eventName, listener);
}
once(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, true);
this._addListener(eventName, wrapped, false);
return this;
}
removeListener(eventName, listener) {
validateListener(listener);
const events = this._events;
const eventList = events[eventName];
if (eventList === void 0) {
return this;
}
if (eventList === listener || eventList.listener === listener) {
if (--this._eventCount === 0) {
this._events = { __proto__: null };
} else {
delete events[eventName];
if (events.removeListener) {
this.emit("removeListener", eventName, eventList.listener ?? eventList);
}
}
} else if (typeof eventList !== "function") {
let position = -1;
for (let i = eventList.length - 1; i >= 0; i--) {
if (eventList[i] === listener || eventList[i].listener === listener) {
position = i;
break;
}
}
if (position < 0) {
return this;
}
if (position === 0) {
eventList.shift();
} else {
spliceOne(eventList, position);
}
if (eventList.length === 0) {
delete events[eventName];
--this._eventCount;
}
if (events.removeListener !== void 0) {
this.emit("removeListener", eventName, listener);
}
}
return this;
}
off(eventName, listener) {
return this.removeListener(eventName, listener);
}
removeAllListeners(event) {
const events = this._events;
if (events.removeListener === void 0) {
if (!event) {
this._events = { __proto__: null };
this._eventCount = 0;
} else if (events[event] !== void 0) {
if (--this._eventCount === 0) {
this._events = { __proto__: null };
} else {
delete events[event];
}
}
return this;
}
if (!event) {
for (const key of Reflect.ownKeys(events)) {
if (key === "removeListener") {
continue;
}
this.removeAllListeners(key);
}
this.removeAllListeners("removeListener");
this._events = { __proto__: null };
this._eventCount = 0;
return this;
}
const listeners = events[event];
if (typeof listeners === "function") {
this.removeListener(event, listeners);
} else if (listeners !== void 0) {
for (let i = listeners.length - 1; i >= 0; i--) {
this.removeListener(event, listeners[i]);
}
}
return this;
}
setMaxListeners(n) {
if (typeof n !== "number" || n < 0 || Number.isNaN(n)) {
throw new RangeError(`Expected to get a non-negative number for "setMaxListeners", got ${n} instead`);
}
this._maxListeners = n;
return this;
}
getMaxListeners() {
return this._maxListeners;
}
listeners(eventName) {
const eventList = this._events[eventName];
if (eventList === void 0) {
return [];
}
if (typeof eventList === "function") {
return [eventList.listener ?? eventList];
}
const ret = arrayClone(eventList);
for (let i = 0; i < ret.length; ++i) {
const orig = ret[i].listener;
if (typeof orig === "function") {
ret[i] = orig;
}
}
return ret;
}
rawListeners(eventName) {
const eventList = this._events[eventName];
if (eventList === void 0) {
return [];
}
if (typeof eventList === "function") {
return [eventList];
}
return arrayClone(eventList);
}
emit(eventName, ...args) {
let doError = eventName === "error";
const events = this._events;
if (events !== void 0) {
doError = doError && events.error === void 0;
} else if (!doError) {
return false;
}
if (doError) {
let er;
if (args.length > 0) {
er = args[0];
}
if (er instanceof Error) {
try {
const capture = {};
Error.captureStackTrace(capture, _AsyncEventEmitter.prototype.emit);
Object.defineProperty(er, "stack", {
value: enhanceStackTrace.call(this, er, capture),
configurable: true
});
} catch {
}
throw er; // Unhandled 'error' event
}
const stringifiedError = String(er);
const err = new Error(`Unhandled 'error' event emitted, received ${stringifiedError}`);
err.context = er;
throw err; // Unhandled 'error' event
}
const handlers = events[eventName];
if (handlers === void 0) {
return false;
}
if (typeof handlers === "function") {
const result = handlers.apply(this, args);
if (result !== void 0 && result !== null) {
handleMaybeAsync(this, result);
}
} else {
const len = handlers.length;
const listeners = arrayClone(handlers);
for (let i = 0; i < len; ++i) {
const result = listeners[i].apply(this, args);
if (result !== void 0 && result !== null) {
handleMaybeAsync(this, result);
}
}
}
return true;
}
listenerCount(eventName) {
const events = this._events;
if (events === void 0) {
return 0;
}
const eventListeners = events[eventName];
if (typeof eventListeners === "function") {
return 1;
}
return eventListeners?.length ?? 0;
}
prependListener(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, false);
this._addListener(eventName, wrapped, true);
return this;
}
prependOnceListener(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, true);
this._addListener(eventName, wrapped, true);
return this;
}
eventNames() {
return this._eventCount > 0 ? Reflect.ownKeys(this._events) : [];
}
async waitForAllListenersToComplete() {
const promises = [...this._internalPromiseMap.values()];
if (promises.length === 0) {
return false;
}
await Promise.all(promises);
return true;
}
_addListener(eventName, wrappedListener, prepend) {
if (this._events.newListener !== void 0) {
this.emit("newListener", eventName, wrappedListener.listener ?? wrappedListener);
}
let existing = this._events[eventName];
if (existing === void 0) {
existing = this._events[eventName] = wrappedListener;
++this._eventCount;
} else if (typeof existing === "function") {
existing = this._events[eventName] = prepend ? [wrappedListener, existing] : [existing, wrappedListener];
} else if (prepend) {
existing.unshift(wrappedListener);
} else {
existing.push(wrappedListener);
}
if (this._maxListeners > 0 && existing.length > this._maxListeners && !existing._hasWarnedAboutMaxListeners) {
existing._hasWarnedAboutMaxListeners = true;
const warningMessage = [
`Possible AsyncEventEmitter memory leak detected. ${existing.length} ${String(eventName)} listeners added to ${this.constructor.name}.`,
`Use emitter.setMaxListeners() to increase the limit.`
].join(" ");
console.warn(warningMessage);
}
}
_wrapListener(eventName, listener, once) {
if (!once) {
return listener;
}
const state = {
fired: false,
wrapFn: void 0,
eventEmitter: this,
eventName,
listener
};
const aliased = onceWrapper;
const wrapped = aliased.bind(state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
static listenerCount(emitter, eventName) {
return emitter.listenerCount(eventName);
}
static async once(emitter, eventName, options = {}) {
const signal = options?.signal;
validateAbortSignal(signal);
if (signal?.aborted) {
throw new AbortError(void 0, { cause: getReason(signal) });
}
return new Promise((resolve, reject) => {
const errorListener = /* @__PURE__ */ __name((err) => {
emitter.removeListener(eventName, resolver);
if (signal) {
eventTargetAgnosticRemoveListener(emitter, eventName, abortListener);
}
reject(err);
}, "errorListener");
const resolver = /* @__PURE__ */ __name((...args) => {
emitter.removeListener("error", errorListener);
if (signal) {
eventTargetAgnosticRemoveListener(signal, "abort", abortListener);
}
resolve(args);
}, "resolver");
emitter.once(eventName, resolver);
if (eventName !== "error") {
emitter.once("error", errorListener);
}
const abortListener = /* @__PURE__ */ __name(() => {
eventTargetAgnosticRemoveListener(emitter, eventName, resolver);
eventTargetAgnosticRemoveListener(emitter, "error", errorListener);
reject(new AbortError(void 0, { cause: getReason(signal) }));
}, "abortListener");
if (signal) {
eventTargetAgnosticAddListener(signal, "abort", abortListener, { once: true });
}
});
}
static on(emitter, eventName, options = {}) {
const signal = options?.signal;
validateAbortSignal(signal);
if (signal?.aborted) {
throw new AbortError(void 0, { cause: getReason(signal) });
}
const unconsumedEvents = [];
const unconsumedPromises = [];
let error = null;
let finished = false;
const abortListener = /* @__PURE__ */ __name(() => {
errorHandler(new AbortError(void 0, { cause: getReason(signal) }));
}, "abortListener");
const eventHandler = /* @__PURE__ */ __name((...args) => {
const promise = unconsumedPromises.shift();
if (promise) {
promise.resolve(createIterResult(args, false));
} else {
unconsumedEvents.push(args);
}
}, "eventHandler");
const errorHandler = /* @__PURE__ */ __name((err) => {
finished = true;
const toError = unconsumedPromises.shift();
if (toError) {
toError.reject(err);
} else {
error = err;
}
void iterator.return();
}, "errorHandler");
const iterator = Object.setPrototypeOf(
{
next() {
const value = unconsumedEvents.shift();
if (value) {
return Promise.resolve(createIterResult(value, false));
}
if (error) {
const p = Promise.reject(error);
error = null;
return p;
}
if (finished) {
return Promise.resolve(createIterResult(void 0, true));
}
return new Promise((resolve, reject) => {
unconsumedPromises.push({ resolve, reject });
});
},
return() {
emitter.off(eventName, eventHandler);
emitter.off("error", errorHandler);
if (signal) {
eventTargetAgnosticRemoveListener(signal, "abort", abortListener);
}
finished = true;
const doneResult = createIterResult(void 0, true);
for (const promise of unconsumedPromises) {
promise.resolve(doneResult);
}
return Promise.resolve(doneResult);
},
throw(err) {
if (!err || !(err instanceof Error)) {
throw new TypeError(`Expected Error instance to be thrown in AsyncEventEmitter.AsyncIterator. Got ${err}`);
}
error = err;
emitter.off(eventName, eventHandler);
emitter.off("error", errorHandler);
},
[Symbol.asyncIterator]() {
return this;
}
},
AsyncIteratorPrototype
);
emitter.on(eventName, eventHandler);
if (eventName !== "error") {
emitter.on("error", errorHandler);
}
if (signal) {
eventTargetAgnosticAddListener(signal, "abort", abortListener);
}
return iterator;
}
};
__name(_AsyncEventEmitter, "AsyncEventEmitter");
var AsyncEventEmitter = _AsyncEventEmitter;
function onceWrapper() {
if (!this.fired) {
this.eventEmitter.removeListener(this.eventName, this.wrapFn);
this.fired = true;
if (arguments.length === 0) {
return this.listener.call(this.eventEmitter);
}
return this.listener.apply(this.eventEmitter, arguments);
}
}
__name(onceWrapper, "onceWrapper");
function getReason(signal) {
return signal?.reason;
}
__name(getReason, "getReason");
function eventTargetAgnosticRemoveListener(emitter, name, listener, flags) {
if (typeof emitter.off === "function") {
emitter.off(name, listener);
} else if (typeof emitter.removeEventListener === "function") {
emitter.removeEventListener(name, listener, flags);
}
}
__name(eventTargetAgnosticRemoveListener, "eventTargetAgnosticRemoveListener");
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
if (typeof emitter.on === "function") {
if (flags?.once) {
emitter.once(name, listener);
} else {
emitter.on(name, listener);
}
} else if (typeof emitter.addEventListener === "function") {
emitter.addEventListener(name, listener, flags);
}
}
__name(eventTargetAgnosticAddListener, "eventTargetAgnosticAddListener");
var AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(async function* () {
}).prototype);
function createIterResult(value, done) {
return { value, done };
}
__name(createIterResult, "createIterResult");
var _AbortError = class _AbortError extends Error {
constructor(message = "The operation was aborted", options = void 0) {
if (options !== void 0 && typeof options !== "object") {
throw new TypeError(`Failed to create AbortError: options is not an object or undefined`);
}
super(message, options);
this.code = "ABORT_ERR";
this.name = "AbortError";
}
};
__name(_AbortError, "AbortError");
var AbortError = _AbortError;
function handleMaybeAsync(emitter, result) {
try {
const fin = result.finally;
if (typeof fin === "function") {
const promiseId = String(++emitter["_wrapperId"]);
emitter["_internalPromiseMap"].set(promiseId, result);
fin.call(result, /* @__PURE__ */ __name(function final() {
emitter["_internalPromiseMap"].delete(promiseId);
}, "final"));
}
} catch (err) {
emitter.emit("error", err);
}
}
__name(handleMaybeAsync, "handleMaybeAsync");
return __toCommonJS(src_exports);
})();
//# sourceMappingURL=index.global.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,549 @@
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
// src/index.ts
function validateListener(input) {
if (typeof input !== "function") {
throw new TypeError(`The listener argument must be a function. Received ${typeof input}`);
}
}
__name(validateListener, "validateListener");
function validateAbortSignal(input) {
if (input && !(input instanceof AbortSignal)) {
throw new TypeError(`The signal option must be an AbortSignal. Received ${input}`);
}
}
__name(validateAbortSignal, "validateAbortSignal");
function spliceOne(list, index) {
for (; index + 1 < list.length; index++) {
list[index] = list[index + 1];
}
list.pop();
}
__name(spliceOne, "spliceOne");
function arrayClone(arr) {
switch (arr.length) {
case 2:
return [arr[0], arr[1]];
case 3:
return [arr[0], arr[1], arr[2]];
case 4:
return [arr[0], arr[1], arr[2], arr[3]];
case 5:
return [arr[0], arr[1], arr[2], arr[3], arr[4]];
case 6:
return [arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]];
}
return arr.slice();
}
__name(arrayClone, "arrayClone");
function identicalSequenceRange(a, b) {
for (let i = 0; i < a.length - 3; i++) {
const pos = b.indexOf(a[i]);
if (pos !== -1) {
const rest = b.length - pos;
if (rest > 3) {
let len = 1;
const maxLen = Math.min(a.length - i, rest);
while (maxLen > len && a[i + len] === b[pos + len]) {
len++;
}
if (len > 3) {
return [len, i];
}
}
}
}
return [0, 0];
}
__name(identicalSequenceRange, "identicalSequenceRange");
function enhanceStackTrace(err, own) {
let ctorInfo = "";
try {
const { name } = this.constructor;
if (name !== "AsyncEventEmitter")
ctorInfo = ` on ${name} instance`;
} catch {
}
const sep = `
Emitted 'error' event${ctorInfo} at:
`;
const errStack = err.stack.split("\n").slice(1);
const ownStack = own.stack.split("\n").slice(1);
const { 0: len, 1: off } = identicalSequenceRange(ownStack, errStack);
if (len > 0) {
ownStack.splice(off + 1, len - 2, " [... lines matching original stack trace ...]");
}
return err.stack + sep + ownStack.join("\n");
}
__name(enhanceStackTrace, "enhanceStackTrace");
var _AsyncEventEmitter = class _AsyncEventEmitter {
constructor() {
this._events = {
__proto__: null
};
this._eventCount = 0;
this._maxListeners = 10;
this._internalPromiseMap = /* @__PURE__ */ new Map();
this._wrapperId = 0n;
}
addListener(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, false);
this._addListener(eventName, wrapped, false);
return this;
}
on(eventName, listener) {
return this.addListener(eventName, listener);
}
once(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, true);
this._addListener(eventName, wrapped, false);
return this;
}
removeListener(eventName, listener) {
validateListener(listener);
const events = this._events;
const eventList = events[eventName];
if (eventList === void 0) {
return this;
}
if (eventList === listener || eventList.listener === listener) {
if (--this._eventCount === 0) {
this._events = { __proto__: null };
} else {
delete events[eventName];
if (events.removeListener) {
this.emit("removeListener", eventName, eventList.listener ?? eventList);
}
}
} else if (typeof eventList !== "function") {
let position = -1;
for (let i = eventList.length - 1; i >= 0; i--) {
if (eventList[i] === listener || eventList[i].listener === listener) {
position = i;
break;
}
}
if (position < 0) {
return this;
}
if (position === 0) {
eventList.shift();
} else {
spliceOne(eventList, position);
}
if (eventList.length === 0) {
delete events[eventName];
--this._eventCount;
}
if (events.removeListener !== void 0) {
this.emit("removeListener", eventName, listener);
}
}
return this;
}
off(eventName, listener) {
return this.removeListener(eventName, listener);
}
removeAllListeners(event) {
const events = this._events;
if (events.removeListener === void 0) {
if (!event) {
this._events = { __proto__: null };
this._eventCount = 0;
} else if (events[event] !== void 0) {
if (--this._eventCount === 0) {
this._events = { __proto__: null };
} else {
delete events[event];
}
}
return this;
}
if (!event) {
for (const key of Reflect.ownKeys(events)) {
if (key === "removeListener") {
continue;
}
this.removeAllListeners(key);
}
this.removeAllListeners("removeListener");
this._events = { __proto__: null };
this._eventCount = 0;
return this;
}
const listeners = events[event];
if (typeof listeners === "function") {
this.removeListener(event, listeners);
} else if (listeners !== void 0) {
for (let i = listeners.length - 1; i >= 0; i--) {
this.removeListener(event, listeners[i]);
}
}
return this;
}
setMaxListeners(n) {
if (typeof n !== "number" || n < 0 || Number.isNaN(n)) {
throw new RangeError(`Expected to get a non-negative number for "setMaxListeners", got ${n} instead`);
}
this._maxListeners = n;
return this;
}
getMaxListeners() {
return this._maxListeners;
}
listeners(eventName) {
const eventList = this._events[eventName];
if (eventList === void 0) {
return [];
}
if (typeof eventList === "function") {
return [eventList.listener ?? eventList];
}
const ret = arrayClone(eventList);
for (let i = 0; i < ret.length; ++i) {
const orig = ret[i].listener;
if (typeof orig === "function") {
ret[i] = orig;
}
}
return ret;
}
rawListeners(eventName) {
const eventList = this._events[eventName];
if (eventList === void 0) {
return [];
}
if (typeof eventList === "function") {
return [eventList];
}
return arrayClone(eventList);
}
emit(eventName, ...args) {
let doError = eventName === "error";
const events = this._events;
if (events !== void 0) {
doError = doError && events.error === void 0;
} else if (!doError) {
return false;
}
if (doError) {
let er;
if (args.length > 0) {
er = args[0];
}
if (er instanceof Error) {
try {
const capture = {};
Error.captureStackTrace(capture, _AsyncEventEmitter.prototype.emit);
Object.defineProperty(er, "stack", {
value: enhanceStackTrace.call(this, er, capture),
configurable: true
});
} catch {
}
throw er; // Unhandled 'error' event
}
const stringifiedError = String(er);
const err = new Error(`Unhandled 'error' event emitted, received ${stringifiedError}`);
err.context = er;
throw err; // Unhandled 'error' event
}
const handlers = events[eventName];
if (handlers === void 0) {
return false;
}
if (typeof handlers === "function") {
const result = handlers.apply(this, args);
if (result !== void 0 && result !== null) {
handleMaybeAsync(this, result);
}
} else {
const len = handlers.length;
const listeners = arrayClone(handlers);
for (let i = 0; i < len; ++i) {
const result = listeners[i].apply(this, args);
if (result !== void 0 && result !== null) {
handleMaybeAsync(this, result);
}
}
}
return true;
}
listenerCount(eventName) {
const events = this._events;
if (events === void 0) {
return 0;
}
const eventListeners = events[eventName];
if (typeof eventListeners === "function") {
return 1;
}
return eventListeners?.length ?? 0;
}
prependListener(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, false);
this._addListener(eventName, wrapped, true);
return this;
}
prependOnceListener(eventName, listener) {
validateListener(listener);
const wrapped = this._wrapListener(eventName, listener, true);
this._addListener(eventName, wrapped, true);
return this;
}
eventNames() {
return this._eventCount > 0 ? Reflect.ownKeys(this._events) : [];
}
async waitForAllListenersToComplete() {
const promises = [...this._internalPromiseMap.values()];
if (promises.length === 0) {
return false;
}
await Promise.all(promises);
return true;
}
_addListener(eventName, wrappedListener, prepend) {
if (this._events.newListener !== void 0) {
this.emit("newListener", eventName, wrappedListener.listener ?? wrappedListener);
}
let existing = this._events[eventName];
if (existing === void 0) {
existing = this._events[eventName] = wrappedListener;
++this._eventCount;
} else if (typeof existing === "function") {
existing = this._events[eventName] = prepend ? [wrappedListener, existing] : [existing, wrappedListener];
} else if (prepend) {
existing.unshift(wrappedListener);
} else {
existing.push(wrappedListener);
}
if (this._maxListeners > 0 && existing.length > this._maxListeners && !existing._hasWarnedAboutMaxListeners) {
existing._hasWarnedAboutMaxListeners = true;
const warningMessage = [
`Possible AsyncEventEmitter memory leak detected. ${existing.length} ${String(eventName)} listeners added to ${this.constructor.name}.`,
`Use emitter.setMaxListeners() to increase the limit.`
].join(" ");
console.warn(warningMessage);
}
}
_wrapListener(eventName, listener, once) {
if (!once) {
return listener;
}
const state = {
fired: false,
wrapFn: void 0,
eventEmitter: this,
eventName,
listener
};
const aliased = onceWrapper;
const wrapped = aliased.bind(state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
static listenerCount(emitter, eventName) {
return emitter.listenerCount(eventName);
}
static async once(emitter, eventName, options = {}) {
const signal = options?.signal;
validateAbortSignal(signal);
if (signal?.aborted) {
throw new AbortError(void 0, { cause: getReason(signal) });
}
return new Promise((resolve, reject) => {
const errorListener = /* @__PURE__ */ __name((err) => {
emitter.removeListener(eventName, resolver);
if (signal) {
eventTargetAgnosticRemoveListener(emitter, eventName, abortListener);
}
reject(err);
}, "errorListener");
const resolver = /* @__PURE__ */ __name((...args) => {
emitter.removeListener("error", errorListener);
if (signal) {
eventTargetAgnosticRemoveListener(signal, "abort", abortListener);
}
resolve(args);
}, "resolver");
emitter.once(eventName, resolver);
if (eventName !== "error") {
emitter.once("error", errorListener);
}
const abortListener = /* @__PURE__ */ __name(() => {
eventTargetAgnosticRemoveListener(emitter, eventName, resolver);
eventTargetAgnosticRemoveListener(emitter, "error", errorListener);
reject(new AbortError(void 0, { cause: getReason(signal) }));
}, "abortListener");
if (signal) {
eventTargetAgnosticAddListener(signal, "abort", abortListener, { once: true });
}
});
}
static on(emitter, eventName, options = {}) {
const signal = options?.signal;
validateAbortSignal(signal);
if (signal?.aborted) {
throw new AbortError(void 0, { cause: getReason(signal) });
}
const unconsumedEvents = [];
const unconsumedPromises = [];
let error = null;
let finished = false;
const abortListener = /* @__PURE__ */ __name(() => {
errorHandler(new AbortError(void 0, { cause: getReason(signal) }));
}, "abortListener");
const eventHandler = /* @__PURE__ */ __name((...args) => {
const promise = unconsumedPromises.shift();
if (promise) {
promise.resolve(createIterResult(args, false));
} else {
unconsumedEvents.push(args);
}
}, "eventHandler");
const errorHandler = /* @__PURE__ */ __name((err) => {
finished = true;
const toError = unconsumedPromises.shift();
if (toError) {
toError.reject(err);
} else {
error = err;
}
void iterator.return();
}, "errorHandler");
const iterator = Object.setPrototypeOf(
{
next() {
const value = unconsumedEvents.shift();
if (value) {
return Promise.resolve(createIterResult(value, false));
}
if (error) {
const p = Promise.reject(error);
error = null;
return p;
}
if (finished) {
return Promise.resolve(createIterResult(void 0, true));
}
return new Promise((resolve, reject) => {
unconsumedPromises.push({ resolve, reject });
});
},
return() {
emitter.off(eventName, eventHandler);
emitter.off("error", errorHandler);
if (signal) {
eventTargetAgnosticRemoveListener(signal, "abort", abortListener);
}
finished = true;
const doneResult = createIterResult(void 0, true);
for (const promise of unconsumedPromises) {
promise.resolve(doneResult);
}
return Promise.resolve(doneResult);
},
throw(err) {
if (!err || !(err instanceof Error)) {
throw new TypeError(`Expected Error instance to be thrown in AsyncEventEmitter.AsyncIterator. Got ${err}`);
}
error = err;
emitter.off(eventName, eventHandler);
emitter.off("error", errorHandler);
},
[Symbol.asyncIterator]() {
return this;
}
},
AsyncIteratorPrototype
);
emitter.on(eventName, eventHandler);
if (eventName !== "error") {
emitter.on("error", errorHandler);
}
if (signal) {
eventTargetAgnosticAddListener(signal, "abort", abortListener);
}
return iterator;
}
};
__name(_AsyncEventEmitter, "AsyncEventEmitter");
var AsyncEventEmitter = _AsyncEventEmitter;
function onceWrapper() {
if (!this.fired) {
this.eventEmitter.removeListener(this.eventName, this.wrapFn);
this.fired = true;
if (arguments.length === 0) {
return this.listener.call(this.eventEmitter);
}
return this.listener.apply(this.eventEmitter, arguments);
}
}
__name(onceWrapper, "onceWrapper");
function getReason(signal) {
return signal?.reason;
}
__name(getReason, "getReason");
function eventTargetAgnosticRemoveListener(emitter, name, listener, flags) {
if (typeof emitter.off === "function") {
emitter.off(name, listener);
} else if (typeof emitter.removeEventListener === "function") {
emitter.removeEventListener(name, listener, flags);
}
}
__name(eventTargetAgnosticRemoveListener, "eventTargetAgnosticRemoveListener");
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
if (typeof emitter.on === "function") {
if (flags?.once) {
emitter.once(name, listener);
} else {
emitter.on(name, listener);
}
} else if (typeof emitter.addEventListener === "function") {
emitter.addEventListener(name, listener, flags);
}
}
__name(eventTargetAgnosticAddListener, "eventTargetAgnosticAddListener");
var AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(async function* () {
}).prototype);
function createIterResult(value, done) {
return { value, done };
}
__name(createIterResult, "createIterResult");
var _AbortError = class _AbortError extends Error {
constructor(message = "The operation was aborted", options = void 0) {
if (options !== void 0 && typeof options !== "object") {
throw new TypeError(`Failed to create AbortError: options is not an object or undefined`);
}
super(message, options);
this.code = "ABORT_ERR";
this.name = "AbortError";
}
};
__name(_AbortError, "AbortError");
var AbortError = _AbortError;
function handleMaybeAsync(emitter, result) {
try {
const fin = result.finally;
if (typeof fin === "function") {
const promiseId = String(++emitter["_wrapperId"]);
emitter["_internalPromiseMap"].set(promiseId, result);
fin.call(result, /* @__PURE__ */ __name(function final() {
emitter["_internalPromiseMap"].delete(promiseId);
}, "final"));
}
} catch (err) {
emitter.emit("error", err);
}
}
__name(handleMaybeAsync, "handleMaybeAsync");
export {
AbortError,
AsyncEventEmitter
};
//# sourceMappingURL=index.mjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,111 @@
{
"name": "@vladfrangu/async_event_emitter",
"version": "2.2.4",
"description": "An event emitter implementation with async support in mind",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"browser": "./dist/index.global.js",
"unpkg": "./dist/index.global.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
},
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/index.cjs"
},
"default": {
"types": "./dist/index.d.ts",
"default": "./dist/index.cjs"
}
}
},
"sideEffects": false,
"author": "Vlad Frangu <kingdgrizzle@gmail.com>",
"license": "MIT",
"scripts": {
"lint": "eslint src tests --ext ts --fix",
"format": "prettier --write \"{src,tests}/**/*.ts\"",
"docs": "typedoc",
"test": "vitest run",
"test:watch": "vitest",
"update": "yarn upgrade-interactive",
"build": "tsc -p src --noEmit && tsup && node ./scripts/postbuild.mjs",
"clean": "node scripts/clean.mjs",
"typecheck": "tsc -p src --noEmit",
"bump": "cliff-jumper",
"check-update": "cliff-jumper --dry-run"
},
"devDependencies": {
"@commitlint/cli": "^18.4.3",
"@commitlint/config-conventional": "^18.4.3",
"@favware/cliff-jumper": "^2.2.3",
"@favware/npm-deprecate": "^1.0.7",
"@sapphire/eslint-config": "^5.0.2",
"@sapphire/prettier-config": "^2.0.0",
"@sapphire/ts-config": "^5.0.0",
"@typescript-eslint/eslint-plugin": "^6.13.1",
"@typescript-eslint/parser": "^6.13.1",
"@vitest/coverage-c8": "^0.33.0",
"@vitest/coverage-v8": "^0.34.6",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.55.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.0.1",
"lint-staged": "^15.1.0",
"prettier": "^3.1.0",
"tsup": "^8.0.1",
"typedoc": "^0.25.4",
"typedoc-plugin-mdn-links": "^3.1.6",
"typescript": "^5.3.2",
"vitest": "^0.34.6"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vladfrangu/async_event_emitter.git"
},
"files": [
"dist",
"!dist/*.tsbuildinfo",
"THIRD_PARTY_LICENSE.md"
],
"engines": {
"node": ">=v14.0.0",
"npm": ">=7.0.0"
},
"keywords": [
"event emitter",
"async",
"event",
"emitter"
],
"bugs": {
"url": "https://github.com/vladfrangu/async_event_emitter/issues"
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"lint-staged": {
"*": "prettier --ignore-unknown --write",
"*.{mjs,js,ts}": "eslint --fix --ext mjs,js,ts"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
"publishConfig": {
"access": "public"
},
"prettier": "@sapphire/prettier-config",
"resolutions": {
"ansi-regex": "^5.0.1",
"minimist": "^1.2.6"
},
"packageManager": "yarn@4.0.2"
}