A VALUE frame and its CRC trailer (TypeScript)¶
The TypeScript core package on its own: encode a VALUE with opt.cr set, decode it,
and watch the trailer catch a flipped bit. The bytes match the Rust example
exactly.
What to notice¶
The encoder computes the trailer. The literal passes
trailer: null;opt.cris the request, anddecodehands backtrailer.crcwith its width and value.Errors carry a wire-named code. The refusal is a thrown
CodecErrorwhose.codeisERROR.FRAME_CRC_FAIL.Without the trailer, the damage passes. Integrity is the sender’s per-frame choice.
Source¶
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright 2026 avatarsd LLC
3
4/**
5 * @file
6 * @brief One concept: a VALUE frame with a CRC trailer, and what `decode` says when a
7 * byte flips in transit. Core package only — no client, no transport.
8 *
9 * Run: `node examples/value-crc.mjs` (from `bindings/typescript/`, after `npm run build`).
10 */
11
12import assert from 'node:assert/strict';
13import { encode, decode, TYPE, ERROR } from '@avatarsd-llc/libtracer';
14
15const opt = { pl: false, ts: false, cr: true, ll: false, cw: false, tf: false };
16const reading = Uint8Array.of(0xfc, 0x53, 0x00, 0x00); // 21500, u32 little-endian
17
18// opt.CR = 1 asks the encoder for a CRC-32C trailer over the payload.
19const frame = encode({ type: TYPE.VALUE, opt, payload: reading, children: [], trailer: null });
20assert.equal(frame.length, 4 + 4 + 4); // header + payload + CRC
21console.log(`frame (${frame.length} bytes): ${Buffer.from(frame).toString('hex')}`);
22
23// Decoding checks the trailer and hands back the payload unchanged.
24const tlv = decode(frame);
25assert.deepEqual(tlv.payload, reading);
26assert.equal(tlv.trailer.crc.width, 'CRC32C');
27console.log(`decoded payload ok, crc32c 0x${tlv.trailer.crc.value.toString(16)}`);
28
29// Flip one payload bit: the frame still parses, but the CRC no longer matches.
30const damaged = Uint8Array.from(frame);
31damaged[4] ^= 0x01;
32assert.throws(() => decode(damaged), (err) => err.code === ERROR.FRAME_CRC_FAIL);
33console.log(`one flipped bit -> ${ERROR.FRAME_CRC_FAIL}`);
34
35// Without the trailer the same damage is invisible to the codec.
36const bare = encode({ type: TYPE.VALUE, opt: { ...opt, cr: false }, payload: reading, children: [], trailer: null });
37bare[4] ^= 0x01;
38decode(bare);
39console.log('same flip without a CRC -> decodes silently');
Run it from bindings/typescript/, after npm ci && npm run build:
$ node examples/value-crc.mjs
See also: the trailer (C++) · data format reference.