Sender
Purpose
The Sender module provides the outbound message pipeline, orchestrating the flow of messages through encryption, serialization, and obfuscation queues before transmission.
Key Interfaces
Sender<T>
The main sender interface combining queue access with send functionality.
interface Sender<T = any> extends OutboundQueues {
send: SendFn<T> // Send messages through the pipeline
stop: () => void // Pause all outbound processing
resume: () => void // Resume outbound processing
encryptionQueue: OutboundQueue
serializationQueue: OutboundQueue
obfuscationQueue: OutboundQueue
}
SendFn<T>
Function type for sending messages with routing information.
type SendFn<T = any> = (origin: string, target: string, data: Data<T>) => void
SendPacketFn
Low-level function type for transmitting obfuscated packets to the transport layer.
type SendPacketFn = (packet: Uint8Array) => void
OutboundQueue
Access to queue size for monitoring.
interface OutboundQueue {
size: number // Current number of messages in the queue
}
OutboundQueues
Combined access to all outbound queues.
interface OutboundQueues {
encryptionQueue: OutboundQueue
serializationQueue: OutboundQueue
obfuscationQueue: OutboundQueue
}
Factory Functions
createSenderFactory
Creates a sender factory with injected serialization.
Location: @hyperfrontend/network-protocol/lib/sender
Signature:
function createSenderFactory(createSerializedEncryptedPacket: PacketSerialization): CreateSender
Parameters:
| Parameter | Type | Description |
|---|---|---|
createSerializedEncryptedPacket |
PacketSerialization |
Function to serialize encrypted packets |
Returns: CreateSender - A factory function that creates Sender instances.
Example:
import { createSerializedEncryptedPacketCreator } from '@hyperfrontend/network-protocol/lib/packet/creators'
import { uint8ArrayToBase64 } from '@hyperfrontend/string-utils/browser'
import { createSenderFactory } from '@hyperfrontend/network-protocol/lib/sender/creators'
// Create serialization function (platform-specific)
const serializePacket = createSerializedEncryptedPacketCreator(uint8ArrayToBase64)
// Create sender factory
const createSender = createSenderFactory(serializePacket)
// Create a sender instance
const sender = createSender(
'my-sender',
(packet) => transport.send(packet), // SendPacketFn
logger,
protocol.packetEncryption,
protocol.packetObfuscation
)
CreateSender<T> (Sender Factory)
The factory function produced by createSenderFactory.
Signature:
type CreateSender<T = any> = (
label: string,
sender: SendPacketFn,
logger: Logger,
packetEncryption: PacketEncryption<T>,
packetObfuscation: PacketObfuscation
) => Sender<T>
Parameters:
| Parameter | Type | Description |
|---|---|---|
label |
string |
Identifier for logging (e.g., 'channel-1 sender') |
sender |
SendPacketFn |
Transport function to send obfuscated packets |
logger |
Logger |
Logger instance from @hyperfrontend/logging |
packetEncryption |
PacketEncryption<T> |
Function to encrypt unencrypted packets |
packetObfuscation |
PacketObfuscation |
Function to obfuscate serialized packets |
Outbound Pipeline
When you call sender.send(origin, target, data):
Lifecycle Management
Stop/Resume
// Pause all outbound processing
sender.stop()
// Messages continue to accumulate in queues
// Resume processing (processes accumulated messages in FIFO order)
sender.resume()
Stop Order
When stop() is called, queues are stopped in order:
- Encryption queue (entry point)
- Serialization queue
- Obfuscation queue
Resume Order
When resume() is called, queues are resumed in reverse order:
- Obfuscation queue (exit point - resume first to accept output)
- Serialization queue
- Encryption queue (resume last to start feeding the chain)
Queue Monitoring
Access queue sizes for backpressure detection:
// Monitor individual queue depths
console.log('Encryption queue:', sender.encryptionQueue.size)
console.log('Serialization queue:', sender.serializationQueue.size)
console.log('Obfuscation queue:', sender.obfuscationQueue.size)
// Total pending outbound messages
const totalPending = sender.encryptionQueue.size + sender.serializationQueue.size + sender.obfuscationQueue.size
// Backpressure detection
const BACKPRESSURE_THRESHOLD = 100
if (totalPending > BACKPRESSURE_THRESHOLD) {
console.warn('Outbound backpressure detected')
sender.stop()
// Signal upstream to slow down
}
Usage Example
import { createProtocol } from '@hyperfrontend/network-protocol/browser/v1'
import { createSenderFactory } from '@hyperfrontend/network-protocol/browser/sender'
import { createLogger } from '@hyperfrontend/logging'
const logger = createLogger({ level: 'info' })
const protocolProvider = createProtocol(logger, 60)
const protocol = protocolProvider(
(packet) => transport.send(packet),
(packet) => {
/* receive callback */
}
)
// Create sender (typically done via channel, but can be standalone)
const sender = createSender('my-sender', protocol.send, logger, protocol.packetEncryption, protocol.packetObfuscation)
// Send a message
sender.send('https://app.example.com', 'https://widget.example.com', createData({ type: 'greeting', message: 'Hello!' }))
Relationship to Other Modules
See Also
- Library Index - All modules
- Architecture Guide - Sender architecture
- Browser Entry - Browser-specific sender
- Node Entry - Node.js-specific sender
Related Modules
| Module | Relationship |
|---|---|
| receiver/ | Counterpart for inbound messages |
| channel/ | Composes sender into channel |
| queue/ | Underlying queue implementation |
| packet/ | Packet types processed |