@hyperfrontend/network-protocol/packet

Packet

Purpose

The Packet module defines the two shapes a message takes on either side of the security pipeline: a plaintext packet (routing fields plus the data envelope) and the sealed wire frame that carries it. It also defines the seal and open operation types and the drop report a pipeline emits when it discards a packet.


Packet Types

PacketBase

Routing fields every plaintext packet carries. Both identifiers are UUID v4 strings.

interface PacketBase {
  readonly origin: string // The sender's identity
  readonly target: string // The recipient's identity
}

UnencryptedPacket<T>

interface UnencryptedPacket<T = any> extends PacketBase {
  readonly data: Data<T> // The data envelope
}

WirePacket

type WirePacket = Uint8Array // A sealed frame carrying one packet

Packet<T>

type Packet<T = any> = UnencryptedPacket<T> | WirePacket

Operation Types

type PacketSealer<T = any> = (packet: UnencryptedPacket<T>) => Promise<WirePacket>
type PacketOpener<T = any> = (packet: WirePacket) => Promise<UnencryptedPacket<T>>

A session protocol supplies both (see protocol/); the seal queue runs the sealer and the open queue runs the opener.


Drop Reports

type PacketDropStage = 'seal' | 'open'

interface PacketDrop {
  readonly direction: 'inbound' | 'outbound'
  readonly stage: PacketDropStage
  readonly reason: string // Why the stage rejected it
  readonly cause?: unknown // The error the stage threw, when it threw one
  readonly packet: unknown // The packet as the stage received it
}

type PacketDropHandler = (drop: PacketDrop) => void

When cause is a ProtocolError, getProtocolErrorCode(drop.cause) from security/ yields the rejection code.


Factory Functions

createUnencryptedPacket

Creates a validated, frozen plaintext packet.

function createUnencryptedPacket<T = any>(origin: string, target: string, data: Data<T>): UnencryptedPacket<T>
import { createUnencryptedPacket } from '@hyperfrontend/network-protocol/browser/packet'
import { createData } from '@hyperfrontend/network-protocol/browser/data'

const packet = createUnencryptedPacket(originId, targetId, await createData(pid, 1, { action: 'ping' }))
// => { origin, target, data: { pid, id, sequence, message, schema, schemaHash } }

createPacketBase

Creates the frozen routing structure alone.

function createPacketBase(origin: string, target: string): PacketBase

Validation Functions

FunctionAccepts
isValidOrigin(value)A 36-character UUID v4 string
isValidTarget(value)A 36-character UUID v4 string
isValidUnencryptedPacket(value)A valid origin, a valid target, and a valid data envelope
isValidWirePacket(value)A Uint8Array with at least one byte
import { isValidUnencryptedPacket, isValidWirePacket } from '@hyperfrontend/network-protocol/browser/packet'

if (isValidWirePacket(event.data)) {
  channel.receive(event.data)
}

Error Handling

The creators throw in the caller's frame:

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

createUnencryptedPacket(originId, 'not-a-uuid', data)
// Error: 'Cannot create a packet without a valid target value'

createUnencryptedPacket(originId, targetId, {})
// Error: 'Cannot create a packet without a valid data value'

The pipelines never throw for a packet they reject; they report it through onDrop (see queue/).


Relationship to Other Modules


See Also

Related Modules

ModuleRelationship
data/Provides the Data envelope a packet carries
protocol/Supplies the sealer and opener
security/Error codes carried in a drop's cause
sender/Builds and seals packets
receiver/Opens frames into packets
queue/Runs the seal and open operations
API reference for packet is not available yet; rebuild docs to regenerate.