Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ReadableStreamLinks for normal data transport, too #424

Open
wants to merge 20 commits into
base: next
Choose a base branch
from

Conversation

phryneas
Copy link
Member

@phryneas phryneas commented Feb 4, 2025

No description provided.

Copy link

changeset-bot bot commented Feb 4, 2025

⚠️ No Changeset found

Latest commit: 49c78d2

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

Copy link

pkg-pr-new bot commented Feb 4, 2025

npm i https://pkg.pr.new/apollographql/apollo-client-nextjs/@apollo/experimental-nextjs-app-support@424
npm i https://pkg.pr.new/apollographql/apollo-client-nextjs/@apollo/client-integration-react-router@424
npm i https://pkg.pr.new/apollographql/apollo-client-nextjs/@apollo/client-react-streaming@424
npm i https://pkg.pr.new/apollographql/apollo-client-nextjs/@apollo/client-integration-tanstack-start@424

commit: 49c78d2

Copy link

vercel bot commented Feb 4, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
apollo__client-integration-react-router ✅ Ready (Inspect) Visit Preview Feb 10, 2025 11:30am
apollo__client-integration-tanstack-start ✅ Ready (Inspect) Visit Preview Feb 10, 2025 11:30am

Copy link

relativeci bot commented Feb 4, 2025

#457 Bundle Size — 1.33MiB (+6.79%).

49c78d2(current) vs 5293db1 main#409(baseline)

Warning

Bundle contains 1 duplicate package – View duplicate packages

Warning

Bundle introduced one new package: process – View changed packages

Bundle metrics  Change 8 changes Regression 1 regression Improvement 2 improvements
                 Current
#457
     Baseline
#409
Regression  Initial JS 1.05MiB(+5.64%) 1016.91KiB
No change  Initial CSS 70B 70B
Change  Cache Invalidation 81.12% 0.08%
Change  Chunks 37(+8.82%) 34
Change  Assets 63(+6.78%) 59
Change  Modules 676(+6.29%) 636
Improvement  Duplicate Modules 98(-7.55%) 106
Change  Duplicate Code 4.31%(-8.3%) 4.7%
Improvement  Packages 25(-3.85%) 26
No change  Duplicate Packages 1 1
Bundle size by type  Change 3 changes Regression 3 regressions
                 Current
#457
     Baseline
#409
Regression  JS 1.32MiB (+100%) undefined
Regression  Other 10.27KiB (+100%) undefined
Regression  CSS 70B (+100%) undefined

Bundle analysis reportBranch pr/use-readable-stream-everywher...Project dashboard


Generated by RelativeCIDocumentationReport issue

@@ -313,6 +315,7 @@ describe(
appendToBody`<div hidden id="S:1"><div id="user">User</div></div>`;
$RS("S:1", "P:1");

await new Promise((resolve) => setTimeout(resolve, 10));
Copy link
Member Author

Choose a reason for hiding this comment

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

Arriving request data (simulateRequestData) now takes a tick as it goes through the link chain instead of directly being written to the store. Without this delay, this test would have written the query first and then the data from the link would have arrived.

Comment on lines +105 to 116
}

setLink(newLink: ApolloLink) {
super.setLink.call(
this,
ApolloLink.from([
new ReadFromReadableStreamLink(),
new TeeToReadableStreamLink(),
newLink,
])
);
}
Copy link
Member Author

Choose a reason for hiding this comment

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

All implementations (SSR, RSC, Browser) now use the same links - RSC could omit the ReadFromReadableStreamLink, but keeping all those separate details is very prone to subtle bugs; this is more reasonable.

Comment on lines -177 to -180
if (
!queryManager["inFlightLinkObservables"].peekArray(cacheKeyArr)
?.observable
) {
Copy link
Member Author

Choose a reason for hiding this comment

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

No more manually added inFlightLinkObservables - we really use a link, so this doesn't need to fiddle with QueryManager internals.

observable: streamObservable,
return super.watchQuery({
...options,
context: teeToReadableStream(() => this.pushEventStream(options), {
Copy link
Member Author

Choose a reason for hiding this comment

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

Moving this into a callback that only executes if the link is actually called means we will never inject a "started" event (or worse, a stream) when the query is deduplicated or for some other reason doesn't cause a network request.

Comment on lines -434 to +314
constructor(options: WrappedApolloClientOptions) {
super(options);
this.setLink(this.link);
}
class ApolloClientBrowserImpl extends ApolloClientClientBaseImpl {}

setLink(newLink: ApolloLink) {
super.setLink.call(this, new ReadFromReadableStreamLink().concat(newLink));
}
}

class ApolloClientRSCImpl extends ApolloClientBase {
constructor(options: WrappedApolloClientOptions) {
super(options);
this.setLink(this.link);
}

setLink(newLink: ApolloLink) {
super.setLink.call(this, new TeeToReadableStreamLink().concat(newLink));
}
}
class ApolloClientRSCImpl extends ApolloClientBase {}
Copy link
Member Author

Choose a reason for hiding this comment

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

Leaving these here even though they're empty - those class names might help in stack traces submitted by users to more quickly identify problems (and tbh., at some point I'll add back some env-specific logic here anyways)

Comment on lines +54 to +59
const script = `__APOLLO_EVENTS__.push(${jsesc(event, {
isScriptContext: true,
wrap: true,
json: true,
})})`;
ssr.injectScript(() => script);
Copy link
Member Author

Choose a reason for hiding this comment

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

This previously had a bug, where the injectScript callback would be called later and at that point in time the AC core had actually written additional properties to event, which meant that unneccessary data was transported over the wire.
We now stringify the object immediately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant