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

Streaming SSR involving Suspense & streaming ReadableStream: chunks arrive before route info, erroring #3117

Closed
phryneas opened this issue Jan 7, 2025 · 0 comments · Fixed by #3158
Labels
start Everything about TanStack Start

Comments

@phryneas
Copy link
Contributor

phryneas commented Jan 7, 2025

Which project does this relate to?

Start

Describe the bug

This is a bug with Router/Start streaming SSR when

  • the route component suspends
  • the loader returns a ReadableStream
  • the stream has a fast first chunk

Under these circumstances, the generated HTML is out of order, containing these three <script tags in this order:

    <script class="tsr-once ">__TSR__.initMatch({ "index": 0, "__beforeLoadContext": "{}", "loaderData": "{\"$undefined\":0}", "extracted": {} })
        console.info(`Injected From Server:
__TSR__.initMatch({"index":0,"__beforeLoadContext":"{}","loaderData":"{\\"$undefined\\":0}","extracted":{}})`)
        if (typeof __TSR__ !== "undefined") __TSR__.cleanScripts()</script>
    <script
        class='tsr-once'>__TSR__.matches[1].extracted[1].value.controller.enqueue(new TextEncoder().encode("this is too soon!")); console.info(`Injected From Server:
__TSR__.matches[1].extracted[1].value.controller.enqueue(new TextEncoder().encode("this is too soon!"))`); if (typeof __TSR__ !== 'undefined') __TSR__.cleanScripts()</script>
    <div hidden id="S:0"><template id="P:1"></template>
        <script class="tsr-once ">__TSR__.initMatch({ "index": 1, "__beforeLoadContext": "{\"delayed\":{\"$undefined\":0},\"nested\":{\"$undefined\":0}}", "loaderData": "{\"delayed\":{\"status\":\"pending\"},\"nested\":{\"stream\":{}}}", "extracted": { "0": { "type": "promise", "path": ["delayed"] }, "1": { "type": "stream", "path": ["nested", "stream"] } } })
            console.info(`Injected From Server:
__TSR__.initMatch({"index":1,"__beforeLoadContext":"{\\"delayed\\":{\\"$undefined\\":0},\\"nested\\":{\\"$undefined\\":0}}","loaderData":"{\\"delayed\\":{\\"status\\":\\"pending\\"},\\"nested\\":{\\"stream\\":{}}}","extracted":{"0":{"type":"promise","path":["delayed"]},"1":{"type":"stream","path":["nested","stream"]}}})`)
            if (typeof __TSR__ !== "undefined") __TSR__.cleanScripts()</script>
        <div class="tsr-once"><!--$?--><template id="B:2"></template><!--/$--></div>
        <div class="tsr-once"><!--$?--><template id="B:3"></template><!--/$--></div>
    </div>

Note that the second script tag tries to access __TSR__.matches[1].extracted[1] - the problem here is that __TSR__.matches[1] will only be initialized as a result of the third script tag, so a Uncaught TypeError: __TSR__.matches[1] is undefined error is thrown.

Your Example Website or App

https://stackblitz.com/~/github.com/phryneas/reproduction-tanstack-router-chunk-stream-order-bug?file=app/routes/index.tsx

Steps to Reproduce the Bug or Issue

Open the console and see the bug.

Expected behavior

The chunk should arrive after the controller is initialized in the browser.

Screenshots or Videos

No response

Platform

  • OS: irrelevant
  • Browser: irrelevant
  • Version: 1.95.1

Additional context

No response

phryneas added a commit to apollographql/apollo-client-nextjs that referenced this issue Jan 7, 2025
@SeanCassiere SeanCassiere added the start Everything about TanStack Start label Jan 8, 2025
schiller-manuel added a commit that referenced this issue Jan 14, 2025
schiller-manuel added a commit that referenced this issue Jan 14, 2025
phryneas added a commit to apollographql/apollo-client-nextjs that referenced this issue Jan 23, 2025
* add `(TeeTo|ReadFrom)ReadableStreamLink` links

* add `skipDataTransport` function

* also export type `ReadableStreamLinkEvent`

* forgot file

* implement multipart streaming

* cleanup

* WIP

* handle re-consumption of readFromReadableStreamKey

* close on unsubscribe, catch errors

* tryClose, test adjustments

* adjust errorlink type

* streamline bundling

* fix jest integration test

* PreloadQuery: add `@defer` example

* add detail, suspense-transition-bug

* work around bug for now

* exports

* add exported types

* initialize basic react-router project

* clean up and `yarn react-router reveal`

* add raw experiment

* move eslint config into shared position

* Fix bundling configuration so parts of the `graphql` package don't end (#388)

* Release version 0.11.6@latest to npm

* Update peer deps for React 19 compatibility (#399)

* update devDependencies to React 19, adjust tests and examples (#400)

* Release version 0.11.7@latest to npm

* add example

* update react-router

* working

* patch PR in

* last adjustments

* fix up test for new deps

* clean up template fluff

* move `IncrementalSchemaLink` and others to `shared`

* use `@defer` in the example

* update turbo-stream patch

* update example to React 19

* adjust `prepublishOnly`

* add to pkg-pr-new-publish

* add empty unit test

* increase delay

* streamline integration test build

* needs more time in CI

* exclude shared

* copy react-router package to tanstack-start folder

* package init

* init tanstack start project

* current progress

* fix duplicate `@apollo/client` dependency

* make things work

* adjustments

* generalize apiRoute

* api, use schemalink on server

* update tanstack start

* add TSR devtools

* workaround for TanStack/router#3117

* trigger CI

* update patchfiles

* add new properties

* changeset

* trigger CI

* fix build warning

* port over vercel template from https://github.com/remix-run/react-router-templates/tree/main/vercel

* adjust folder structure

* more vercel adjustments

* use `promiscade` instead of a patched `turbo-stream` package

* update promiscade

* add promiscade-related comment

* lockfile

* workarounds for promiscade

* move `graphql` dependency into monorepo
to prevent type mismatches

* adjust comments

* these types are correct now

* update lockfile

* rename route

* add `useSuspenseQuery` demo, too

* fix import

* simplify client-side

* remove log

* remove unneccessary type assertion

* slight changes, README

* fix up important block

* fix typo, reorder

* fixup shape test

* add bundleInfo, adjust tests

* adjust tests

* adjust for old node

* add globalThis.window in test

* bump promiscade

* update tanstack start, remove workaround for fixed bug

* update package.json

* add TanStack/router#3161

* lockfile

* update correct react types

* eliminate context reliance

this makes it easier to use `yalc`

* sync updates from TanStack/router#2698

* lockfiles

* script

* fighting with duplicate dependencies

* unify react types version

* remove unused path

* more config file mentions

* TSR 6d6780b255c458e9776f15c134d93fab0aeafa80

* pass `request` to `makeClient` in entry.server.tsx

* delete file after merge

* lockfile

* Update packages/tanstack-start/README.md

Co-authored-by: Jerel Miller <[email protected]>

---------

Co-authored-by: phryneas <[email protected]>
Co-authored-by: Nick Muller <[email protected]>
Co-authored-by: Jerel Miller <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
start Everything about TanStack Start
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants