Skip to content

Low-level messaging

registerOsraMessageListener and sendOsraMessage are escape hatches under the connection layer: they move raw wire-protocol envelopes over any transport without a handshake or connection state. relay() is built on exactly these.

const registerOsraMessageListener: (options: {
listener: (message: Message, context: MessageContext) => void
transport: ReceiveTransport
remoteName?: string
key?: string // default OSRA_DEFAULT_KEY
origin?: string // default '*'
unregisterSignal?: AbortSignal
}) => void

Subscribes to raw osra envelopes on any receive transport, and filters them by key, remoteName, and origin. It handles the per-transport quirks for you:

  • JSON string parsing on WebSocket
  • .port indirection on SharedWorker
  • MessagePort.start()
  • the WebExtension listener families

MessageContext is { port?, sender?, receiveTransport?, source?, origin? }.

const sendOsraMessage: (
transport: EmitTransport,
message: Message,
origin?: string, // default '*', Window targetOrigin
transferables?: Transferable[],
) => void

Sends a raw envelope on any emit transport. It JSON-stringifies for WebSocket and queues while the socket is CONNECTING, and routes via .port for SharedWorker.

  • Wire protocol: the envelope format these functions carry
  • Custom transports: wrapping your own channel in { emit, receive } instead of dropping below the connection layer