fix(vanilla): remove Object.preventExtensions from createSnapshotDefault for Hermes compatibility#1220
Conversation
Dropped `Object.preventExtensions` to simplify snapshot behavior. Also removed associated test cases, as immutability is no longer enforced. This fixes the issue of Hermes enforcing strict Proxy invariant checks.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
commit: |
|
The Vercel deployment is failing, but I don't have permission to view the logs. Could you please take a look? |
It's not your fault obviously. |
|
Still trying to figure out #1221. But maybe I can merge this without waiting for it. |
Thanks! I appreciate your help. |
Related Bug Reports or Discussions
Fixes #874
Summary
Removes
Object.preventExtensions(snap)fromcreateSnapshotDefaultto fix aTypeErrorthat occurs on React Native (Hermes).Problem
Hermes enforces strict Proxy invariant checks. When a Proxy target is non-extensible, Hermes requires that the
ownKeystrap returns every key present on the target — any mismatch throws:createSnapshotDefaultcallsObject.preventExtensions(snap)at the end of snapshot creation. BecauseObject.preventExtensionsis irreversible, there is no way to undo it after the fact. The only viable fix is to not call it in the first place.This is particularly pronounced with arrays (e.g.
InformationItem[]), since their dynamic key structure ('0','1','length', etc.) makes Hermes's invariant check especially strict.The error surfaces at render time rather than at the point of assignment, because
createSnapshotDefaultis only called whenuseSnapshotruns during the render phase — not when the value is written to the store.Note: A fix on the Hermes side is not planned. The React Native team has indicated that the
ProxyAPI is internally discouraged at Meta. See: facebook/hermes#1609Change
Object.preventExtensions(snap)fromcreateSnapshotDefaultTrade-off
Removing
Object.preventExtensionsmeans snapshots are no longer guaranteed to be non-extensible. New properties could technically be added to a snapshot object at runtime. However, since snapshots are intended to be consumed as read-only values within a render cycle, this is unlikely to cause issues in practice.Check List
pnpm run fixfor formatting and linting code and docs