Collapse retrying into loading with stale-while-revalidate semantics#1677
Collapse retrying into loading with stale-while-revalidate semantics#1677mcintyre94 wants to merge 1 commit into
retrying into loading with stale-while-revalidate semantics#1677Conversation
🦋 Changeset detectedLatest commit: bb74599 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 |
loading and retrying into a single loading statusretrying into loading with stale-while-revalidate semantics
BundleMonFiles updated (22)
Unchanged files (125)
Total files change +7.45KB +1.41% Final result: ✅ View report in BundleMon website ➡️ |
trevor-cortex
left a comment
There was a problem hiding this comment.
Collapses retrying into loading on ReactiveStreamStore, mirroring the action store's running, and widens loading to carry data: T | undefined + error: unknown so the prior outcome is preserved across reconnects (SWR). Reasonable shape change — the implementation in both stores becomes uniformly setState({ data: currentState.data, error: currentState.error, status: 'loading' }) and the existing setState identity guard naturally no-ops the loading → loading re-entry (already covered by the pre-existing 'does not notify subscribers on the loading → loading re-entry' test).
packages/subscribable/README.md is half-migrated and now self-contradictory. The PR only made minimal textual tweaks here, leaving stale retrying references that disagree with the implementation. Three spots:
- The
ReactiveState<T>snippet in the README still lists aretryingvariant (lines 38–42 of the new README). The diff just changederror: undefined→error: unknownon that line; the line should be removed outright, sinceretryingis no longer part of the type. As-is, the README contradicts the source. - The paragraph just below (line 47) still says "transitions through
retryingwhile preserving the last known value and the last error". - Further down (around line 135), the
createReactiveStoreFromDataPublisherFactory"Things to note" bullet wasn't touched at all and still reads: "Fromidle, the store transitions throughloading; from any other status, throughretryingwhile preserving the last known value." Same problem.
Inline comments on the first two. #3 isn't part of the diff so flagging it here.
Things to watch out for / verify:
- Migration heuristic in the changeset (
status === 'loading' && data !== undefined) misses the case where a retry was kicked off fromerrorbut noloadedhad ever occurred before that error — thendata === undefinedand the loading is indistinguishable from a first-load from idle. The changeset already acknowledges this loosely ("or juststatus === 'loading'if you don't need to distinguish"), so this is fine, but worth keeping in mind for downstream callers that genuinely need the first-load-vs-reconnect distinction — the new model doesn't preserve it. - Test coverage looks good: kit's
error → loading (preserves data + error), subscribable'serror → loadingandloaded → loading, and theloading → loadingno-notify case are all covered. The notify-on-transition tests still assert the right thing (the status discriminator changes, so subscribers still fire). - Behavioural diff worth keeping in the back of the head for downstream consumers: previously, a
connect()fromerrorclearederrorimmediately on transition, so any UI gated onerror !== undefinedwould clear at that moment. Nowerrorsurvives across the transition until the nextloaded(or a newerror) replaces it. This is the intended SWR semantic and matches the changeset, just want it surfaced for review.
Notes for subsequent reviewers:
- Pre-existing staleness elsewhere in the README that's outside the scope of this PR but worth a follow-up: the bottom
createReactiveStoreFromDataPublisherFactorysnippet still shows anabortSignal:property on the config and the bullet about "Triggering the caller'sabortSignaldisconnects the store permanently" — neither matches the currentwithSignal()-per-connect API. Not blocking this PR, but worth knowing while the file is open. - No other call sites in the repo reference
'retrying'as far as I can see; the type-system removal of the variant would surface any stragglers at compile time.
|
Documentation Preview: https://kit-docs-i5tmvjnys-anza-tech.vercel.app |
efde42d to
2fd75aa
Compare
|
Oops missed some changes to the readme. Please re-review @trevor-cortex |
|
Re-reviewed the README diff — all three stale
Nice bonus: the pre-existing Nothing else to flag. LGTM. 👍 |
85182fc to
6169ab5
Compare
2fd75aa to
38cc195
Compare
lorisleiva
left a comment
There was a problem hiding this comment.
Nice, one less state to worry about!
38cc195 to
74b30a6
Compare
6169ab5 to
1b2b3f3
Compare
74b30a6 to
abd86ff
Compare
0c67325 to
ade3616
Compare
abd86ff to
a484aef
Compare
d5542a7 to
8733cab
Compare
1ec234a to
7615ebb
Compare
c3ebc28 to
fcfdbd1
Compare
Mirrors the action store's `running` (which already merged "first call vs subsequent call"). `data` and `error` are preserved through `loading` for stale-while-revalidate UX.
`ReactiveState<T>` drops the `retrying` variant. `loading` widens from `{ data: undefined, error: undefined }` to `{ data: T | undefined, error: unknown }`. Both `createReactiveStoreFromDataPublisherFactory` and `createReactiveStoreWithInitialValueAndSlotTracking` transition every `connect()` through `loading`, preserving `currentState.data` and `currentState.error`.
Consumers that need to distinguish first-load from reconnect inspect `data === undefined` instead of relying on a separate `retrying` status. Bumps `@solana/subscribable` and `@solana/kit` major.
Tests in both packages updated: `retrying`-state assertions now assert `loading` carrying stale data + error. Downstream `useSubscription` (next commit) drops `retrying` from `SubscriptionResult.status` and passes data + error through the `loading` case.
fcfdbd1 to
bb74599
Compare
4197ebe to
51febd9
Compare

Summary of Changes
This PR modifies the states for the stream-store.
The
retryingstate is removed, and we now useloadingfor both first connects and subsequent ones. This matcheshow we structure the action store, and minimises states.Additionally we preserve the last error (in addition to data) in the
loadingstate, to improve SWR. Again this matches a change made to the action store.