await-event-emitter
Version:
Await events library like EventEmitter
148 lines (147 loc) • 5 kB
JavaScript
"use strict";
/**
* Await events library like EventEmitter
* @author imcuttle
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const isPromise = require('is-promise');
const TYPE_KEY_NAME = typeof Symbol === 'function' ? Symbol.for('--[[await-event-emitter]]--') : '--[[await-event-emitter]]--';
function assertType(type) {
if (typeof type !== 'string' && typeof type !== 'symbol') {
throw new TypeError('type is not type of string or symbol!');
}
}
function assertFn(fn) {
if (typeof fn !== 'function') {
throw new TypeError('fn is not type of Function!');
}
}
function alwaysListener(fn) {
return {
[TYPE_KEY_NAME]: 'always',
fn
};
}
function onceListener(fn) {
return {
[TYPE_KEY_NAME]: 'once',
fn
};
}
class AwaitEventEmitter {
constructor() {
this._events = {};
}
addListener(type, fn) {
return this.on(type, fn);
}
on(type, fn) {
assertType(type);
assertFn(fn);
this._events[type] = this._events[type] || [];
this._events[type].push(alwaysListener(fn));
return this;
}
prependListener(type, fn) {
return this.prepend(type, fn);
}
prepend(type, fn) {
assertType(type);
assertFn(fn);
this._events[type] = this._events[type] || [];
this._events[type].unshift(alwaysListener(fn));
return this;
}
prependOnceListener(type, fn) {
return this.prependOnce(type, fn);
}
prependOnce(type, fn) {
assertType(type);
assertFn(fn);
this._events[type] = this._events[type] || [];
this._events[type].unshift(onceListener(fn));
return this;
}
listeners(type) {
return (this._events[type] || []).map((x) => x.fn);
}
once(type, fn) {
assertType(type);
assertFn(fn);
this._events[type] = this._events[type] || [];
this._events[type].push(onceListener(fn));
return this;
}
removeAllListeners() {
this._events = {};
}
off(type, nullOrFn) {
return this.removeListener(type, nullOrFn);
}
removeListener(type, nullOrFn) {
assertType(type);
const listeners = this.listeners(type);
if (typeof nullOrFn === 'function') {
let index = -1;
let found = false;
while ((index = listeners.indexOf(nullOrFn)) >= 0) {
listeners.splice(index, 1);
this._events[type].splice(index, 1);
found = true;
}
return found;
}
else {
return delete this._events[type];
}
}
emit(type, ...args) {
return __awaiter(this, void 0, void 0, function* () {
assertType(type);
const listeners = this.listeners(type);
const onceListeners = [];
if (listeners && listeners.length) {
for (let i = 0; i < listeners.length; i++) {
const event = listeners[i];
const rlt = event.apply(this, args);
if (isPromise(rlt)) {
yield rlt;
}
if (this._events[type] && this._events[type][i] && this._events[type][i][TYPE_KEY_NAME] === 'once') {
onceListeners.push(event);
}
}
onceListeners.forEach((event) => this.removeListener(type, event));
return true;
}
return false;
});
}
emitSync(type, ...args) {
assertType(type);
const listeners = this.listeners(type);
const onceListeners = [];
if (listeners && listeners.length) {
for (let i = 0; i < listeners.length; i++) {
const event = listeners[i];
event.apply(this, args);
if (this._events[type] && this._events[type][i] && this._events[type][i][TYPE_KEY_NAME] === 'once') {
onceListeners.push(event);
}
}
onceListeners.forEach((event) => this.removeListener(type, event));
return true;
}
return false;
}
}
exports.default = AwaitEventEmitter;