All notable changes to this project are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Full TypeScript rewrite.
- New codec-token API:
t.bool,t.i8/u8/i16/u16/i32/u32,t.f32/f64,t.i64/u64,t.string,t.shortBytes,t.bytes. - Little-endian variants under
t.le.*. struct(schema)factory that compiles a schema once and reuses it acrossencode/decode/sizeOfcalls.- Functional
encode(value, schema)anddecode(buf, schema). Infer<S>type helper that derives the TypeScript shape of decoded values from a schema.DataStructErrorwith codes (VALUE_OUT_OF_RANGE,STRING_TOO_LONG,BYTES_TOO_LONG,ARRAY_TOO_LONG,BUFFER_UNDERFLOW,SCHEMA_MISMATCH,INVALID_SCHEMA),path(e.g.$.skills[1].description), andoffset(for decode errors).- Dual ESM + CommonJS build with separate
.d.mts/.d.ctstype declarations. - Vitest test suite (wire-format goldens, roundtrip, error paths) with v8 coverage.
tinybench-based benchmark suite.- GitHub Actions: CI matrix (Node 20/22/24 on Linux + Node 22 on macOS/Windows), on-demand benchmark workflow, tag-triggered release with npm provenance.
- Dependabot, PR template, CODEOWNERS.
- Module format: package is now
"type": "module"; entry points aredist/index.mjs(ESM) anddist/index.cjs(CJS). - Minimum Node.js version:
>=20.9. - Encoder now allocates the output
Bufferexactly once via a two-pass measure/write strategy (noBuffer.concat). - Decoded
shortBytes/bytesare returned as independent copies of the source memory rather than aliased views. - Replaced deprecated
new Buffer(...)calls withBuffer.allocUnsafe(for output) andTextEncoder/TextDecoderfor string codecs. - Build:
tsupnow emits minified output.dist/index.mjsshrinks from ~15 KB to7.5 KB (-50%); behaviour is unchanged.
- Legacy exports
DataTypes,DataReader,DataWriter(clean break — see README migration table). grunt,grunt-simple-mocha,jit-grunt,grunt-contrib-jshint,chai,benchmark.
- Byte-identical with
0.0.xfor the corresponding new codecs. The previous test suite's golden buffers are preserved as goldens intest/wire-format.test.ts.
- Field-iteration path strings (
${path}.${key},${path}[${i}]) are no longer allocated on the happy path.struct/arraycodecs now wrap each child call intry { ... } catch (e) { rethrowWithPrefix(e, segment) }and build the error path only when something throws. Measured on Node 22:nestedencode (compiled): -33%list of listencode (compiled): -59%list of listdecode (compiled): -45%heroencode / decode (compiled): -17% each
- Decoded structs are now created with a
nullprototype, neutralising prototype-pollution risk if a schema is built from untrusted input that contains a__proto__key. - String decoder now uses
TextDecoderinfatal: truemode and throwsSCHEMA_MISMATCHon malformed UTF-8 (previously such bytes were silently replaced withU+FFFD). struct.encodenow asserts thatwrite()emits exactly as many bytes asmeasure()reported. Defends against codec bugs leaking uninitialised memory fromBuffer.allocUnsafe.- CI now runs
npm audit --audit-level=high --omit=devand fails on high/critical advisories in production dependencies.