@hyperfrontend/network-protocol/sender

Sender

Purpose

The Sender module provides the outbound half of a channel: packets are assembled from an origin, a target, and a data envelope, sealed one at a time on the session's sending key, and handed to the transport as wire frames.


Key Interfaces

Sender<T>

interface Sender<T = any> {
  readonly send: SendFn<T> // Builds a packet and queues it for sealing
  readonly stop: () => void // Pauses sealing (packets accumulate)
  readonly resume: () => void // Resumes sealing
  readonly queue: OutboundQueue // The packets waiting to be sealed
}

SendFn<T>

type SendFn<T = any> = (origin: string, target: string, data: Data<T>) => void

SendPacketFn

Transmits a sealed frame to the transport.

type SendPacketFn = (packet: Uint8Array) => void

OutboundQueue

interface OutboundQueue {
  readonly size: number // Packets waiting to be sealed
}

CreateSender<T> and SenderFactory

type CreateSender<T = any> = (
  label: string,
  sender: SendPacketFn,
  logger: Logger,
  seal: PacketSealer<T>,
  onDrop?: PacketDropHandler
) => Sender<T>

type SenderFactory = CreateSender

Factory Functions

createSender

Location: @hyperfrontend/network-protocol/browser/sender, @hyperfrontend/network-protocol/node/sender

ParameterTypeDescription
labelstringIdentifier for logging (a channel passes '<label> sender')
sendPacketSendPacketFnTransmits each sealed frame
loggerLoggerLogger instance from @hyperfrontend/logging
sealPacketSealer<T>The session's sealer, protocol.seal
onDropPacketDropHandlerOptional; receives each packet the sealer rejects
import { createSender } from '@hyperfrontend/network-protocol/browser/sender'

const sender = createSender(
  'host sender',
  (frame) => frameWindow.postMessage(frame, origin, [frame.buffer]),
  logger,
  protocol.seal,
  (drop) => report(drop)
)
sender.send(originId, targetId, data)

A channel creates its sender for you; standalone use needs a Protocol instance from a provider (see protocol/).


Outbound Pipeline

send validates the origin, the target, and the data envelope synchronously and throws in the caller's frame on a malformed packet. Everything after that is asynchronous: the seal queue processes one packet at a time, and each sealed frame goes to sendPacket in order.


Lifecycle Management

sender.stop() // Packets keep accumulating; nothing is sealed
sender.resume() // Accumulated packets seal in FIFO order

Queue Monitoring

if (sender.queue.size > 100) {
  sender.stop()
}

Error Handling

send throws for invalid input (see packet/):

sender.send('not-a-uuid', targetId, data)
// Error: 'Cannot create a packet without a valid origin value'

A packet the sealer rejects is logged and reported through onDrop as { direction: 'outbound', stage: 'seal', reason, cause, packet }, never thrown. The reasons are those of the seal queue (see queue/); a cause that is a ProtocolError carries a code such as counter-exhausted or invalid-session.


Relationship to Other Modules


See Also

Related Modules

ModuleRelationship
receiver/Counterpart for inbound frames
channel/Composes sender into channel
queue/The seal queue
packet/Packet types processed
API reference for sender is not available yet; rebuild docs to regenerate.