Rewrite to Typescript#1
Merged
Merged
Conversation
- typed codec tokens (`t.bool`, `t.u32`, `t.string`, `t.le.*`, `t.i64/u64`) - `struct(schema)` factory + functional `encode` / `decode` - `Infer<S>` derives the TS shape of decoded values from a schema - two-pass writer: measure once, allocate once, no `Buffer.concat` - `DataStructError` with codes, field path, and decode offset - dual ESM + CJS build via tsup (`.mjs` / `.cjs` / `.d.ts` / `.d.cts`) - vitest suite (wire-format goldens, roundtrip, error paths) with v8 coverage - tinybench benchmark suite - biome for lint + format - GitHub Actions CI matrix (Node 20/22/24 on linux + macOS/Windows on 22), on-demand benchmark workflow, tag-triggered release with npm provenance - dependabot, PR template, CODEOWNERS Wire format is byte-identical to 0.0.x for the corresponding new codecs; legacy DataTypes/DataReader/DataWriter exports are removed (clean break).
- struct.encode: assert measure() size == write() bytes emitted; protects against allocUnsafe leaking uninitialised memory if a codec measure diverges from its write - struct decode: build output objects with Object.create(null) so a stray __proto__ key in an untrusted schema cannot pollute the prototype chain - string codec: TextDecoder(fatal:true), surfaces invalid UTF-8 as SCHEMA_MISMATCH instead of silently replacing with U+FFFD - ci: add audit job running `npm audit --audit-level=high --omit=dev` so high/critical advisories in production deps fail the build; dev-only moderate advisories (vitest dev-server chain) remain tolerated Adds tests covering invalid UTF-8 and null-prototype output. Coverage remains above threshold.
Regression guard that the existing Schema/Infer types correctly compute
the value shape for `[codec]`, `[codec] as const`, `[[codec]]` and
`[{...}]` forms, including the struct() factory accepting an array
schema directly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Full rewrite of
data-structin TypeScript with a new codec-token API,two-pass encoder, dual ESM/CJS build, vitest + benchmarks + CI, plus a
follow-up security pass and a perf pass on the field-iteration hot path.
Wire format is byte-identical with
0.0.xfor the corresponding newcodecs; legacy
DataTypes/DataReader/DataWriterexports areremoved (clean break, ships as
0.1.0).Changes
API
t.bool,t.i8/u8/...i32/u32,t.f32/f64,t.i64/u64,t.string,t.shortBytes,t.bytes, witht.le.*little-endian variants.
struct(schema)factory that compiles a schema once and reuses itacross
encode/decode/sizeOf.encode(value, schema)anddecode(buf, schema).Infer<S>derives the TypeScript shape of decoded values from aschema (including top-level array forms — pinned by tests).
DataStructErrorwith codes (VALUE_OUT_OF_RANGE,STRING_TOO_LONG,BYTES_TOO_LONG,ARRAY_TOO_LONG,BUFFER_UNDERFLOW,SCHEMA_MISMATCH,INVALID_SCHEMA), fieldpath(e.g.$.skills[1].description), and decodeoffset.Build & packaging
tsupwith separate.d.ts/.d.cts. Minifiedoutput:
dist/index.mjsis ~7.5 KB (down from ~15 KB)."type": "module",engines.node >= 20.9,sideEffects: false.Performance
Buffer.concat).try/catch + rethrowWithPrefixinstead of allocating
${path}.${key}strings per field. Measured onNode 22:
list of listencode -59% / decode -45%,nestedencode-33%,
heroencode/decode -17% each.Security hardening
Object.create(null)— neutralises prototypepollution from a
__proto__key in an untrusted schema.TextDecoder({ fatal: true })— invalid UTF-8 nowraises
SCHEMA_MISMATCHinstead of silently substitutingU+FFFD.struct.encodeassertsmeasure()bytes ==write()bytes, so abuggy codec can't leak uninitialised memory from
Buffer.allocUnsafe.npm audit --audit-level=high --omit=dev.Tooling & CI
coverage.
tinybenchbenchmark suite + on-demandbenchmark.ymlworkflow..editorconfig,.nvmrc.Examples & docs
examples/01..06-*.tscovering basics, the hero struct, functionalform, errors, little-endian, and
sizeOf.CHANGELOG.mdadded.Testing
npm testpasses (vitest: wire-format goldens, roundtrip, errors)npm run lintpasses (biome)npm run typecheckpassesnpm run bench— perf numbers reported aboveNotes
Breaking changes. This ships as
0.1.0. LegacyDataTypes,DataReader, andDataWriterexports are gone; consumers move tostruct(...)/encode/decode/t.*. The README has a migrationtable. Minimum Node is now
>=20.9.Wire format. Byte-identical with
0.0.xfor the corresponding newcodecs — the previous test suite's golden buffers are preserved in
test/wire-format.test.tsto lock this in.Removed dev deps.
grunt,grunt-simple-mocha,jit-grunt,grunt-contrib-jshint,chai,benchmark.