Nothing has been published, so a 1.0.0/2.0.0 split claimed a stability and a
history that do not exist. Staying on 0.x says what is true: the API may still
move. Under semver a breaking change is then a minor bump, which is exactly the
relationship between the two lines — 0.1.x keeps legacy experimentalDecorators,
0.2.x moves to TC39 standard decorators.
Branch renamed 1.x -> 0.1.x to match, along with its CI trigger and the
maintenance-line notice in the README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAcqrz3FcadkYr3xG32CjK
The 2.x README tells projects on an oxc-based toolchain to stay on 1.x, but no
such line existed — this branch point was version 0.1.0, so the advice pointed
at nothing installable.
- version 1.0.0
- CI runs on this branch as well as main and develop
- README opens with a maintenance-line notice pointing new projects at 2.x and
naming the one reason to stay here: oxc does not implement the TC39 standard
decorator transform, while tsc and esbuild do
- CHANGELOG names the release
No functional change: the code is exactly the state merged as PR #3.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAcqrz3FcadkYr3xG32CjK
Profiling the validator showed roughly half of all validation time re-deriving
answers that cannot change — collectConstraints 22%, getOwnMetadata 12%,
getMetadataChain 9%, getProperties 4%, getMetadata 3%, plus 8% GC from the
allocation churn. The constraint predicates themselves were under 1%.
Decorator metadata is fixed once classes are declared, so the derived structures
are now memoized per prototype: the validation plan, the serialization plan, the
deserialization plan, and serializer/deserializer instances, which were being
constructed fresh for every property of every object. MetadataStorage carries a
version counter that invalidates the caches when metadata is written, so
registerDecorator after first use still works — covered by a test.
Measured against JSON.parse + JSON.stringify as a fixed reference:
validate (50 orders) 221.6 us -> 49.6 us 4.5x
validate (10 orders) 47.8 us -> 12.9 us 3.7x
toInstance (50 orders) 255.1 us -> 74.0 us 3.4x
toInstance (10 orders) 64.6 us -> 19.0 us 3.4x
toPlain (50 orders) 294.4 us -> 95.3 us 3.1x
Reliability, in the same pass:
- maxDepth option (default 64) on every mapping function, on validate(), and on
configure(). All three engines recurse, so a payload nested thousands of levels
deep could exhaust the call stack. Cycles were already handled; legitimate deep
nesting was not bounded.
- each: true failures now name the element that failed ("failed at index 3"). A
bad entry in a 200-item array previously produced a message that could not
locate it. A message function now receives the failing element as args.value
rather than the whole array; caller-supplied strings stay verbatim.
150 tests (up from 136), all green on the existing suite unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAcqrz3FcadkYr3xG32CjK
The vitest suite silently ran zero tests: vitest 4 transpiles with oxc, which
does not pick up `experimentalDecorators` from a tsconfig that excludes the
files being transformed, so every decorator-using suite failed to parse and was
reported as "0 test". A vitest.config.ts enabling legacy decorators brings all
40 existing tests back to life.
- Add vitest.config.ts (oxc legacy decorators + v8 coverage config)
- Type-check test files: move the test/demo exclusions from the base tsconfig
onto the two build configs, and fix the strict-mode errors this surfaced
- Stop shipping src/example.ts in dist (it invokes runExample() at import time,
a side effect in a package declaring "sideEffects": false)
- CI: run lint, tests with coverage, build and entry-point smoke checks; drop
EOL Node 18, add Node 24; commit package-lock.json so `npm ci` works
- Add `verify`, `test:watch` and `build:docs` scripts, and an engines field;
`build:docs` regenerates the previously hand-maintained docs/cereale.js
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAcqrz3FcadkYr3xG32CjK