mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
chore: extract event-emitter from core
Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
1 parent
09aab1b45c
commit
1c23162b58
16 files changed
+134
-31
No files matched your search
@@ -0,0 +1,115 @@
|
||||
import { EventEmitter } from "./event-emitter";
|
||||
|
||||
describe("EventEmitter", () => {
|
||||
it("should stop early if a listener returns false", () => {
|
||||
let called = false;
|
||||
const e = new EventEmitter<[]>();
|
||||
|
||||
e.addListener(() => false, {});
|
||||
e.addListener(() => {
|
||||
called = true;
|
||||
}, {});
|
||||
e.emit();
|
||||
|
||||
expect(called).toBe(false);
|
||||
});
|
||||
|
||||
it("shouldn't stop early if a listener returns 0", () => {
|
||||
let called = false;
|
||||
const e = new EventEmitter<[]>();
|
||||
|
||||
e.addListener(() => 0 as never, {});
|
||||
e.addListener(() => {
|
||||
called = true;
|
||||
}, {});
|
||||
e.emit();
|
||||
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
|
||||
it("prepended listeners should be called before others", () => {
|
||||
const callOrder: number[] = [];
|
||||
const e = new EventEmitter<[]>();
|
||||
|
||||
e.addListener(() => {
|
||||
callOrder.push(1);
|
||||
}, {});
|
||||
e.addListener(() => {
|
||||
callOrder.push(2);
|
||||
}, {});
|
||||
e.addListener(
|
||||
() => {
|
||||
callOrder.push(3);
|
||||
},
|
||||
{ prepend: true },
|
||||
);
|
||||
e.emit();
|
||||
|
||||
expect(callOrder).toStrictEqual([3, 1, 2]);
|
||||
});
|
||||
|
||||
it("once listeners should be called only once", () => {
|
||||
const callOrder: number[] = [];
|
||||
const e = new EventEmitter<[]>();
|
||||
|
||||
e.addListener(() => {
|
||||
callOrder.push(1);
|
||||
}, {});
|
||||
e.addListener(() => {
|
||||
callOrder.push(2);
|
||||
}, {});
|
||||
e.addListener(
|
||||
() => {
|
||||
callOrder.push(3);
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
e.emit();
|
||||
e.emit();
|
||||
|
||||
expect(callOrder).toStrictEqual([1, 2, 3, 1, 2]);
|
||||
});
|
||||
|
||||
it("removeListener should stop the listener from being called", () => {
|
||||
const callOrder: number[] = [];
|
||||
const e = new EventEmitter<[]>();
|
||||
const r = () => {
|
||||
callOrder.push(3);
|
||||
};
|
||||
|
||||
e.addListener(() => {
|
||||
callOrder.push(1);
|
||||
}, {});
|
||||
e.addListener(() => {
|
||||
callOrder.push(2);
|
||||
}, {});
|
||||
e.addListener(r);
|
||||
|
||||
e.emit();
|
||||
e.removeListener(r);
|
||||
e.emit();
|
||||
|
||||
expect(callOrder).toStrictEqual([1, 2, 3, 1, 2]);
|
||||
});
|
||||
|
||||
it("removeAllListeners should stop the all listeners from being called", () => {
|
||||
const callOrder: number[] = [];
|
||||
const e = new EventEmitter<[]>();
|
||||
|
||||
e.addListener(() => {
|
||||
callOrder.push(1);
|
||||
});
|
||||
e.addListener(() => {
|
||||
callOrder.push(2);
|
||||
});
|
||||
e.addListener(() => {
|
||||
callOrder.push(3);
|
||||
});
|
||||
|
||||
e.emit();
|
||||
e.removeAllListeners();
|
||||
e.emit();
|
||||
|
||||
expect(callOrder).toStrictEqual([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
export interface EventEmitterOptions {
|
||||
once?: boolean; // call once and remove
|
||||
prepend?: boolean; // put listener to the beginning
|
||||
}
|
||||
|
||||
export type EventEmitterCallback<D extends any[]> = (...data: D) => void | boolean;
|
||||
|
||||
export class EventEmitter<D extends any[]> {
|
||||
protected listeners: [EventEmitterCallback<D>, EventEmitterOptions][] = [];
|
||||
|
||||
addListener(callback: EventEmitterCallback<D>, options: EventEmitterOptions = {}) {
|
||||
const fn = options.prepend ? "unshift" : "push";
|
||||
|
||||
this.listeners[fn]([callback, options]);
|
||||
}
|
||||
|
||||
removeListener(callback: EventEmitterCallback<D>) {
|
||||
this.listeners = this.listeners.filter(([cb]) => cb !== callback);
|
||||
}
|
||||
|
||||
removeAllListeners() {
|
||||
this.listeners.length = 0;
|
||||
}
|
||||
|
||||
emit(...data: D) {
|
||||
for (const [callback, { once }] of this.listeners) {
|
||||
if (once) {
|
||||
this.removeListener(callback);
|
||||
}
|
||||
|
||||
if (callback(...data) === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user