3.0 KiB
transport/native
Purpose
nativeChannelFactory is a thin adapter that exposes the global BroadcastChannel
constructor as a ChannelLike. Use this in any environment where the
native API is available — every modern browser, Bun, and recent Node (with
the BroadcastChannel global). The companion helper
isNativeBroadcastChannelAvailable() is a one-line feature detect so callers
can branch between the native transport and the StorageLike-backed
fallback at runtime without try/catching around constructor lookups.
The adapter exists to fix the upstream "addEventListener(event: any)" smell:
the native BroadcastChannel already hands back MessageEvent objects, and
the wrapper preserves that static type in the ChannelLike signature. The
surface never lets any leak from this code path.
Features
- Zero-cost wrapper around the native
BroadcastChannel. - Statically-typed
(event: MessageEvent) => voidlistener forwarding. isNativeBroadcastChannelAvailable()feature detect.- Sideeffect-free —
nativeChannelFactoryonly constructsBroadcastChannelwhen invoked.
Usage: Basic
import {
nativeChannelFactory,
TypedBroadcastChannel,
} from "@suaveplan/broadcast-channel";
const channel = new TypedBroadcastChannel({
config: { name: "app-bus" },
factory: nativeChannelFactory,
});
channel.open();
Usage: Advanced
import {
createLocalStorageChannelFactory,
isNativeBroadcastChannelAvailable,
nativeChannelFactory,
TypedBroadcastChannel,
} from "@suaveplan/broadcast-channel";
import type { StorageLike } from "@suaveplan/types";
declare const storage: StorageLike;
const channel = new TypedBroadcastChannel({
config: { name: "app-bus" },
factory: isNativeBroadcastChannelAvailable()
? nativeChannelFactory
: createLocalStorageChannelFactory(storage),
});
API Reference
const nativeChannelFactory: ChannelFactory—(name) => ChannelLikewrappingnew BroadcastChannel(name).function isNativeBroadcastChannelAvailable(): boolean— returnstrueifglobalThis.BroadcastChannelis a function.
Implementation Notes
The wrapper does not extend BroadcastChannel directly because the suaveplan
ChannelLike interface narrows addEventListener to a single literal type
("message") — extending the host type would re-introduce the overloaded
union the original surface carried and force callers to handle event types
the channel never delivers (messageerror). Forwarding through a small
adapter keeps the public type small and prevents accidental binding of the
messageerror event, which the channel's leader-election and presence
machinery is not designed to react to. The feature-detect helper checks for
typeof globalThis.BroadcastChannel === "function" rather than "undefined" !== typeof BroadcastChannel: the literal-function check sidesteps the
edge case where a host puts a non-callable stub on the global (some
extension sandboxes do this) and forces the caller into the fallback path.