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
Compile protocol buffer schema files (.proto) into optimized JavaScript read/write functions. The compilation system generates highly optimized code for encoding and decoding specific protobuf schemas.
Compile a parsed protocol buffer schema into executable functions:
/**
* Compile a protobuf schema into read/write functions
* @param proto - Parsed protobuf schema object
* @returns Object containing generated read and write functions
*/
function compile(proto: object): Record<string, Function>;Generate raw JavaScript/TypeScript code from a protobuf schema:
interface CompileOptions {
dev?: boolean; // Include development features and comments
legacy?: boolean; // Generate CommonJS instead of ESM
noRead?: boolean; // Skip generating read functions
noWrite?: boolean; // Skip generating write functions
}
/**
* Compile a protobuf schema into raw JavaScript code
* @param proto - Parsed protobuf schema object
* @param options - Compilation options
* @returns Generated JavaScript code as string
*/
function compileRaw(proto: object, options?: CompileOptions): string;The compilation functions expect a parsed protobuf schema object (typically from resolve-protobuf-schema):
interface ProtoSchema {
name?: string;
syntax?: number; // Protocol buffer version (2 or 3)
fields?: ProtoField[];
messages?: ProtoSchema[];
enums?: ProtoEnum[];
extensions?: any;
}
interface ProtoField {
name: string;
type: string;
tag: number;
repeated?: boolean;
required?: boolean;
optional?: boolean;
oneof?: string;
map?: {
from: string; // Key type
to: string; // Value type
};
options?: {
packed?: string; // "true" or "false"
default?: string;
jstype?: string; // "JS_STRING" for string representation
};
}
interface ProtoEnum {
name: string;
values: Record<string, { value: number }>;
}For each message type in the schema, the compiler generates corresponding read and write functions:
// Generated read function signature
type ReadFunction<T> = (pbf: Pbf, end?: number) => T;
// Generated write function signature
type WriteFunction<T> = (obj: T, pbf: Pbf) => void;
// Example generated functions for a "Person" message
interface GeneratedFunctions {
readPerson: ReadFunction<Person>;
writePerson: WriteFunction<Person>;
}import { compile } from "pbf/compile";
import schema from "protocol-buffers-schema";
import fs from "fs";
// Parse .proto file
const proto = schema.parse(fs.readFileSync("person.proto"));
// Compile to functions
const { readPerson, writePerson } = compile(proto);
// Use generated functions
const person = readPerson(new Pbf(buffer));
const pbf = new Pbf();
writePerson(person, pbf);
const encoded = pbf.finish();import { compileRaw } from "pbf/compile";
import schema from "protocol-buffers-schema";
import fs from "fs";
// Parse .proto file
const proto = schema.parse(fs.readFileSync("person.proto"));
// Generate JavaScript code
const jsCode = compileRaw(proto);
// Write to file
fs.writeFileSync("person.js", jsCode);import { compileRaw } from "pbf/compile";
// Generate CommonJS module with only write functions
const code = compileRaw(proto, {
legacy: true, // Use CommonJS exports
noRead: true, // Skip read functions
dev: false // Production mode
});
// Generate ESM module with development features
const devCode = compileRaw(proto, {
legacy: false, // Use ESM exports
dev: true // Include comments and debug info
});// Schema with nested messages and enums
const proto = {
name: "AddressBook",
fields: [
{ name: "people", type: "Person", tag: 1, repeated: true }
],
messages: [
{
name: "Person",
fields: [
{ name: "name", type: "string", tag: 1 },
{ name: "id", type: "int32", tag: 2 },
{ name: "email", type: "string", tag: 3 },
{ name: "phones", type: "PhoneNumber", tag: 4, repeated: true },
{ name: "type", type: "PhoneType", tag: 5 }
]
},
{
name: "PhoneNumber",
fields: [
{ name: "number", type: "string", tag: 1 },
{ name: "type", type: "PhoneType", tag: 2 }
]
}
],
enums: [
{
name: "PhoneType",
values: {
MOBILE: { value: 0 },
HOME: { value: 1 },
WORK: { value: 2 }
}
}
]
};
const { readAddressBook, writeAddressBook, readPerson, writePerson, PhoneType } = compile(proto);// Schema with map fields
const proto = {
name: "MapExample",
fields: [
{
name: "attributes",
type: "map",
tag: 1,
map: { from: "string", to: "string" }
},
{
name: "counters",
type: "map",
tag: 2,
map: { from: "string", to: "int32" }
}
]
};
const { readMapExample, writeMapExample } = compile(proto);
// Usage
const data = {
attributes: { "color": "red", "size": "large" },
counters: { "views": 100, "likes": 25 }
};// Proto3 schema with packed repeated fields
const proto = {
name: "PackedExample",
syntax: 3, // Proto3
fields: [
{
name: "numbers",
type: "int32",
tag: 1,
repeated: true,
options: { packed: "true" }
},
{
name: "flags",
type: "bool",
tag: 2,
repeated: true,
options: { packed: "true" }
}
]
};
const { readPackedExample, writePackedExample } = compile(proto);// Schema with oneof fields
const proto = {
name: "OneOfExample",
fields: [
{ name: "name", type: "string", tag: 1 },
{ name: "email", type: "string", tag: 2, oneof: "contact" },
{ name: "phone", type: "string", tag: 3, oneof: "contact" }
]
};
const { readOneOfExample, writeOneOfExample } = compile(proto);
// Usage - only one field in the oneof group will be set
const data1 = { name: "John", email: "john@example.com", contact: "email" };
const data2 = { name: "Jane", phone: "555-1234", contact: "phone" };The compilation functions may throw errors for invalid schemas:
try {
const functions = compile(proto);
} catch (error) {
// Handle compilation errors:
// - "Unexpected type: [type]" for unsupported types
// - Schema validation errors
// - Missing field type definitions
console.error("Compilation failed:", error.message);
}Install with Tessl CLI
npx tessl i tessl/npm-pbf