CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-cbor

Encode and parse data in the Concise Binary Object Representation (CBOR) data format (RFC8949).

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

cbor-types.mddocs/

CBOR Types

Special CBOR types for representing semantic values, tagged data, and CBOR-specific data structures that extend beyond standard JavaScript types.

Capabilities

Simple Values

Represent CBOR Simple Values including special values like true, false, null, undefined, and custom simple values.

/**
 * Represent CBOR Simple Values
 */
class Simple {
  /**
   * Create Simple value instance
   * @param {number} value - The simple value's integer value
   */
  constructor(value);
  
  /**
   * The simple value's integer value
   * @type {number}
   */
  value;
  
  /**
   * Debug string representation
   * @returns {string} String representation
   */
  toString();
  
  /**
   * Encode to CBOR stream
   * @param {Encoder} gen - Encoder instance
   * @returns {boolean} Success indicator
   */
  encodeCBOR(gen);
  
  /**
   * Test if object is a Simple value
   * @param {any} obj - Object to test
   * @returns {boolean} True if object is a Simple value
   */
  static isSimple(obj);
  
  /**
   * Decode CBOR simple value
   * @param {number} val - Simple value code
   * @param {boolean} [has_parent] - Has parent context
   * @param {boolean} [parent_indefinite] - Parent is indefinite length
   * @returns {any} Decoded simple value
   */
  static decode(val, has_parent, parent_indefinite);
}

Usage Examples:

const cbor = require("cbor");

// Create simple values
const simpleTrue = new cbor.Simple(21);  // CBOR true
const simpleFalse = new cbor.Simple(20); // CBOR false
const simpleNull = new cbor.Simple(22);  // CBOR null
const customSimple = new cbor.Simple(100); // Custom simple value

// Test if value is Simple
console.log(cbor.Simple.isSimple(simpleTrue)); // true
console.log(cbor.Simple.isSimple(42)); // false

// Encode and decode simple values
const encoded = cbor.encode(customSimple);
const decoded = cbor.decode(encoded);
console.log(decoded instanceof cbor.Simple); // true
console.log(decoded.value); // 100

// Simple values in objects
const data = {
  flag: new cbor.Simple(21),
  marker: new cbor.Simple(200),
  normal: true
};

const encodedData = cbor.encode(data);
const decodedData = cbor.decode(encodedData);
console.log(decodedData.flag instanceof cbor.Simple); // true
console.log(decodedData.normal); // true (regular boolean)

Tagged Values

Represent CBOR tagged items with semantic meaning for extending CBOR with application-specific types.

/**
 * Represent CBOR tagged items with semantic meaning
 */
class Tagged {
  /**
   * Create tagged value
   * @param {number} tag - Tag number
   * @param {any} value - Tagged value
   * @param {Error} [err] - Parse error if any
   */
  constructor(tag, value, err);
  
  /**
   * Tag number
   * @type {number}
   */
  tag;
  
  /**
   * Tagged value
   * @type {any}
   */
  value;
  
  /**
   * Parse error if any
   * @type {Error}
   */
  err;
  
  /**
   * JSON representation
   * @returns {Object} JSON representation
   */
  toJSON();
  
  /**
   * String representation
   * @returns {string} String representation
   */
  toString();
  
  /**
   * Encode to CBOR stream
   * @param {Encoder} gen - Encoder instance
   * @returns {boolean} Success indicator
   */
  encodeCBOR(gen);
  
  /**
   * Convert using provided converters
   * @param {Object} converters - Tag conversion functions
   * @returns {any} Converted value
   */
  convert(converters);
  
  /**
   * Get/set supported tag mappings
   * @type {TagMap}
   */
  static TAGS;
  
  /**
   * Reset tags to original set
   */
  static reset();
}

Usage Examples:

const cbor = require("cbor");

// Create tagged values
const dateString = new cbor.Tagged(0, "2023-12-25T10:30:00Z"); // Date string
const epochTime = new cbor.Tagged(1, 1703505000); // Epoch timestamp
const base64Data = new cbor.Tagged(34, "SGVsbG8gV29ybGQ="); // Base64 encoded
const customTag = new cbor.Tagged(1000, { type: "Point", x: 10, y: 20 });

