chiptime
v0.9.0
Published
Recovery-grade FIT file processing: parse anything, lose nothing silently, explain everything.
Maintainers
Readme
chiptime (TypeScript)
Recovery-grade FIT file processing. Parse anything, lose nothing silently, explain everything.
The TypeScript twin of chiptime on PyPI, built against the
same conformance corpus. Both implementations must produce byte-identical canonical JSON for every
case in corpus/ — that shared corpus, not shared code, is the contract between them
(ADR-0001,
ADR-0009).
0.1.0— parity with PyPI0.1.0. Decode, recovery, the semantic model, canonical JSON, and theparse/inspect/codesCLI. All 72 corpus cases produce byte-identical canonical output to the Python implementation, and 507 CLI invocations produce identical stdout and exit codes. The remaining verbs (repair,validate,analyze,edit,trim,reveal/scrub,doctor) arrive on the ladder below.
Parity
npm 0.N.0 mirrors the feature surface of PyPI 0.N.0. Patch numbers are independent; from
0.7.0 onward the two version lines move in lockstep.
| npm | mirrors | surface |
|---|---|---|
| 0.1.0 | PyPI 0.1.0 | decode, recovery, semantics, canonical JSON, parse/inspect/codes |
| 0.2.0 | PyPI 0.2.0 | encoder, repair, validate |
| 0.4.0 | PyPI 0.4.0 | metrics, analyze |
| 0.5.0–0.7.0 | same | edit, trim, reveal/scrub |
| 0.8.0+ | same | doctor, and whatever else Python ships while this port runs |
There is no npm 0.3.0: PyPI 0.3.0 was internal work (profile generation, performance, soak
fixes) that this port inherits from the code it mirrors.
The top of that table moves — Python keeps shipping while the port runs — so the two version lines merge when npm catches up to the then-current Python version, not at a fixed number.
Design constraints
- Zero runtime dependencies. Adding one requires an ADR, exactly as on the Python side.
- Synchronous, everywhere. Node, browsers, Deno and Bun run the same code path; container
unwrapping uses an internal inflate rather than
node:zlibor the asyncDecompressionStream. - No environment assumptions in
src/. No DOM lib, nonode:import at module load.
Usage
import { parse } from "chiptime";
import { readFileSync } from "node:fs";
const result = parse(new Uint8Array(readFileSync("ride.fit")));
result.ok; // usable output produced?
result.fileType; // "activity" | "course" | "workout" | ...
result.recovery; // null unless salvage engaged
result.provenance; // every drop, repair and synthesis, typed
result.toCanonicalJson(); // RFC 8785 bytes — byte-identical to Python'snpx chiptime parse ride.fit --json
npx chiptime inspect ride.fit
npx chiptime codesExit codes: 0 clean · 2 recovered with data loss · 3 unusable · 4 not a FIT file ·
64 usage error.
Development
npm install
npm run typecheck && npm run lint && npm test && npm run guardsThe differential vectors under test/vectors/ are generated from CPython by
scripts/gen_parity_vectors.py at the repo root and regenerated in CI — a Python-side behavior
change cannot silently invalidate them.
License
MIT. Not affiliated with Garmin. FIT and Garmin are trademarks of Garmin Ltd.
