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 protomuxQuickstart
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])
- Signature:
const mux = new Protomux(stream, [options])(GitHub) - Parameters:
streamis a framed stream that preserves message boundaries.options.allocoptionally overrides the buffer allocator used for outgoing frames. (GitHub) - Returns: A
Protomuxinstance bound to that stream. (GitHub) - Example:
const mux = new Protomux(secretStream)const mux = Protomux.from(streamOrMux, [options])
- Signature:
const mux = Protomux.from(streamOrMux, [options])(GitHub) - Parameters:
streamOrMuxis either an existing Protomux instance or a framed stream.optionsare 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)
- Signature:
const isMux = Protomux.isProtomux(value)(GitHub) - Parameters:
valueis any unknown object. (GitHub) - Returns:
truewhenvaluelooks like a Protomux instance. (GitHub) - Example:
console.log(Protomux.isProtomux(mux))mux.cork()
- 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()
- 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()
- Signature:
const idle = mux.isIdle()(GitHub) - Parameters: None. (GitHub)
- Returns:
truewhen there are currently no open local channels. (GitHub) - Example:
console.log(mux.isIdle())for (const channel of mux)
- 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)
- Signature:
mux.pair({ protocol, [id] }, notify)(GitHub) - Parameters:
protocolis the protocol name to match,idoptionally narrows the match to one binary channel identifier, andnotifyis 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] })
- Signature:
mux.unpair({ protocol, [id] })(GitHub) - Parameters:
protocoland optionalididentify the pairing callback to remove. (GitHub) - Returns: Nothing. (GitHub)
- Example:
mux.unpair({ protocol: 'chat' })const opened = mux.opened({ protocol, [id] })
- Signature:
const opened = mux.opened({ protocol, [id] })(GitHub) - Parameters:
protocoland optionalididentify the channel family to inspect. (GitHub) - Returns:
trueif at least one matching channel is currently open. (GitHub) - Example:
console.log(mux.opened({ protocol: 'chat' }))const channel = mux.getLastChannel({ protocol, [id] })
- Signature:
const channel = mux.getLastChannel({ protocol, [id] })(GitHub) - Parameters:
protocoland optionalididentify the channel family to inspect. (GitHub) - Returns: The most recently opened matching channel, or
nullif none is open. (GitHub) - Example:
const latest = mux.getLastChannel({ protocol: 'chat' })Creating channels
const channel = mux.createChannel(options)
- Signature:
const channel = mux.createChannel(options)(GitHub) - Parameters:
options.protocolnames the protocol,idoptionally distinguishes multiple channels under one protocol,aliasesadds alternate protocol names,uniquedefaults totrue,handshakesupplies an optional compact encoder for open-time handshake payloads,messagespre-registers message descriptors,userDatastores arbitrary metadata, andonopen,onclose,ondestroy, andondrainregister lifecycle callbacks. (GitHub) - Returns: A
Channelinstance, ornullwhen 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
- Returns: The framed transport stream backing this mux. (GitHub)
mux.drained
- Returns: The current writable backpressure state from the underlying stream. (GitHub)
Channel lifecycle
channel.open([handshake])
- Signature:
channel.open([handshake])(GitHub) - Parameters:
handshakeis 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()
- Signature:
const opened = await channel.fullyOpened()(GitHub) - Parameters: None. (GitHub)
- Returns: A promise resolving to
truewhen the channel fully opens orfalseif it closes first. (GitHub) - Example:
channel.open()
const opened = await channel.fullyOpened()await channel.fullyClosed()
- 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()
- 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()
- 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()
- 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])
- Signature:
const message = channel.addMessage([options])(GitHub) - Parameters:
options.encodingis the compact encoder for the message payload,options.onmessagehandles incoming payloads, andoptions.autoBatchdefaults totrue. (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])
- Signature:
const drained = message.send(data, [session])(GitHub) - Parameters:
datais the payload to encode.sessionoptionally 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
falseif the target channel is already closed or if the underlying stream applied backpressure. (GitHub) - Example:
ping.send('hello')message.encoding
- Returns: The compact encoder associated with this message type. (GitHub)
message.onmessage
- Returns: The handler that runs when a message of this type arrives. (GitHub)
Channel properties
channel.userData
- Returns: The arbitrary metadata value passed to
mux.createChannel(...). (GitHub)
channel.protocol
- Returns: The channel protocol name. (GitHub)
channel.aliases
- Returns: The list of alternate protocol names registered for this channel family. (GitHub)
channel.id
- Returns: The optional binary identifier distinguishing this channel family. (GitHub)
channel.handshake
- Returns: The decoded handshake payload after the channel fully opens, or
nullwhen no handshake encoder was configured. (GitHub)
channel.messages
- Returns: The array of registered message descriptors in type order. (GitHub)
channel.opened
- Returns:
trueafter the channel has fully opened. (GitHub)
channel.closed
- Returns:
trueafter either side closes the channel. (GitHub)
channel.destroyed
- Returns:
trueafter the close lifecycle and pending handlers have fully drained. (GitHub)
channel.drained
- Returns: The current mux backpressure state for this channel's transport. (GitHub)
Lifecycle callbacks
onopen(handshake, channel)
- Signature:
onopen(handshake, channel)(GitHub) - Parameters:
handshakeis the decoded open payload ornull.channelis 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)
- Signature:
onclose(isRemote, channel)(GitHub) - Parameters:
isRemoteistruewhen the remote side initiated the close.channelis 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)
- Signature:
ondestroy(channel)(GitHub) - Parameters:
channelis 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)
- Signature:
ondrain(channel)(GitHub) - Parameters:
channelis 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.