// Encode and decode tagged values
const encoded = cbor.encode(dateString);
const decoded = cbor.decode(encoded);
console.log(decoded instanceof cbor.Tagged); // true
console.log(decoded.tag); // 0
console.log(decoded.value); // "2023-12-25T10:30:00Z"

// Convert tagged values
const dateTagged = new cbor.Tagged(0, "2023-12-25T10:30:00Z");
const converted = dateTagged.convert({
  0: (dateStr) => new Date(dateStr),
  1: (epoch) => new Date(epoch * 1000)
});
console.log(converted instanceof Date); // true

// Custom tag handling during decode
const decodedWithHandler = cbor.decode(encoded, {
  tags: {
    0: (dateString) => new Date(dateString),
    1000: (value) => new Point(value.x, value.y)
  }
});

// Working with tag mappings
console.log(cbor.Tagged.TAGS[0]); // Built-in date string handler
cbor.Tagged.TAGS[1001] = (value) => new MyCustomType(value);

// Reset to defaults
cbor.Tagged.reset();

CBOR Map

CBOR Map with complex key support and value-based comparison, extending JavaScript's Map for CBOR-specific needs.

/**
 * CBOR Map with complex key support and value-based comparison
 */
class Map extends Map {
  /**
   * Create CborMap from iterable
   * @param {Iterable} [iterable] - Initial key-value pairs
   */
  constructor(iterable);
  
  /**
   * Set key-value pair (keys compared by value, not reference)
   * @param {any} key - Map key (any CBOR-serializable value)
   * @param {any} val - Map value
   * @returns {Map} This map instance for chaining
   */
  set(key, val);
  
  /**
   * Iterator over decoded keys
   * @returns {Iterator} Key iterator
   */
  keys();
  
  /**
   * Iterator over [key, value] pairs
   * @returns {Iterator} Entry iterator
   */
  entries();
  
  /**
   * Execute function for each key-value pair
   * @param {Function} func - Function to execute
   * @param {any} [thisArg] - Value to use as this when executing func
   */
  forEach(func, thisArg);
  
  /**
   * Encode to CBOR stream
   * @param {Encoder} gen - Encoder instance
   * @returns {boolean} Success indicator
   */
  encodeCBOR(gen);
  
  /**
   * Default iterator (same as entries())
   * @returns {Iterator} Entry iterator
   */
  [Symbol.iterator]();
  
  /**
   * Encode key for comparison (internal)
   * @param {any} key - Key to encode
   * @returns {string} Encoded key
   * @private
   */
  static _encode(key);
  
  /**
   * Decode key from encoded form (internal)
   * @param {string} key - Encoded key
   * @returns {any} Decoded key
   * @private
   */
  static _decode(key);
}

Usage Examples:

const cbor = require("cbor");

// Create Map with complex keys
const map = new cbor.Map();

// Keys can be any CBOR-serializable type
map.set(1, "number key");
map.set("string", "string key");
map.set(true, "boolean key");
map.set([1, 2, 3], "array key");
map.set({ x: 10, y: 20 }, "object key");
map.set(new Date(), "date key");

console.log(map.size); // 6

// Value-based key comparison (not reference-based)
const key1 = { a: 1, b: 2 };
const key2 = { a: 1, b: 2 }; // Same value, different object

map.set(key1, "first");
map.set(key2, "second"); // Overwrites "first" because keys are value-equal

console.log(map.get(key1)); // "second"
console.log(map.get(key2)); // "second"
console.log(map.size); // Still 6

// Initialize from iterable
const map2 = new cbor.Map([
  ["name", "Alice"],
  [42, "answer"],
  [new Date("2023-01-01"), "new year"]
]);

// Iterate over map
for (const [key, value] of map2) {
  console.log(`${key} => ${value}`);
}

map2.forEach((value, key) => {
  console.log(`Key: ${key}, Value: ${value}`);
});

// Encode and decode maps
const encoded = cbor.encode(map2);
const decoded = cbor.decode(encoded, { preferMap: true });
console.log(decoded instanceof cbor.Map); // true

