@hyperfrontend/network-protocol/queue

Queue

Purpose

The Queue module provides the FIFO processing queue behind each pipeline stage, and the two specialised queues built on it: the seal queue (plaintext packets in, sealed frames out) and the open queue (frames in, plaintext packets out). Strict one-at-a-time processing is what lets a protocol assign a monotonically increasing counter to every frame.


Key Interfaces

Queue<T>

interface Queue<T extends object> {
  readonly addMessage: (message: T) => void // Enqueue; starts processing when autoStart is on
  readonly isRunning: () => boolean // Whether the queue is processing
  readonly stop: () => void // Pause processing (messages accumulate)
  readonly resume: () => void // Resume processing accumulated messages
  readonly size: () => number // Number of messages waiting
  readonly currentMessage: () => T | null // The message being processed
}

MessageHandler<T>

type MessageHandler<T extends object> = (message: T) => Promise<void> | void

QueueFailureHandler

Called with the rejected input, why it was rejected, and the error the operation threw when it threw one.

type QueueFailureHandler = (raw: unknown, reason: string, cause?: unknown) => void

QueueOperation, QueueCreatorArguments, QueueCreatorValidity

type QueueOperation = PacketSealer | PacketOpener

interface QueueCreatorArguments<T = any> {
  label: string
  operation: QueueOperation
  logger: Logger
  onSuccess: (packet: T) => void
  onFail: QueueFailureHandler
}

interface QueueCreatorValidity {
  label: boolean
  operation: boolean
  logger: boolean
  onSuccess: boolean
  onFail: boolean
}

SealQueueCreater and OpenQueueCreater

type SealQueueCreater = (
  label: string,
  seal: PacketSealer,
  logger: Logger,
  onSuccess: (packet: WirePacket) => void,
  onFail: QueueFailureHandler
) => Queue<UnencryptedPacket>

type OpenQueueCreater = (
  label: string,
  open: PacketOpener,
  logger: Logger,
  onSuccess: (packet: UnencryptedPacket) => void,
  onFail: QueueFailureHandler
) => Queue<WirePacket>

Queue Types


Factory Functions

createQueue<T>

Location: @hyperfrontend/network-protocol/queue

function createQueue<T extends Record<string, any>>(processMessage: MessageHandler<T>, autoStart = true): Queue<T>

Messages are processed strictly one at a time in arrival order; the next one starts only after the handler's promise settles. The backing store is an array with a moving head, so a pull is constant time; once 1024 pulled slots sit at the front the array is compacted.

import { createQueue } from '@hyperfrontend/network-protocol/queue'

const queue = createQueue<{ id: string }>(async (message) => {
  await handle(message)
})
queue.addMessage({ id: '1' }) // starts processing at once

Throws processMessage must be a function and autoStart must be a boolean at creation; addMessage throws a TypeError (Message must be a non-null object) for anything that is not an object.

createSealQueue

import { createSealQueue } from '@hyperfrontend/network-protocol/queue'

const sealing = createSealQueue(
  'comms sender',
  protocol.seal,
  logger,
  (frame) => transport.post(frame),
  (packet, reason, cause) => report(reason, cause)
)
sealing.addMessage(unencryptedPacket)

Each packet is checked with isValidUnencryptedPacket, sealed, and the result checked with isValidWirePacket before onSuccess.

createOpenQueue

import { createOpenQueue } from '@hyperfrontend/network-protocol/queue'

const opening = createOpenQueue(
  'comms receiver',
  protocol.open,
  logger,
  (packet) => deliver(packet),
  (frame, reason, cause) => report(reason, cause)
)
opening.addMessage(frame)

Each frame is checked with isValidWirePacket, opened, and the result checked with isValidUnencryptedPacket before onSuccess.


Lifecycle Management

queue.stop()
queue.isRunning() // false once the current message settles

queue.addMessage(a) // accumulates while stopped
queue.addMessage(b)
queue.size() // 2

queue.resume() // processes a, then b

currentMessage() returns the message in flight, or null between messages.


Error Handling

A rejected input never blocks the queue: the stage logs it, calls onFail, and moves on to the next message.

