summaryrefslogtreecommitdiff
path: root/std/node/events.ts
diff options
context:
space:
mode:
authorGuy Bedford <guybedford@gmail.com>2020-11-09 06:25:13 -0800
committerGitHub <noreply@github.com>2020-11-09 09:25:13 -0500
commit8b7f5531ee1ccde897e87890e9aabc554fedb9dd (patch)
tree117a85b98d1488c290d8acc392cfb99b1b21f8e0 /std/node/events.ts
parent293cae5e1ff2a5768e2f3a73cc18f99acc3fbfbd (diff)
feat(std/node): consistent Node.js builtin shapes (#8274)
Diffstat (limited to 'std/node/events.ts')
-rw-r--r--std/node/events.ts316
1 files changed, 164 insertions, 152 deletions
diff --git a/std/node/events.ts b/std/node/events.ts
index 568393f7f..16790907e 100644
--- a/std/node/events.ts
+++ b/std/node/events.ts
@@ -31,12 +31,36 @@ export interface WrappedFunction extends Function {
listener: GenericFunction;
}
+// deno-lint-ignore no-explicit-any
+function createIterResult(value: any, done: boolean): IteratorResult<any> {
+ return { value, done };
+}
+
+interface AsyncIterable {
+ // deno-lint-ignore no-explicit-any
+ next(): Promise<IteratorResult<any, any>>;
+ // deno-lint-ignore no-explicit-any
+ return(): Promise<IteratorResult<any, any>>;
+ throw(err: Error): void;
+ // deno-lint-ignore no-explicit-any
+ [Symbol.asyncIterator](): any;
+}
+
+export let defaultMaxListeners = 10;
+
/**
* See also https://nodejs.org/api/events.html
*/
export default class EventEmitter {
- public static defaultMaxListeners = 10;
+ public static captureRejectionSymbol = Symbol.for("nodejs.rejection");
public static errorMonitor = Symbol("events.errorMonitor");
+ public static get defaultMaxListeners() {
+ return defaultMaxListeners;
+ }
+ public static set defaultMaxListeners(value: number) {
+ defaultMaxListeners = value;
+ }
+
private maxListeners: number | undefined;
private _events: Map<
string | symbol,
@@ -367,180 +391,168 @@ export default class EventEmitter {
this.maxListeners = n;
return this;
}
-}
-export { EventEmitter };
-
-/**
- * Creates a Promise that is fulfilled when the EventEmitter emits the given
- * event or that is rejected when the EventEmitter emits 'error'. The Promise
- * will resolve with an array of all the arguments emitted to the given event.
- */
-export function once(
- emitter: EventEmitter | EventTarget,
- name: string,
- // deno-lint-ignore no-explicit-any
-): Promise<any[]> {
- return new Promise((resolve, reject) => {
- if (emitter instanceof EventTarget) {
- // EventTarget does not have `error` event semantics like Node
- // EventEmitters, we do not listen to `error` events here.
- emitter.addEventListener(
- name,
- (...args) => {
- resolve(args);
- },
- { once: true, passive: false, capture: false },
- );
- return;
- } else if (emitter instanceof EventEmitter) {
- // deno-lint-ignore no-explicit-any
- const eventListener = (...args: any[]): void => {
- if (errorListener !== undefined) {
- emitter.removeListener("error", errorListener);
- }
- resolve(args);
- };
- let errorListener: GenericFunction;
-
- // Adding an error listener is not optional because
- // if an error is thrown on an event emitter we cannot
- // guarantee that the actual event we are waiting will
- // be fired. The result could be a silent way to create
- // memory or file descriptor leaks, which is something
- // we should avoid.
- if (name !== "error") {
+ /**
+ * Creates a Promise that is fulfilled when the EventEmitter emits the given
+ * event or that is rejected when the EventEmitter emits 'error'. The Promise
+ * will resolve with an array of all the arguments emitted to the given event.
+ */
+ public static once(
+ emitter: EventEmitter | EventTarget,
+ name: string,
+ // deno-lint-ignore no-explicit-any
+ ): Promise<any[]> {
+ return new Promise((resolve, reject) => {
+ if (emitter instanceof EventTarget) {
+ // EventTarget does not have `error` event semantics like Node
+ // EventEmitters, we do not listen to `error` events here.
+ emitter.addEventListener(
+ name,
+ (...args) => {
+ resolve(args);
+ },
+ { once: true, passive: false, capture: false },
+ );
+ return;
+ } else if (emitter instanceof EventEmitter) {
// deno-lint-ignore no-explicit-any
- errorListener = (err: any): void => {
- emitter.removeListener(name, eventListener);
- reject(err);
+ const eventListener = (...args: any[]): void => {
+ if (errorListener !== undefined) {
+ emitter.removeListener("error", errorListener);
+ }
+ resolve(args);
};
+ let errorListener: GenericFunction;
+
+ // Adding an error listener is not optional because
+ // if an error is thrown on an event emitter we cannot
+ // guarantee that the actual event we are waiting will
+ // be fired. The result could be a silent way to create
+ // memory or file descriptor leaks, which is something
+ // we should avoid.
+ if (name !== "error") {
+ // deno-lint-ignore no-explicit-any
+ errorListener = (err: any): void => {
+ emitter.removeListener(name, eventListener);
+ reject(err);
+ };
+
+ emitter.once("error", errorListener);
+ }
- emitter.once("error", errorListener);
+ emitter.once(name, eventListener);
+ return;
}
+ });
+ }
- emitter.once(name, eventListener);
- return;
- }
- });
-}
+ /**
+ * Returns an AsyncIterator that iterates eventName events. It will throw if
+ * the EventEmitter emits 'error'. It removes all listeners when exiting the
+ * loop. The value returned by each iteration is an array composed of the
+ * emitted event arguments.
+ */
+ public static on(
+ emitter: EventEmitter,
+ event: string | symbol,
+ ): AsyncIterable {
+ // deno-lint-ignore no-explicit-any
+ const unconsumedEventValues: any[] = [];
+ // deno-lint-ignore no-explicit-any
+ const unconsumedPromises: any[] = [];
+ let error: Error | null = null;
+ let finished = false;
-// deno-lint-ignore no-explicit-any
-function createIterResult(value: any, done: boolean): IteratorResult<any> {
- return { value, done };
-}
+ const iterator = {
+ // deno-lint-ignore no-explicit-any
+ next(): Promise<IteratorResult<any>> {
+ // First, we consume all unread events
+ // deno-lint-ignore no-explicit-any
+ const value: any = unconsumedEventValues.shift();
+ if (value) {
+ return Promise.resolve(createIterResult(value, false));
+ }
-interface AsyncInterable {
- // deno-lint-ignore no-explicit-any
- next(): Promise<IteratorResult<any, any>>;
- // deno-lint-ignore no-explicit-any
- return(): Promise<IteratorResult<any, any>>;
- throw(err: Error): void;
- // deno-lint-ignore no-explicit-any
- [Symbol.asyncIterator](): any;
-}
+ // Then we error, if an error happened
+ // This happens one time if at all, because after 'error'
+ // we stop listening
+ if (error) {
+ const p: Promise<never> = Promise.reject(error);
+ // Only the first element errors
+ error = null;
+ return p;
+ }
-/**
- * Returns an AsyncIterator that iterates eventName events. It will throw if
- * the EventEmitter emits 'error'. It removes all listeners when exiting the
- * loop. The value returned by each iteration is an array composed of the
- * emitted event arguments.
- */
-export function on(
- emitter: EventEmitter,
- event: string | symbol,
-): AsyncInterable {
- // deno-lint-ignore no-explicit-any
- const unconsumedEventValues: any[] = [];
- // deno-lint-ignore no-explicit-any
- const unconsumedPromises: any[] = [];
- let error: Error | null = null;
- let finished = false;
+ // If the iterator is finished, resolve to done
+ if (finished) {
+ return Promise.resolve(createIterResult(undefined, true));
+ }
+
+ // Wait until an event happens
+ return new Promise(function (resolve, reject) {
+ unconsumedPromises.push({ resolve, reject });
+ });
+ },
- const iterator = {
- // deno-lint-ignore no-explicit-any
- next(): Promise<IteratorResult<any>> {
- // First, we consume all unread events
// deno-lint-ignore no-explicit-any
- const value: any = unconsumedEventValues.shift();
- if (value) {
- return Promise.resolve(createIterResult(value, false));
- }
+ return(): Promise<IteratorResult<any>> {
+ emitter.removeListener(event, eventHandler);
+ emitter.removeListener("error", errorHandler);
+ finished = true;
- // Then we error, if an error happened
- // This happens one time if at all, because after 'error'
- // we stop listening
- if (error) {
- const p: Promise<never> = Promise.reject(error);
- // Only the first element errors
- error = null;
- return p;
- }
+ for (const promise of unconsumedPromises) {
+ promise.resolve(createIterResult(undefined, true));
+ }
- // If the iterator is finished, resolve to done
- if (finished) {
return Promise.resolve(createIterResult(undefined, true));
- }
-
- // Wait until an event happens
- return new Promise(function (resolve, reject) {
- unconsumedPromises.push({ resolve, reject });
- });
- },
+ },
- // deno-lint-ignore no-explicit-any
- return(): Promise<IteratorResult<any>> {
- emitter.removeListener(event, eventHandler);
- emitter.removeListener("error", errorHandler);
- finished = true;
+ throw(err: Error): void {
+ error = err;
+ emitter.removeListener(event, eventHandler);
+ emitter.removeListener("error", errorHandler);
+ },
- for (const promise of unconsumedPromises) {
- promise.resolve(createIterResult(undefined, true));
- }
+ // deno-lint-ignore no-explicit-any
+ [Symbol.asyncIterator](): any {
+ return this;
+ },
+ };
- return Promise.resolve(createIterResult(undefined, true));
- },
+ emitter.on(event, eventHandler);
+ emitter.on("error", errorHandler);
- throw(err: Error): void {
- error = err;
- emitter.removeListener(event, eventHandler);
- emitter.removeListener("error", errorHandler);
- },
+ return iterator;
// deno-lint-ignore no-explicit-any
- [Symbol.asyncIterator](): any {
- return this;
- },
- };
-
- emitter.on(event, eventHandler);
- emitter.on("error", errorHandler);
-
- return iterator;
-
- // deno-lint-ignore no-explicit-any
- function eventHandler(...args: any[]): void {
- const promise = unconsumedPromises.shift();
- if (promise) {
- promise.resolve(createIterResult(args, false));
- } else {
- unconsumedEventValues.push(args);
+ function eventHandler(...args: any[]): void {
+ const promise = unconsumedPromises.shift();
+ if (promise) {
+ promise.resolve(createIterResult(args, false));
+ } else {
+ unconsumedEventValues.push(args);
+ }
}
- }
- // deno-lint-ignore no-explicit-any
- function errorHandler(err: any): void {
- finished = true;
+ // deno-lint-ignore no-explicit-any
+ function errorHandler(err: any): void {
+ finished = true;
- const toError = unconsumedPromises.shift();
- if (toError) {
- toError.reject(err);
- } else {
- // The next time we call next()
- error = err;
- }
+ const toError = unconsumedPromises.shift();
+ if (toError) {
+ toError.reject(err);
+ } else {
+ // The next time we call next()
+ error = err;
+ }
- iterator.return();
+ iterator.return();
+ }
}
}
-export const captureRejectionSymbol = Symbol.for("nodejs.rejection");
+
+export { EventEmitter };
+export const once = EventEmitter.once;
+export const on = EventEmitter.on;
+export const captureRejectionSymbol = EventEmitter.captureRejectionSymbol;
+export const errorMonitor = EventEmitter.errorMonitor;