@endo/lp32Length-prefixed message streams using 32-bit host byte order framing, implemented as async iterators.
This package implements the binary message framing protocol used by WebExtension Native Messaging. Each message is prefixed with a 32-bit unsigned integer indicating the message length in bytes, using host byte order.
The protocol is simple:
For example, a 5-byte message hello is transmitted as:
[0x05, 0x00, 0x00, 0x00] [h, e, l, l, o]
This package provides hardened async iterator streams for reading and writing
these length-prefixed messages, represented as Uint8Arrays.
Use makeLp32Reader to wrap an async iterable of byte chunks and produce
an async iterable of complete messages:
import { makeLp32Reader } from '@endo/lp32';
const reader = makeLp32Reader(byteStream, {
name: '<my-stream>', // optional, for error messages
maxMessageLength: 1024 * 1024, // optional, defaults to 1MB
});
for await (const message of reader) {
// message is a Uint8Array containing one complete message
console.log(new TextDecoder().decode(message));
}
Use makeLp32Writer to wrap an output stream and automatically frame
messages with length prefixes:
import { makeLp32Writer } from '@endo/lp32';
const writer = makeLp32Writer(outputStream, {
name: '<my-writer>',
maxMessageLength: 1024 * 1024,
});
const encoder = new TextEncoder();
await writer.next(encoder.encode('hello'));
await writer.next(encoder.encode('world'));
await writer.return();
import { makePipe } from '@endo/stream';
import { makeLp32Reader, makeLp32Writer } from '@endo/lp32';
const [input, output] = makePipe();
const writer = makeLp32Writer(output);
const reader = makeLp32Reader(input);
const encoder = new TextEncoder();
const decoder = new TextDecoder();
// Producer
await writer.next(encoder.encode('message 1'));
await writer.next(encoder.encode('message 2'));
await writer.return();
// Consumer
for await (const message of reader) {
console.log(decoder.decode(message));
}
makeLp32Reader(reader, options?)Creates a reader that decodes length-prefixed messages from a byte stream.
Parameters:
reader - An Iterable<Uint8Array> or AsyncIterable<Uint8Array>options.name - Optional name for error messagesoptions.maxMessageLength - Maximum allowed message size (default: 1MB)options.initialCapacity - Initial buffer size (default: 1024)Returns: An async iterator yielding Uint8Array messages.
makeLp32Writer(output, options?)Creates a writer that encodes messages with length prefixes.
Parameters:
output - A Writer<Uint8Array, undefined> from @endo/streamoptions.name - Optional name for error messagesoptions.maxMessageLength - Maximum allowed message size (default: 1MB)Returns: A Writer<Uint8Array, undefined> that frames messages.
This package depends on Hardened JavaScript.
The environment must be locked down before use, typically via @endo/init.
All exported functions and the streams they produce are hardened.
npm install @endo/lp32
Or with yarn:
yarn add @endo/lp32