@solid-primitives/event-bus
Version:
A collection of SolidJS primitives providing various features of a pubsub/event-emitter/event-bus.
97 lines (96 loc) • 2.6 kB
JavaScript
import { tryOnCleanup } from "@solid-primitives/utils";
import { onCleanup } from "solid-js";
import { createEventBus, EventBusCore } from "./eventBus.js";
export class EmitterCore extends Map {
on(event, listener) {
let bus = this.get(event);
bus || this.set(event, (bus = new EventBusCore()));
bus.add(listener);
}
off(event, listener) {
const bus = this.get(event);
bus?.delete(listener) && !bus.size && this.delete(event);
}
emit(event, value) {
this.get(event)?.emit(value);
}
}
/**
* Creates an emitter with which you can listen to and emit various events.
*
* @returns emitter mathods: `{on, emit, clear}`
*
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/event-bus#createEmitter
*
* @example
* const emitter = createEmitter<{
* foo: number;
* bar: string;
* }>();
* // can be destructured
* const { on, emit, clear } = emitter;
*
* emitter.on("foo", e => {});
* emitter.on("bar", e => {});
*
* emitter.emit("foo", 0);
* emitter.emit("bar", "hello");
*/
export function createEmitter() {
const emitter = new EmitterCore();
return {
on(event, listener) {
emitter.on(event, listener);
return tryOnCleanup(emitter.off.bind(emitter, event, listener));
},
emit: emitter.emit.bind(emitter),
clear: onCleanup(emitter.clear.bind(emitter)),
};
}
/**
* Creates an emitter with which you can listen to and emit various events. With this emitter you can also listen to all events.
*
* @returns emitter mathods: `{on, listen, emit, clear}`
*
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/event-bus#createGlobalEmitter
*
* @example
* const emitter = createGlobalEmitter<{
* foo: number;
* bar: string;
* }>();
* // can be destructured
* const { on, emit, clear, listen } = emitter;
*
* emitter.on("foo", e => {});
* emitter.on("bar", e => {});
*
* emitter.emit("foo", 0);
* emitter.emit("bar", "hello");
*
* emitter.listen(e => {
* switch (e.name) {
* case "foo": {
* e.details;
* break;
* }
* case "bar": {
* e.details;
* break;
* }
* }
* })
*/
export function createGlobalEmitter() {
const emitter = createEmitter();
const global = createEventBus();
return {
on: emitter.on,
clear: emitter.clear,
listen: global.listen,
emit(name, details) {
global.emit({ name, details });
emitter.emit(name, details);
},
};
}