CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-msgpackr

Ultra-fast MessagePack implementation with extensions for records and structured cloning

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

extensions.mddocs/

Extensions

Custom MessagePack extensions and utility functions for specialized use cases, enabling support for custom data types and advanced functionality.

Capabilities

addExtension Function

Registers custom MessagePack extensions to handle specialized data types or implement custom serialization logic.

/**
 * Registers a custom MessagePack extension
 * @param extension - Extension definition object
 */
function addExtension(extension: Extension): void;

interface Extension {
  Class?: Function;                              // Constructor function to match
  type?: number;                                // MessagePack extension type number (0-127)
  pack?(value: any): Buffer | Uint8Array;       // Custom packing function
  unpack?(messagePack: Buffer | Uint8Array): any; // Custom unpacking function
  read?(datum: any): any;                       // Read transformation
  write?(instance: any): any;                   // Write transformation
}

Usage Examples:

import { addExtension, pack, unpack } from "msgpackr";

// Custom Date extension with millisecond precision
addExtension({
  type: 1,
  Class: Date,
  write: (date) => date.getTime(),
  read: (timestamp) => new Date(timestamp)
});

// Usage
const now = new Date();
const packed = pack({ timestamp: now, message: "Hello" });
const unpacked = unpack(packed);
console.log(unpacked.timestamp instanceof Date); // true

// Custom class extension
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  
  distance(other) {
    return Math.sqrt((this.x - other.x) ** 2 + (this.y - other.y) ** 2);
  }
}

addExtension({
  type: 2,
  Class: Point,
  write: (point) => [point.x, point.y],
  read: (coords) => new Point(coords[0], coords[1])
});

// Usage
const point = new Point(10, 20);
const packed = pack({ location: point });
const unpacked = unpack(packed);
console.log(unpacked.location instanceof Point); // true
console.log(unpacked.location.distance(new Point(0, 0))); // 22.36...

Binary Data Extensions

Handling specialized binary data formats.

import { addExtension } from "msgpackr";

// Custom binary format extension
addExtension({
  type: 10,
  pack: (value) => {
    if (value && value.type === 'customBinary') {
      return Buffer.from(value.data, 'base64');
    }
  },
  unpack: (buffer) => ({
    type: 'customBinary',
    data: buffer.toString('base64'),
    size: buffer.length
  })
});

// UUID extension
addExtension({
  type: 11,
  pack: (value) => {
    if (typeof value === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f-]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)) {
      return Buffer.from(value.replace(/-/g, ''), 'hex');
    }
  },
  unpack: (buffer) => {
    const hex = buffer.toString('hex');
    return `${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20,32)}`;
  }
});

Compression Extensions

Implementing compression for large data structures.

import { addExtension } from "msgpackr";
import { gzipSync, gunzipSync } from "zlib";

// Compression extension for large objects
addExtension({
  type: 20,
  pack: (value) => {
    if (value && value.compress === true) {
      const json = JSON.stringify(value.data);
      if (json.length > 1000) { // Only compress large objects
        return gzipSync(Buffer.from(json));
      }
    }
  },
  unpack: (buffer) => {
    const decompressed = gunzipSync(buffer);
    return {
      compress: true,
      data: JSON.parse(decompressed.toString())
    };
  }
});

// Usage
const largeData = {
  compress: true,
  data: { /* large object */ }
};

const packed = pack(largeData); // Automatically compressed
const unpacked = unpack(packed); // Automatically decompressed

clearSource Function

Clears internal source buffer references to free memory and prevent memory leaks.

/**
 * Clears internal source buffer references
 * Useful for memory management in long-running applications
 */
function clearSource(): void;

Usage Examples:

import { unpack, clearSource } from "msgpackr";

// Process large amounts of data
for (let i = 0; i < 10000; i++) {
  const data = unpack(someBuffer);
  processData(data);
  
  // Periodically clear source references to prevent memory buildup
  if (i % 1000 === 0) {
    clearSource();
  }
}

// Clear after batch processing
function processBatch(buffers) {
  const results = buffers.map(buffer => unpack(buffer));
  clearSource(); // Free memory after batch
  return results;
}

roundFloat32 Function

Rounds a number to float32 precision, useful for ensuring consistent floating-point behavior.

/**
 * Rounds a number to float32 precision
 * @param float32Number - Number to round to float32 precision
 * @returns Number rounded to float32 precision
 */
function roundFloat32(float32Number: number): number;

Usage Examples:

import { roundFloat32, pack, unpack, FLOAT32_OPTIONS, Packr } from "msgpackr";

// Manual float32 rounding
const preciseNumber = 1.23456789012345;
const rounded = roundFloat32(preciseNumber);
console.log(rounded); // 1.2345678806304932 (float32 precision)

// Use with float32 packing
const packr = new Packr({ useFloat32: FLOAT32_OPTIONS.ALWAYS });

