-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
fix: streaming #6175
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
fix: streaming #6175
Changes from all commits
bfd5811
e224b6a
5b62483
9c7d91b
a17a597
b17bf72
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| node_modules | ||
| package-lock.json | ||
| yarn.lock | ||
|
|
||
| .DS_Store | ||
| .cache | ||
| .env | ||
| .vercel | ||
| .output | ||
| /build/ | ||
| /api/ | ||
| /server/build | ||
| /public/build | ||
| .env.sentry-build-plugin | ||
| /test-results/ | ||
| /playwright-report/ | ||
| /blob-report/ | ||
| /playwright/.cache/ | ||
| /dist/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| { | ||
| "name": "tanstack-react-start-e2e-streaming-ssr", | ||
| "private": true, | ||
| "sideEffects": false, | ||
| "type": "module", | ||
| "scripts": { | ||
| "dev": "vite dev --port 3000", | ||
| "dev:e2e": "vite dev", | ||
| "build": "vite build && tsc --noEmit", | ||
| "start": "pnpx srvx --prod -s ../client dist/server/server.js", | ||
| "test:e2e": "rm -rf port*.txt; playwright test --project=chromium" | ||
| }, | ||
| "dependencies": { | ||
| "@tanstack/react-query": "^5.80.7", | ||
| "@tanstack/react-router": "workspace:^", | ||
| "@tanstack/react-router-ssr-query": "workspace:^", | ||
| "@tanstack/react-start": "workspace:^", | ||
| "react": "^19.0.0", | ||
| "react-dom": "^19.0.0", | ||
| "vite": "^7.1.7" | ||
| }, | ||
| "devDependencies": { | ||
| "@playwright/test": "^1.50.1", | ||
| "@tanstack/router-e2e-utils": "workspace:^", | ||
| "@types/node": "^22.10.2", | ||
| "@types/react": "^19.0.8", | ||
| "@types/react-dom": "^19.0.3", | ||
| "srvx": "^0.9.8", | ||
| "typescript": "^5.7.2" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import { defineConfig, devices } from '@playwright/test' | ||
| import { getTestServerPort } from '@tanstack/router-e2e-utils' | ||
| import packageJson from './package.json' with { type: 'json' } | ||
|
|
||
| const PORT = await getTestServerPort(packageJson.name) | ||
| const baseURL = `http://localhost:${PORT}` | ||
|
|
||
| /** | ||
| * See https://playwright.dev/docs/test-configuration. | ||
| */ | ||
| export default defineConfig({ | ||
| testDir: './tests', | ||
| workers: 1, | ||
|
|
||
| reporter: [['line']], | ||
|
|
||
| use: { | ||
| /* Base URL to use in actions like `await page.goto('/')`. */ | ||
| baseURL, | ||
| }, | ||
|
|
||
| webServer: { | ||
| command: `VITE_SERVER_PORT=${PORT} pnpm build && PORT=${PORT} VITE_SERVER_PORT=${PORT} pnpm start`, | ||
| url: baseURL, | ||
| reuseExistingServer: !process.env.CI, | ||
| stdout: 'pipe', | ||
| }, | ||
|
Comment on lines
+22
to
+27
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Check usage of PORT and VITE_SERVER_PORT in the streaming-ssr project
# Search for PORT usage (excluding this config file)
echo "=== PORT usage ==="
rg -n '\bPORT\b' e2e/react-start/streaming-ssr --type ts --type tsx -g '!playwright.config.ts' 2>/dev/null || echo "No PORT matches"
echo ""
echo "=== VITE_SERVER_PORT usage ==="
rg -n 'VITE_SERVER_PORT' e2e/react-start/streaming-ssr --type ts --type tsx -g '!playwright.config.ts' 2>/dev/null || echo "No VITE_SERVER_PORT matches"
# Also check for package.json scripts
echo ""
echo "=== Check package.json for scripts ==="
find e2e/react-start/streaming-ssr -name 'package.json' -exec head -50 {} \; 2>/dev/null | grep -A 10 '"scripts"' || echo "No package.json found"Repository: TanStack/router Length of output: 617 Remove the unnecessary VITE_SERVER_PORT environment variable. The 🤖 Prompt for AI Agents |
||
|
|
||
| projects: [ | ||
| { | ||
| name: 'chromium', | ||
| use: { ...devices['Desktop Chrome'] }, | ||
| }, | ||
| ], | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,261 @@ | ||
| /* eslint-disable */ | ||
|
|
||
| // @ts-nocheck | ||
|
|
||
| // noinspection JSUnusedGlobalSymbols | ||
|
|
||
| // This file was automatically generated by TanStack Router. | ||
| // You should NOT make any changes in this file as it will be overwritten. | ||
| // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. | ||
|
|
||
| import { Route as rootRouteImport } from './routes/__root' | ||
| import { Route as SyncOnlyRouteImport } from './routes/sync-only' | ||
| import { Route as StreamRouteImport } from './routes/stream' | ||
| import { Route as SlowRenderRouteImport } from './routes/slow-render' | ||
| import { Route as QueryHeavyRouteImport } from './routes/query-heavy' | ||
| import { Route as NestedDeferredRouteImport } from './routes/nested-deferred' | ||
| import { Route as ManyPromisesRouteImport } from './routes/many-promises' | ||
| import { Route as FastSerialRouteImport } from './routes/fast-serial' | ||
| import { Route as DeferredRouteImport } from './routes/deferred' | ||
| import { Route as ConcurrentRouteImport } from './routes/concurrent' | ||
| import { Route as IndexRouteImport } from './routes/index' | ||
|
|
||
| const SyncOnlyRoute = SyncOnlyRouteImport.update({ | ||
| id: '/sync-only', | ||
| path: '/sync-only', | ||
| getParentRoute: () => rootRouteImport, | ||
| } as any) | ||
| const StreamRoute = StreamRouteImport.update({ | ||
| id: '/stream', | ||
| path: '/stream', | ||
| getParentRoute: () => rootRouteImport, | ||
| } as any) | ||
| const SlowRenderRoute = SlowRenderRouteImport.update({ | ||
| id: '/slow-render', | ||
| path: '/slow-render', | ||
| getParentRoute: () => rootRouteImport, | ||
| } as any) | ||
| const QueryHeavyRoute = QueryHeavyRouteImport.update({ | ||
| id: '/query-heavy', | ||
| path: '/query-heavy', | ||
| getParentRoute: () => rootRouteImport, | ||
| } as any) | ||
| const NestedDeferredRoute = NestedDeferredRouteImport.update({ | ||
| id: '/nested-deferred', | ||
| path: '/nested-deferred', | ||
| getParentRoute: () => rootRouteImport, | ||
| } as any) | ||
| const ManyPromisesRoute = ManyPromisesRouteImport.update({ | ||
| id: '/many-promises', | ||
| path: '/many-promises', | ||
| getParentRoute: () => rootRouteImport, | ||
| } as any) | ||
| const FastSerialRoute = FastSerialRouteImport.update({ | ||
| id: '/fast-serial', | ||
| path: '/fast-serial', | ||
| getParentRoute: () => rootRouteImport, | ||
| } as any) | ||
| const DeferredRoute = DeferredRouteImport.update({ | ||
| id: '/deferred', | ||
| path: '/deferred', | ||
| getParentRoute: () => rootRouteImport, | ||
| } as any) | ||
| const ConcurrentRoute = ConcurrentRouteImport.update({ | ||
| id: '/concurrent', | ||
| path: '/concurrent', | ||
| getParentRoute: () => rootRouteImport, | ||
| } as any) | ||
| const IndexRoute = IndexRouteImport.update({ | ||
| id: '/', | ||
| path: '/', | ||
| getParentRoute: () => rootRouteImport, | ||
| } as any) | ||
|
|
||
| export interface FileRoutesByFullPath { | ||
| '/': typeof IndexRoute | ||
| '/concurrent': typeof ConcurrentRoute | ||
| '/deferred': typeof DeferredRoute | ||
| '/fast-serial': typeof FastSerialRoute | ||
| '/many-promises': typeof ManyPromisesRoute | ||
| '/nested-deferred': typeof NestedDeferredRoute | ||
| '/query-heavy': typeof QueryHeavyRoute | ||
| '/slow-render': typeof SlowRenderRoute | ||
| '/stream': typeof StreamRoute | ||
| '/sync-only': typeof SyncOnlyRoute | ||
| } | ||
| export interface FileRoutesByTo { | ||
| '/': typeof IndexRoute | ||
| '/concurrent': typeof ConcurrentRoute | ||
| '/deferred': typeof DeferredRoute | ||
| '/fast-serial': typeof FastSerialRoute | ||
| '/many-promises': typeof ManyPromisesRoute | ||
| '/nested-deferred': typeof NestedDeferredRoute | ||
| '/query-heavy': typeof QueryHeavyRoute | ||
| '/slow-render': typeof SlowRenderRoute | ||
| '/stream': typeof StreamRoute | ||
| '/sync-only': typeof SyncOnlyRoute | ||
| } | ||
| export interface FileRoutesById { | ||
| __root__: typeof rootRouteImport | ||
| '/': typeof IndexRoute | ||
| '/concurrent': typeof ConcurrentRoute | ||
| '/deferred': typeof DeferredRoute | ||
| '/fast-serial': typeof FastSerialRoute | ||
| '/many-promises': typeof ManyPromisesRoute | ||
| '/nested-deferred': typeof NestedDeferredRoute | ||
| '/query-heavy': typeof QueryHeavyRoute | ||
| '/slow-render': typeof SlowRenderRoute | ||
| '/stream': typeof StreamRoute | ||
| '/sync-only': typeof SyncOnlyRoute | ||
| } | ||
| export interface FileRouteTypes { | ||
| fileRoutesByFullPath: FileRoutesByFullPath | ||
| fullPaths: | ||
| | '/' | ||
| | '/concurrent' | ||
| | '/deferred' | ||
| | '/fast-serial' | ||
| | '/many-promises' | ||
| | '/nested-deferred' | ||
| | '/query-heavy' | ||
| | '/slow-render' | ||
| | '/stream' | ||
| | '/sync-only' | ||
| fileRoutesByTo: FileRoutesByTo | ||
| to: | ||
| | '/' | ||
| | '/concurrent' | ||
| | '/deferred' | ||
| | '/fast-serial' | ||
| | '/many-promises' | ||
| | '/nested-deferred' | ||
| | '/query-heavy' | ||
| | '/slow-render' | ||
| | '/stream' | ||
| | '/sync-only' | ||
| id: | ||
| | '__root__' | ||
| | '/' | ||
| | '/concurrent' | ||
| | '/deferred' | ||
| | '/fast-serial' | ||
| | '/many-promises' | ||
| | '/nested-deferred' | ||
| | '/query-heavy' | ||
| | '/slow-render' | ||
| | '/stream' | ||
| | '/sync-only' | ||
| fileRoutesById: FileRoutesById | ||
| } | ||
| export interface RootRouteChildren { | ||
| IndexRoute: typeof IndexRoute | ||
| ConcurrentRoute: typeof ConcurrentRoute | ||
| DeferredRoute: typeof DeferredRoute | ||
| FastSerialRoute: typeof FastSerialRoute | ||
| ManyPromisesRoute: typeof ManyPromisesRoute | ||
| NestedDeferredRoute: typeof NestedDeferredRoute | ||
| QueryHeavyRoute: typeof QueryHeavyRoute | ||
| SlowRenderRoute: typeof SlowRenderRoute | ||
| StreamRoute: typeof StreamRoute | ||
| SyncOnlyRoute: typeof SyncOnlyRoute | ||
| } | ||
|
|
||
| declare module '@tanstack/react-router' { | ||
| interface FileRoutesByPath { | ||
| '/sync-only': { | ||
| id: '/sync-only' | ||
| path: '/sync-only' | ||
| fullPath: '/sync-only' | ||
| preLoaderRoute: typeof SyncOnlyRouteImport | ||
| parentRoute: typeof rootRouteImport | ||
| } | ||
| '/stream': { | ||
| id: '/stream' | ||
| path: '/stream' | ||
| fullPath: '/stream' | ||
| preLoaderRoute: typeof StreamRouteImport | ||
| parentRoute: typeof rootRouteImport | ||
| } | ||
| '/slow-render': { | ||
| id: '/slow-render' | ||
| path: '/slow-render' | ||
| fullPath: '/slow-render' | ||
| preLoaderRoute: typeof SlowRenderRouteImport | ||
| parentRoute: typeof rootRouteImport | ||
| } | ||
| '/query-heavy': { | ||
| id: '/query-heavy' | ||
| path: '/query-heavy' | ||
| fullPath: '/query-heavy' | ||
| preLoaderRoute: typeof QueryHeavyRouteImport | ||
| parentRoute: typeof rootRouteImport | ||
| } | ||
| '/nested-deferred': { | ||
| id: '/nested-deferred' | ||
| path: '/nested-deferred' | ||
| fullPath: '/nested-deferred' | ||
| preLoaderRoute: typeof NestedDeferredRouteImport | ||
| parentRoute: typeof rootRouteImport | ||
| } | ||
| '/many-promises': { | ||
| id: '/many-promises' | ||
| path: '/many-promises' | ||
| fullPath: '/many-promises' | ||
| preLoaderRoute: typeof ManyPromisesRouteImport | ||
| parentRoute: typeof rootRouteImport | ||
| } | ||
| '/fast-serial': { | ||
| id: '/fast-serial' | ||
| path: '/fast-serial' | ||
| fullPath: '/fast-serial' | ||
| preLoaderRoute: typeof FastSerialRouteImport | ||
| parentRoute: typeof rootRouteImport | ||
| } | ||
| '/deferred': { | ||
| id: '/deferred' | ||
| path: '/deferred' | ||
| fullPath: '/deferred' | ||
| preLoaderRoute: typeof DeferredRouteImport | ||
| parentRoute: typeof rootRouteImport | ||
| } | ||
| '/concurrent': { | ||
| id: '/concurrent' | ||
| path: '/concurrent' | ||
| fullPath: '/concurrent' | ||
| preLoaderRoute: typeof ConcurrentRouteImport | ||
| parentRoute: typeof rootRouteImport | ||
| } | ||
| '/': { | ||
| id: '/' | ||
| path: '/' | ||
| fullPath: '/' | ||
| preLoaderRoute: typeof IndexRouteImport | ||
| parentRoute: typeof rootRouteImport | ||
| } | ||
| } | ||
| } | ||
|
|
||
| const rootRouteChildren: RootRouteChildren = { | ||
| IndexRoute: IndexRoute, | ||
| ConcurrentRoute: ConcurrentRoute, | ||
| DeferredRoute: DeferredRoute, | ||
| FastSerialRoute: FastSerialRoute, | ||
| ManyPromisesRoute: ManyPromisesRoute, | ||
| NestedDeferredRoute: NestedDeferredRoute, | ||
| QueryHeavyRoute: QueryHeavyRoute, | ||
| SlowRenderRoute: SlowRenderRoute, | ||
| StreamRoute: StreamRoute, | ||
| SyncOnlyRoute: SyncOnlyRoute, | ||
| } | ||
| export const routeTree = rootRouteImport | ||
| ._addFileChildren(rootRouteChildren) | ||
| ._addFileTypes<FileRouteTypes>() | ||
|
|
||
| import type { getRouter } from './router.tsx' | ||
| import type { createStart } from '@tanstack/react-start' | ||
| declare module '@tanstack/react-start' { | ||
| interface Register { | ||
| ssr: true | ||
| router: Awaited<ReturnType<typeof getRouter>> | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { QueryClient } from '@tanstack/react-query' | ||
| import { createRouter } from '@tanstack/react-router' | ||
| import { setupRouterSsrQueryIntegration } from '@tanstack/react-router-ssr-query' | ||
| import { routeTree } from './routeTree.gen' | ||
|
|
||
| export function getRouter() { | ||
| const queryClient = new QueryClient() | ||
| const router = createRouter({ | ||
| routeTree, | ||
| context: { queryClient }, | ||
| scrollRestoration: true, | ||
| }) | ||
| setupRouterSsrQueryIntegration({ | ||
| router, | ||
| queryClient, | ||
| }) | ||
| return router | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use
workspace:*protocol for internal dependencies per coding guidelines.The workspace dependencies are currently using
workspace:^, but the coding guidelines specify that internal dependencies should useworkspace:*.As per coding guidelines, the workspace protocol should be
workspace:*for all internal TanStack packages.🔎 Proposed fix
"devDependencies": { "@playwright/test": "^1.50.1", - "@tanstack/router-e2e-utils": "workspace:^", + "@tanstack/router-e2e-utils": "workspace:*", "@types/node": "^22.10.2",Also applies to: 24-24
🤖 Prompt for AI Agents