feat(graphql-react-ws): syncStore opt-out for callback-only subscriptions - #180
Conversation
…riptions High-frequency consumers that only use onData/onError (e.g. chat cache writers) were forced to re-render on every frame because useSubscription always mirrored results into a valtio store read via useSnapshot. syncStore: false skips those writes while keeping callbacks and default reactive behavior unchanged.
🦋 Changeset detectedLatest commit: f361306 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 |
|
bugbot run |
|
Skipping Bugbot: Bugbot is disabled for this repository. Visit the Bugbot dashboard to update your settings. |
|
bugbot run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5fe13f6. Configure here.
…is false Callback-only listeners share the valtio store and the same broadcast result object with syncStore:true peers. Updating store.ref.current from a syncStore:false listener could mark the result as applied before a reactive peer wrote data/error, leaving returned values stale. Only syncStore:true consumers participate in the shared-store dedup now.
|
Re: Bugbot shared-store skip via ref — confirmed real, fixed in 63cf309. Same Fix: only advance |
…e snapshot syncStore:false still called useProxySnapshot on the shared store and could write initialData into it, so a reactive peer's store write re-rendered the callback-only mount and contradicted the no-re-render guarantee. Snapshot an inert proxy instead, skip initialData store writes, and return null data/error.

Summary
syncStoretouseSubscription(defaulttrue, backwards compatible).syncStore: false, results are delivered only viaonData/onErrorand are not mirrored into the valtio store — souseSnapshotdoes not re-render the calling component on every frame.data/error.Why
Today every subscription frame does
store.data = …+useProxySnapshot(store), which forces a React re-render of whatever component called the hook — even if the app only usesonData. Under chat fan-out that re-renders entire channel shells.App-side workarounds (null-rendering leaf components) work but push the cost of a library default onto every consumer. This flag fixes it at the source.
API
Returned
data/errordo not update whilesyncStoreisfalse.Test plan
onDatastill fires withsyncStore: falsesyncStore: falsesyncStore: truestill updates returneddataonErrorstill fires withsyncStore: false@soundxyz/graphql-react-wspatch), Vault can passsyncStore: falsefromuseResilientSubscriptionand optionally remove the*Subscriberleaf componentsDeployment considerations
@soundxyz/graphql-react-wsand opt in withsyncStore: falseto benefit — no behavior change at default.Other call outs
N/A
Made with Cursor