3rd / zodbus

ZodBus is a fully-typed event bus powered by Zod, with nested namespace & wildcard support and payload validation.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ZodBus

ZodBus is a fully-typed event bus powered by Zod, with nested namespace & wildcard support and payload validation.

setup.mp4

Installation

ZodBus is published on the NPM Registry: https://npmjs.com/package/zodbus

npm install -D zod zodbus
pnpm install -D zod zodbus
yarn add -D zod zodbus

Usage

import { z } from "zod";
import { create } from "zodbus";

// This is how you define your event schema.
//  By traversing the schema, event names are built by concatenating the parent keys with dots,
//  and when a ZodType is encountered it means we have reached the end of the key definition,
//  and the ZodType describes the payload signature for the current event.
const schema = {
  foo: {
    bar: {
      baz: z.object({    // this creates the event "foo.bar.baz",
        id: z.string(),  // with the { id: string; val: number } payload type
        val: z.number()
      })
    }
  },
  zip: {
    za: z.string(),      // this creates the event "zip.za" with a string payload
    zb: z.number(),      // this creates the event "zip.zb" with a number payload
  }
};

const bus = create({ schema, validate: true });

// Non-wildcard subscription signatures are fully-typed.
bus.subscribe("foo.bar.baz", (data: { id: string; val: number; }, event: "foo.bar.baz") => {});
bus.subscribe("zip.za", (data: string, event: "zip.za") => {});

// Wildcard event signatures are typed as (data: unknown; event: string), it's up to you to handle the type.
//  The "*" wildcard is special, as it refers to all events, regardless of the nesting depth.
//  All other wildcard patterns refer to a specific event shape.
bus.subscribe("*", (data: unknown, event: string) => {}); // will be called for all events
bus.subscribe("foo.*.baz", ...); // will be called when publishing a "foo.bar.baz" event
bus.subscribe("foo.bar.*", ...); // same
bus.subscribe("*.bar.*", ...); // same
bus.subscribe("*.*.*", ...); // same
bus.subscribe("*.*", ...); // will be called for "zip.za" and "zip.zb"
bus.subscribeOnce("*.*", ...); // you can also subscribe to an event only once

// You can unsubscribe one or all handlers from one or multiple events.
bus.unsubscribe("zip.za", handler); // unsubscribe handler from "zip.za"
bus.unsubscribe("zip.*", handler); // unsubscribe handler from "zip.za" and "zip.bzb"
bus.unsubscribe("zip.*"); // unsubscribe all handlers from "zip.za" and "zip.bzb"
bus.unsubscribe("*", handler); // unsubscribe handler from all events
bus.unsubscribe("*"); // unsubscribe all handlers from all events

// Publishing is only allowed on fully-qualified event names.
bus.publish("foo.bar.baz", { id: "uwu", val: 4815162342 });

// Utilities
bus.getEventNames(); // ["foo.bar.baz", "zip.za", "zip.zb"]
bus.getListeners("zip.*"); // gets the listeners for "zip.*"
bus.getListeners(); // gets all listeners
const data = await bus.waitFor("zip.zap"); // typed waitFor with timeout and filter support

Payload validation

Payload validation is performed by Zod based on the schema, and enabled by default.
It is however optional if you don't have to validate external data.
For most use-cases the type checking is enough as it won't allow you to make mistakes.

About

ZodBus is a fully-typed event bus powered by Zod, with nested namespace & wildcard support and payload validation.

License:MIT License


Languages

Language:TypeScript 69.2%Language:JavaScript 30.5%Language:Shell 0.3%