const data = {
  value1: roundFloat32(3.14159265359),
  value2: roundFloat32(2.71828182846)
};

const packed = packr.pack(data);
const unpacked = packr.unpack(packed);

// Verify consistency
console.log(data.value1 === unpacked.value1); // true

// Precision comparison
function compareFloatPrecision(original) {
  const float32Rounded = roundFloat32(original);
  const packed = pack(original);
  const unpacked = unpack(packed);
  
  console.log('Original:', original);
  console.log('Float32 rounded:', float32Rounded);
  console.log('Pack/unpack result:', unpacked);
}

compareFloatPrecision(Math.PI);

Advanced Extension Patterns

Conditional Extensions

Extensions that apply based on runtime conditions.

import { addExtension } from "msgpackr";

// Environment-specific extension
addExtension({
  type: 30,
  pack: (value) => {
    if (value && value.type === 'encrypted' && process.env.NODE_ENV === 'production') {
      return encryptData(value.data);
    }
  },
  unpack: (buffer) => {
    if (process.env.NODE_ENV === 'production') {
      return {
        type: 'encrypted',
        data: decryptData(buffer)
      };
    }
  }
});

// Size-based extension
addExtension({
  type: 31,
  pack: (value) => {
    if (Array.isArray(value) && value.length > 1000) {
      // Use special encoding for large arrays
      return Buffer.concat([
        Buffer.from([0x01]), // Format marker
        Buffer.from(JSON.stringify(value.length)),
        ...value.map(item => Buffer.from(JSON.stringify(item)))
      ]);
    }
  },
  unpack: (buffer) => {
    if (buffer[0] === 0x01) {
      // Decode special large array format
      // Implementation would parse the custom format
    }
  }
});

Versioned Extensions

Extensions that handle different data format versions.

import { addExtension } from "msgpackr";

// Versioned data extension
addExtension({
  type: 40,
  pack: (value) => {
    if (value && value._version) {
      const version = Buffer.from([value._version]);
      const data = Buffer.from(JSON.stringify(value.data));
      return Buffer.concat([version, data]);
    }
  },
  unpack: (buffer) => {
    const version = buffer[0];
    const data = JSON.parse(buffer.slice(1).toString());
    
    // Handle different versions
    switch (version) {
      case 1:
        return { _version: 1, data: upgradeV1ToV2(data) };
      case 2:
        return { _version: 2, data };
      default:
        throw new Error(`Unsupported version: ${version}`);
    }
  }
});

Performance-Optimized Extensions

Extensions designed for maximum performance.

import { addExtension } from "msgpackr";

// High-performance binary data extension
const binaryPool = new Map(); // Reuse buffers

addExtension({
  type: 50,
  pack: (value) => {
    if (value instanceof Uint8Array) {
      // Direct binary pass-through for optimal performance
      return value;
    }
  },
  unpack: (buffer) => {
    // Reuse typed array views for better performance
    const key = buffer.length;
    if (!binaryPool.has(key)) {
      binaryPool.set(key, new Uint8Array(key));
    }
    
    const result = binaryPool.get(key);
    result.set(buffer);
    return result;
  }
});

// Fast string interning extension
const stringInternMap = new Map();
let stringId = 0;

addExtension({
  type: 51,
  pack: (value) => {
    if (typeof value === 'string' && value.length > 20) {
      if (!stringInternMap.has(value)) {
        stringInternMap.set(value, stringId++);
      }
      const id = stringInternMap.get(value);
      return Buffer.from([id & 0xFF, (id >> 8) & 0xFF]);
    }
  },
  unpack: (buffer) => {
    const id = buffer[0] | (buffer[1] << 8);
    // Reverse lookup would need additional data structure
    // This is a simplified example
    return `interned_string_${id}`;
  }
});

Constants and Utilities

Acceleration Status

Check if native acceleration is available and enabled.

/**
 * Indicates whether native acceleration (msgpackr-extract) is enabled
 */
let isNativeAccelerationEnabled: boolean;

Usage Examples:

import { isNativeAccelerationEnabled } from "msgpackr";

console.log('Native acceleration:', isNativeAccelerationEnabled);

if (isNativeAccelerationEnabled) {
  console.log('Using optimized native implementation');
} else {
  console.log('Using pure JavaScript implementation');
}

// Conditional configuration based on acceleration
const options = {
  useRecords: true,
  // Use more aggressive optimizations if native acceleration is available
  sequential: isNativeAccelerationEnabled,
  bundleStrings: isNativeAccelerationEnabled
};

Special Constants

Special constant objects used internally by msgpackr.

/**
 * Internal constant object used by msgpackr
 */
const C1: {};

This constant is primarily for internal use and typically not needed in application code.

docs

advanced-classes.md

core-operations.md

extensions.md

index.md

iterators.md

streaming.md

tile.json