configcat-common
Version:
ConfigCat is a configuration as a service that lets you manage your features and configurations without actually deploying new code.
191 lines (190 loc) • 6.91 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultEventEmitter = void 0;
function isSingle(listeners) {
return !!listeners.fn;
}
// NOTE: It's better to place this class into a separate module so
// it can be omitted from the final bundle in case we choose to
// make the common library EventEmitter implementation-agnostic in the future.
/** A platform-independent implementation of `IEventEmitter`. */
var DefaultEventEmitter = /** @class */ (function () {
function DefaultEventEmitter() {
this.events = {};
this.eventCount = 0;
this.addListener = this.on;
this.off = this.removeListener;
}
DefaultEventEmitter.prototype.addListenerCore = function (eventName, fn, once) {
if (typeof fn !== "function") {
throw new TypeError("Listener must be a function");
}
// TODO: remove `as string` when updating to TypeScript 4.4 or newer (https://stackoverflow.com/a/64943542/8656352)
var listeners = this.events[eventName];
var listener = { fn: fn, once: once };
if (!listeners) {
this.events[eventName] = listener;
this.eventCount++;
}
else if (isSingle(listeners)) {
this.events[eventName] = [listeners, listener];
}
else {
listeners.push(listener);
}
return this;
};
DefaultEventEmitter.prototype.removeListenerCore = function (eventName, state, isMatch) {
var listeners = this.events[eventName];
if (!listeners) {
return this;
}
if (!isSingle(listeners)) {
for (var i = listeners.length - 1; i >= 0; i--) {
if (isMatch(listeners[i], state)) {
listeners.splice(i, 1);
if (!listeners.length) {
this.removeEvent(eventName);
}
else if (listeners.length === 1) {
this.events[eventName] = listeners[0];
}
break;
}
}
}
else if (isMatch(listeners, state)) {
this.removeEvent(eventName);
}
return this;
};
DefaultEventEmitter.prototype.removeEvent = function (eventName) {
if (--this.eventCount === 0) {
this.events = {};
}
else {
delete this.events[eventName];
}
};
DefaultEventEmitter.prototype.on = function (eventName, listener) {
return this.addListenerCore(eventName, listener, false);
};
DefaultEventEmitter.prototype.once = function (eventName, listener) {
return this.addListenerCore(eventName, listener, true);
};
DefaultEventEmitter.prototype.removeListener = function (eventName, listener) {
if (typeof listener !== "function") {
throw new TypeError("Listener must be a function");
}
return this.removeListenerCore(eventName, listener, function (listener, fn) { return listener.fn === fn; });
};
DefaultEventEmitter.prototype.removeAllListeners = function (eventName) {
if (!eventName) {
this.events = {};
this.eventCount = 0;
}
else if (this.events[eventName]) {
this.removeEvent(eventName);
}
return this;
};
DefaultEventEmitter.prototype.listeners = function (eventName) {
var listeners = this.events[eventName];
if (!listeners) {
return [];
}
if (isSingle(listeners)) {
return [listeners.fn];
}
var length = listeners.length, fns = new Array(length);
for (var i = 0; i < length; i++) {
fns[i] = listeners[i].fn;
}
return fns;
};
DefaultEventEmitter.prototype.listenerCount = function (eventName) {
var listeners = this.events[eventName];
if (!listeners) {
return 0;
}
if (isSingle(listeners)) {
return 1;
}
return listeners.length;
};
DefaultEventEmitter.prototype.eventNames = function () {
var names = [];
if (this.eventCount === 0) {
return names;
}
var events = this.events;
for (var name in events) {
if (Object.prototype.hasOwnProperty.call(events, name)) {
names.push(name);
}
}
if (Object.getOwnPropertySymbols) {
return names.concat(Object.getOwnPropertySymbols(events));
}
return names;
};
DefaultEventEmitter.prototype.emit = function (eventName, arg0, arg1, arg2, arg3) {
var _a, _b;
var moreArgs = [];
for (var _i = 5; _i < arguments.length; _i++) {
moreArgs[_i - 5] = arguments[_i];
}
var listeners = this.events[eventName];
if (!listeners) {
return false;
}
var listener, length;
if (isSingle(listeners)) {
_a = [listeners, 1], listener = _a[0], length = _a[1];
}
else {
// According to the specification, potential removes during emit should not change the list of notified listeners,
// so we need to create a local copy of the current listeners.
listeners = listeners.slice();
_b = [listeners[0], listeners.length], listener = _b[0], length = _b[1];
}
var argCount = arguments.length - 1;
for (var i = 0;;) {
if (listener.once) {
this.removeListenerCore(eventName, listener, function (listener, toRemove) { return listener === toRemove; });
}
switch (argCount) {
case 0:
listener.fn.call(this);
break;
case 1:
listener.fn.call(this, arg0);
break;
case 2:
listener.fn.call(this, arg0, arg1);
break;
case 3:
listener.fn.call(this, arg0, arg1, arg2);
break;
case 4:
listener.fn.call(this, arg0, arg1, arg2, arg3);
break;
default:
var args = new Array(argCount);
for (var j = 0; j < argCount; j++) {
// eslint-disable-next-line prefer-rest-params
args[j] = arguments[j + 1];
}
listener.fn.apply(this, args);
break;
}
if (++i >= length) {
break;
}
listener = listeners[i];
}
return true;
};
return DefaultEventEmitter;
}());
exports.DefaultEventEmitter = DefaultEventEmitter;