Skip to content

Releases: mas-bandwidth/serialize.js

serialize.js 1.4.0: format version 1.1

Choose a tag to compare

@gafferongames gafferongames released this 04 Sep 07:51
6783596

This release brings the JavaScript runtime to format version 1.1 of the wire standard. int_relative reconstructs every tier in a width that cannot wrap and refuses a result outside 0 to 2^31 - 1 or not strictly above previous; the absolute tier reads its 32 raw bits unsigned and refuses a set top bit; a refused read writes nothing to a scalar destination and is terminal until the stream is re-initialized; a ranged int128 with min equal to max is legal and costs zero bits. The standard's conformance corpus is vendored and every vector runs in the test suite, so this runtime's verdict on hostile bytes is now the same as every other runtime's, and the vendored STANDARD.md and corpus are checked against upstream in CI. The wire is unchanged: every packet a previous release wrote reads the same, and every accepted vector round-trips byte for byte. package.json carries the version the tag names, which it did not for 1.3.0.

v1.3.0 — single-word bit staging

Choose a tag to compare

@gafferongames gafferongames released this 01 Sep 16:13
1b7ecb3

What you get

  • The bit writer is up to 1.2x faster on bit-packed writes and 1.36x on byte runs. Wide values stage through a single 32-bit word instead of a split 64-bit pair — fewer BigInt boundary crossings on the hot path. Wire bytes are identical, held by the golden battery and a 65,536-byte old-vs-new identity sweep.
  • The flush contract is now tested at its edges: a write ending exactly on a 32-bit boundary zeroes its full 8-byte span, and the new tail suite pins every ending in [0, 384] bits against buffer reuse.

Wire compatible with the whole serialize family, as always.

v1.2.0 — top-of-range compressed floats round-trip everywhere

Choose a tag to compare

@rowan-claude rowan-claude released this 23 Aug 14:17

Top-of-range compressed floats now survive the round trip in every declaration, and the vendored wire standard is back in step with the rest of the family.

STANDARD.md is re-vendored verbatim from serialize main and carries the 2026-08-23 amendment ruled by Glenn: the writer takes the floor, then clamps the resulting integer to max_integer_value. serialize.js was the last of the six runtimes on the pre-clamp copy.

Once max_integer_value reaches 2^23 the float32 ulp at the top of the range is 1, so floor(scaled + 0.5) could land one step above max_integer_value when max was written. That produced two distinct failures, both fixed here and both now pinned as tests:

  • [0, 8388609] at resolution 1 — the code fit the 24-bit field, so the write reported success and this library's own reader refused the packet with value_out_of_range.
  • [0, 16777215] at resolution 1 — the code needed 25 bits, the top bit was masked away, and max decoded as 0 with no error on either side.

Both writer entry points are covered, checked and production, each proven able to fail on its own.

No byte changes for any declaration outside [2^23, 2^24).

serialize.js 1.1.0 — production mode arrives and the port gets 1.76x faster

Choose a tag to compare

@rowan-claude rowan-claude released this 17 Aug 09:29

The write path forks once at module load: NODE_ENV=production selects production variants that trust the caller exactly as a C release build does — per-operation caller validation gone, the sticky overflow latch and every read-side content refusal kept in every mode, the wire byte-identical in both (golden-pinned). Seven measured optimizations land from the speed campaign (persistent DataView reset, snapshot reads, u64 through the scratch view, single-question write tails, fused writer core, allocation-free bulk bytes, try-path tails), each carrying its numbers in its commit. The benchmark gains 4-decimal CSV resolution and the README documents the V8 inlining-flag recommendation for throughput-sensitive use. End to end vs 1.0.0 checked: ~1.76x faster blended; raw bitpacker write +30% in production mode alone.

serialize.js 1.0.0 — the sixth implementation speaks the family wire

Choose a tag to compare

@rowan-claude rowan-claude released this 17 Aug 04:39

serialize.js is a complete hand-port of the serialize family to JavaScript: the full operation surface (bits, ints, 64/128-bit, floats, compressed float, bytes, UTF-8 strings, UTF-16 wide strings, relative ints, fixed point) on all three streams, wire-identical to the C++ reference.

  • Conformance-pinned against the reference: the 112-byte golden wire vector decodes exactly, the emoji-first family pin holds (13 bytes, 99 bits), and every op class carries pinned vectors. The sabotage battery proves the battery can fail: flipping any single one of the golden stream's 891 bits makes the read refuse.
  • 274 tests, zero dependencies, node:test only. Checked runtime with NODE_ENV-frozen dev asserts; ruling #8 content refusals bind in every build.
  • A benchmark mirroring serialize.c's bench row-for-row (npm run bench), so the family's cross-language tables can include JavaScript.

The wire is one wire, now in six languages.