Quick Start
This guide walks you through building a simple real-time notification system.
Prerequisites
Section titled “Prerequisites”Make sure you have:
- Node.js 18+ or Bun
- TypeScript configured in your project
- PubSubJS packages installed (see Installation)
Step 1: Define Events
Section titled “Step 1: Define Events”First, define the events your application will use:
import { z } from "zod";import { defineEvent } from "@pubsubjs/core";
export const events = defineEvent([ { name: "notification.created", schema: z.object({ id: z.string(), userId: z.string(), title: z.string(), message: z.string(), type: z.enum(["info", "warning", "error"]), createdAt: z.string().datetime(), }), }, { name: "notification.read", schema: z.object({ id: z.string(), userId: z.string(), readAt: z.string().datetime(), }), },]);
// TypeScript infers the event types automaticallyexport type Events = typeof events;Step 2: Create a Transport
Section titled “Step 2: Create a Transport”Choose a transport based on your use case. For this example, we’ll use WebSocket:
import { WebSocketServerTransport } from "@pubsubjs/transport-websocket";
const transport = new WebSocketServerTransport({ port: 8080,});
console.log("WebSocket server running on ws://localhost:8080");Step 3: Set Up the Publisher
Section titled “Step 3: Set Up the Publisher”Create a publisher to send events:
import { Publisher } from "@pubsubjs/core";import { events } from "./events";
export function createNotificationPublisher(transport) { const publisher = new Publisher({ events, transport, });
return { async sendNotification(userId: string, title: string, message: string, type: "info" | "warning" | "error") { await publisher.publish("notification.created", { id: crypto.randomUUID(), userId, title, message, type, createdAt: new Date().toISOString(), }); },
async markAsRead(id: string, userId: string) { await publisher.publish("notification.read", { id, userId, readAt: new Date().toISOString(), }); }, };}Step 4: Set Up the Subscriber
Section titled “Step 4: Set Up the Subscriber”Create a subscriber to receive events:
import { Subscriber } from "@pubsubjs/core";import { events } from "./events";
export function createNotificationSubscriber(transport) { const subscriber = new Subscriber({ events, transport, onError: (error, eventName, payload) => { console.error(`Error handling ${eventName}:`, error); }, });
subscriber.on("notification.created", (payload, { ctx }) => { console.log(`[${ctx.messageId}] New notification for user ${payload.userId}:`); console.log(` ${payload.type.toUpperCase()}: ${payload.title}`); console.log(` ${payload.message}`); });
subscriber.on("notification.read", (payload) => { console.log(`Notification ${payload.id} marked as read by user ${payload.userId}`); });
return subscriber;}Step 5: Put It Together
Section titled “Step 5: Put It Together”import { WebSocketServerTransport } from "@pubsubjs/transport-websocket";import { events } from "./events";import { createNotificationPublisher } from "./publisher";import { createNotificationSubscriber } from "./subscriber";
async function main() { // Create transport const transport = new WebSocketServerTransport({ port: 8080 });
// Create publisher and subscriber const notifications = createNotificationPublisher(transport); const subscriber = createNotificationSubscriber(transport);
// Start subscribing await subscriber.subscribe(); console.log("Notification system ready!");
// Send a test notification await notifications.sendNotification( "user-123", "Welcome!", "Thanks for trying PubSubJS", "info" );
// Mark it as read after 2 seconds setTimeout(async () => { await notifications.markAsRead("notif-1", "user-123"); }, 2000);}
main().catch(console.error);Step 6: Run It
Section titled “Step 6: Run It”bun main.tsYou should see:
WebSocket server running on ws://localhost:8080Notification system ready![abc123] New notification for user user-123: INFO: Welcome! Thanks for trying PubSubJSNotification notif-1 marked as read by user user-123Adding Middleware
Section titled “Adding Middleware”Enhance your subscriber with middleware:
import { Subscriber, createSubscriberLoggingMiddleware, createRateLimitMiddleware,} from "@pubsubjs/core";
const subscriber = new Subscriber({ events, transport, middleware: [ createSubscriberLoggingMiddleware(), createRateLimitMiddleware({ maxEvents: 100, windowMs: 1000, onLimit: (eventName) => { console.warn(`Rate limit exceeded for ${eventName}`); }, }), ],});Next Steps
Section titled “Next Steps”- Events & Schemas - Learn more about event definitions
- Middleware - Add logging, rate limiting, and more
- Transports - Explore different transport options
- React Integration - Use PubSubJS in React applications