LogoPear Docs
ReferencesHelpers

Protomux

Multiplex multiple framed protocols over one transport stream.

stable

Protomux multiplexes multiple message-oriented subprotocols over one framed stream. It is typically layered on top of Secretstream and uses Compact encoding for message schemas. For source and releases, see the Protomux repository.

Install

npm i protomux

Quickstart

import Protomux from 'protomux'
import cenc from 'compact-encoding'

const mux = new Protomux(aFramedEncryptedStream)

const channel = mux.createChannel({
  protocol: 'chat',
  onopen() {
    console.log('chat channel opened')
  }
})

const message = channel.addMessage({
  encoding: cenc.string,
  onmessage(text) {
    console.log(text)
  }
})

channel.open()
message.send('hello')

API Reference

Constructor and mux helpers

mux = new Protomux(stream, [options])

src

Make a new instance. stream should be a framed stream, preserving the messages written.

ParameterTypeDefaultDescription
streamobject
optionsProtomuxOptions{}Optional configuration for the instance, such as a custom buffer allocator.
{
  // Called when the muxer wants to allocate a message that is written, defaults to Buffer.allocUnsafe.
  alloc (size) {}
}

mux = Protomux.from(stream | muxer, [options])

src

Helper to accept either an existing muxer instance or a stream (which creates a new one).

ParameterTypeDescription
streamobjectA framed stream or an existing Protomux instance.
optsProtomuxOptionsMuxer options passed through when a new instance is created.
  • Returns: Protomux — The existing or newly created Protomux instance.
const mux = Protomux.from(someStream)

Protomux.isProtomux(mux)

src

Returns true when value looks like a Protomux instance.

ParameterTypeDescription
muxobjectValue to test.
  • Returns: booleantrue when mux is a Protomux instance.
Protomux.isProtomux(mux) // true
Protomux.isProtomux({})  // false

mux.cork()

src

Same as channel.cork but on the muxer instance.

  • Returns: void
mux.cork()
channelA.messages[0].send('hello')
channelB.messages[0].send('world')
mux.uncork() // sends both as one frame

mux.uncork()

src

Same as channel.uncork but on the muxer instance.

  • Returns: void
mux.cork()
msg.send('hello')
mux.uncork()

mux.isIdle()

src

Convenience method that returns true if the number of channels is currently 0.

  • Returns: booleantrue if the channel count is currently zero.
if (mux.isIdle()) console.log('no open channels')

for (const channel of muxer) { ... }

The muxer instance is iterable, so you can iterate over all the channels.

Pairing and channel discovery

mux.pair({ protocol, id }, callback)

src

Register a callback to be called everytime a new channel is requested.

ParameterTypeDescription
optionsChannelKeyProtocol name and optional binary id to match.
notifyFunctionAsync callback called with the channel's binary id when a matching remote channel opens.
  • Returns: void
mux.pair({ protocol: 'my-protocol' }, async (id) => {
  const channel = mux.createChannel({ protocol: 'my-protocol' })
  channel.open()
})

mux.unpair({ protocol, id })

src

Unregisters the pair callback.

ParameterTypeDescription
optionsChannelKeyProtocol name and optional binary id to deregister.
  • Returns: void
mux.unpair({ protocol: 'my-protocol' })

mux.opened({ protocol, id })

src

Boolean that indicates if the channel is opened.

ParameterTypeDescription
optionsChannelKeyProtocol name and optional binary id to check.
  • Returns: booleantrue when one or more matching channels are open.
if (mux.opened({ protocol: 'my-protocol' })) {
  console.log('already open')
}

mux.getLastChannel(options)

src

Returns the most recently opened matching channel, or null if none is open.

ParameterTypeDescription
optionsChannelKeyProtocol name and optional binary id.
  • Returns: Channel\|null — The most recently opened matching channel, or null.
const ch = mux.getLastChannel({ protocol: 'my-protocol' })

Creating channels

mux.createChannel(opts)

src

Add a new protocol channel.

ParameterTypeDescription
optsCreateChannelOptionsChannel creation options.
  • Returns: Channel\|null — The new channel, or null if it cannot be opened.

Mux properties

mux.stream

src

The framed transport stream backing this mux.

  • Returns: object

mux.drained

src

The current writable backpressure state from the underlying stream.

  • Returns: boolean

Channel lifecycle

channel.open([handshake])

src

Open the channel.

ParameterTypeDescription
handshake*Optional handshake value encoded with the handshake encoding provided to createChannel.
  • Returns: void
const channel = mux.createChannel({ protocol: 'my-protocol' })
channel.open()

