typed-cbor
v1.0.1
Published
Subset of CBOR encoder/decoder with schema validation and type inference, designed for browser environments.
Readme
typed-cbor
A lightweight, schema-first CBOR (Concise Binary Object Representation) encoder/decoder for JavaScript. It is dependency-free and targets modern runtimes (browser and Node.js).
Overview
typed-cbor serializes and deserializes CBOR data using explicit schemas. Schemas are used for:
- Runtime validation during encode and decode
- Type annotations exposed through generated declaration files
The implementation follows core CBOR behavior from RFC 8949, with a deliberate subset of features.
Installation
npm install typed-cborFor local development in this repository, import from ./lib/cbor.js.
Quick Start
import { integer, text, map, createEncoder, decode } from 'typed-cbor';
const userSchema = map({
id: integer(),
name: text(),
email: text(),
});
const encoder = createEncoder();
const user = { id: 1n, name: 'Alice', email: '[email protected]' };
const encoded = encoder.encode(userSchema, user);
const decoded = decode(userSchema, encoded);
console.log(decoded);Schema API
Primitive schemas
import { integer, text, bytes, boolean, nil, undef, float } from 'typed-cbor';
const id = integer(); // bigint
const name = text(); // string
const payload = bytes(); // Uint8Array
const active = boolean(); // boolean
const empty = nil(); // null
const missing = undef(); // undefined
const score = float(); // numberComposite schemas
import { array, map, oneOf, integer, text, boolean } from 'typed-cbor';
const tags = array(text());
const person = map({
name: text(),
age: integer(),
active: boolean(),
});
// Union of variants (not tagged/discriminated by the library)
const idOrName = oneOf(integer(), text());TypeScript Notes
InferValue can be used to derive a value type from a schema:
import { map, text, integer, InferValue, createEncoder } from 'typed-cbor';
const userSchema = map({
name: text(),
age: integer(),
});
type User = InferValue<typeof userSchema>;
const encoder = createEncoder();
const user: User = { name: 'Bob', age: 30n };
const encoded = encoder.encode(userSchema, user);Note: runtime validation is authoritative. Depending on TypeScript configuration and declaration-generation details, inferred editor types may be less strict than runtime checks.
Encoding and Decoding Behavior
createEncoder()returns a reusable encoder instance.- The internal buffer grows when needed and is reused between calls.
decode(shape, cbor)fully decodes one CBOR item and rejects trailing bytes.- Decoding validates the result against the given schema and throws on mismatch.
Supported CBOR Major Types
| Major Type | Support | Details | |-----------|---------|---------| | 0 | Yes | Unsigned integers | | 1 | Yes | Negative integers | | 2 | Yes | Byte strings | | 3 | Yes | Text strings (UTF-8) | | 4 | Yes | Arrays | | 5 | Yes | Maps | | 6 | No | Tags are unsupported | | 7 | Yes | booleans, null, undefined, floats |
Important Limitations
- No semantic tags (major type 6).
- No indefinite-length (streaming) items.
- Map keys must decode to strings.
- Integer encoding is limited to CBOR uint64 payload size; encodable bigint range is
[-18446744073709551616, 18446744073709551615]. float()rejectsNaN,Infinity, and-Infinityduring encoding.
Error Handling
Both encode and decode throw Error instances for invalid input, including:
- Type mismatches against schema
- Truncated or malformed CBOR data
- Duplicate keys in CBOR maps
- Extra bytes after a decoded value
Development
Build
npm run buildGenerates declaration files into types/ from JSDoc annotations.
Test
npm testRuns the Node.js test suite in lib/cbor.test.js.
License
MIT © Faisal Hakim
