LogoPear Docs
ReferenceHelpers

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

const mux = new Protomux(stream, [options])

API definition on GitHub

  • Signature: const mux = new Protomux(stream, [options]) (GitHub)
  • Parameters: stream is a framed stream that preserves message boundaries. options.alloc optionally overrides the buffer allocator used for outgoing frames. (GitHub)
  • Returns: A Protomux instance bound to that stream. (GitHub)
  • Example:
const mux = new Protomux(secretStream)

const mux = Protomux.from(streamOrMux, [options])

API definition on GitHub

  • Signature: const mux = Protomux.from(streamOrMux, [options]) (GitHub)
  • Parameters: streamOrMux is either an existing Protomux instance or a framed stream. options are forwarded when a new mux has to be created. (GitHub)
  • Returns: An existing mux when one is already attached, otherwise a new Protomux. (GitHub)
  • Example:
const mux = Protomux.from(secretStream)

const isMux = Protomux.isProtomux(value)

API definition on GitHub

  • Signature: const isMux = Protomux.isProtomux(value) (GitHub)
  • Parameters: value is any unknown object. (GitHub)
  • Returns: true when value looks like a Protomux instance. (GitHub)
  • Example:
console.log(Protomux.isProtomux(mux))

mux.cork()

API definition on GitHub

  • Signature: mux.cork() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Nothing. Subsequent control and message frames are buffered into one batch until mux.uncork() runs. (GitHub)
  • Example:
mux.cork()
messageA.send('a')
messageB.send('b')
mux.uncork()

mux.uncork()

API definition on GitHub

  • Signature: mux.uncork() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Nothing. Flushes the current batch when the cork depth returns to zero. (GitHub)
  • Example:
mux.uncork()

const idle = mux.isIdle()

API definition on GitHub

  • Signature: const idle = mux.isIdle() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: true when there are currently no open local channels. (GitHub)
  • Example:
console.log(mux.isIdle())

for (const channel of mux)

API definition on GitHub

  • Signature: for (const channel of mux) (GitHub)
  • Parameters: None. (GitHub)
  • Returns: An iterator over the currently tracked local channels. (GitHub)
  • Example:
for (const channel of mux) {
  console.log(channel.protocol)
}

Pairing and channel discovery

mux.pair({ protocol, [id] }, notify)

API definition on GitHub

  • Signature: mux.pair({ protocol, [id] }, notify) (GitHub)
  • Parameters: protocol is the protocol name to match, id optionally narrows the match to one binary channel identifier, and notify is called whenever the remote side requests that channel. (GitHub)
  • Returns: Nothing. (GitHub)
  • Example:
mux.pair({ protocol: 'chat' }, async () => {
  console.log('remote requested chat')
})

mux.unpair({ protocol, [id] })

API definition on GitHub

  • Signature: mux.unpair({ protocol, [id] }) (GitHub)
  • Parameters: protocol and optional id identify the pairing callback to remove. (GitHub)
  • Returns: Nothing. (GitHub)
  • Example:
mux.unpair({ protocol: 'chat' })

const opened = mux.opened({ protocol, [id] })

API definition on GitHub

  • Signature: const opened = mux.opened({ protocol, [id] }) (GitHub)
  • Parameters: protocol and optional id identify the channel family to inspect. (GitHub)
  • Returns: true if at least one matching channel is currently open. (GitHub)
  • Example:
console.log(mux.opened({ protocol: 'chat' }))

const channel = mux.getLastChannel({ protocol, [id] })

API definition on GitHub

  • Signature: const channel = mux.getLastChannel({ protocol, [id] }) (GitHub)
  • Parameters: protocol and optional id identify the channel family to inspect. (GitHub)
  • Returns: The most recently opened matching channel, or null if none is open. (GitHub)
  • Example:
const latest = mux.getLastChannel({ protocol: 'chat' })

Creating channels

const channel = mux.createChannel(options)

API definition on GitHub

  • Signature: const channel = mux.createChannel(options) (GitHub)
  • Parameters: options.protocol names the protocol, id optionally distinguishes multiple channels under one protocol, aliases adds alternate protocol names, unique defaults to true, handshake supplies an optional compact encoder for open-time handshake payloads, messages pre-registers message descriptors, userData stores arbitrary metadata, and onopen, onclose, ondestroy, and ondrain register lifecycle callbacks. (GitHub)
  • Returns: A Channel instance, or null when a unique channel already exists or the remote has already rejected/closed the matching request. (GitHub)
  • Example:
const channel = mux.createChannel({
  protocol: 'chat',
  handshake: cenc.string,
  onopen(handshake) {
    console.log(handshake)
  }
})

Mux properties

mux.stream

API definition on GitHub

  • Returns: The framed transport stream backing this mux. (GitHub)

mux.drained

API definition on GitHub

  • Returns: The current writable backpressure state from the underlying stream. (GitHub)

Channel lifecycle

channel.open([handshake])

