Skip to content

Conversation

@mfrancis107
Copy link

@mfrancis107 mfrancis107 commented Jan 30, 2026

🎯 Changes

  • Fix adapter default shallow equality to avoid treating all “keyless” objects as equal (Temporal objects expose no enumerable keys).
  • Preserve value semantics for value-objects by using .equals() when available (e.g. Temporal).
  • Add Temporal regression tests across adapters (React/Preact/Solid/Vue/Svelte) plus an Angular integration test to ensure Temporal updates trigger re-render.

Why

The adapters default to shallow equality. Previously, shallow could return true for two different object instances if both had zero enumerable keys, because there were no keys to compare. Temporal types from temporal-polyfill are keyless, so updates to Temporal values could be incorrectly treated as “unchanged” and skip UI updates.

Behavioral notes

  • Existing behavior for primitives, Maps, Sets, and Dates is preserved.
  • Plain objects/arrays keep their expected semantics.
  • {} vs [] is now treated as not equal (previously could be considered equal due to both being “keyless”).
  • Keyless non-plain objects are treated as not equal unless:
    • they are the same reference (Object.is), or
    • they implement .equals() (Temporal), in which case .equals() is used.

Consumers can still provide options.equal for custom semantics.

Related issues

Fixes:
TanStack/form#1628
#218

Verification in downstream

  • Verified in local TanStack Form

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

The adapters’ default `shallow` equality treated any two “keyless” objects as
equal (no enumerable keys => no comparisons), which caused Temporal objects to
be considered unchanged and skip UI updates.

Adjust `shallow` so keyless values are only equal for plain objects/arrays, and
use `.equals()` when available (e.g. Temporal) to preserve value semantics.

Add Temporal regression coverage across React/Preact/Solid/Vue/Svelte, plus an
Angular integration test to ensure Temporal updates trigger re-render.
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