-
Notifications
You must be signed in to change notification settings - Fork 152
Fix date field corruption after app restart #1127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…ing conversion
The JSON.parse reviver in deserialize() was converting ALL ISO date
strings to Date objects, including plain string values that happened
to match the ISO format. This corrupted user data after app restarts.
The serializer already has an explicit date marker system:
- serializeValue() wraps Date objects as { __type: 'Date', value: '...' }
- deserializeValue() restores dates from those markers
The fix removes the eager reviver and only converts the top-level
createdAt field, letting the marker system handle dates in mutation data.
Adds TransactionSerializer.test.ts with tests covering:
- Plain ISO strings preserved as strings
- Actual Date objects correctly restored via marker system
- Mixed Date objects and ISO strings handled correctly
- Nested ISO string values not corrupted
- Top-level createdAt correctly restored as Date
🦋 Changeset detectedLatest commit: 8fdbb2e The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
More templates
@tanstack/angular-db
@tanstack/db
@tanstack/db-ivm
@tanstack/electric-db-collection
@tanstack/offline-transactions
@tanstack/powersync-db-collection
@tanstack/query-db-collection
@tanstack/react-db
@tanstack/rxdb-db-collection
@tanstack/solid-db
@tanstack/svelte-db
@tanstack/trailbase-db-collection
@tanstack/vue-db
commit: |
|
Size Change: 0 B Total Size: 90.5 kB ℹ️ View Unchanged
|
|
Size Change: 0 B Total Size: 3.47 kB ℹ️ View Unchanged
|
Code reviewFound 1 issue:
db/.github/pull_request_template.md Lines 5 to 6 in b475edd
Run 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
- Fix SerializedOfflineTransaction.createdAt type to string (matches JSON-parsed reality) - Remove JSON.stringify replacer in favor of explicit createdAt conversion - Remove unnecessary double cast in deserialize Co-Authored-By: Claude Opus 4.5 <[email protected]>
…ures - Validate createdAt in deserialize() throws on Invalid Date - Validate Date markers have value field before deserializing - Validate Date marker values produce valid dates - Remove stray whitespace in types.ts Co-Authored-By: Claude Opus 4.5 <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
Summary
Fixes date field corruption that occurred after app restart. String values that happened to match ISO date format (e.g.,
eventId: "2024-01-15T10:30:00.000Z") were being incorrectly converted to Date objects during deserialization, corrupting user data.Root Cause
The
JSON.parsereviver indeserialize()used a regex to detect ISO date strings and eagerly converted ALL matches to Date objects:This ignored that the serializer already has an explicit marker system for Date objects:
serializeValue()wraps actual Dates as{ __type: 'Date', value: '...' }deserializeValue()only converts values with that marker back to DatesThe reviver was converting things it shouldn't, bypassing the marker system entirely.
Approach
JSON.parsereturn raw datacreatedAtexplicitly - The only top-level Date field gets explicit conversion{ __type: 'Date' }markers, handled by existingdeserializeValue()SerializedOfflineTransaction.createdAtis nowstring(matches JSON-parsed reality)Key Invariants
{ __type: 'Date' }Non-goals
OutboxManager's catch blocks (separate concern)Trade-offs
Alternative considered: Keep the reviver but add an exclusion list for fields that shouldn't be converted.
Why rejected: Fragile - requires maintaining a list of every string field that might contain ISO-formatted values. The marker system already solves this correctly.
Verification
The new test file covers:
createdAtcorrectly restored as DateFiles Changed
TransactionSerializer.tscreatedAtconversion, add date validationtypes.tsSerializedOfflineTransaction.createdAt:Date→stringTransactionSerializer.test.ts