Skip to content

feat(DataArray): add preserveTypedArrays option to getState()#3472

Open
PaulHax wants to merge 1 commit intoKitware:masterfrom
PaulHax:dataarray-getstate-options
Open

feat(DataArray): add preserveTypedArrays option to getState()#3472
PaulHax wants to merge 1 commit intoKitware:masterfrom
PaulHax:dataarray-getstate-options

Conversation

@PaulHax
Copy link
Copy Markdown
Collaborator

@PaulHax PaulHax commented Apr 5, 2026

Context

vtkDataArray.getState() calls Array.from() on typed array values, which creates a plain JS Array with Numbers. For large arrays this causes an out-of-memory crash (RangeError: Invalid array length).

Real-world case: Kitware/VolView#852 — saving a session with a 1024×1024×256 labelmap (268M Uint8 elements) crashes because Array.from() tries to allocate ~1.6GB of heap for the boxed Number array.

The Array.from() conversion in the base getState() was added in #2927 to fix JSON serialization of Float64Array properties like direction (Kitware/glance#480).

Related: see this Discourse thread on web workers and this thread on REST API serialization. The preserveTypedArrays option formalizes that pattern in the existing API.

If this gets merged, should open another breaking change PR to remove getStateArrayMapFunc from macros.js.

Results

Before: No built-in way to serialize DataArrays without copying TypedArrays to plain Arrays.
After: getState({ preserveTypedArrays: true }) preserves TypedArray values without converting and copying. Default getState() behavior is unchanged.

// Default — JSON-safe, same as before
const jsonState = dataset.getState();
JSON.stringify(jsonState); // works

// New option — efficient for structured clone / postMessage
const state = dataset.getState({ preserveTypedArrays: true });
worker.postMessage(state);

Changes

  • macros.js: Added preserveTypedArrays option to the base getState(). When true, skips Array.from() on TypedArrays and propagates the option to nested objects.

  • DataArray/index.js: Updated getState() to conditionally skip Array.from() on values when preserveTypedArrays is true.

  • FieldData.js: Updated getState() to forward options to nested DataArrays.

  • interfaces.d.ts: Added GetStateOptions type and updated getState() signature.

  • DataArray/index.d.ts: Updated getState() signature.

  • testDataArray.js: Added tests for preserveTypedArrays option.

  • Documentation and TypeScript definitions were updated to match those changes

PR and Code Checklist

  • semantic-release commit messages
  • Run npm run reformat to have correctly formatted code

Testing

  • This change adds or fixes unit tests
  • Tested environment:
    • OS: Linux
    • Browser: Chrome Headless 138.0.0.0

getState({ preserveTypedArrays: true }) preserves TypedArray values
without converting and copying to plain Arrays. This avoids
out-of-memory crashes for large data arrays (e.g. 268M-element
labelmaps where Array.from() would allocate ~1.6GB of boxed Numbers).

The default behavior is unchanged — getState() without options still
returns JSON-safe plain Arrays.
@PaulHax PaulHax force-pushed the dataarray-getstate-options branch from d23a17b to f123de2 Compare April 7, 2026 17:22
Copy link
Copy Markdown
Member

@finetjul finetjul left a comment

Choose a reason for hiding this comment

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

LGTM

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.

2 participants