Skip to content

Add Date, ArrayBuffer, and TypedArray support; establish golden test vectors#1

Merged
Gityosan merged 9 commits into
mainfrom
claude/nice-clarke-xyPYK
May 31, 2026
Merged

Add Date, ArrayBuffer, and TypedArray support; establish golden test vectors#1
Gityosan merged 9 commits into
mainfrom
claude/nice-clarke-xyPYK

Conversation

@Gityosan
Copy link
Copy Markdown
Owner

Summary

This PR implements support for Date, ArrayBuffer, and TypedArray types in the Graft binary format (tasks 1–3 from CLAUDE.md), and establishes the conformance testing infrastructure.

Key Changes

Format & Codec Extensions

  • Added Tag.Date (40) and Tag.Bytes (41) and Tag.TypedArray (42) to format.ts
  • Added ElementType enum with codes 0–10 for all TypedArray variants (Uint8, Int8, Float32, Float64, BigInt64, etc.)
  • Implemented Date encoding/decoding in encode.ts and decode.ts:
    • Stores unix_ms (signed) and sub_ms_nanos (always 0 in JS)
    • Preserves identity and special values (epoch, pre-epoch, far future)
  • Implemented ArrayBuffer encoding/decoding as raw byte sequences
  • Implemented TypedArray encoding/decoding with element-type dispatch:
    • Respects instanceof order (concrete types before abstract)
    • Handles all 11 element types including BigInt64Array and Uint8ClampedArray
    • Preserves special float values (NaN, ±0, ±Infinity)

Test Infrastructure

  • Migrated from imperative test script to vitest framework:
    • Replaced test/roundtrip.ts (manual check/fail counters) with test/roundtrip.test.ts (vitest describe/it)
    • Added test/property.test.ts for property-based testing with fast-check
    • All 28 existing test cases now run as individual assertions
  • Added golden vector generation (js/scripts/gen-golden.ts):
    • Generates 9 .bin files in spec/golden/ covering all major types
    • Each file is a single Object root with named test cases
    • Covers primitives, bigint, strings, dates, bytes, typed arrays, maps/sets, symbols, and cycles

Conformance Documentation

  • Created conformance/README.md defining the testing contract:
    • Specifies how to read and validate golden vectors
    • Documents the two-pass decode algorithm requirement
    • Establishes directory convention for future language ports
    • Clarifies that round-trip byte equality is not required (only decoded value equality)

Build & Package Configuration

  • Updated package.json:
    • Added test runner: vitest (4.1.7)
    • Added property testing: fast-check (4.8.0)
    • Added linting: oxlint (1.67.0), oxfmt (0.52.0)
    • Added build tool: tsdown (0.22.1)
    • Configured exports, types, and build scripts
    • Set packageManager to pnpm 11.5.0
  • Added configuration files:
    • vitest.config.ts — test environment setup
    • tsdown.config.ts — ESM build with .d.ts generation
    • .oxlintrc.json — linting rules
    • .oxfmtrc.json — formatting config
    • .npmrc — save-exact pinning
    • pnpm-workspace.yaml — workspace config

Import Path Cleanup

  • Removed .js extensions from all internal imports (TypeScript module resolution)
  • Updated index.ts to export ElementType

Implementation Details

  • Date storage: Uses signed varint for milliseconds to handle pre-epoch dates (negative values)
  • TypedArray dispatch: Checks concrete subclasses before abstract ones to avoid instanceof ambiguity
  • Golden vectors: Each .bin file is a complete Graft stream (MAGIC + VERSION + ROOT + COUNT + NODEs) with a single Object root
  • Test coverage: Roundtrip tests verify type preservation, value equality, identity preservation, and special numeric values; property tests use fast-check to shrink counter-examples

All existing 28 tests pass

https://claude.ai/code/session_01AAcPMoZL93BdAkPyYT9yvs

Claude added 9 commits May 31, 2026 01:27
…rmance docs

- format.ts: add Tag.Date(40), Tag.Bytes(41), Tag.TypedArray(42) and
  ElementType enum, in sync with spec/FORMAT.md §5.3/§5.1/§5.4
- encode.ts: encode Date (svarint ms + 0 nanos), every TypedArray subtype
  (concrete-before-abstract instanceof order), and ArrayBuffer as Bytes
- decode.ts: decode Date / Bytes / TypedArray, error on unknown element type
- index.ts: export ElementType
- test/roundtrip.ts: +14 cases (Date incl. identity, all TypedArrays,
  ArrayBuffer, special floats, empty arrays) — 42 passed, 0 failed
- scripts/gen-golden.ts: generate spec/golden/*.bin vectors
- spec/golden/: 9 golden binary vectors
- conformance/README.md: harness contract, vector table, per-language layout
- package.json: drop caret ranges (@types/node, tsx, typescript) → exact pins
- pnpm-lock.yaml: update specifier fields to match (lockfile format kept at 6.0)
- add js/.npmrc with save-exact=true so future installs pin by default
- package.json: add packageManager "pnpm@11.5.0+sha512..." (Corepack pin)
- pnpm-lock.yaml: regenerate with pnpm 11.5.0 (lockfile format 6.0 -> 9.0)

Corepack now enforces pnpm 11.5.0 for everyone using this repo.
- devDeps: vitest@4.1.7, tsdown@0.22.1 (exact pins)
- migrate test/roundtrip.ts -> test/roundtrip.test.ts (describe/it/expect),
  all assertions preserved; run via `pnpm test` (vitest run)
- vitest.config.ts: include test/**/*.test.ts, node environment
- tsdown.config.ts: bundle src/index.ts -> dist (ESM + d.ts), `pnpm build`
- package.json: proper ESM exports/main/module/types pointing at dist,
  files: [dist], scripts: build / test / test:watch / typecheck
- tsdown: outExtensions -> .js / .d.ts (was .mjs / .d.mts); package.json
  main/module/types/exports realigned to dist/index.js + dist/index.d.ts
- devDeps (exact pins): oxlint@1.67.0, oxfmt@0.52.0, fast-check@4.8.0
- scripts: lint, lint:fix, format, format:check
- .oxlintrc.json: correctness category; disable unicorn/no-new-array
  (intentional length-preallocation in encode/decode)
- .oxfmtrc.json: defaults; formatted all sources (cosmetic only:
  trailing commas / wrapping)
- test/property.test.ts: fast-check property roundtrips (nested values,
  Int32Array, Date)
- drop unused loss-of-precision literal from roundtrip test

Verified: typecheck + lint + format:check clean, 43 tests pass, build ok.
moduleResolution is "bundler" and the lib is bundled by tsdown (run via
tsx/vitest), so explicit .js extensions are unnecessary. Extensionless
specifiers across src/test/scripts; behavior unchanged.

Verified: typecheck + lint + format:check clean, 43 tests pass, build ok,
golden vectors byte-identical.
Next session will extend existing modules, so the "完了済み(触らないこと)"
prohibition no longer applies. Heading is now just "完了済み".
Runs on push to main and all PRs. Node 22 + Corepack-pinned pnpm 11.5.0,
working-directory js/. Steps: install --frozen-lockfile, typecheck, lint,
format:check, test, build. Caches the pnpm store keyed on the lockfile.
Add a build matrix over Node 22/24/26 (fail-fast disabled). pnpm store
cache key now includes the node version to avoid cross-job collisions.
@Gityosan Gityosan merged commit 747ab97 into main May 31, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant