Skip to content

Truncate @stream arrays only on last chunk by default#13069

Merged
phryneas merged 59 commits intorelease-4.1from
jerel/refetch-maintain
Dec 23, 2025
Merged

Truncate @stream arrays only on last chunk by default#13069
phryneas merged 59 commits intorelease-4.1from
jerel/refetch-maintain

Conversation

@jerelmiller
Copy link
Copy Markdown
Member

Updates the default @stream behavior to maintain existing cache data as much as possible. Currently the @stream array is truncated when the first chunk arrives which means you might lose data on screen suddenly while the data is fetched. We want to maintain the truncation, but only when the server completes the stream of data.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Dec 20, 2025

⚠️ No Changeset found

Latest commit: 5a90bc7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Dec 20, 2025

npm i https://pkg.pr.new/apollographql/apollo-client/@apollo/client@13069

commit: 5a90bc7

@jerelmiller jerelmiller force-pushed the jerel/refetch-maintain branch from b26c7ba to 9b209ac Compare December 20, 2025 09:13
@jerelmiller jerelmiller changed the title [WIP] Truncate @stream arrays only on last chunk by default Truncate @stream arrays only on last chunk by default Dec 20, 2025
) => mergeObjects(existing, incoming);
const mergeFalseFn: FieldMergeFunction<any> = (_, incoming) => incoming;

export const defaultStreamFieldMergeFn: FieldMergeFunction<Array<any>> = (
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm doing the work to combine/truncate the array in a default merge function instead of the incremental handler because it makes it much easier to implement a custom merge function that takes the truncated array immediately (i.e. you just need (_, incoming) => incoming). This ensures incoming is set to the array emitted from the server in a @stream field rather than the combination of the cached array and streamed field.

@jerelmiller
Copy link
Copy Markdown
Member Author

@phryneas I think I have this in a pretty good spot. I've added comments to both highlight some areas of code with an explainer or to get your opinion. Feel free to make tweaks as you see fit so we can get this out and release an rc 🙂. Thanks so much!

@phryneas phryneas self-requested a review December 22, 2025 08:26
@jerelmiller jerelmiller marked this pull request as ready for review December 22, 2025 15:06
private extensions: Record<string, any> = {};
private pending = new Map<string, GraphQL17Alpha9Handler.PendingResult>();
private streamDetails = new Trie<{ current: Incremental.StreamFieldDetails }>(
true,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
true,
false,

Given that path is (string|number)[], this can never be weak, so let's keep it as an explicitly strong Trie from the start.

* This field is only available in `merge` functions when the `@stream`
* directive is used on the field.
*/
streamFieldDetails?: Incremental.StreamFieldDetails;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer streamFieldInfo, renaming :)

fieldName: field.name.value,
field,
variables: context.variables,
path,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say we can add it in the future. It might be useful, but it might also be a foot gun. Let's not do this too quickly without good use cases.

})
);
// friend:2 ["one"]
expect(merge).toHaveBeenNthCalledWith(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea, but in the spirit of getting this published today, I'm not going to add it now. We should look at this again in the new year, though.

@github-actions github-actions bot added the auto-cleanup 🤖 label Dec 23, 2025
@phryneas phryneas merged commit 9cad04a into release-4.1 Dec 23, 2025
45 checks passed
@phryneas phryneas deleted the jerel/refetch-maintain branch December 23, 2025 12:48
phryneas pushed a commit that referenced this pull request Dec 23, 2025
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to release-4.1, this
PR will be updated.

⚠️⚠️⚠️⚠️⚠️⚠️

`release-4.1` is currently in **pre mode** so this branch has
prereleases rather than normal releases. If you want to exit
prereleases, run `changeset pre exit` on `release-4.1`.

⚠️⚠️⚠️⚠️⚠️⚠️

# Releases
## @apollo/[email protected]

### Patch Changes

- [#12884](#12884)
[`d329790`](d329790)
Thanks [@phryneas](https://github.com/phryneas)! - Ensure that
`PreloadedQueryRef` instances are unsubscribed when garbage collected

- [#13069](#13069)
[`9cad04a`](9cad04a)
Thanks [@jerelmiller](https://github.com/jerelmiller)! - Truncate
@stream arrays only on last chunk by default

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
jerelmiller added a commit that referenced this pull request Jan 5, 2026
Finish rename of some variables from `streamDetails` to `streamInfo`
from #13069 for consistency

---------

Co-authored-by: jerelmiller <[email protected]>
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 23, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants