hfs
Version:
HTTP File Server
100 lines (99 loc) • 3.53 kB
JavaScript
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
Object.defineProperty(exports, "__esModule", { value: true });
exports.BetterEventEmitter = void 0;
const LISTENERS_SUFFIX = '\0listeners';
class BetterEventEmitter {
constructor() {
this.listeners = new Map();
this.preventDefault = Symbol();
this.stop = this.preventDefault; // legacy pre-0.54 (introduced in 0.53)
}
on(event, listener, { warnAfter = 10, callNow = false } = {}) {
if (typeof event === 'string')
event = [event];
for (const e of event) {
let cbs = this.listeners.get(e);
if (!cbs)
this.listeners.set(e, cbs = new Set());
cbs.add(listener);
if (cbs.size > warnAfter)
console.warn("Warning: many event listeners for ", e);
this.emit(e + LISTENERS_SUFFIX, cbs, listener);
}
if (callNow)
try {
listener();
}
catch (_a) { }
return () => {
for (const e of event) {
const cbs = this.listeners.get(e);
if (!cbs)
continue;
cbs.delete(listener);
this.emit(e + LISTENERS_SUFFIX, cbs);
}
};
}
// call me when listeners for event have changed
onListeners(event, listener) {
return this.on(event + LISTENERS_SUFFIX, listener);
}
once(event, listener) {
let off;
const pro = new Promise(resolve => {
off = this.on(event, function (...args) {
off();
resolve(args.slice(0, -1)); // remove the extra argument at the end of our emit()
return listener === null || listener === void 0 ? void 0 : listener(...args);
});
});
return Object.assign(off, { then: pro.then.bind(pro) });
}
multi(map) {
const cbs = Object.entries(map).map(([name, cb]) => this.on(name.split(' '), cb));
return () => {
for (const cb of cbs)
cb();
};
}
anyListener(event) {
var _a;
return Boolean((_a = this.listeners.get(event)) === null || _a === void 0 ? void 0 : _a.size);
}
emit(event, ...args) {
let cbs = this.listeners.get(event);
if (!(cbs === null || cbs === void 0 ? void 0 : cbs.size))
return;
const output = [];
let prevented = false;
const extra = {
output,
preventDefault() { prevented = true; }
};
for (const cb of cbs) {
const res = cb(...args, extra);
if (res === this.preventDefault)
extra.preventDefault();
else if (res !== undefined)
output.push(res);
}
return Object.assign(output, {
isDefaultPrevented: () => prevented,
});
}
async emitAsync(event, ...args) {
const syncRet = this.emit(event, ...args);
if (!syncRet)
return;
const asyncRet = await Promise.all(syncRet);
return Object.assign(asyncRet, {
isDefaultPrevented: () => syncRet.isDefaultPrevented()
|| asyncRet.some((r) => r === this.preventDefault)
});
}
}
exports.BetterEventEmitter = BetterEventEmitter;
// app-wide events
exports.default = new BetterEventEmitter;
;