Quickstart
The Encoder is designed to be easily installed and implemented in both browser and server environments.
Installation
Install @nhtio/encoder directly from your preferred package manager using one of the following commands:
npm i @nhtio/encoderpnpm add @nhtio/encoderyarn add @nhtio/encoderBasic Usage
The encoder provides two primary functions: encode() and decode().
import { encode, decode } from '@nhtio/encoder'
// Encode any supported value into a compressed base64 string
const encoded = encode({ hello: 'world' })
// Decode the string back to the original value
const decoded = decode(encoded)Supported Types
The encoder handles a wide range of JavaScript types and automatically preserves their structure and type information. See the Encodable type for the complete type definition.
Primitives
string,number,bigint,boolean,null,undefined
Built-in Objects
Date,RegExp,ErrorArrayBuffer,DataView
Typed Arrays
Int8Array,Uint8Array,Uint8ClampedArrayInt16Array,Uint16ArrayInt32Array,Uint32ArrayFloat32Array,Float64ArrayBigInt64Array,BigUint64Array
Collections
Array,Map,Set- Plain objects (including those with null prototypes)
Functions
- Regular functions, arrow functions, async functions
- Generator functions and async generators
- Functions with default, rest, and destructured parameters
Special Types
- Luxon:
DateTime,Duration,Interval - Phone:
Phoneobjects from@nhtio/phone-object - Custom classes: any class that implements the
CustomEncodableinterface
Examples
Complex Nested Structures
import { encode, decode } from '@nhtio/encoder'
import { DateTime, Duration, Interval } from 'luxon'
import { Phone } from '@nhtio/phone-object'
const data = {
users: [
{
id: 1,
name: 'John Doe',
phone: new Phone('+1234567890', 'US'),
createdAt: DateTime.now(),
preferences: new Map([
['theme', 'dark'],
['notifications', true]
]),
tags: new Set(['admin', 'verified'])
}
],
metadata: {
duration: Duration.fromObject({ minutes: 5 }),
period: Interval.fromDateTimes(
DateTime.fromISO('2023-01-01'),
DateTime.fromISO('2023-12-31')
)
}
}
const encoded = encode(data)
const decoded = decode(encoded)
// All types are preserved
decoded.users[0].phone instanceof Phone // true
decoded.users[0].createdAt instanceof DateTime // true
decoded.users[0].preferences instanceof Map // trueEncoding Functions
import { encode, decode } from '@nhtio/encoder'
const calculator = {
add: (a: number, b: number) => a + b,
subtract: function(a: number, b: number) { return a - b },
multiply: async (a: number, b: number) => a * b
}
const encoded = encode(calculator)
const decoded = decode(calculator)
decoded.add(5, 3) // 8
decoded.subtract(10, 4) // 6
await decoded.multiply(6, 7) // 42Working with Typed Arrays
import { encode, decode } from '@nhtio/encoder'
const buffer = new Uint8Array([1, 2, 3, 4, 5])
const encoded = encode(buffer)
const decoded = decode<Uint8Array>(encoded)
decoded instanceof Uint8Array // true
Array.from(decoded) // [1, 2, 3, 4, 5]Custom Classes
Any class can opt in to encoding by implementing two symbol methods. The class itself does not need to depend on @nhtio/encoder — the symbols are recreatable from plain strings:
import { encode, decode, registerClass, ENCODE_METHOD, DECODE_METHOD } from '@nhtio/encoder'
class Point {
constructor(public x: number, public y: number) {}
[ENCODE_METHOD]() { return { x: this.x, y: this.y } }
static [DECODE_METHOD](data: { x: number; y: number }) {
return new Point(data.x, data.y)
}
}
registerClass(Point)
const decoded = decode<Point>(encode(new Point(3, 7)))
decoded instanceof Point // true
decoded.x // 3See the Custom Classes guide for full details including zero-dependency usage, nesting, and error handling.
Error Handling
The encoder throws specific exceptions for different error conditions. See the exceptions documentation for all available exception types.
import { encode, decode } from '@nhtio/encoder'
import {
E_CIRCULAR_REFERENCE,
E_UNENCODABLE_VALUE,
E_NOT_AN_ENCODED_VALUE,
E_INCOMPATIBLE_VERSION
} from '@nhtio/encoder/exceptions'
try {
// Circular references are detected and throw E_CIRCULAR_REFERENCE
const obj: any = { name: 'test' }
obj.self = obj
encode(obj)
} catch (error) {
if (error instanceof E_CIRCULAR_REFERENCE) {
console.error('Circular reference detected')
}
}
try {
// Invalid encoded strings throw E_NOT_AN_ENCODED_VALUE
decode('not-a-valid-encoded-string')
} catch (error) {
if (error instanceof E_NOT_AN_ENCODED_VALUE) {
console.error('Invalid encoded value')
}
}
try {
// Unsupported types throw E_UNENCODABLE_VALUE
encode(Symbol('test') as any)
} catch (error) {
if (error instanceof E_UNENCODABLE_VALUE) {
console.error('Type not supported')
}
}Type Safety
Use TypeScript generics for type-safe decoding:
import { encode, decode } from '@nhtio/encoder'
interface User {
name: string
age: number
active: boolean
}
const user: User = { name: 'Alice', age: 30, active: true }
const encoded = encode(user)
const decoded = decode<User>(encoded)
// TypeScript knows the shape of decoded
decoded.name // string
decoded.age // number
decoded.active // boolean