Files
suaveplan/packages/api-stack/api/api-plugin-example/src/trusted/events/events.md
2026-05-27 23:29:53 +01:00

2.3 KiB

events — topics + payload schemas published and subscribed

(no submodules)

Purpose

The reference plugin both publishes and subscribes to events. This module exposes the topic names and the Zod payload schemas so the manifest, the runtime, and the integration test all agree on the shape. The integration test publishes a users.user.deleted payload through the in-memory bus and asserts the subscriber handler ran exactly once with the parsed payload.

The publication side mirrors that — the plugin's POST /example/invoices handler emits example.invoice.created after a successful insert and the test asserts the payload landed on the bus via host.waitForEvent.

Features

  • EXAMPLE_INVOICE_CREATED_TOPIC / USERS_USER_DELETED_TOPIC literals.
  • ExampleInvoiceCreatedPayload / UsersUserDeletedPayload Zod schemas.
  • makeUserDeletedHandler({ seen }) — factory returning a parsed-payload handler that records into a caller-owned sink.

Usage: Basic

import {
    EXAMPLE_INVOICE_CREATED_TOPIC,
    ExampleInvoiceCreatedPayload,
} from "@suaveplan/api-plugin-example/events/events";

host.adapters.eventBus.publish(EXAMPLE_INVOICE_CREATED_TOPIC, {
    id: "i-1",
    customerId: "c-1",
    amountCents: 100,
    currency: "USD",
});

Usage: Advanced

The subscriber-side factory accepts a sink so tests can observe delivery without mutating module state:

import { makeUserDeletedHandler } from "@suaveplan/api-plugin-example/events/events";
const sink = { seen: new Set<string>() };
host.adapters.eventBus.on("users.user.deleted", makeUserDeletedHandler(sink));

API Reference

  • EXAMPLE_INVOICE_CREATED_TOPIC: "example.invoice.created"
  • USERS_USER_DELETED_TOPIC: "users.user.deleted"
  • ExampleInvoiceCreatedPayload: ZodObject — published payload.
  • UsersUserDeletedPayload: ZodObject — subscribed payload.
  • makeUserDeletedHandler({ seen: Set<string> }): (raw: unknown) => void.

Implementation Notes

makeUserDeletedHandler swallows parse failures rather than throwing because the in-memory event bus delivers FIFO with Promise.resolve chaining — a throwing handler would terminate the chain for every downstream subscriber. The integration test asserts a valid payload populates the sink; a malformed payload simply doesn't.