Serialize and deserialize data, manage offsets, and work with complex types.
Want the easy path? If you have more than a couple of message types, start with the Schema Quick Start instead. Define your types in a .sia file and get generated encode/decode functions for every language — no manual serialization code needed.
import { Sia } from "@timeleap/sia";
const sia = new Sia();
The default constructor uses a shared 32 MB global buffer (lazy-allocated on first use) for maximum performance. This is ideal for serializing data in hot paths where you process one message at a time. For isolated buffers, use Sia.alloc(size) or pass your own Uint8Array to the constructor.
::
import sia "github.com/TimeleapLabs/go-sia/v2/pkg"
s := sia.New()
Read fields back in the same order they were written:
const reader = new Sia(bytes);
const name = reader.readString8(); // "Alice"
const age = reader.readUInt8(); // 30
const email = reader.readString16(); // "alice@example.com"
const active = reader.readBool(); // true
reader := sia.NewFromBytes(bytes)
name := reader.ReadString8() // "Alice"
age := reader.ReadUInt8() // 30
email := reader.ReadString16() // "alice@example.com"
active := reader.ReadBool() // true
reader = Sia()
reader.set_content(raw_bytes)
name = reader.read_string8() # "Alice"
age = reader.read_uint8() # 30
email = reader.read_string16() # "alice@example.com"
active = reader.read_bool() # True
auto reader = sia::NewFromBytes(bytes);
auto name = reader->ReadString8(); // "Alice"
auto age = reader->ReadUInt8(); // 30
auto email = reader->ReadString16(); // "alice@example.com"
auto active = reader->ReadBool(); // true
You must read fields in the exact same order and with the same types as they were written. Sia is a sequential format with no field names or type markers: reading out of order will produce corrupted data or throw errors.
Sia maintains an internal offset that advances automatically as you read or write data.
const sia = new Sia();
// offset starts at 0
sia.addUInt8(10); // writes 1 byte, offset is now 1
sia.addUInt32(1000); // writes 4 bytes, offset is now 5
sia.addString8("hi"); // writes 1 (length) + 2 (data) = 3 bytes, offset is now 8
// To read, reset the offset
sia.seek(0); // offset is back to 0
sia.readUInt8(); // reads 1 byte, offset is now 1
sia.readUInt32(); // reads 4 bytes, offset is now 5
sia.readString8(); // reads 3 bytes, offset is now 8
TypeScript also provides standalone functions that work directly on a Buffer. These are tree-shakeable: your bundler can drop any functions you don't use.