Skip to content

fix: support BigInt64Array and BigUint64Array serialization - #353

Merged
Skn0tt merged 1 commit into
flightcontrolhq:mainfrom
chatman-media:fix/bigint-typed-arrays
Jun 18, 2026
Merged

fix: support BigInt64Array and BigUint64Array serialization#353
Skn0tt merged 1 commit into
flightcontrolhq:mainfrom
chatman-media:fix/bigint-typed-arrays

Conversation

@chatman-media

@chatman-media chatman-media commented Jun 15, 2026

Copy link
Copy Markdown

Problem

BigInt64Array and BigUint64Array are detected as typed arrays by isTypedArray (they pass ArrayBuffer.isView and aren't DataView), so superjson annotates them as ['typed-array', 'BigInt64Array'] and tries to round-trip them. But the round-trip is broken in two ways:

  • serialize/stringify throws — the transform produces an array of raw bigint elements, which JSON.stringify cannot represent: TypeError: Do not know how to serialize a BigInt.
  • deserialize throwsconstructorToName only lists the numeric typed arrays, so the BigInt variants hit Error: Trying to deserialize unknown typed array.

Reproduction on main:

import superjson from 'superjson';

superjson.stringify(new BigInt64Array([1n, 2n, 3n]));
// TypeError: Do not know how to serialize a BigInt

superjson.deserialize(superjson.serialize(new BigUint64Array([1n])));
// Error: Trying to deserialize unknown typed array

Fix

bigint isn't valid JSON, so (mirroring how the existing code stores NaN/Infinity as strings) BigInt typed-array elements are serialized as decimal strings and parsed back with BigInt(...) on deserialization. A small bigIntConstructorToName lookup maps the two BigInt typed-array constructors back to their classes.

The constructor registration is guarded with typeof BigInt64Array !== 'undefined', consistent with the existing BigInt-polyfill defensiveness in transformer.ts, so environments without these globals are unaffected.

Serialized form (now JSON-safe):

{ "json": ["1", "2", "3"], "meta": { "values": [["typed-array", "BigInt64Array"]], "v": 1 } }

Tests

Added a works with BigInt typed arrays case to the stringify & parse fixtures (which round-trips through JSON.parse(JSON.stringify(...)), so it also covers the stringify path). It verifies the serialized shape, the type annotations, that values revive to the correct typed-array class, and exact element equality — including values that would lose precision as number (9007199254740993n) and BigUint64Array's max (18446744073709551615n).

The new test fails on main (Do not know how to serialize a BigInt) and passes with this change. Full suite (pnpm test) and tsc build both pass.

Greptile Summary

This PR fixes broken serialization of BigInt64Array and BigUint64Array by converting their bigint elements to/from decimal strings during JSON encoding — mirroring the existing NaN/Infinity string strategy for numeric typed arrays.

  • src/transformer.ts: A bigIntConstructorToName lookup (guarded by typeof BigInt64Array !== 'undefined') maps constructor names to their classes; the serialize path calls n.toString() for bigint elements, and the deserialize path calls BigInt(n) and reconstructs the correct typed-array subclass.
  • src/is.ts: Adds BigIntTypedArrayConstructor and widens TypedArray to include BigInt64Array/BigUint64Array instances, keeping the type definitions consistent with the new runtime support.
  • src/index.test.ts: Adds a fixture that round-trips both array types, including a value that would lose precision as a number (9007199254740993n) and BigUint64Array's maximum (18446744073709551615n).

Confidence Score: 4/5

Safe to merge; the fix is narrowly scoped to the two BigInt typed-array classes and does not touch existing numeric typed-array paths.

The serialization and deserialization logic is correct and follows the established NaN/Infinity string pattern. The bigIntConstructorToName lookup is properly guarded for environments without BigInt typed arrays. Tests cover precision-critical values and the full round-trip through JSON.stringify/parse.

The deserialization branch in src/transformer.ts (lines 254–258) is the most sensitive change — worth a quick read to confirm the BigInt(n) call aligns with all expected input shapes.

Important Files Changed

Filename Overview
src/is.ts Adds BigIntTypedArrayConstructor type and expands TypedArray to include BigInt64Array and BigUint64Array instances — clean, minimal type-level change.
src/transformer.ts Adds bigIntConstructorToName lookup and updates typedArrayRule to serialize bigint elements as strings and deserialize them back with BigInt(n). Logic is sound; naming follows existing convention.
src/index.test.ts Adds a round-trip test case for both BigInt64Array and BigUint64Array covering precision-exceeding values (9007199254740993n) and BigUint64 max (18446744073709551615n).

Sequence Diagram

sequenceDiagram
    participant Caller
    participant typedArrayRule
    participant JSON

    Note over Caller,JSON: Serialize BigInt64Array([1n, 2n, -3n])
    Caller->>typedArrayRule: transform(BigInt64Array)
    typedArrayRule->>typedArrayRule: "[...v].map(n => n.toString()) for bigint"
    typedArrayRule-->>Caller: ["1", "2", "-3"] + annotation ["typed-array", "BigInt64Array"]
    Caller->>JSON: JSON.stringify(["1","2","-3"])
    JSON-->>Caller: valid JSON

    Note over Caller,JSON: Deserialize
    Caller->>JSON: JSON.parse(...)
    JSON-->>Caller: ["1", "2", "-3"]
    Caller->>typedArrayRule: untransform(["1","2","-3"], ["typed-array","BigInt64Array"])
    typedArrayRule->>typedArrayRule: "bigIntConstructorToName["BigInt64Array"] -> BigInt64Array"
    typedArrayRule->>typedArrayRule: "v.map(n => BigInt(n)) -> [1n, 2n, -3n]"
    typedArrayRule->>typedArrayRule: new BigInt64Array([1n, 2n, -3n])
    typedArrayRule-->>Caller: BigInt64Array([1n, 2n, -3n])
Loading

Reviews (1): Last reviewed commit: "fix: support BigInt64Array and BigUint64..." | Re-trigger Greptile

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes SuperJSON’s handling of BigInt64Array and BigUint64Array by ensuring their elements are serialized into JSON-safe values and correctly revived on deserialization, aligning their behavior with existing typed-array support.

Changes:

  • Serialize BigInt typed-array elements as decimal strings (since JSON cannot represent bigint).
  • Add guarded constructor lookup for BigInt64Array / BigUint64Array to enable correct deserialization.
  • Add a round-trip fixture test covering precision-critical BigInt values and the BigUint64Array max.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/transformer.ts Adds BigInt typed-array handling in the typed-array transform/untransform logic (string encoding + constructor mapping).
src/is.ts Expands typed-array typings to include BigInt typed arrays for internal narrowing consistency.
src/index.test.ts Adds a fixture ensuring BigInt typed arrays serialize to JSON-safe strings and revive to the correct typed-array classes with exact values.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Skn0tt Skn0tt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonderful, thank you!

@Skn0tt
Skn0tt merged commit aaa65e3 into flightcontrolhq:main Jun 18, 2026
4 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.

3 participants