Add useTrackedDataSwr to the @solana/react/swr adapter#1727
Conversation
🦋 Changeset detectedLatest commit: b0480c0 The changes in this PR will be included in the next version bump. This PR includes changesets to release 47 packages
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 |
BundleMonFiles updated (25)
Unchanged files (122)
Total files change +9.01KB +1.71% Final result: ✅ View report in BundleMon website ➡️ |
|
Documentation Preview: https://kit-docs-4t3ristse-anza-tech.vercel.app |
948f9b8 to
3457bd3
Compare
f3f39e1 to
7f08fc4
Compare
3457bd3 to
b7e063e
Compare
7f08fc4 to
948efe9
Compare
b7e063e to
3a03ef4
Compare
948efe9 to
603b8f5
Compare
3a03ef4 to
24923d0
Compare
603b8f5 to
783f65e
Compare
24923d0 to
1eca8d4
Compare
trevor-cortex
left a comment
There was a problem hiding this comment.
LGTM — would approve if I had the rights to; submitting as a comment review instead.
Adds useTrackedDataSWR — the SWR-backed counterpart to useTrackedData. Wraps createReactiveStoreWithInitialValueAndSlotTracking in useSWRSubscription, bridges getUnifiedState() into next(err, data), ref-syncs the spec and getAbortSignal factory, and uses the established either-null disable pattern (spec == null ? null : key). Ships a thorough browser test suite (loaded/error from both sources, key/spec null transitions, key-change teardown, shared key, abort-signal forwarding, stale-slot dedup, error-after-load retention, stable-key-with-changing-spec, SSR), a typetest, README docs, and a minor changeset.
Structurally a near-mirror of useSubscriptionSWR — same ref-sync, same subscribe-with-empty-deps, same either-null gate, same SSR safety. The only meaningful divergence is the store construction (createReactiveStoreWithInitialValueAndSlotTracking(spec) instead of source.reactiveStore()), which is exactly what the PR description claims. Generics, JSDoc structure, and option merging (SWRConfiguration & UseTrackedDataOptions) all line up with the existing adapters.
Things to watch out for / verify
TErrordefaults tounknownhere (matchinguseSubscriptionSWR), whileuseRequestSWRdefaults toError. Pre-existing inconsistency, not introduced by this PR — flagging only so subsequent reviewers don't waste cycles on it.- Like
useSubscriptionSWR, when the spec identity changes but the SWR key stays stable, the new mappers never take effect (the test "keeps the current store when the spec identity changes but the key is stable" pins this behavior). That's the right call for cache-keyed sharing, but it's a sharp edge for users — calling out below as a doc nit. - Unlike core
useTrackedData, there's norefresh()/reconnect(). PR description explicitly calls this out; the README could mention it too for users coming from the core hook (doc nit below). - StrictMode tolerance is exercised via the latching mocks (
createMockInitialValueSourcereplays the settled outcome to remount dispatches;createMockStreamSourcereplays the log to late subscribers). Worth keeping in mind on any future refactor — these mocks are intentionally shaped to survive the dev double-render, and a naive replacement would surface flakes. - No real network / RPC integration test — the bridge is fully exercised against mocks. That's consistent with the sibling hooks; just noting for future reviewers.
783f65e to
f835130
Compare
1eca8d4 to
d346a51
Compare
Updated |
d346a51 to
c57c231
Compare
f835130 to
378f178
Compare
378f178 to
7491dbe
Compare
6e705cf to
f9a0c0c
Compare
7491dbe to
de50afe
Compare
f9a0c0c to
3739f3c
Compare
de50afe to
d07c735
Compare
3739f3c to
98e12a4
Compare
SWR-backed counterpart to `useTrackedData`. Takes the same `TrackedDataSpec` (RPC fetch + subscription pair + value mappers) and routes the unified, slot-deduped stream through SWR's `useSWRSubscription`, building a fresh `createReactiveStoreWithInitialValueAndSlotTracking` per subscription.
Returns the same `SlotTaggedValue<TItem>` shape that `useSubscriptionSwr` exports — `data.value` is the unified item produced by the spec's mappers; `data.slot` is the envelope's `context.slot`. Mirrors core `useTrackedData`'s top-level `{ data, slot }` flattened into SWR's `data` slot, and matches `useSubscriptionSwr` so a switch between the two SWR hooks is just a different generic, not a different access pattern.
Either `key === null` or `spec === null` disables the subscription, mirroring `useTrackedData`'s nullable-spec pattern. Options merge SWR's config with `useTrackedData`'s `UseTrackedDataOptions` (`getAbortSignal` for per-attempt signals threaded into the underlying store via `withSignal(signal).connect()`).
d07c735 to
b1c4037
Compare
98e12a4 to
b0480c0
Compare

Summary of Changes
This PR adds
useTrackedDataSWR, the SWR shaped version ofuseTrackedData.As with the other SWR hooks the third param is an
SWRConfiguration, with our usualgetAbortSignalfactory to add a custom signal. It also disables when either key or source are null. Note that SWR subscriptions don't include thereconnectfunction fromuseTrackedData.Note that under the hood this uses
useSWRSubscription, which enables cleaning up the subscription and resetting the store.Note that the issue from
useSubscriptionSWRaround forwarding initial store state does not apply here, because this hook creates its own store combining the two inputs (usingcreateReactiveStoreWithInitialValueAndSlotTrackingfrom Kit).