npm.io
0.1.1 • Published 6d ago

@billdaddy/typemit

Licence
MIT
Version
0.1.1
Deps
0
Size
33 kB
Vulns
0
Weekly
57

typemit

All Contributors

Tiny, fully type-safe event emitter — with a wildcard listener and a promise-based waitFor. Zero dependencies.

CI npm version bundle size types license

Most event emitters take (string, ...any[]) and hope for the best. typemit takes an event map, so the event name is checked, the payload type is inferred, and a typo or wrong payload is a compile error — not a 2 a.m. bug.

import { createEmitter } from "@billdaddy/typemit";

const bus = createEmitter<{
  login: { id: string };
  message: string;
  ready: void;
}>();

bus.on("login", (user) => console.log(user.id)); // user: { id: string }
bus.emit("login", { id: "42" });
bus.emit("ready");                                // void event — no payload
bus.emit("login", "oops");                        // ❌ compile error

Why typemit?

  • Type-safe end to end. on/once/emit/waitFor are all checked against your event map; void events take no payload.
  • waitFor as a promise. Await the next event — with an optional filter and an AbortSignal to bail out. Great for tests and request/response flows.
  • Wildcard listener. onAny((event, payload) => …) for logging/debugging.
  • Tidy lifecycle. on/once/onAny return an unsubscribe; clear() and listenerCount() for housekeeping. Handlers may unsubscribe themselves mid-emit.
  • Zero dependencies, ESM + CJS + types, ~1 kB.

Install

npm install @billdaddy/typemit
# or: pnpm add @billdaddy/typemit  /  yarn add @billdaddy/typemit  /  bun add @billdaddy/typemit

API

const bus = createEmitter<Events>();
Subscribe / emit
const off = bus.on("message", (text) => …);  // returns unsubscribe
bus.once("ready", () => …);                    // fires once
bus.off("message", handler);
bus.emit("message", "hello");
off();
waitFor(event, { signal?, filter? }) → Promise<payload>
const user = await bus.waitFor("login");
const big = await bus.waitFor("message", { filter: (m) => m.length > 100 });

const ac = new AbortController();
const next = bus.waitFor("login", { signal: ac.signal }); // rejects if aborted
Wildcard & housekeeping
const offAny = bus.onAny((event, payload) => log(event, payload));
bus.listenerCount("message"); // listeners for one event
bus.listenerCount();          // all listeners, incl. wildcard
bus.clear("message");         // remove one event's listeners
bus.clear();                  // remove everything

Pairs well with

  • timefence — race waitFor against a deadline.

Contributors

This project follows the all-contributors specification. Contributions of any kind are welcome — code, docs, bug reports, ideas, reviews! See the emoji key for how each contribution is recognized, and open a PR or issue to get involved.

Thanks goes to these wonderful people:

Tung Tran
Tung Tran

License

MIT Tung Tran

Keywords