apollographql / apollographql/apollo-client-integrations

TanStack Start integration fails to hydrate in WebKit without ReadableStream async iteration

Open
#559 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
556
Forks
53
PR merge metrics
No merged PRs in 30d

Description

### Summary

`@apollo/client-integration-tanstack-start` crashes during hydration in Safari and other WebKit-based browsers that expose `ReadableStream` but not `ReadableStream.prototype[Symbol.asyncIterator]`.

`ClientTransport.consume` uses async iteration:

```ts
for await (const event of stream) {
// ...
}
```

Affected browsers throw:

```text
TypeError: undefined is not a function (near "...event of stream...")
```

The production stack resolves directly to this loop:

```text
ClientTransport.consume (dist/index.js:128:22)
new ClientTransport (dist/index.js:125:10)
transportSerializationAdapter.fromSerializable (dist/index.js:67:16)
hydrate
```

### Versions

- `@apollo/client-integration-tanstack-start`: `0.14.4-rc.0`
- `@apollo/client`: `4.1.6`
- `@tanstack/react-start`: `1.167.6`
- `@tanstack/react-router`: `1.168.3`

The published `0.14.5-rc.0` package and the current `main` branch contain the same loop.

### Reproduction

1. Configure TanStack Start with `routerWithApolloClient`.
2. Render an SSR route that serializes the Apollo transport.
3. Open the route in a browser without `ReadableStream` async iteration.

The missing capability can also be simulated in Playwright:

```ts
await page.addInitScript(() => {
Reflect.deleteProperty(
ReadableStream.prototype,
Symbol.asyncIterator,
);
});

await page.goto(ssrRoute);
```

Hydration fails when Apollo constructs `ClientTransport` and consumes the serialized stream.

### Observed behavior

We observed 176 production occurrences affecting 129 users. Every event came from a WebKit-based browser: Safari, Mobile Safari, Chrome on iOS, DuckDuckGo on iOS, or WKWebView.

The serialized hydration payload constructs the transported value with `new ReadableStream(...)`, which rules out a non-stream value reaching `ClientTransport`.

### Expected behavior

The integration hydrates streamed Apollo data in supported browsers, or documents the required `ReadableStream` async-iteration capability.

### Additional context

WebKit added `ReadableStream` async iteration in [WebKit/WebKit#54622](https://github.com/WebKit/WebKit/pull/54622), but released browsers without that capability remain in use.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at ClientTransport.consume, where the reported async iteration failure occurs, and reproduce it with the Playwright addInitScript that removes ReadableStream.prototype[Symbol.asyncIterator]. Trace hydration from the serialized ReadableStream into ClientTransport, then verify in the affected-browser scenario that streamed Apollo data hydrates without crashing.

Written by the indexing model from the issue text.

Assessment

Tech stack
playwright, typescript
Domain
frontend, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.