Queuereasoncause
sealInvalid packet ignorednone
sealthe message of the error seal threw (a ProtocolError)the thrown error
sealSealed packet is not validnone
openInvalid frame ignorednone
openthe message of the error open threw (replay, forgery, malformed frame)the thrown ProtocolError
openOpened packet is not validnone
bothAn unexpected error occurred. <error>the thrown error

The sender and receiver translate these calls into PacketDrop reports for the channel's onDrop.

Validation Errors

The specialised creators validate their arguments and throw Cannot create seal queue without ... or Cannot create open queue without ... followed by a label, seal function / open function, a logger, a success callback function, or a failed callback function.


Relationship to Other Modules


See Also

Related Modules

ModuleRelationship
sender/Wraps the seal queue
receiver/Wraps the open queue
packet/Packet types processed in queues
protocol/Supplies the seal and open operations

API Reference§

ƒ Functions

§function

createQueue<T>(processMessage: MessageHandler<T>, autoStart: boolean): Queue<T>

Creates a message processing queue with FIFO ordering.
Messages are processed strictly one at a time in arrival order; the next one starts only after the handler's promise settles. That ordering is what lets a protocol assign a monotonically increasing counter to each frame it seals or opens.
A handler that rejects loses only its own message: the rejection is contained, the next message starts, and the queue stays resumable. Reporting the failure is the handler's job.

Parameters

NameTypeDescription
§processMessage
MessageHandler<T>
The handler function to process each message
§autoStart
boolean
Whether to automatically start processing messages (default: true)
(default: true)

Returns

Queue<T>
A Queue instance with methods to manage message processing

Example

Creating a message processing queue

const queue = createQueue(async (message) => {
  await processMessage(message)
})
queue.addMessage({ type: 'ping', data: {} })

Interfaces

§interface

Queue

Message processing queue interface

Properties

§readonly addMessage:(message: T) => void
Adds a message to the queue
§readonly currentMessage:() => T
Returns the message currently being processed
§readonly isRunning:() => boolean
Returns whether the queue is processing messages
§readonly resume:() => void
Resumes queue processing
§readonly size:() => number
Returns the number of messages in the queue
§readonly stop:() => void
Stops queue processing
§interface

QueueCreatorArguments

Arguments for creating a queue instance

Properties

§label:string
Queue label for logging
§logger:Logger
Logger instance
§onFail:QueueFailureHandler
Callback on packet processing failure
§onSuccess:(packet: T) => void
Callback on successful packet processing
§operation:QueueOperation
Packet operation function
§interface

QueueCreatorValidity

Validation result for queue creator arguments

Properties

§label:boolean
Whether label is valid
§logger:boolean
Whether logger is valid
§onFail:boolean
Whether onFail callback is valid
§onSuccess:boolean
Whether onSuccess callback is valid
§operation:boolean
Whether operation is valid

Types

§type

MessageHandler

Function that handles messages from a queue
type MessageHandler = (message: T) => Promise<void> | void
§type

OpenQueueCreater

Factory function for creating open queues
type OpenQueueCreater = (label: string, open: PacketOpener, logger: Logger, onSuccess: (packet: UnencryptedPacket) => void, onFail: QueueFailureHandler) => Queue<WirePacket>
§type

QueueFailureHandler

Called with the rejected input, why it was rejected, and the error the operation threw when it threw one
type QueueFailureHandler = (raw: unknown, reason: string, cause?: unknown) => void
§type

QueueOperation

The packet operation a specialised queue runs
type QueueOperation = PacketSealer | PacketOpener
§type

SealQueueCreater

Factory function for creating seal queues
type SealQueueCreater = (label: string, seal: PacketSealer, logger: Logger, onSuccess: (packet: WirePacket) => void, onFail: QueueFailureHandler) => Queue<UnencryptedPacket>

Variables

§type

createOpenQueue

Creates the inbound queue: wire bytes in, plaintext packets out, one at a time.
Bytes that are not a wire packet, an open that throws (a forged, replayed, or foreign frame), or an open that yields an invalid packet are reported through onFail and the queue moves on. Processing one frame at a time is what keeps a session's replay counter exact.
§type

createSealQueue

Creates the outbound queue: plaintext packets in, sealed wire bytes out, one at a time.
A packet that is not a valid plaintext packet, a seal that throws, or a seal that yields something other than wire bytes is reported through onFail and the queue moves on.