channel.fullyOpened()

src

Resolves to true when the channel fully opens or false if it closes first.

const opened = await channel.fullyOpened()
if (opened) console.log('channel is open')

channel.fullyClosed()

src

Resolves once the channel has been destroyed and all pending async handlers have finished.

await channel.fullyClosed()
console.log('channel destroyed')

channel.close()

src

Closes the protocol channel.

  • Returns: void
channel.close()

channel.cork()

src

Corking the protocol channel, makes it buffer messages and send them all in a batch when it uncorks.

  • Returns: void
channel.cork()
one.send('hello')
two.send(true)
channel.uncork() // sends both as a single batch

channel.uncork()

src

Uncork and send the batch.

  • Returns: void
channel.cork()
one.send('hello')
channel.uncork()

Registering and sending messages

channel.addMessage(opts)

src

Add/register a message type for a certain encoding. Options include:

ParameterTypeDescription
optsAddMessageOptionsMessage options including encoding and onmessage handler.
  • Returns: object — Message object with a send(data) method for sending encoded messages.

m.send(data)

Send a message.

m.encoding

The encoding for this message.

m.onmessage

Function that is called when a message arrives.

Channel properties

channel.userData

src

  • Returns: The arbitrary metadata value passed to mux.createChannel(...).

channel.protocol

src

  • Returns: The channel protocol name.

channel.aliases

src

  • Returns: The list of alternate protocol names registered for this channel family.

channel.id

src

  • Returns: The optional binary identifier distinguishing this channel family.

channel.handshake

src

  • Returns: The decoded handshake payload after the channel fully opens, or null when no handshake encoder was configured.

channel.messages

src

  • Returns: The array of registered message descriptors in type order.

channel.opened

src

channel.closed

src

  • Returns: true after either side closes the channel.

channel.destroyed

src

  • Returns: true after the close lifecycle and pending handlers have fully drained.

channel.drained

src

true when the underlying stream's write buffer is empty.

  • Returns: boolean

Lifecycle callbacks

channel.onopen

src

  • Returns: Called when the channel opens. handshake is the decoded open payload or null, and channel is the channel instance.

channel.onclose

src

  • Returns: Called when the channel closes. isRemote is true when the remote side initiated the close, and channel is the channel instance.

channel.ondestroy

src

  • Returns: Called when the channel is destroyed. channel is the destroyed channel instance.

channel.ondrain

src

  • Returns: Called when the channel's underlying mux becomes writable again. channel is that channel instance.

Types

ProtomuxOptions

Options for allocating buffers in a Protomux instance.

PropertyTypeDefaultDescription
allocFunctionCustom allocator; called with (size) and must return a Buffer. Defaults to Buffer.allocUnsafe.

CreateChannelOptions

Options for creating a protocol channel.

PropertyTypeDefaultDescription
protocolstringProtocol name used to match channels between peers.
idBuffer|nullnullOptional binary identifier to distinguish multiple channels with the same protocol name.
handshake*nullCompact-encoding codec for encoding/decoding the handshake value exchanged on open.
messagesArray<AddMessageOptions>[]Array of message descriptors registered on channel open.
uniquebooleantrueWhen true, returns null if a channel with this protocol+id is already open.
aliasesArray<string>[]Alternative protocol names that also match this channel.
userData*nullArbitrary value stored as channel.userData; not transmitted.
onopenFunctionCalled with (handshake, channel) when the remote side opens this protocol.
oncloseFunctionCalled with (isRemote, channel) when either side closes the channel.
ondestroyFunctionCalled with (channel) after onclose resolves and all pending promises settle.
ondrainFunctionCalled with (channel) when the underlying stream drains.

AddMessageOptions

Options for registering a message type on a channel.

PropertyTypeDefaultDescription
encodingobjectA compact-encoding codec. Defaults to raw binary (c.raw).
autoBatchbooleantrueWhen true, batch replies are collected before the next tick.
onmessageFunctionCalled with (message, channel) when the remote sends a message of this type.

ChannelKey

Protocol + id selector used by pair/unpair/opened/getLastChannel.

PropertyTypeDefaultDescription
protocolstringProtocol name to match.
idBuffer|nullnullOptional binary id to narrow the match.

See also

  • Secretstream—the encrypted framed stream most commonly used underneath Protomux.
  • Compact encoding—the schema toolkit Protomux uses for handshakes and message payloads.
  • Hyperswarm—common peer-transport entry point before you layer on Secretstream and Protomux.
  • Upstream Protomux repository—source, releases, and implementation details.

On this page