Integration support for databases and frameworks, plus utility functions for package management and system reset capabilities.
Codec for leveldb integration providing seamless CBOR encoding/decoding for keys and values in LevelDB databases.
/**
* Codec for leveldb integration
*/
const leveldb = {
/**
* Decoder function for leveldb (decodeFirstSync)
* @param {BufferLike} input - CBOR data to decode
* @param {DecoderOptions} [options] - Decoding options
* @returns {any} Decoded value
*/
decode: function(input, options),
/**
* Encoder function for leveldb (encode)
* @param {...any} objs - Objects to encode
* @returns {Buffer} CBOR encoded data
*/
encode: function(...objs),
/**
* Buffer support flag
* @type {boolean}
*/
buffer: true,
/**
* Codec name identifier
* @type {string}
*/
name: "cbor"
};Usage Examples:
const cbor = require("cbor");
const level = require("level");
// Use CBOR codec with LevelDB
const db = level('./my-database', {
keyEncoding: cbor.leveldb,
valueEncoding: cbor.leveldb
});
// Store complex data types as keys and values
async function storeCBORData() {
// Complex keys - objects, arrays, dates, etc.
const complexKey = { type: "user", id: 12345, timestamp: new Date() };
const complexValue = {
name: "Alice Johnson",
profile: {
age: 30,
skills: ["JavaScript", "Python", "CBOR"],
active: true,
lastLogin: new Date(),
preferences: new Map([
["theme", "dark"],
["notifications", true]
])
},
bigNumber: 123456789012345678901234567890n
};
// Store with complex key/value
await db.put(complexKey, complexValue);
// Retrieve using the same complex key structure
const retrieved = await db.get(complexKey);
console.log('Retrieved user:', retrieved);
// BigInt and other complex types are preserved
console.log('BigInt value:', typeof retrieved.bigNumber); // 'bigint'
console.log('Map preferences:', retrieved.profile.preferences instanceof Map); // true
}
// Numeric keys work seamlessly
async function useNumericKeys() {
await db.put(42, "The answer to everything");
await db.put(3.14159, "Pi value");
const answer = await db.get(42);
const pi = await db.get(3.14159);
console.log(answer); // "The answer to everything"
console.log(pi); // "Pi value"
}
// Array and object keys
async function useComplexKeys() {
const arrayKey = [1, 2, "three", true];
const objectKey = { x: 10, y: 20, z: 30 };
await db.put(arrayKey, "Array key data");
await db.put(objectKey, "Object key data");
// Keys are compared by value, not reference
const sameArrayKey = [1, 2, "three", true];
const sameObjectKey = { x: 10, y: 20, z: 30 };
const arrayData = await db.get(sameArrayKey);
const objectData = await db.get(sameObjectKey);
console.log(arrayData); // "Array key data"
console.log(objectData); // "Object key data"
}
// Batch operations with CBOR
async function batchOperations() {
const operations = [
{ type: 'put', key: { type: 'batch', id: 1 }, value: 'First batch item' },
{ type: 'put', key: { type: 'batch', id: 2 }, value: 'Second batch item' },
{ type: 'put', key: { type: 'batch', id: 3 }, value: 'Third batch item' }
];
await db.batch(operations);
// Read back batch items
for (let i = 1; i <= 3; i++) {
const key = { type: 'batch', id: i };
const value = await db.get(key);
console.log(`Batch ${i}:`, value);
}
}
// Error handling with complex keys
async function handleErrors() {
try {
const nonExistentKey = { type: 'missing', id: 999 };
const value = await db.get(nonExistentKey);
} catch (error) {
if (error.code === 'LEVEL_NOT_FOUND') {
console.log('Key not found in database');
}
}
}Reset encoder/decoder semantic types and configurations to their original defaults.
/**
* Reset encoder/decoder semantic types to defaults
* Resets both Encoder and Tagged semantic type mappings
*/
function reset();Usage Examples:
const cbor = require("cbor");
// Add custom semantic types
cbor.Encoder.SEMANTIC_TYPES.MyClass = (encoder, obj) => {
encoder.pushAny({ customEncoding: obj.serialize() });
return true;
};
cbor.Tagged.TAGS[9999] = (value) => new MyClass(value.data);
// Custom encoding/decoding works
const customObj = new MyClass("test data");
const encoded = cbor.encode(customObj);
const decoded = cbor.decode(encoded);
// Reset everything to defaults
cbor.reset();
// Custom types are no longer available
console.log(cbor.Encoder.SEMANTIC_TYPES.MyClass); // undefined
console.log(cbor.Tagged.TAGS[9999]); // undefined
// Built-in types still work normally
const normalData = { name: "Alice", date: new Date() };
const normalEncoded = cbor.encode(normalData);
const normalDecoded = cbor.decode(normalEncoded);
console.log(normalDecoded); // Works as expectedAccess to CBOR constants and internal type definitions for advanced usage.
/**
* CBOR Major Types
*/
const MT = {
POS_INT: 0, // Positive integer
NEG_INT: 1, // Negative integer
BYTE_STRING: 2, // Byte string
UTF8_STRING: 3, // UTF-8 string
ARRAY: 4, // Array
MAP: 5, // Map
TAG: 6, // Tag
SIMPLE_FLOAT: 7 // Simple/Float
};
/**
* CBOR Tag Numbers
*/
const TAG = {
DATE_STRING: 0, // Date string (ISO 8601)
DATE_EPOCH: 1, // Epoch timestamp
POS_BIGINT: 2, // Positive bigint
NEG_BIGINT: 3, // Negative bigint
DECIMAL_FRAC: 4, // Decimal fraction
BIGFLOAT: 5, // Big float
BASE64URL_EXPECTED: 21, // Base64url encoding expected
BASE64_EXPECTED: 22, // Base64 encoding expected
BASE16_EXPECTED: 23, // Base16 encoding expected
CBOR: 24, // Embedded CBOR
URI: 32, // URI
BASE64URL: 33, // Base64url
BASE64: 34, // Base64
REGEXP: 35, // Regular expression
MIME: 36, // MIME message
SET: 258 // Set
};
/**
* CBOR Simple Values
*/
const SIMPLE = {
FALSE: 20, // False
TRUE: 21, // True
NULL: 22, // Null
UNDEFINED: 23 // Undefined
};Usage Examples:
const cbor = require("cbor");
// Access constants for custom implementations
console.log(cbor.MT?.POS_INT); // 0 (if available)
// Create custom tagged values using standard tag numbers
const dateTagged = new cbor.Tagged(cbor.TAG?.DATE_STRING || 0, "2023-12-25T10:30:00Z");
const regexTagged = new cbor.Tagged(cbor.TAG?.REGEXP || 35, "pattern");
// Custom simple values
const customSimple = new cbor.Simple(cbor.SIMPLE?.TRUE || 21);Various utility functions for CBOR data manipulation and analysis.
/**
* Convert CBOR null/undefined symbols to actual values
* @param {any} val - Value to check and convert
* @returns {any} Converted value
*/
function nullcheck(val);Usage Examples:
const cbor = require("cbor");
// Null check utility
const data = cbor.decode(someEncodedData);
const checkedData = cbor.Decoder.nullcheck(data);
// Useful when working with streaming data where nulls might be symbols
function processStreamData(streamValue) {
const actualValue = cbor.Decoder.nullcheck(streamValue);
if (actualValue === null) {
console.log('Received null value');
} else if (actualValue === undefined) {
console.log('Received undefined value');
} else {
console.log('Received value:', actualValue);
}
}Common patterns for integrating CBOR with various frameworks and libraries.
Usage Examples:
const cbor = require("cbor");
// Express.js integration
const express = require("express");
const app = express();
// CBOR middleware
app.use('/api/cbor', (req, res, next) => {
if (req.headers['content-type'] === 'application/cbor') {
let buffer = Buffer.alloc(0);
req.on('data', chunk => {
buffer = Buffer.concat([buffer, chunk]);
});
req.on('end', () => {
try {
req.body = cbor.decode(buffer);
next();
} catch (error) {
res.status(400).json({ error: 'Invalid CBOR data' });
}
});
} else {
next();
}
});
// CBOR response helper
app.use((req, res, next) => {
res.cbor = (data) => {
res.setHeader('Content-Type', 'application/cbor');
res.send(cbor.encode(data));
};
next();
});
// Redis integration with CBOR
const redis = require("redis");
const client = redis.createClient();
// CBOR-enabled Redis operations
const redisCBOR = {
async set(key, value, options = {}) {
const encoded = cbor.encode(value);
return await client.set(key, encoded, options);
},
async get(key) {
const encoded = await client.get(key);
return encoded ? cbor.decode(encoded) : null;
},
async mset(keyValuePairs) {
const encoded = keyValuePairs.map(([key, value]) => [key, cbor.encode(value)]);
return await client.mset(encoded.flat());
},
async mget(keys) {
const encoded = await client.mget(keys);
return encoded.map(data => data ? cbor.decode(data) : null);
}
};
// Socket.io integration
const { Server } = require("socket.io");
const io = new Server();
// CBOR packet handling
io.on('connection', (socket) => {
socket.on('cbor-message', (encodedData) => {
try {
const message = cbor.decode(Buffer.from(encodedData));
console.log('Received CBOR message:', message);
// Process and respond with CBOR
const response = { status: 'received', echo: message };
socket.emit('cbor-response', cbor.encode(response));
} catch (error) {
socket.emit('cbor-error', { error: 'Invalid CBOR data' });
}
});
});
// Configuration management with CBOR
class CBORConfig {
constructor(filePath) {
this.filePath = filePath;
}
async load() {
try {
const fs = require('fs').promises;
const data = await fs.readFile(this.filePath);
return cbor.decode(data);
} catch (error) {
return {}; // Return empty config if file doesn't exist
}
}
async save(config) {
const fs = require('fs').promises;
const encoded = cbor.encode(config);
await fs.writeFile(this.filePath, encoded);
}
async update(updates) {
const current = await this.load();
const updated = { ...current, ...updates };
await this.save(updated);
return updated;
}
}
// Usage
const config = new CBORConfig('./app-config.cbor');
await config.save({
database: { host: 'localhost', port: 5432 },
features: { enableLogging: true, maxUsers: 1000 },
version: '1.2.0'
});Integration utilities handle various error conditions:
const cbor = require("cbor");
// Robust error handling for integrations
async function safeIntegration() {
try {
// LevelDB operations
const db = level('./db', { valueEncoding: cbor.leveldb });
await db.put(complexKey, complexValue);
} catch (error) {
if (error.code === 'LEVEL_DATABASE_NOT_OPEN') {
console.error('Database not open');
} else if (error.message.includes('CBOR')) {
console.error('CBOR encoding/decoding error:', error);
} else {
console.error('Unexpected error:', error);
}
}
// Reset with error handling
try {
cbor.reset();
} catch (error) {
console.error('Reset failed:', error);
}
}