Decoder Internals
The decode function in decoder.ts performs sequential binary parsing with validation at every step.
Parsing Flow
1. Validate minimum length (≥ 4 bytes)
2. Validate magic bytes (0x4C, 0x44)
3. Read version byte, compare to schema version
4. Read field count byte
5. For each field:
a. Read field_id (1 byte)
b. Read type_tag (1 byte)
c. Read length (2 bytes, big-endian)
d. Validate remaining bytes ≥ length
e. Look up field_id in schema
f. If unknown: skip (advance offset by length)
g. If known: decode value, store in result
6. Verify all required fields are present
7. Return result objectSchema Lookup
The decoder builds a Map<number, LodeField> from the schema for O(1) field lookup:
const fieldMap = new Map<number, LodeField>();
for (const field of schema.fields) {
fieldMap.set(field.id, field);
}Forward Compatibility
When a field ID is not found in the schema map, the decoder skips it:
const field = fieldMap.get(fieldId);
if (!field) {
offset += length; // skip unknown field
continue;
}This allows a consumer built against v1 of a schema to read v2 payloads that contain additional fields.
Value Decoding
String
decoder.decode(data) // TextDecoder, UTF-8Bool
data[0] === 0x01 // true if 0x01, false if 0x00String Array
const count = view.getUint16(0, false);
// For each item: read uint16 length, decode UTF-8 sliceMap
const count = view.getUint16(0, false);
// For each entry: read key (uint16 + bytes), read value (uint16 + bytes)Error Handling
The decoder throws specific errors at each validation point. These are designed to be diagnostic — they include the field ID, expected values, and byte positions.
Unlike verify, the decode function does throw on invalid input. Use verify when you want a boolean result without exception handling.
Last updated on