1.1.3 • Published 4 months ago

zodbus v1.1.3

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

ZodBus

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

https://github.com/3rd/zodbus/assets/59587503/08d2c13c-cccd-407f-b14c-957d7dd5115d

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.

1.1.1

4 months ago

1.1.0

4 months ago

1.1.3

4 months ago

1.0.4

7 months ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago