CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-protobufjs

Protocol Buffers for JavaScript with TypeScript support, providing pure JavaScript implementation for serializing and deserializing structured data using Google's Protocol Buffer format.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

code-generation.mddocs/

Code Generation

Static code generation and compilation utilities for creating optimized protobuf implementations with high-performance encoding, decoding, and validation functions.

Capabilities

Encoder Generation

Generates optimized encoding functions for specific message types.

/**
 * Generates encoder function for message type
 * @param mtype - Message type to generate encoder for
 * @returns Generated encoder function
 */
function encoder(mtype: Type): Codegen;

interface Codegen {
  /**
   * Generated function source code
   */
  source: string;
  
  /**
   * Compiled function
   */
  fn: Function;
  
  /**
   * Function generation context
   */
  gen: object;
}

Usage Examples:

const protobuf = require("protobufjs");

protobuf.load("schema.proto", function(err, root) {
    const MessageType = root.lookupType("package.Message");
    
    // Generate optimized encoder
    const encoderFn = protobuf.encoder(MessageType);
    console.log("Generated encoder:", encoderFn.source);
    
    // Use generated encoder
    const message = { field1: "value", field2: 42 };
    const writer = protobuf.Writer.create();
    encoderFn.fn(message, writer);
    const buffer = writer.finish();
});

Decoder Generation

Generates optimized decoding functions for specific message types.

/**
 * Generates decoder function for message type
 * @param mtype - Message type to generate decoder for
 * @returns Generated decoder function
 */
function decoder(mtype: Type): Codegen;

Usage Examples:

// Generate optimized decoder
const decoderFn = protobuf.decoder(MessageType);
console.log("Generated decoder:", decoderFn.source);

// Use generated decoder
const reader = protobuf.Reader.create(buffer);
const decoded = decoderFn.fn(reader, reader.uint32());
console.log("Decoded message:", decoded);

Verifier Generation

Generates validation functions for message types to check data integrity.

/**
 * Generates verifier function for message type
 * @param mtype - Message type to generate verifier for
 * @returns Generated verifier function
 */
function verifier(mtype: Type): Codegen;

Usage Examples:

// Generate optimized verifier
const verifierFn = protobuf.verifier(MessageType);
console.log("Generated verifier:", verifierFn.source);

// Use generated verifier
const message = { field1: "invalid-type", field2: "not-a-number" };
const error = verifierFn.fn(message);
if (error) {
    console.log("Validation error:", error);
} else {
    console.log("Message is valid");
}

Converter Generation

Generates object conversion functions for transforming between plain objects and message instances.

namespace converter {
  /**
   * Generates fromObject converter for message type
   * @param mtype - Message type to generate converter for
   * @returns Generated fromObject function
   */
  function fromObject(mtype: Type): Codegen;
  
  /**
   * Generates toObject converter for message type
   * @param mtype - Message type to generate converter for
   * @returns Generated toObject function
   */
  function toObject(mtype: Type): Codegen;
}

Usage Examples:

// Generate object converters
const fromObjectFn = protobuf.converter.fromObject(MessageType);
const toObjectFn = protobuf.converter.toObject(MessageType);

console.log("FromObject source:", fromObjectFn.source);
console.log("ToObject source:", toObjectFn.source);

// Use generated converters
const plainObject = { field1: "value", field2: "42" };
const message = fromObjectFn.fn(plainObject);  // Converts string "42" to number

const options = { longs: String, enums: String };
const converted = toObjectFn.fn(message, options);

Code Generation Context

Context and utilities used during code generation.

interface CodegenContext {
  /**
   * Code generation utilities
   */
  gen: {
    /**
     * Generates code block
     * @param format - Format string with placeholders
     * @param args - Arguments for placeholders
     * @returns Generated code
     */
    (format: string, ...args: any[]): string;
    
    /**
     * Indents code block
     * @param level - Indentation level
     * @returns Code generator with indentation
     */
    indent(level: number): Function;
    
    /**
     * Creates scope for variable declarations
     * @param vars - Variable declarations
     * @returns Scoped code generator
     */
    scope(vars: object): Function;
  };
  
  /**
   * Generated source code
   */
  source: string;
  
  /**
   * Compiled function
   */
  fn: Function;
}

Usage Examples:

// Access generation context
const encoderCode = protobuf.encoder(MessageType);

// Inspect generated source
console.log("Generated encoder source:");
console.log(encoderCode.source);

// Use context for custom generation
const customGenerator = encoderCode.gen;
const customCode = customGenerator("if (%s !== null) {", "field");
console.log("Custom code fragment:", customCode);

Static Code Generation

Utilities for generating static JavaScript code from protobuf definitions.

interface StaticGeneration {
  /**
   * Generates static module code
   * @param root - Root namespace
   * @param options - Generation options
   * @returns Generated module code
   */
  generateModule(root: Root, options?: StaticOptions): string;
  
  /**
   * Generates TypeScript definitions
   * @param root - Root namespace
   * @param options - Generation options
   * @returns Generated TypeScript code
   */
  generateTypes(root: Root, options?: StaticOptions): string;
}

interface StaticOptions {
  /**
   * Module format (commonjs, es6, amd, etc.)
   */
  wrap?: string;
  
  /**
   * Include imports for dependencies
   */
  imports?: string[];
  
  /**
   * Target path for imports
   */
  target?: string;
  
  /**
   * Create one file per type
   */
  oneFilePerType?: boolean;
}

Usage Examples:

// Generate static code
protobuf.load("schema.proto", function(err, root) {
    // Generate CommonJS module
    const moduleCode = protobuf.util.generateModule(root, {
        wrap: "commonjs",
        target: "static"
    });
    
    console.log("Generated static module:");
    console.log(moduleCode);
    
    // Generate TypeScript definitions
    const typeCode = protobuf.util.generateTypes(root, {
        target: "static"
    });
    
    console.log("Generated TypeScript definitions:");
    console.log(typeCode);
});

Performance Optimization

Code generation features for performance optimization.

interface OptimizationFeatures {
  /**
   * Inline field encoding/decoding
   */
  inlineFields: boolean;
  
  /**
   * Unroll loops for repeated fields
   */
  unrollLoops: boolean;
  
  /**
   * Generate specialized functions for common cases
   */
  specialize: boolean;
  
  /**
   * Optimize for message size vs speed
   */
  optimizeSize: boolean;
}

Usage Examples:

// Performance comparison
const standardEncoder = MessageType.encode;
const optimizedEncoder = protobuf.encoder(MessageType).fn;

// Benchmark encoding performance
const message = { field1: "test", field2: 42 };
const iterations = 100000;

console.time("Standard encoding");
for (let i = 0; i < iterations; i++) {
    const writer = protobuf.Writer.create();
    standardEncoder(message, writer);
    writer.finish();
}
console.timeEnd("Standard encoding");

console.time("Optimized encoding");  
for (let i = 0; i < iterations; i++) {
    const writer = protobuf.Writer.create();
    optimizedEncoder(message, writer);
    writer.finish();
}
console.timeEnd("Optimized encoding");

Dynamic vs Static Generation

Comparison and usage patterns for dynamic vs static code generation.

interface GenerationModes {
  /**
   * Dynamic generation - runtime code generation
   */
  dynamic: {
    benefits: ["Smaller bundle size", "Schema flexibility", "Runtime loading"];
    costs: ["Slower first execution", "Runtime compilation overhead"];
  };
  
  /**
   * Static generation - build-time code generation
   */
  static: {
    benefits: ["Faster execution", "No runtime compilation", "Better optimization"];
    costs: ["Larger bundle size", "Build step required", "Less flexibility"];
  };
}

Usage Examples:

// Dynamic generation (runtime)
protobuf.load("schema.proto", function(err, root) {
    const MessageType = root.lookupType("Message");
    
    // Functions are generated at runtime
    const message = MessageType.create({ field: "value" });
    const encoded = MessageType.encode(message).finish();
});

// Static generation (build time)
// Use CLI tools to generate static code:
// pbjs -t static-module -w commonjs -o generated.js schema.proto
// Then use the generated module:

const generated = require("./generated");
const message = new generated.Message({ field: "value" });
const encoded = generated.Message.encode(message).finish();

Error Handling in Generated Code

Error handling patterns in generated encoding/decoding functions.

interface GeneratedErrorHandling {
  /**
   * Type validation errors
   */
  typeErrors: {
    invalidType: string;
    missingRequired: string;
    outOfRange: string;
  };
  
  /**
   * Encoding/decoding errors
   */
  processErrors: {
    bufferUnderflow: string;
    invalidWireFormat: string;
    corruptedData: string;
  };
}

Usage Examples:

// Error handling with generated functions
const encoderFn = protobuf.encoder(MessageType).fn;
const decoderFn = protobuf.decoder(MessageType).fn;

try {
    // Encoding with type validation
    const invalidMessage = { stringField: 12345 };  // Wrong type
    const writer = protobuf.Writer.create();
    encoderFn(invalidMessage, writer);  // May throw TypeError
} catch (err) {
    console.error("Encoding error:", err.message);
}

try {
    // Decoding with format validation
    const corruptedBuffer = new Uint8Array([0xFF, 0xFF, 0xFF]);
    const reader = protobuf.Reader.create(corruptedBuffer);
    const decoded = decoderFn(reader, corruptedBuffer.length);
} catch (err) {
    console.error("Decoding error:", err.message);
}

Types

interface Codegen {
  /**
   * Generated function source code
   */
  source: string;
  
  /**
   * Compiled executable function
   */
  fn: Function;
  
  /**
   * Code generation context and utilities
   */
  gen: Function;
}

interface StaticOptions {
  wrap?: string;
  imports?: string[];
  target?: string;
  oneFilePerType?: boolean;
  keepCase?: boolean;
  alternateCommentMode?: boolean;
}

Install with Tessl CLI

npx tessl i tessl/npm-protobufjs

docs

binary-io.md

cli-tools.md

code-generation.md

index.md

proto-loading.md

reflection.md

rpc-services.md

serialization.md

tile.json