Repository navigation
v0.1.10
Release the work that landed after the last published version
The registry now carries the version this package.json was still on, so
everything committed since ships under the next one rather than
retroactively changing what a published version means.
Build the cross-platform matrix only when the version moves
The five-runner matrix exists to produce the prebuilt binaries a release
ships. It ran on every push to main, rebuilding artefacts nobody
downloads — five runners, every time, for a comment fix.
A version-gate job now compares the package version at HEAD^ with
the one at HEAD and the matrix runs only when they differ. Anything
that is not a push passes the gate unconditionally, so workflow_dispatch
— how a release is actually cut — is unaffected, and so is publish,
which still waits on the full matrix. A missing HEAD^ reads as a bump:
erring towards building is the safe direction.
The test signal deliberately does NOT move with it. quality and the
cargo/integration jobs were already independent of the matrix, but
vitest ran INSIDE it, so gating the matrix alone would have quietly
taken the TypeScript suite off every ordinary push. A ts-tests job now
runs it on ubuntu, building its own napi binary rather than waiting on a
gated artefact. On a push without a bump that leaves typecheck, lint,
cargo and vitest — one runner instead of five.
Derive the native TypeScript surface from the Rust
The hand-written interface describing the .node binary was a second
description of the same thing, and nothing on this side noticed when the
first one changed: a pub fn could gain a parameter, stop being async
or change its return with the declaration still claiming otherwise.
napi-derive can emit the declarations itself. Its type-def feature
writes one JSON line per #[napi] item while cargo compiles;
scripts/build-napi-types.mjs collects them and
scripts/generate-napi-types.mjs turns them into
src/native/generated.ts. build:napi regenerates it, and the
TypeScript side consumes it instead of restating it.
Three things the generation had to handle:
type-defAPPENDS to its output file, so a parallel cargo build
interleaves the writes and definitions go missing, silently, leaving
the generated file short. Crates are built one at a time, and a crate
that emits nothing fails the script rather than producing a partial
surface.- A Rust doc example holding a cron expression (
0 */5 * * *) closes
the generated comment early. Every*/is escaped except the one
that legitimately closes the block — escaping that one breaks the
file just as thoroughly. - The driver is Node rather than bash, because
build:napialso runs
on the Windows prebuild runner: a Git Bashmktemppath is not
something the native proc-macro can write to, and the type-def file
would come back empty with nothing to explain why.
The generated file is a .ts holding only ambient declarations rather
than a .d.ts, so tsc carries it into dist/native/ and the
reference from the emitted declarations still resolves for consumers.
Changes since v0.1.9.