A low-level, lightweight protocol buffers implementation for JavaScript with high-performance binary serialization and deserialization capabilities.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core protocol buffer reading and writing functionality with support for all protocol buffer data types, packed fields, and direct buffer manipulation.
Read protocol buffer messages using field-based callbacks:
class Pbf {
/**
* Read all fields in a message using a callback function
*/
readFields<T>(readField: (tag: number, result: T, pbf: Pbf) => void, result: T, end?: number): T;
/**
* Read an embedded message
*/
readMessage<T>(readField: (tag: number, result: T, pbf: Pbf) => void, result: T): T;
}Read individual data types from the buffer:
class Pbf {
// Integer types
readVarint(isSigned?: boolean): number;
readSVarint(): number;
readFixed32(): number;
readSFixed32(): number;
readFixed64(): number;
readSFixed64(): number;
// Floating point types
readFloat(): number;
readDouble(): number;
// Other types
readBoolean(): boolean;
readString(): string;
readBytes(): Uint8Array;
// Legacy compatibility
readVarint64(): number;
// Internal helper for packed field reading
readPackedEnd(): number;
}Read packed repeated fields efficiently:
class Pbf {
readPackedVarint(arr?: number[], isSigned?: boolean): number[];
readPackedSVarint(arr?: number[]): number[];
readPackedBoolean(arr?: boolean[]): boolean[];
readPackedFloat(arr?: number[]): number[];
readPackedDouble(arr?: number[]): number[];
readPackedFixed32(arr?: number[]): number[];
readPackedSFixed32(arr?: number[]): number[];
readPackedFixed64(arr?: number[]): number[];
readPackedSFixed64(arr?: number[]): number[];
}Control reading position and skip unwanted fields:
class Pbf {
buf: Uint8Array; // Underlying buffer
dataView: DataView; // Data view for binary operations
pos: number; // Current reading/writing position
type: number; // Current field wire type
length: number; // Total buffer length
/**
* Skip a field value based on its wire type
*/
skip(val: number): void;
/**
* Internal helper method for packed field reading
* Determines the end position for packed field data
*/
readPackedEnd(): number;
}Manage buffer allocation and finalization:
class Pbf {
/**
* Ensure buffer has space for at least min bytes
*/
realloc(min: number): void;
/**
* Finalize buffer and return the written data
*/
finish(): Uint8Array;
/**
* Write a field tag and wire type
*/
writeTag(tag: number, type: number): void;
}Write individual data types to the buffer:
class Pbf {
// Integer types
writeVarint(val: number): void;
writeSVarint(val: number): void;
writeFixed32(val: number): void;
writeSFixed32(val: number): void;
writeFixed64(val: number): void;
writeSFixed64(val: number): void;
// Floating point types
writeFloat(val: number): void;
writeDouble(val: number): void;
// Other types
writeBoolean(val: boolean): void;
writeString(str: string): void;
writeBytes(buffer: Uint8Array): void;
}Write fields with tags and wire types:
class Pbf {
// Field writing with tags
writeVarintField(tag: number, val: number): void;
writeSVarintField(tag: number, val: number): void;
writeFixed32Field(tag: number, val: number): void;
writeSFixed32Field(tag: number, val: number): void;
writeFixed64Field(tag: number, val: number): void;
writeSFixed64Field(tag: number, val: number): void;
writeFloatField(tag: number, val: number): void;
writeDoubleField(tag: number, val: number): void;
writeBooleanField(tag: number, val: boolean): void;
writeStringField(tag: number, str: string): void;
writeBytesField(tag: number, buffer: Uint8Array): void;
}Write embedded messages and raw message data:
class Pbf {
/**
* Write an embedded message with tag
*/
writeMessage<T>(tag: number, fn: (obj: T, pbf: Pbf) => void, obj: T): void;
/**
* Write a raw message without tag
*/
writeRawMessage<T>(fn: (obj: T, pbf: Pbf) => void, obj: T): void;
}Write packed repeated fields efficiently:
class Pbf {
writePackedVarint(tag: number, arr: number[]): void;
writePackedSVarint(tag: number, arr: number[]): void;
writePackedBoolean(tag: number, arr: boolean[]): void;
writePackedFloat(tag: number, arr: number[]): void;
writePackedDouble(tag: number, arr: number[]): void;
writePackedFixed32(tag: number, arr: number[]): void;
writePackedSFixed32(tag: number, arr: number[]): void;
writePackedFixed64(tag: number, arr: number[]): void;
writePackedSFixed64(tag: number, arr: number[]): void;
}const pbf = new Pbf(buffer);
const data = pbf.readFields(readDataField, {});
function readDataField(tag, data, pbf) {
if (tag === 1) data.name = pbf.readString();
else if (tag === 2) data.version = pbf.readVarint();
else if (tag === 3) data.tags = pbf.readPackedVarint(data.tags || []);
else if (tag === 4) {
data.metadata = pbf.readMessage(readMetadata, {});
}
}
function readMetadata(tag, metadata, pbf) {
if (tag === 1) metadata.author = pbf.readString();
else if (tag === 2) metadata.timestamp = pbf.readFixed64();
}const pbf = new Pbf();
writeData(data, pbf);
const buffer = pbf.finish();
function writeData(data, pbf) {
if (data.name) pbf.writeStringField(1, data.name);
if (data.version) pbf.writeVarintField(2, data.version);
if (data.tags && data.tags.length) pbf.writePackedVarint(3, data.tags);
if (data.metadata) pbf.writeMessage(4, writeMetadata, data.metadata);
}
function writeMetadata(metadata, pbf) {
if (metadata.author) pbf.writeStringField(1, metadata.author);
if (metadata.timestamp) pbf.writeFixed64Field(2, metadata.timestamp);
}const pbf = new Pbf(buffer);
let metadataPos = -1;
// First pass - save position of expensive field
pbf.readFields((tag, result, pbf) => {
if (tag === 1) result.name = pbf.readString();
else if (tag === 4) metadataPos = pbf.pos; // Save position, don't read yet
}, {});
// Later - decode the expensive field when needed
if (metadataPos >= 0) {
pbf.pos = metadataPos;
const metadata = pbf.readMessage(readMetadata, {});
}declare const PBF_VARINT: 0; // int32, int64, uint32, uint64, sint32, sint64, bool, enum
declare const PBF_FIXED64: 1; // double, fixed64, sfixed64
declare const PBF_BYTES: 2; // string, bytes, embedded messages, packed repeated fields
declare const PBF_FIXED32: 5; // float, fixed32, sfixed32Install with Tessl CLI
npx tessl i tessl/npm-pbf