// Convert to regular Map if needed
const regularMap = new Map(decoded.entries());

SharedValueEncoder

Encoder with value sharing and deduplication support for reducing output size when encoding repeated values.

/**
 * Encoder with value sharing/deduplication support
 */
class SharedValueEncoder extends Encoder {
  /**
   * Create value-sharing encoder
   * @param {EncodingOptions} opts - Encoding options
   */
  constructor(opts);
  
  /**
   * Object tracking recorder
   * @type {ObjectRecorder}
   */
  valueSharing;
  
  /**
   * Stop recording duplicates and start outputting reference tags
   */
  stopRecording();
  
  /**
   * Clear recording state
   */
  clearRecording();
}

Usage Examples:

const cbor = require("cbor");

// Create shared value encoder
const sharedEncoder = new cbor.SharedValueEncoder({
  canonical: true
});

// Data with repeated values
const person1 = { name: "Alice", department: "Engineering" };
const person2 = { name: "Bob", department: "Engineering" }; // Same department
const person3 = { name: "Charlie", department: "Engineering" }; // Same department

const data = [person1, person2, person3];

// First pass: record which values are duplicated
sharedEncoder.write(data);

// Stop recording and start using reference tags
sharedEncoder.stopRecording();

// Second pass: encode with value sharing
sharedEncoder.write(data);
sharedEncoder.end();

// The "Engineering" string will be encoded once and referenced with tags

ObjectRecorder

Track object usage for value sharing and deduplication.

/**
 * Object recorder for tracking duplicates
 */
class ObjectRecorder {
  /**
   * Create object recorder
   */
  constructor();
  
  /**
   * Object tracking map
   * @type {WeakMap}
   */
  map;
  
  /**
   * Object counter
   * @type {number}
   */
  count;
  
  /**
   * Recording state
   * @type {boolean}
   */
  recording;
  
  /**
   * Clear all tracked objects
   */
  clear();
  
  /**
   * Stop recording
   */
  stop();
  
  /**
   * Check object usage status
   * @param {any} obj - Object to check
   * @returns {number} Usage status (NEVER, FIRST, or count)
   */
  check(obj);
  
  /**
   * Never duplicated constant
   * @type {number}
   */
  static NEVER;
  
  /**
   * First use constant
   * @type {number}
   */
  static FIRST;
}

Usage Examples:

const cbor = require("cbor");

// Manual object recording
const recorder = new cbor.ObjectRecorder();

const sharedString = "repeated value";
const obj1 = { data: sharedString };
const obj2 = { data: sharedString };

// Check usage
console.log(recorder.check(sharedString)); // FIRST (0)
console.log(recorder.check(sharedString)); // 1 (second use)
console.log(recorder.check(sharedString)); // 2 (third use)

// Clear tracking
recorder.clear();
console.log(recorder.check(sharedString)); // FIRST again

// Stop recording
recorder.stop();
console.log(recorder.recording); // false

Common CBOR Tags

Standard CBOR tags supported by the library:

  • Tag 0: Date string (ISO 8601)
  • Tag 1: Epoch timestamp (seconds since Unix epoch)
  • Tag 2: Positive bigint
  • Tag 3: Negative bigint
  • Tag 21: Base64url encoding expected
  • Tag 22: Base64 encoding expected
  • Tag 23: Base16 encoding expected
  • Tag 24: Embedded CBOR data
  • Tag 32: URI
  • Tag 35: Regular expression
  • Tag 258: Set

Error Handling

CBOR type operations can throw errors for:

  • Invalid tag numbers or values
  • Unsupported simple value codes
  • Conversion errors with tagged values
  • Map key encoding/decoding failures
const cbor = require("cbor");

try {
  const tagged = new cbor.Tagged(99999, "invalid");
  const converted = tagged.convert({
    // Missing converter for tag 99999
  });
} catch (error) {
  console.error('Tag conversion failed:', error);
}

Install with Tessl CLI

npx tessl i tessl/npm-cbor

docs

advanced-decoding.md

cbor-types.md

diagnostic-tools.md

encoding-decoding.md

index.md

integration-utilities.md

stream-processing.md

tile.json