NotificationMiddleware

Middleware

Retry, rate-limit, circuit-breaker, dedupe and logging

Middleware

Middleware wraps every send. The first registered middleware is the outermost wrapper (runs first on the way in, last on the way out).

import { retryMiddleware, rateLimitMiddleware, circuitBreakerMiddleware, dedupeMiddleware, loggingMiddleware } from "@visulima/notification/middleware";

notify
    .use(loggingMiddleware())
    .use(retryMiddleware({ retries: 3, baseDelay: 250 }))
    .use(rateLimitMiddleware({ rate: 100, interval: 1000 }))
    .use(circuitBreakerMiddleware({ threshold: 5, resetTimeout: 30_000 }))
    .use(dedupeMiddleware({ ttl: 60_000 }));

Built-ins

MiddlewarePurpose
retryMiddlewareRetry failed sends with exponential backoff + jitter. shouldRetry hook.
rateLimitMiddlewareToken-bucket throttle (rate per interval).
circuitBreakerMiddlewareOpen the circuit after N consecutive failures; trial after cool-off.
dedupeMiddlewareSuppress duplicate sends within a TTL, keyed by idempotencyKey.
loggingMiddlewareLog each attempt and outcome.
suppressionMiddlewareShort-circuit sends to suppressed recipients (unsubscribe / bounce list).
telemetryMiddlewareEmit an OpenTelemetry span + counter/histogram per send (optional peer).
import { suppressionMiddleware, telemetryMiddleware } from "@visulima/notification/middleware";

notify.use(suppressionMiddleware({ isSuppressed: (recipient, channel) => suppressionList.has(recipient) })).use(telemetryMiddleware({ tracer })); // edge-safe; no-op without a tracer/meter

Writing middleware

import type { Middleware } from "@visulima/notification";

const stamp: Middleware = async (context, next) => {
    context.payload.metadata = { ...context.payload.metadata, sentAt: Date.now() };

    return next(context);
};

notify.use(stamp);

The context carries { channel, provider, payload }. Return the Result from next(context) (or short-circuit with your own).

Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues