Skip to content

Wire Taps

A wire tap is a global observer that sees every envelope flowing through postal — across all channels and topics. Wire taps fire for publishes, requests, handler replies, and inbound envelopes from transports.

import { addWiretap } from "postal";

const removeTap = addWiretap(envelope => {
    console.log(`[${envelope.channel}] ${envelope.topic}`, envelope.payload);
});
addWiretap(envelope => {
    console.log(
        `[${envelope.type}] ${envelope.channel}/${envelope.topic}`,
        JSON.stringify(envelope.payload)
    );
});
addWiretap(envelope => {
    if (envelope.channel === "orders" && envelope.topic.startsWith("item.")) {
        debugger;
    }
});
const counts = new Map<string, number>();

addWiretap(envelope => {
    const key = `${envelope.channel}/${envelope.topic}`;
    counts.set(key, (counts.get(key) ?? 0) + 1);
});

Errors thrown by wiretaps are silently swallowed. Wiretaps are passive observers — they must never affect message dispatch:

addWiretap(() => {
    throw new Error("this won't break anything");
});

// Publishing still works normally
ch.publish("order.placed", { id: "abc" }); // No error thrown

addWiretap returns a remove function:

const removeTap = addWiretap(callback);

// Later...
removeTap();

Calling the remove function multiple times is safe — subsequent calls are no-ops.

resetWiretaps() removes all registered wiretaps. Wiretaps are also cleared when resetChannels() is called, which is primarily useful for test isolation:

import { resetWiretaps, resetChannels } from "postal";

// Remove just wiretaps
resetWiretaps();

// Or reset everything (channels, wiretaps, transports, RPC state)
resetChannels();
  • Transports — bridge messages across tabs, iframes, and workers
  • Concepts — channels, topics, wildcards, and envelopes
  • Getting Started — installation and first message