Skip to content

fix: hydrate relational values - #377

Merged
kettanaito merged 3 commits into
mainfrom
fix/hydration-issues
Aug 30, 2026
Merged

fix: hydrate relational values#377
kettanaito merged 3 commits into
mainfrom
fix/hydration-issues

Conversation

@kettanaito

@kettanaito kettanaito commented Aug 30, 2026

Copy link
Copy Markdown
Member

Root cause

persist/sync strip relational values before storing a record, then restore it via collection.create(), which validates against the schema before relations are initialized. Any required relation is therefore missing at validation time and hydration throws does not match the schema. Existing tests only used .optional() relations, so this went unnoticed.

In the future, it'd be best to migrate all Collection operations to be async and unlock async schema support. That's a breaking change so I'm skipping it for now.

Changes

  • Prevent record duplication on sync+persist synergy.
  • Enforce sync schemas to guarantee sync hydration.
  • Move Collection#sanitizeInitialValues to utils.ts and reuse it in persist: a serialized record is now the same sanitized tree the collection itself validates on update() — relations inlined as foreign-record snapshots, cycles cut identically.
  • Store primary keys of the record and every nested snapshot in metadata; deserializeRecord restores them (plus an empty relation map on snapshots so unique relations hydrate).
  • createFromSerializedRecord becomes collection.create(deserializeRecord(...)) — relations pick up foreign keys from the snapshots, no post-hoc key patching.
  • Bump storage version to 2; skip incompatible persisted data with a warning.
  • Defer hydration by a microtask so relations defined right after construction apply to hydrated records (previously relied on validate() being async).
  • Tests: Date-through-schema, required relation (persist + sync), unique relation.

@kettanaito
kettanaito merged commit 09ea6b4 into main Aug 30, 2026
3 checks passed
@kettanaito
kettanaito deleted the fix/hydration-issues branch August 30, 2026 12:59
@kettanaito

Copy link
Copy Markdown
Member Author

Released: v1.1.8 🎉

This has been released in v1.1.8.

Get these changes by running the following command:

npm i @msw/data@latest

Predictable release automation by Release.

noveogroup-amorgunov added a commit to noveogroup-amorgunov/nukeapp that referenced this pull request Sep 3, 2026
* refactor: migrate from forked @mswjs/data to @msw/data v1.1.8

- Replace the forked @mswjs/data (feat-persist branch) with the official
  @msw/data package, which now ships the persist extension with fixed
  relational hydration (mswjs/data#343, fixed in mswjs/data#377)
- Rewrite serverDb to Collection + zod schemas with defineRelations
- Add custom persist extension with configurable storage
  (localStorage/sessionStorage via VITE_API_STORAGE_MODE) and legacy
  'mswjs-data/*' storage keys cleanup
- Expose dbHydration promise; await migration before starting the MSW worker
- Update mock handlers to the new query syntax (q.where predicates)

* fix: provide defaults for optional product mock fields

Products in the mock data may miss the description and detailsImageUrl
keys, but ProductDetailsDto requires them. Add schema defaults so the
records always match the DTO contract (the previous nullable fields
could be absent, crashing mapProductDetails on detailsImageUrl.length).
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.

Persist extention hydration

1 participant