API definition on GitHub

  • Signature: channel.open([handshake]) (GitHub)
  • Parameters: handshake is encoded with the channel's configured handshake encoder when one was supplied. (GitHub)
  • Returns: Nothing. It allocates a local channel id and sends the open control message. (GitHub)
  • Example:
channel.open('hello-handshake')

const opened = await channel.fullyOpened()

API definition on GitHub

  • Signature: const opened = await channel.fullyOpened() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: A promise resolving to true when the channel fully opens or false if it closes first. (GitHub)
  • Example:
channel.open()
const opened = await channel.fullyOpened()

await channel.fullyClosed()

API definition on GitHub

  • Signature: await channel.fullyClosed() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: A promise resolving once the channel has been destroyed and all pending async handlers have finished. (GitHub)
  • Example:
channel.close()
await channel.fullyClosed()

channel.close()

API definition on GitHub

  • Signature: channel.close() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Nothing. Sends a close control frame and marks the channel closed locally. (GitHub)
  • Example:
channel.close()

channel.cork()

API definition on GitHub

  • Signature: channel.cork() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Nothing. Delegates to mux.cork() so this channel's writes can be batched. (GitHub)
  • Example:
channel.cork()
message.send('a')
channel.uncork()

channel.uncork()

API definition on GitHub

  • Signature: channel.uncork() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Nothing. Delegates to mux.uncork(). (GitHub)
  • Example:
channel.uncork()

Registering and sending messages

const message = channel.addMessage([options])

API definition on GitHub

  • Signature: const message = channel.addMessage([options]) (GitHub)
  • Parameters: options.encoding is the compact encoder for the message payload, options.onmessage handles incoming payloads, and options.autoBatch defaults to true. (GitHub)
  • Returns: A message descriptor with .send(...), .encoding, and .onmessage. (GitHub)
  • Example:
const ping = channel.addMessage({
  encoding: cenc.string,
  onmessage(text) {
    console.log(text)
  }
})

const drained = message.send(data, [session])

API definition on GitHub

  • Signature: const drained = message.send(data, [session]) (GitHub)
  • Parameters: data is the payload to encode. session optionally targets another channel instance that uses the same message descriptor; it defaults to the channel the message was registered on. (GitHub)
  • Returns: The mux backpressure boolean. It returns false if the target channel is already closed or if the underlying stream applied backpressure. (GitHub)
  • Example:
ping.send('hello')

message.encoding

API definition on GitHub

  • Returns: The compact encoder associated with this message type. (GitHub)

message.onmessage

API definition on GitHub

  • Returns: The handler that runs when a message of this type arrives. (GitHub)

Channel properties

channel.userData

API definition on GitHub

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

channel.protocol

API definition on GitHub

  • Returns: The channel protocol name. (GitHub)

channel.aliases

API definition on GitHub

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

channel.id

API definition on GitHub

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

channel.handshake

API definition on GitHub

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

channel.messages

API definition on GitHub

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

channel.opened

API definition on GitHub

  • Returns: true after the channel has fully opened. (GitHub)

channel.closed

API definition on GitHub

  • Returns: true after either side closes the channel. (GitHub)

channel.destroyed

API definition on GitHub

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

channel.drained

API definition on GitHub

  • Returns: The current mux backpressure state for this channel's transport. (GitHub)

Lifecycle callbacks

onopen(handshake, channel)

API definition on GitHub

  • Signature: onopen(handshake, channel) (GitHub)
  • Parameters: handshake is the decoded open payload or null. channel is the channel instance. (GitHub)
  • Returns: The callback return value is ignored, but async promises are tracked and awaited before destruction. (GitHub)
  • Example:
const channel = mux.createChannel({
  protocol: 'chat',
  onopen(handshake) {
    console.log('opened with', handshake)
  }
})

onclose(isRemote, channel)

API definition on GitHub

  • Signature: onclose(isRemote, channel) (GitHub)
  • Parameters: isRemote is true when the remote side initiated the close. channel is the channel instance. (GitHub)
  • Returns: The callback return value is ignored, but async promises are tracked. (GitHub)
  • Example:
const channel = mux.createChannel({
  protocol: 'chat',
  onclose(isRemote) {
    console.log('closed by remote?', isRemote)
  }
})

ondestroy(channel)

API definition on GitHub

  • Signature: ondestroy(channel) (GitHub)
  • Parameters: channel is the destroyed channel instance. (GitHub)
  • Returns: The callback return value is ignored, but async promises are tracked. (GitHub)
  • Example:
const channel = mux.createChannel({
  protocol: 'chat',
  ondestroy() {
    console.log('channel fully destroyed')
  }
})

ondrain(channel)

API definition on GitHub

  • Signature: ondrain(channel) (GitHub)
  • Parameters: channel is the channel whose underlying mux became writable again. (GitHub)
  • Returns: The callback return value is ignored, but async promises are tracked. (GitHub)
  • Example:
const channel = mux.createChannel({
  protocol: 'chat',
  ondrain() {
    console.log('ready for more writes')
  }
})

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