Skip to content

Commit

Permalink
refactor(remitter): replace count with has
Browse files Browse the repository at this point in the history
  • Loading branch information
crimx committed Aug 23, 2023
1 parent c620b74 commit 16ba81d
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 17 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ remitter.once("event1", value => {
console.log("event1-once", value);
});

remitter.count("event1"); // 2
remitter.has("event1"); // true

remitter.emit("event1", "hello"); // logs "event1 hello" and "event1-once hello"

Expand All @@ -54,7 +54,8 @@ disposer();
remitter.emit("event1", "world"); // nothing logs

remitter.clear("event2"); // remove all listeners for event2
remitter.count(); // 0

remitter.has(); // false

remitter.dispose(); // removes all listeners and dispose tapped events
```
Expand Down
17 changes: 8 additions & 9 deletions src/relay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ export const tryStartAllRelay = (
Sugar for
```
listener.eventName_ === ANY_EVENT
? remitter.count() > 0
: remitter.count(listener.eventName_) > 0 ||
remitter.count(ANY_EVENT) > 0
? remitter.has()
: remitter.has(listener.eventName_) ||
remitter.has(ANY_EVENT)
```
`tryStartAll_` will always be called when remitter.count() > 0
`tryStartAll_` will always be called when remitter.has() is `true`
*/
listener.eventName_ === ANY_EVENT ||
remitter.count(listener.eventName_) > 0 ||
remitter.count(ANY_EVENT) > 0
remitter.has(listener.eventName_) ||
remitter.has(ANY_EVENT)
) {
startRelay(listener, remitter);
}
Expand All @@ -55,9 +55,8 @@ export const tryStopAllRelay = (
if (listener.disposer_) {
if (
listener.eventName_ === ANY_EVENT
? remitter.count() <= 0
: remitter.count(ANY_EVENT) <= 0 &&
remitter.count(listener.eventName_) <= 0
? !remitter.has()
: !remitter.has(ANY_EVENT) && !remitter.has(listener.eventName_)
) {
stopRelay(listener);
}
Expand Down
31 changes: 26 additions & 5 deletions src/remitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class ReadonlyRemitter<TConfig = any> {
tryCall(listener, data as RemitterConfig<TConfig>[TEventName]);
}
}
if (event !== ANY_EVENT && this.count(ANY_EVENT)) {
if (event !== ANY_EVENT && this.has(ANY_EVENT)) {
(this as ReadonlyRemitter<RemitterConfig<TConfig>>).emit(ANY_EVENT, {
event,
data,
Expand Down Expand Up @@ -174,9 +174,10 @@ export class ReadonlyRemitter<TConfig = any> {
}

/**
* @deprecated Use `has` instead.
* Returns the number of listeners for the eventName.
* @param eventName If empty returns the number of listeners for all events.
* @returns
* @param eventName Optional eventName to check.
* @returns The number of listeners for the eventName. If no eventName is provided, returns the total count of all listeners.
*/
public count<TEventName extends AllRemitterEventNames<TConfig>>(
eventName?: TEventName
Expand All @@ -192,6 +193,26 @@ export class ReadonlyRemitter<TConfig = any> {
}
}

/**
* If the eventName has any listener.
* @param eventName Optional eventName to check.
* @returns `true` if the eventName has any listener, `false` otherwise. If no eventName is provided, returns `true` if the Remitter has any listener.
*/
public has<TEventName extends AllRemitterEventNames<TConfig>>(
eventName?: TEventName
): boolean {
if (eventName) {
return (this.listeners_.get(eventName)?.size as number) > 0;
} else {
for (const listeners of this.listeners_.values()) {
if (listeners.size > 0) {
return true;
}
}
return false;
}
}

/**
* Start a side effect when the eventName has a first listener.
* Dispose the side effect when the eventName has no listeners.
Expand All @@ -215,8 +236,8 @@ export class ReadonlyRemitter<TConfig = any> {
);
if (
eventName === ANY_EVENT
? this.count() > 0
: this.count(eventName) > 0 || this.count(ANY_EVENT) > 0
? this.has()
: this.has(eventName) || this.has(ANY_EVENT)
) {
startRelay(relayListener, this as unknown as Remitter<TConfig>);
}
Expand Down
63 changes: 62 additions & 1 deletion test/basic-usage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe("basic usage", () => {
const remitter = new Remitter<RemitterConfig>();
remitter.on("event1", spy);

expect(remitter.has()).toBe(true);
expect(remitter.count()).toBe(1);
expect(remitter.count("event1")).toBe(1);
expect(spy).toHaveBeenCalledTimes(0);
Expand All @@ -30,10 +31,12 @@ describe("basic usage", () => {
const disposer = remitter.on("event1", spy);

expect(remitter.count()).toBe(1);
expect(remitter.has()).toBe(true);
expect(remitter.count("event1")).toBe(1);
expect(spy).toHaveBeenCalledTimes(0);

disposer();
expect(remitter.has()).toBe(false);
expect(remitter.count()).toBe(0);

remitter.emit("event1", 1);
Expand Down Expand Up @@ -64,11 +67,13 @@ describe("basic usage", () => {
const remitter = new Remitter<RemitterConfig>();
remitter.on("event1", spy);

expect(remitter.has()).toBe(true);
expect(remitter.count()).toBe(1);
expect(remitter.count("event1")).toBe(1);
expect(spy).toHaveBeenCalledTimes(0);

expect(remitter.off("event1", spy)).toBe(true);
expect(remitter.has()).toBe(false);
expect(remitter.count()).toBe(0);

expect(remitter.off("event1", spy)).toBe(false);
Expand All @@ -89,11 +94,13 @@ describe("basic usage", () => {
const remitter = new Remitter<RemitterConfig>();
remitter.once("event1", spy);

expect(remitter.has()).toBe(true);
expect(remitter.count()).toBe(1);
expect(remitter.count("event1")).toBe(1);
expect(spy).toHaveBeenCalledTimes(0);

expect(remitter.off("event1", spy)).toBe(true);
expect(remitter.has()).toBe(false);
expect(remitter.count()).toBe(0);
expect(remitter.off("event1", spy)).toBe(false);

Expand All @@ -112,6 +119,8 @@ describe("basic usage", () => {
remitter.on("event1", spy);
});

expect(remitter.has()).toBe(true);
expect(remitter.has("event1")).toBe(true);
expect(remitter.count()).toBe(spies.length);
expect(remitter.count("event1")).toBe(spies.length);
spies.forEach(spy => {
Expand All @@ -125,7 +134,10 @@ describe("basic usage", () => {
});

remitter.clear("event1");
expect(remitter.has()).toBe(false);
expect(remitter.has("event1")).toBe(false);
expect(remitter.count()).toBe(0);
expect(remitter.count("event1")).toBe(0);

remitter.emit("event1", 2);
spies.forEach(spy => {
Expand All @@ -150,6 +162,9 @@ describe("basic usage", () => {
remitter.on("event2", spy);
});

expect(remitter.has()).toBe(true);
expect(remitter.has("event1")).toBe(true);
expect(remitter.has("event2")).toBe(true);
expect(remitter.count()).toBe(spies1.length + spies2.length);
expect(remitter.count("event1")).toBe(spies1.length);
expect(remitter.count("event2")).toBe(spies2.length);
Expand All @@ -170,6 +185,9 @@ describe("basic usage", () => {
});

remitter.clear();
expect(remitter.has()).toBe(false);
expect(remitter.has("event1")).toBe(false);
expect(remitter.has("event2")).toBe(false);
expect(remitter.count()).toBe(0);
expect(remitter.count("event1")).toBe(0);
expect(remitter.count("event2")).toBe(0);
Expand All @@ -193,18 +211,24 @@ describe("basic usage", () => {
const remitter = new Remitter<RemitterConfig>();
remitter.once("event1", spy);

expect(remitter.has()).toBe(true);
expect(remitter.has("event1")).toBe(true);
expect(remitter.count()).toBe(1);
expect(remitter.count("event1")).toBe(1);
expect(spy).toHaveBeenCalledTimes(0);

remitter.emit("event1", 1);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).lastCalledWith(1);
expect(remitter.has()).toBe(false);
expect(remitter.has("event1")).toBe(false);
expect(remitter.count()).toBe(0);
expect(remitter.count("event1")).toBe(0);

spy.mockClear();

remitter.emit("event1", 2);
expect(remitter.has()).toBe(false);
expect(remitter.count()).toBe(0);
expect(spy).toHaveBeenCalledTimes(0);
});
Expand All @@ -220,16 +244,22 @@ describe("basic usage", () => {
const disposer1 = remitter.on("event1", spy1);
const disposer2 = remitter.once("event1", spy2);

expect(remitter.has()).toBe(true);
expect(remitter.has("event1")).toBe(true);
expect(remitter.count()).toBe(2);
expect(remitter.count("event1")).toBe(2);
expect(spy1).toHaveBeenCalledTimes(0);
expect(spy2).toHaveBeenCalledTimes(0);

disposer2();
expect(remitter.has()).toBe(true);
expect(remitter.has("event1")).toBe(true);
expect(remitter.count()).toBe(1);
expect(remitter.off("event1", spy2)).toBe(false);

disposer1();
expect(remitter.has()).toBe(false);
expect(remitter.has("event1")).toBe(false);
expect(remitter.count()).toBe(0);
expect(remitter.off("event1", spy1)).toBe(false);

Expand All @@ -254,6 +284,9 @@ describe("basic usage", () => {
remitter.on("event2", spy);
});

expect(remitter.has()).toBe(true);
expect(remitter.has("event1")).toBe(true);
expect(remitter.has("event2")).toBe(true);
expect(remitter.count()).toBe(spies1.length + spies2.length);
expect(remitter.count("event1")).toBe(spies1.length);
expect(remitter.count("event2")).toBe(spies2.length);
Expand All @@ -274,6 +307,9 @@ describe("basic usage", () => {
});

remitter.dispose();
expect(remitter.has()).toBe(false);
expect(remitter.has("event1")).toBe(false);
expect(remitter.has("event2")).toBe(false);
expect(remitter.count()).toBe(0);
expect(remitter.count("event1")).toBe(0);
expect(remitter.count("event2")).toBe(0);
Expand All @@ -298,19 +334,27 @@ describe("basic usage", () => {
remitter.on("event1", spy);
remitter.once("event1", spy);

expect(remitter.has()).toBe(true);
expect(remitter.has("event1")).toBe(true);
expect(remitter.count()).toBe(2);
expect(remitter.count("event1")).toBe(2);
expect(spy).toHaveBeenCalledTimes(0);

remitter.emit("event1", 1);
expect(remitter.has()).toBe(true);
expect(remitter.has("event1")).toBe(true);
expect(remitter.count()).toBe(1);
expect(remitter.count("event1")).toBe(1);
expect(spy).toHaveBeenCalledTimes(2);
expect(spy).lastCalledWith(1);

spy.mockClear();

remitter.emit("event1", 2);
expect(remitter.has()).toBe(true);
expect(remitter.has("event1")).toBe(true);
expect(remitter.count()).toBe(1);
expect(remitter.count("event1")).toBe(1);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).lastCalledWith(2);
});
Expand All @@ -325,12 +369,16 @@ describe("basic usage", () => {
remitter.on("event1", spy);
remitter.once("event1", spy);

expect(remitter.has()).toBe(true);
expect(remitter.has("event1")).toBe(true);
expect(remitter.count()).toBe(2);
expect(remitter.count("event1")).toBe(2);
expect(spy).toHaveBeenCalledTimes(0);

remitter.off("event1", spy);

expect(remitter.has()).toBe(false);
expect(remitter.has("event1")).toBe(false);
expect(remitter.count()).toBe(0);
expect(remitter.count("event1")).toBe(0);
expect(spy).toHaveBeenCalledTimes(0);
Expand All @@ -346,20 +394,33 @@ describe("basic usage", () => {
remitter.on(ANY_EVENT, spy);
remitter.once(ANY_EVENT, spy);

expect(remitter.count("event1")).toBe(0);
expect(remitter.has()).toBe(true);
expect(remitter.has(ANY_EVENT)).toBe(true);
expect(remitter.has("event1")).toBe(false);
expect(remitter.count()).toBe(2);
expect(remitter.count(ANY_EVENT)).toBe(2);
expect(remitter.count("event1")).toBe(0);
expect(spy).toHaveBeenCalledTimes(0);

remitter.emit("event1", 1);
expect(remitter.has()).toBe(true);
expect(remitter.has(ANY_EVENT)).toBe(true);
expect(remitter.has("event1")).toBe(false);
expect(remitter.count()).toBe(1);
expect(remitter.count(ANY_EVENT)).toBe(1);
expect(remitter.count("event1")).toBe(0);
expect(spy).toHaveBeenCalledTimes(2);
expect(spy).lastCalledWith({ event: "event1", data: 1 });

spy.mockClear();

remitter.emit("event1", 2);
expect(remitter.has()).toBe(true);
expect(remitter.has(ANY_EVENT)).toBe(true);
expect(remitter.has("event1")).toBe(false);
expect(remitter.count()).toBe(1);
expect(remitter.count(ANY_EVENT)).toBe(1);
expect(remitter.count("event1")).toBe(0);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).lastCalledWith({ event: "event1", data: 2 });
});
Expand Down

0 comments on commit 16ba81d

Please sign in to comment.