-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
test(vue-start, solid-start): raw sync tests #6234
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
Conversation
📝 WalkthroughWalkthroughAdds a RawStream e2e feature set: shared stream utilities and fixtures, many server-side stream handlers, a /raw-stream route subtree (index, client-call, SSR variants), UI pages that consume/verify streams, and comprehensive browser tests for multiplexing, hinting, and edge cases. Changes
Sequence Diagram(s)sequenceDiagram
participant Browser as Client
participant Router as RouteLoader
participant Factory as StreamFactory
participant Server as RawStreamWrapper
participant Consumer as StreamConsumer
participant UI
Browser->>Router: GET /raw-stream/ssr-single (navigation)
Router->>Factory: createDelayedStream(chunks, delayMs)
Factory-->>Server: ReadableStream<Uint8Array>
Router-->>Browser: loader payload { message, rawData: RawStream }
Browser->>Consumer: createStreamConsumer()
Browser->>Consumer: consume(rawData)
activate Consumer
loop read chunks
Consumer->>Server: getReader()/read()
Server-->>Consumer: Uint8Array chunk (delayed)
Consumer->>Consumer: concatBytes(...)
end
Consumer-->>Browser: bytes/string result
deactivate Consumer
Browser->>UI: setState(streamContent)
UI->>Browser: render content + JSON results
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
View your CI Pipeline Execution ↗ for commit fc217fe
☁️ Nx Cloud last updated this comment at |
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.
Actionable comments posted: 18
🧹 Nitpick comments (1)
e2e/vue-start/basic/src/raw-stream-fns.ts (1)
41-41: Consider: Move export after function definition for clarity.The export statement at line 41 references
concatByteswhich is defined later at line 78. While this works due to JavaScript hoisting for function declarations, it can be confusing. Consider moving the export statement after all exported items are defined, or definingconcatBytesbefore the export.Also applies to: 78-87
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
e2e/solid-start/basic/src/raw-stream-fns.tse2e/solid-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/routes/__root.tsxe2e/solid-start/basic/src/routes/raw-stream.tsxe2e/solid-start/basic/src/routes/raw-stream/client-call.tsxe2e/solid-start/basic/src/routes/raw-stream/index.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/solid-start/basic/tests/raw-stream.spec.tse2e/vue-start/basic/src/raw-stream-fns.tse2e/vue-start/basic/src/routeTree.gen.tse2e/vue-start/basic/src/routes/__root.tsxe2e/vue-start/basic/src/routes/raw-stream.tsxe2e/vue-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/index.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/tests/raw-stream.spec.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
e2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/index.tsxe2e/vue-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream.tsxe2e/solid-start/basic/src/routes/raw-stream/index.tsxe2e/solid-start/basic/src/routes/raw-stream.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/solid-start/basic/tests/raw-stream.spec.tse2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/tests/raw-stream.spec.tse2e/vue-start/basic/src/routes/__root.tsxe2e/vue-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/routes/__root.tsxe2e/solid-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/raw-stream-fns.tse2e/vue-start/basic/src/raw-stream-fns.tse2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
e2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/index.tsxe2e/vue-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream.tsxe2e/solid-start/basic/src/routes/raw-stream/index.tsxe2e/solid-start/basic/src/routes/raw-stream.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/solid-start/basic/tests/raw-stream.spec.tse2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/tests/raw-stream.spec.tse2e/vue-start/basic/src/routes/__root.tsxe2e/vue-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/routes/__root.tsxe2e/solid-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/raw-stream-fns.tse2e/vue-start/basic/src/raw-stream-fns.tse2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsx
🧠 Learnings (9)
📓 Common learnings
Learnt from: nlynzaad
Repo: TanStack/router PR: 6215
File: e2e/react-start/custom-basepath/package.json:13-17
Timestamp: 2025-12-25T13:04:55.492Z
Learning: In the TanStack Router repository, e2e test scripts are specifically designed to run in CI (which uses a Unix environment), so Unix-specific commands (like `rm -rf`, `&` for backgrounding, and direct environment variable assignments without `cross-env`) are acceptable in e2e test npm scripts.
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
e2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/index.tsxe2e/vue-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream.tsxe2e/solid-start/basic/src/routes/raw-stream/index.tsxe2e/solid-start/basic/src/routes/raw-stream.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/index.tsxe2e/vue-start/basic/src/routes/raw-stream.tsxe2e/solid-start/basic/src/routes/raw-stream/index.tsxe2e/solid-start/basic/src/routes/raw-stream.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/index.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/routeTree.gen.ts
📚 Learning: 2025-12-17T02:17:55.086Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream.tsxe2e/solid-start/basic/src/routes/raw-stream.tsxe2e/vue-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/routeTree.gen.ts
📚 Learning: 2025-12-21T12:52:35.231Z
Learnt from: Sheraff
Repo: TanStack/router PR: 6171
File: packages/router-core/src/new-process-route-tree.ts:898-898
Timestamp: 2025-12-21T12:52:35.231Z
Learning: In `packages/router-core/src/new-process-route-tree.ts`, the matching logic intentionally allows paths without trailing slashes to match index routes with trailing slashes (e.g., `/a` can match `/a/` route), but not vice-versa (e.g., `/a/` cannot match `/a` layout route). This is implemented via the condition `!pathIsIndex || node.kind === SEGMENT_TYPE_INDEX` and is a deliberate design decision to provide better UX by being permissive with missing trailing slashes.
Applied to files:
e2e/solid-start/basic/src/routes/raw-stream.tsxe2e/vue-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/routeTree.gen.ts
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
e2e/vue-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/routeTree.gen.ts
📚 Learning: 2025-09-28T21:41:45.233Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5284
File: e2e/react-start/basic/server.js:50-0
Timestamp: 2025-09-28T21:41:45.233Z
Learning: In Express v5, catch-all routes must use named wildcards. Use `/*splat` to match everything except root path, or `/{*splat}` (with braces) to match including root path. The old `*` syntax is not allowed and will cause "Missing parameter name" errors. This breaking change requires explicit naming of wildcard parameters.
Applied to files:
e2e/vue-start/basic/src/routeTree.gen.tse2e/solid-start/basic/src/routeTree.gen.ts
🧬 Code graph analysis (14)
e2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsx (1)
e2e/solid-start/basic/src/raw-stream-fns.ts (2)
collectBytes(418-444)compareBytes(447-480)
e2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx (2)
e2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
Route(10-23)e2e/solid-start/basic/src/raw-stream-fns.ts (3)
createDelayedStream(41-41)encode(41-41)createStreamConsumer(371-394)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (4)
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
Route(22-46)e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx (1)
Route(10-27)e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
Route(10-23)e2e/vue-start/basic/src/raw-stream-fns.ts (3)
createDelayedStream(41-41)encode(41-41)createStreamConsumer(371-394)
e2e/vue-start/basic/src/routes/raw-stream/index.tsx (5)
e2e/vue-start/basic/src/routes/raw-stream/client-call.tsx (1)
Route(37-39)e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
Route(22-46)e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (1)
Route(10-29)e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx (1)
Route(10-27)e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
Route(10-23)
e2e/solid-start/basic/src/routes/raw-stream/index.tsx (6)
e2e/solid-start/basic/src/routes/raw-stream/client-call.tsx (1)
Route(37-39)e2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
Route(22-46)e2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx (1)
Route(10-29)e2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsx (1)
Route(10-27)e2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
Route(10-23)e2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsx (1)
Route(34-69)
e2e/solid-start/basic/src/routes/raw-stream.tsx (6)
e2e/solid-start/basic/src/routes/raw-stream/client-call.tsx (1)
Route(37-39)e2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
Route(22-46)e2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx (1)
Route(10-29)e2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsx (1)
Route(10-27)e2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
Route(10-23)e2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsx (1)
Route(34-69)
e2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsx (2)
e2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
Route(22-46)e2e/solid-start/basic/src/raw-stream-fns.ts (3)
createDelayedStream(41-41)encode(41-41)createStreamConsumer(371-394)
e2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
e2e/solid-start/basic/src/raw-stream-fns.ts (2)
collectBytes(418-444)compareBytes(447-480)
e2e/solid-start/basic/src/routes/raw-stream/client-call.tsx (4)
e2e/solid-start/basic/src/routes/__root.tsx (1)
Route(16-66)e2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
Route(10-23)e2e/solid-start/basic/src/raw-stream-fns.ts (30)
createStreamConsumer(371-394)singleRawStreamFn(90-99)multipleRawStreamsFn(102-116)jsonEndsFirstFn(119-130)rawEndsFirstFn(133-147)largeBinaryFn(150-164)consumeBinaryStream(396-415)mixedStreamingFn(167-180)textHintPureTextFn(183-189)collectBytes(418-444)TEST7_EXPECTED(50-50)textHintPureBinaryFn(192-198)TEST8_EXPECTED(57-57)textHintMixedFn(201-207)TEST9_EXPECTED(65-65)binaryHintTextFn(210-216)TEST10_EXPECTED(69-69)binaryHintBinaryFn(219-225)TEST11_EXPECTED(75-75)interleavedStreamsFn(296-305)TEST12_STREAM_A_EXPECTED(245-247)TEST12_STREAM_B_EXPECTED(248-250)burstPauseBurstFn(308-315)TEST13_EXPECTED(262-264)threeStreamsFn(318-329)TEST14_STREAM_A_EXPECTED(285-287)TEST14_STREAM_B_EXPECTED(288-290)TEST14_STREAM_C_EXPECTED(291-293)emptyStreamFn(336-348)errorStreamFn(351-365)e2e/vue-start/basic/src/raw-stream-fns.ts (30)
createStreamConsumer(371-394)singleRawStreamFn(90-99)multipleRawStreamsFn(102-116)jsonEndsFirstFn(119-130)rawEndsFirstFn(133-147)largeBinaryFn(150-164)consumeBinaryStream(396-415)mixedStreamingFn(167-180)textHintPureTextFn(183-189)collectBytes(418-444)TEST7_EXPECTED(50-50)textHintPureBinaryFn(192-198)TEST8_EXPECTED(57-57)textHintMixedFn(201-207)TEST9_EXPECTED(65-65)binaryHintTextFn(210-216)TEST10_EXPECTED(69-69)binaryHintBinaryFn(219-225)TEST11_EXPECTED(75-75)interleavedStreamsFn(296-305)TEST12_STREAM_A_EXPECTED(245-247)TEST12_STREAM_B_EXPECTED(248-250)burstPauseBurstFn(308-315)TEST13_EXPECTED(262-264)threeStreamsFn(318-329)TEST14_STREAM_A_EXPECTED(285-287)TEST14_STREAM_B_EXPECTED(288-290)TEST14_STREAM_C_EXPECTED(291-293)emptyStreamFn(336-348)errorStreamFn(351-365)
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (3)
e2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
Route(10-23)e2e/vue-start/basic/src/raw-stream-fns.ts (3)
createDelayedStream(41-41)encode(41-41)createStreamConsumer(371-394)e2e/react-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
SSRSingleTest(25-75)
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
e2e/vue-start/basic/src/raw-stream-fns.ts (2)
collectBytes(418-444)compareBytes(447-480)
e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx (1)
e2e/vue-start/basic/src/raw-stream-fns.ts (2)
collectBytes(418-444)compareBytes(447-480)
e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx (2)
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
Route(10-23)e2e/vue-start/basic/src/raw-stream-fns.ts (3)
createDelayedStream(41-41)encode(41-41)createStreamConsumer(371-394)
e2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsx (2)
e2e/solid-start/basic/src/raw-stream-fns.ts (3)
createDelayedStream(41-41)encode(41-41)createStreamConsumer(371-394)packages/router-core/src/ssr/tsrScript.ts (1)
p(16-18)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test
- GitHub Check: Preview
🔇 Additional comments (14)
e2e/vue-start/basic/src/routes/__root.tsx (1)
142-149: LGTM!The new "Raw Stream" navigation link follows the same pattern as existing links with consistent styling (
activePropswithfont-bold). The route path/raw-streamaligns with the new route tree additions.e2e/solid-start/basic/src/routes/__root.tsx (1)
142-149: LGTM!The navigation link to
/raw-streamis correctly added following the existing pattern. Uses proper Solid.js JSX syntax withclassattribute.e2e/solid-start/basic/src/routes/raw-stream/index.tsx (1)
1-71: LGTM!This index route is correctly implemented for Solid.js - no React imports, proper use of
@tanstack/solid-router, and appropriate JSX syntax. ThereloadDocument={true}on SSR links ensures full page reloads for proper SSR testing.e2e/vue-start/basic/src/routes/raw-stream/index.tsx (1)
1-71: LGTM!The Vue index route is correctly implemented with proper
@tanstack/vue-routerimports and appropriate JSX syntax. Structure mirrors the Solid version as intended by the PR objectives.e2e/vue-start/basic/src/routes/raw-stream.tsx (1)
1-70: LGTM!The layout route is well-structured with proper navigation to all child routes. The use of
reloadDocument={true}for SSR routes ensures full server-side rendering during tests, and theactivePropsprovide visual feedback for the current route.e2e/solid-start/basic/src/routes/raw-stream.tsx (1)
1-70: LGTM!The Solid layout route correctly mirrors the Vue version with appropriate imports from
@tanstack/solid-router. The structure is consistent across frameworks, which aids maintainability.e2e/solid-start/basic/tests/raw-stream.spec.ts (3)
1-17: Well-structured test suite with comprehensive coverage.The test file is well-organized with clear test blocks covering Client RPC, SSR Loader, Hint Parameters, Multiplexing, Cross Navigation, and Edge Cases. The documentation comment (lines 5-12) clearly explains the RawStream functionality being tested.
186-208: Good handling of prerender limitation.The conditional skip for prerender mode with a clear explanation of the limitation is a good practice. This prevents flaky tests while documenting the known behavior.
;(isPrerender ? test.skip : test)( 'SSR mixed streaming - RawStream with deferred data', // ... )
622-666: Edge case coverage is thorough.Testing empty streams and error propagation are important edge cases. The assertions verify both the error state and the error message content.
e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx (1)
12-32: Good practice: Module-level expected data for client-side verification.Defining the expected byte sequences at module level ensures consistency between what the loader produces and what the client verifies. This pattern is clean and maintainable.
e2e/vue-start/basic/src/routeTree.gen.ts (1)
1-9: Skipping review of autogenerated file.This is an autogenerated route tree file that should not be manually modified. Based on learnings from the repository.
e2e/solid-start/basic/src/routeTree.gen.ts (1)
1-9: Skipping review of autogenerated file.This is an autogenerated route tree file that should not be manually modified. Based on learnings from the repository.
e2e/vue-start/basic/src/raw-stream-fns.ts (1)
371-394: Good implementation of stream consumer with dual-type support.The
createStreamConsumerfunction correctly handles bothRawStream(from type system) andReadableStream(at runtime) with appropriate type checking. The factory pattern provides a clean interface for stream consumption.e2e/solid-start/basic/src/raw-stream-fns.ts (1)
1-41: LGTM with same optional suggestion as Vue version.This file correctly imports from
@tanstack/solid-startand provides comprehensive test utilities. The same optional refactor suggestion about export ordering applies here as noted for the Vue version.
e2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx
Outdated
Show resolved
Hide resolved
| // Wait time for hydration to complete after page load | ||
| // This needs to be long enough for React hydration to attach event handlers | ||
| const HYDRATION_WAIT = 1000 |
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.
Minor: Comment mentions React hydration in Vue test file.
The comment refers to "React hydration" but this is a Vue test file. Consider updating to "Vue hydration" for accuracy.
// Wait time for hydration to complete after page load
-// This needs to be long enough for React hydration to attach event handlers
+// This needs to be long enough for Vue hydration to attach event handlers
const HYDRATION_WAIT = 1000🤖 Prompt for AI Agents
In e2e/vue-start/basic/tests/raw-stream.spec.ts around lines 14 to 16, the
inline comment incorrectly references "React hydration" in a Vue test file;
update the comment to say "Vue hydration" (or a neutral term like "framework
hydration") so it accurately describes that the wait time is for Vue's hydration
to attach event handlers.
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.
Actionable comments posted: 1
🧹 Nitpick comments (5)
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
83-96: Add explicit return type for improved type safety.The loader function lacks an explicit return type annotation. Per the coding guidelines requiring "extensive type safety for all code," adding an explicit type improves code clarity and compiler diagnostics.
🔎 Proposed type annotation
export const Route = createFileRoute('/raw-stream/ssr-single')({ - loader: async () => { + loader: async (): Promise<{ + message: string + timestamp: number + rawData: RawStream + }> => { const stream = createDelayedStream( [encode('ssr-chunk1'), encode('ssr-chunk2'), encode('ssr-chunk3')], 50, ) return { message: 'SSR Single Stream Test', timestamp: Date.now(), rawData: new RawStream(stream), } }, component: SSRSingleTest, })As per coding guidelines, extensive type safety is required for all TypeScript code.
e2e/vue-start/basic/src/routes/raw-stream/client-call.tsx (1)
49-61: Consider using reactive object updates instead of spread for state.The current pattern creates new objects on each state update. While functional, Vue's reactivity works more efficiently with direct property assignment on reactive objects.
🔎 Alternative using reactive
-const results = ref<Record<string, any>>({}) -const loading = ref<Record<string, boolean>>({}) +import { reactive } from 'vue' +const results = reactive<Record<string, any>>({}) +const loading = reactive<Record<string, boolean>>({}) // Then use direct assignment: -loading.value = { ...loading.value, [testName]: true } +loading[testName] = truee2e/solid-start/basic/src/raw-stream-fns.ts (1)
40-41: Export statement referencesconcatBytesbefore its definition.The export at line 41 references
concatByteswhich is defined at line 78. While JavaScript function hoisting makes this work at runtime, placing exports after definitions improves readability and aligns with common conventions.🔎 Move export after definitions
-// Export helpers for use in components and SSR routes -export { encode, createDelayedStream, concatBytes } - // Expected data for hint tests... // ... (test data definitions) // Helper to concatenate byte arrays function concatBytes(chunks: Array<Uint8Array>): Uint8Array { // ... } + +// Export helpers for use in components and SSR routes +export { encode, createDelayedStream, concatBytes }e2e/solid-start/basic/src/routes/raw-stream/client-call.tsx (1)
41-41: Consider memoizing the stream consumer.The
consumeStreamhelper is recreated on every component render. While this is likely not a performance issue for test code, you could use Solid'screateMemoor move it outside the component for consistency.🔎 Optional refactor to memoize consumeStream
+import { createFileRoute } from '@tanstack/solid-router' +import { createSignal, createMemo } from 'solid-js' -import { createSignal } from 'solid-js' function ClientCallTests() { const [results, setResults] = createSignal<Record<string, any>>({}) const [loading, setLoading] = createSignal<Record<string, boolean>>({}) - const consumeStream = createStreamConsumer() + const consumeStream = createMemo(() => createStreamConsumer())Then update usages to call
consumeStream()():- streamContent: await consumeStream(result.data), + streamContent: await consumeStream()(result.data),Alternatively, move
createStreamConsumer()outside the component entirely if the decoder doesn't need to be scoped per component instance.e2e/vue-start/basic/src/raw-stream-fns.ts (1)
36-41: Refactor: Export after definition for better readability.Line 41 exports
concatBytesbefore it's defined at line 78. While this works due to function hoisting, it makes the code harder to follow and maintain. Consider moving the export statement after theconcatBytesfunction definition.🔎 Proposed fix to improve code organization
Move the export statement to after the
concatBytesdefinition:// Helper to encode text to Uint8Array function encode(text: string): Uint8Array { return new TextEncoder().encode(text) } -// Export helpers for use in components and SSR routes -export { encode, createDelayedStream, concatBytes } - // Expected data for hint tests - defined here for both server and client verification // Test 7: Text hint with pure text export const TEST7_CHUNKS = [ encode('Hello, '), encode('World! '), encode('This is text.'), ] export const TEST7_EXPECTED = concatBytes(TEST7_CHUNKS) // ... (other test constants) // Helper to concatenate byte arrays function concatBytes(chunks: Array<Uint8Array>): Uint8Array { const totalLength = chunks.reduce((acc, c) => acc + c.length, 0) const result = new Uint8Array(totalLength) let offset = 0 for (const chunk of chunks) { result.set(chunk, offset) offset += chunk.length } return result } + +// Export helpers for use in components and SSR routes +export { encode, createDelayedStream, concatBytes }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
e2e/solid-start/basic/src/raw-stream-fns.tse2e/solid-start/basic/src/routes/raw-stream/client-call.tsxe2e/solid-start/basic/src/routes/raw-stream/index.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/src/raw-stream-fns.tse2e/vue-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/index.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx
🚧 Files skipped from review as they are similar to previous changes (5)
- e2e/solid-start/basic/src/routes/raw-stream/ssr-single.tsx
- e2e/solid-start/basic/src/routes/raw-stream/index.tsx
- e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx
- e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx
- e2e/vue-start/basic/src/routes/raw-stream/index.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/solid-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/raw-stream-fns.tse2e/solid-start/basic/src/raw-stream-fns.tse2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/solid-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/raw-stream-fns.tse2e/solid-start/basic/src/raw-stream-fns.tse2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx
🧠 Learnings (4)
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/solid-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/client-call.tsx
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/solid-start/basic/src/routes/raw-stream/client-call.tsxe2e/vue-start/basic/src/routes/raw-stream/client-call.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Separate framework-agnostic core logic from React/Solid bindings
Applied to files:
e2e/solid-start/basic/src/routes/raw-stream/client-call.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx
🧬 Code graph analysis (7)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (1)
e2e/vue-start/basic/src/raw-stream-fns.ts (1)
createStreamConsumer(371-394)
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
e2e/vue-start/basic/src/raw-stream-fns.ts (1)
createStreamConsumer(371-394)
e2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsx (1)
e2e/solid-start/basic/src/raw-stream-fns.ts (2)
collectBytes(418-444)compareBytes(447-480)
e2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
e2e/solid-start/basic/src/raw-stream-fns.ts (5)
encode(41-41)concatBytes(41-41)collectBytes(418-444)compareBytes(447-480)createDelayedStream(41-41)
e2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsx (2)
e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx (1)
Route(84-101)e2e/solid-start/basic/src/raw-stream-fns.ts (3)
createStreamConsumer(371-394)createDelayedStream(41-41)encode(41-41)
e2e/solid-start/basic/src/raw-stream-fns.ts (1)
e2e/vue-start/basic/src/raw-stream-fns.ts (13)
createDelayedStream(41-41)encode(41-41)TEST7_CHUNKS(45-49)TEST7_EXPECTED(50-50)concatBytes(41-41)TEST8_CHUNKS(53-56)TEST8_EXPECTED(57-57)TEST9_CHUNKS(60-64)TEST9_EXPECTED(65-65)TEST10_CHUNKS(68-68)TEST10_EXPECTED(69-69)TEST11_CHUNKS(72-74)TEST11_EXPECTED(75-75)
e2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx (1)
e2e/solid-start/basic/src/raw-stream-fns.ts (3)
createStreamConsumer(371-394)createDelayedStream(41-41)encode(41-41)
🪛 Biome (2.1.2)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx
[error] 58-58: Avoid passing children using a prop
The canonical way to pass children in React is to use JSX elements
(lint/correctness/noChildrenProp)
e2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx
[error] 52-52: Avoid passing children using a prop
The canonical way to pass children in React is to use JSX elements
(lint/correctness/noChildrenProp)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (24)
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (2)
1-8: LGTM!Imports are correct for Vue implementation. The previous issue with React imports has been properly resolved.
39-79: LGTM!The render function properly handles loading, error, and success states with appropriate test identifiers for e2e testing.
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (2)
1-8: LGTM - Vue Composition API correctly applied.The imports and component structure now properly use Vue's
defineComponent,ref,watch, andSuspense. The previous React-related issues have been resolved.
53-63: Thechildrenprop pattern is the correct API for@tanstack/vue-router'sAwaitcomponent. The component explicitly defineschildrenas a requiredFunctionprop, and all usages throughout the codebase follow this exact pattern. Biome's flag is a false positive. No changes needed.e2e/vue-start/basic/src/routes/raw-stream/client-call.tsx (1)
1-35: LGTM - Correct Vue implementation with comprehensive test coverage.The component properly uses Vue's
defineComponentandreffor reactive state management. All 16 test cases are well-structured with consistent patterns for execution, loading states, and result display.e2e/solid-start/basic/src/raw-stream-fns.ts (2)
89-99: LGTM - Well-structured server function implementations.The server functions are correctly implemented using
createServerFn().handler()pattern with proper RawStream wrapping. Good coverage of streaming scenarios including single/multiple streams, timing variations, and hint configurations.
371-393: LGTM - Stream consumer with proper type handling.The
createStreamConsumerfunction correctly handles bothRawStreamandReadableStream<Uint8Array>types, with appropriate runtime type checking viainstanceof. The eslint-disable for the while loop is appropriate.e2e/solid-start/basic/src/routes/raw-stream/ssr-text-hint.tsx (2)
1-10: LGTM - Correct Solid.js implementation.The file properly uses Solid's
createSignalandcreateEffectprimitives. The previous React-related issues have been resolved.
58-100: LGTM - Well-structured async effect with proper error handling.The
createEffectcorrectly:
- Tracks reactive dependencies via
loaderData()access- Uses
Promise.allfor concurrent stream processing- Properly handles errors with catch block
- Updates loading state appropriately
e2e/solid-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (2)
1-10: LGTM - Correct Solid.js implementation with proper primitives.Imports and component structure correctly use Solid's
createSignalandcreateEffect. The component follows the same well-established pattern as other SSR hint test routes.
117-141: LGTM - Loader correctly configures binary hint.The loader properly creates two
RawStreaminstances with{ hint: 'binary' }configuration, testing both text data and pure binary data with the binary hint setting.e2e/solid-start/basic/src/routes/raw-stream/ssr-multiple.tsx (2)
1-8: LGTM - Correct Solid.js implementation.The imports and component structure properly use Solid's
createSignalandcreateEffectprimitives. The dual-stream consumption pattern is well-implemented.
80-97: LGTM - Consistent with Vue implementation.The loader structure matches the Vue counterpart (
e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx), ensuring cross-framework test parity with identical stream configurations (multi-1a/1b, multi-2a/2b with 30ms/50ms delays).e2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx (3)
1-8: LGTM - Correct Solid.js implementation.The imports properly use Solid's primitives (
Suspense,createEffect,createSignal) along with TanStack'sAwaitcomponent.
77-96: LGTM - Mixed streaming loader correctly configured.The loader properly demonstrates the mixed streaming scenario with:
- Immediate synchronous value
- Deferred Promise (100ms delay)
- RawStream with delayed chunks (50ms intervals)
This matches the Vue implementation for cross-framework test consistency.
49-54: Thechildrenprop pattern is correct per the Await component's type definition. The component explicitly expectschildrenas a function prop, as shown in the type signature:children: (result: T) => SolidNode. While the JSX children syntax (<Await>{(data) => ...}</Await>) is more idiomatic in Solid and would be functionally equivalent, the current prop-based approach is valid and follows the documented API.e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx (3)
1-10: LGTM - Correct Vue Composition API implementation.The file properly uses Vue's
defineComponent,ref, andwatchprimitives with the{ immediate: true }option for initial execution.
58-107: LGTM - Watch handler with proper async processing.The watch correctly:
- Tracks all three loader data properties as dependencies
- Uses
Promise.allfor concurrent byte collection- Compares collected bytes against expected values
- Handles errors appropriately
The
{ immediate: true }option ensures the handler runs on initial mount.
170-205: LGTM - Loader matches Solid counterpart.The loader configuration is identical to the Solid version, ensuring cross-framework test parity for the text-hint streaming scenario.
e2e/solid-start/basic/src/routes/raw-stream/client-call.tsx (2)
37-61: LGTM! Well-structured test harness.The component correctly uses Solid primitives (
createSignal) and implements a clean, reusable test runner pattern. The error handling and state management are appropriate for this e2e test scenario.
63-484: Excellent test coverage with consistent patterns.All 16 tests follow a consistent structure with proper test IDs, loading states, error handling, and result displays. The test suite comprehensively covers single/multiple streams, ordering scenarios, large binary data, hints, multiplexing, and edge cases.
e2e/vue-start/basic/src/raw-stream-fns.ts (3)
90-365: Well-structured server function implementations.All 16 server functions follow consistent patterns and are well-documented with clear test scenarios. The implementations properly use
createServerFn().handler()and correctly instantiateRawStreamobjects with appropriate options (hints, delays, etc.).
371-444: Excellent stream consumer utilities with proper type handling.The helper functions correctly handle the dual nature of
RawStream(type system marker) vsReadableStream<Uint8Array>(runtime type after SSR deserialization). The ESLint disable comments on lines 385, 407, and 429 are appropriate for thewhile (true)loops, which have explicit break conditions.
446-480: Robust byte comparison utility.The
compareBytesfunction provides detailed mismatch information (index, lengths) which is valuable for debugging test failures. The implementation correctly handles both length mismatches and byte-level differences.
| watch( | ||
| () => loaderData.value.rawData, | ||
| (rawData) => { | ||
| if (!rawData) { | ||
| return | ||
| } | ||
| const consumeStream = createStreamConsumer() | ||
| isConsuming.value = true | ||
| error.value = null | ||
| consumeStream(rawData) | ||
| .then((content) => { | ||
| streamContent.value = content | ||
| isConsuming.value = false | ||
| }) | ||
| .catch((err) => { | ||
| error.value = String(err) | ||
| isConsuming.value = false | ||
| }) | ||
| }, | ||
| { immediate: true }, | ||
| ) |
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.
Add cleanup to prevent resource leaks and race conditions.
The watch callback starts async stream consumption but provides no mechanism to cancel it when the component unmounts or when rawData changes before the previous consumption completes. This causes:
- Resource leaks (ReadableStream reader remains active)
- Race conditions (multiple concurrent consumptions updating state)
🔎 Proposed fix with cleanup logic
+import { defineComponent, ref, watch, onUnmounted } from 'vue'
const SSRSingleTest = defineComponent({
setup() {
const loaderData = Route.useLoaderData()
const streamContent = ref('')
const isConsuming = ref(true)
const error = ref<string | null>(null)
+ let abortController: AbortController | null = null
- watch(
+ const stopWatch = watch(
() => loaderData.value.rawData,
(rawData) => {
+ // Cancel previous stream consumption if still ongoing
+ if (abortController) {
+ abortController.abort()
+ }
+
if (!rawData) {
return
}
+ abortController = new AbortController()
+ const signal = abortController.signal
+
const consumeStream = createStreamConsumer()
isConsuming.value = true
error.value = null
consumeStream(rawData)
.then((content) => {
+ if (!signal.aborted) {
streamContent.value = content
isConsuming.value = false
+ }
})
.catch((err) => {
+ if (!signal.aborted) {
error.value = String(err)
isConsuming.value = false
+ }
})
},
{ immediate: true },
)
+
+ onUnmounted(() => {
+ stopWatch()
+ if (abortController) {
+ abortController.abort()
+ }
+ })
return () => (Note: You may also need to update createStreamConsumer in raw-stream-fns.ts to accept an AbortSignal and cancel the reader when the signal is aborted.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| watch( | |
| () => loaderData.value.rawData, | |
| (rawData) => { | |
| if (!rawData) { | |
| return | |
| } | |
| const consumeStream = createStreamConsumer() | |
| isConsuming.value = true | |
| error.value = null | |
| consumeStream(rawData) | |
| .then((content) => { | |
| streamContent.value = content | |
| isConsuming.value = false | |
| }) | |
| .catch((err) => { | |
| error.value = String(err) | |
| isConsuming.value = false | |
| }) | |
| }, | |
| { immediate: true }, | |
| ) | |
| let abortController: AbortController | null = null | |
| const stopWatch = watch( | |
| () => loaderData.value.rawData, | |
| (rawData) => { | |
| // Cancel previous stream consumption if still ongoing | |
| if (abortController) { | |
| abortController.abort() | |
| } | |
| if (!rawData) { | |
| return | |
| } | |
| abortController = new AbortController() | |
| const signal = abortController.signal | |
| const consumeStream = createStreamConsumer() | |
| isConsuming.value = true | |
| error.value = null | |
| consumeStream(rawData) | |
| .then((content) => { | |
| if (!signal.aborted) { | |
| streamContent.value = content | |
| isConsuming.value = false | |
| } | |
| }) | |
| .catch((err) => { | |
| if (!signal.aborted) { | |
| error.value = String(err) | |
| isConsuming.value = false | |
| } | |
| }) | |
| }, | |
| { immediate: true }, | |
| ) | |
| onUnmounted(() => { | |
| stopWatch() | |
| if (abortController) { | |
| abortController.abort() | |
| } | |
| }) |
🤖 Prompt for AI Agents
In e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx around lines 17 to
37, the watch callback starts async stream consumption but never cancels it,
causing leaked readers and race conditions; fix by creating an AbortController
for each consumption, pass its signal into createStreamConsumer (update
raw-stream-fns.ts to accept an AbortSignal and cancel the reader when aborted),
store the controller for the active consumption and call controller.abort()
before starting a new one, and register a stop/unmounted cleanup to abort any
in-flight consumption so readers are always released and state updates from
stale consumptions are prevented.
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.
Actionable comments posted: 3
🧹 Nitpick comments (4)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (1)
22-24: Remove redundant state assignment.Line 23 sets
isConsuming.value = true, but it's already initialized totrueon line 14. This assignment is unnecessary.🔎 Proposed fix
const consumeStream = createStreamConsumer() - isConsuming.value = true error.value = nulle2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (2)
51-51: Remove redundant state initialization.
isLoadingis already initialized totrueon line 42, so setting it again here is unnecessary.🔎 Proposed fix
- isLoading.value = true error.value = null
57-61: Remove redundant field assignments.
compareBytesalready returnsactualLengthandexpectedLength, so overwriting these fields with the same values is redundant.🔎 Proposed fix
const textComp = compareBytes(textBytes, TEXT_EXPECTED) const decoder = new TextDecoder() textMatch.value = { ...textComp, - actualLength: textBytes.length, - expectedLength: TEXT_EXPECTED.length, asText: decoder.decode(textBytes), }Apply the same pattern for binary match (lines 63-68):
const binaryComp = compareBytes(binaryBytes, BINARY_EXPECTED) - binaryMatch.value = { - ...binaryComp, - actualLength: binaryBytes.length, - expectedLength: BINARY_EXPECTED.length, - } + binaryMatch.value = binaryCompe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx (1)
25-26: Consider removing redundant state initialization.These assignments reset
isConsuminganderrorto their initial values (already set on lines 15-16). While harmless, removing them would reduce redundancy.🔎 Suggested refactor
const consumeStream = createStreamConsumer() - isConsuming.value = true - error.value = null Promise.all([consumeStream(first), consumeStream(second)])
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx
- e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx
🧠 Learnings (3)
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx
🧬 Code graph analysis (2)
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
e2e/vue-start/basic/src/raw-stream-fns.ts (5)
encode(41-41)concatBytes(41-41)collectBytes(418-444)compareBytes(447-480)createDelayedStream(41-41)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (1)
e2e/vue-start/basic/src/raw-stream-fns.ts (1)
createStreamConsumer(371-394)
🪛 Biome (2.1.2)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx
[error] 55-55: Avoid passing children using a prop
The canonical way to pass children in React is to use JSX elements
(lint/correctness/noChildrenProp)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Preview
- GitHub Check: Test
🔇 Additional comments (9)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (3)
1-8: LGTM! Imports are correct for Vue.The imports properly use Vue-specific APIs (Composition API hooks, Suspense, defineComponent) and TanStack Vue Router/Start libraries. The previous React import issue has been successfully resolved.
50-60: Static analysis false positive: Biome applies React rules to Vue code.Biome's warning about the
childrenprop on line 55 is a false positive. Biome is applying React-specific linting rules (lint/correctness/noChildrenProp) to Vue code. The Suspense slot object syntax{{ default: ..., fallback: ... }}is the correct Vue JSX pattern, and thechildrenprop usage depends on the Await component's API from@tanstack/vue-router.Since this code mirrors React tests (per PR objectives) and uses framework-specific imports correctly, the pattern is intentional.
84-103: LGTM! Route configuration is correct.The loader properly implements the "mixed" streaming pattern by returning:
- Immediate data available synchronously
- Deferred promise resolving after 100ms
- RawStream with delayed chunks for client-side consumption
The component wiring and route export follow Vue Router conventions correctly.
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (3)
1-10: LGTM! Vue Composition API imports are now correct.The previous critical issue (React hooks in Vue component) has been successfully resolved. All imports now correctly use Vue's Composition API.
77-125: LGTM! Render function correctly uses Vue refs.All reactive state is properly accessed with
.valuesyntax, and the conditional rendering logic is sound.
128-152: LGTM! Route definition follows TanStack Router best practices.The loader correctly creates RawStream instances with binary hints for testing, and the component is properly wired.
e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx (3)
1-8: LGTM! Imports correctly use Vue Composition API.The imports are now properly aligned with Vue 3 Composition API (
defineComponent,onMounted,ref) and the framework-specific router/start packages. The previous React import issue has been addressed.
39-78: LGTM! Render logic correctly implements Vue JSX patterns.The render function properly accesses reactive values with
.value, implements clear loading/error/success states, and includes test-friendly attributes for e2e verification.
82-99: LGTM! Loader correctly creates and wraps multiple streams.The loader creates two independent delayed streams with different timing characteristics (30ms vs 50ms), properly wraps them in
RawStreamfor SSR serialization, and returns a well-structured payload for concurrent consumption testing.
| if (!textData || !binaryData) { | ||
| return | ||
| } |
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.
Handle loading state in early return path.
If textData or binaryData is falsy, the early return leaves isLoading as true indefinitely, causing the UI to display "Loading..." forever.
🔎 Proposed fix
if (!textData || !binaryData) {
+ isLoading.value = false
+ error.value = 'Missing stream data from loader'
return
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!textData || !binaryData) { | |
| return | |
| } | |
| if (!textData || !binaryData) { | |
| isLoading.value = false | |
| error.value = 'Missing stream data from loader' | |
| return | |
| } |
🤖 Prompt for AI Agents
In e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx around lines 48
to 50, the early return when textData or binaryData is falsy leaves isLoading
true causing a permanent "Loading..." state; update the early-return path to
update loading state (e.g., set isLoading to false) and optionally set an error
or empty-data flag before returning so the UI can render a non-loading state.
| onMounted(() => { | ||
| const rawData = loaderData.value.rawData | ||
| if (!rawData) { | ||
| return | ||
| } |
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.
Misleading state when rawData is missing.
If rawData doesn't exist, the function returns early while isConsuming remains true (initialized on line 14). This causes the UI to display "Loading..." indefinitely even though no stream consumption is happening.
🔎 Proposed fix
onMounted(() => {
const rawData = loaderData.value.rawData
if (!rawData) {
+ isConsuming.value = false
return
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| onMounted(() => { | |
| const rawData = loaderData.value.rawData | |
| if (!rawData) { | |
| return | |
| } | |
| onMounted(() => { | |
| const rawData = loaderData.value.rawData | |
| if (!rawData) { | |
| isConsuming.value = false | |
| return | |
| } |
🤖 Prompt for AI Agents
In e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx around lines 17 to
21, the onMounted early-return leaves isConsuming true when
loaderData.value.rawData is missing, causing the UI to show "Loading..."
forever; update the branch so that before returning you set isConsuming to false
(or explicitly toggle the consuming state to false) so the component reflects
that no stream will be consumed, or alternatively check rawData earlier and only
set isConsuming to true after confirming rawData exists.
| if (!first || !second) { | ||
| return | ||
| } |
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.
Handle missing streams more gracefully.
The early return leaves isConsuming as true, causing the UI to display "Loading..." indefinitely if streams are missing. While this is a defensive check that shouldn't trigger during normal operation, consider cleaning up the loading state for better UX in edge cases.
🔎 Suggested fix
const first = loaderData.value.first
const second = loaderData.value.second
if (!first || !second) {
+ isConsuming.value = false
+ error.value = 'Streams not available'
return
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!first || !second) { | |
| return | |
| } | |
| if (!first || !second) { | |
| isConsuming.value = false | |
| error.value = 'Streams not available' | |
| return | |
| } |
🤖 Prompt for AI Agents
In e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx around lines 21 to
23, the early return when either `first` or `second` stream is missing leaves
`isConsuming` true and the UI stuck on "Loading..."; fix by clearing the loading
state before returning (set `isConsuming = false`) and optionally set an
error/cleanup flag or call any stream close/cleanup logic so the component exits
the loading state gracefully in this edge case.
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.
Actionable comments posted: 0
♻️ Duplicate comments (1)
e2e/vue-start/basic/tests/raw-stream.spec.ts (1)
14-16: Comment incorrectly references React instead of Vue.The comment mentions "React hydration" but this is a Vue test file. This was flagged in a previous review.
🔎 Suggested fix
// Wait time for hydration to complete after page load -// This needs to be long enough for React hydration to attach event handlers +// This needs to be long enough for Vue hydration to attach event handlers const HYDRATION_WAIT = 1000
🧹 Nitpick comments (2)
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
102-115: Consider removing unnecessaryasynckeyword.The loader is marked
asyncbutcreateDelayedStreamreturns synchronously. Theasynckeyword is not needed here, though it's harmless.🔎 Suggested simplification
export const Route = createFileRoute('/raw-stream/ssr-single')({ - loader: async () => { + loader: () => { const stream = createDelayedStream(e2e/vue-start/basic/src/raw-stream-fns.ts (1)
40-41: Export references function defined later in file.
concatBytesis exported on line 41 but defined at line 78. While this works due to JavaScript hoisting for function declarations, placing exports after their definitions improves readability.🔎 Consider moving exports after definitions
+// Export helpers for use in components and SSR routes +export { encode, createDelayedStream, concatBytes } + // Helper to concatenate byte arrays function concatBytes(chunks: Array<Uint8Array>): Uint8Array { ... } - -// Export helpers for use in components and SSR routes -export { encode, createDelayedStream, concatBytes }Alternatively, add
exportdirectly to the function definition.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
e2e/vue-start/basic/src/raw-stream-fns.tse2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/tests/raw-stream.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx
- e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/tests/raw-stream.spec.tse2e/vue-start/basic/src/raw-stream-fns.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/tests/raw-stream.spec.tse2e/vue-start/basic/src/raw-stream-fns.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx
🧬 Code graph analysis (3)
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
e2e/vue-start/basic/src/raw-stream-fns.ts (1)
createStreamConsumer(392-425)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (2)
e2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx (1)
Route(77-96)e2e/vue-start/basic/src/raw-stream-fns.ts (3)
createStreamConsumer(392-425)createDelayedStream(41-41)encode(41-41)
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
e2e/solid-start/basic/src/raw-stream-fns.ts (2)
collectBytes(418-444)compareBytes(447-480)
🪛 Biome (2.1.2)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx
[error] 84-84: Avoid passing children using a prop
The canonical way to pass children in React is to use JSX elements
(lint/correctness/noChildrenProp)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (16)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (3)
1-15: Correct Vue imports and setup.The imports are properly using Vue's Composition API (
ref,watch,onMounted,onBeforeUnmount,Suspense,defineComponent) along with TanStack router utilities. This correctly addresses the previous React import issue.
79-89: Vue Await component useschildrenprop intentionally.The Biome linter flags the
childrenprop usage, but this is the documented pattern for@tanstack/vue-router'sAwaitcomponent in Vue JSX. Unlike React where children are passed as nested elements, Vue's JSX often uses thechildrenprop for render functions. This is a false positive from Biome which is React-focused.
44-59: Well-structured lifecycle and cleanup handling.The
hasStartedflag prevents duplicate stream consumption, and the watcher is properly stopped inonBeforeUnmount. The guard conditions at line 51 correctly prevent re-consumption when data already exists or errors occurred.e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (2)
1-8: Proper Vue framework imports.The file correctly uses Vue's Composition API imports and TanStack router/start utilities. Previous React import issues have been resolved.
37-56: Robust stream consumption lifecycle.The
hasStartedflag and watcher cleanup pattern properly prevents race conditions and resource leaks. The guard at line 44 ensures the stream is consumed only once.e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (3)
1-10: Correct Vue framework imports and utilities.The file properly uses Vue's Composition API and TanStack utilities. The binary comparison helpers (
collectBytes,compareBytes,concatBytes) are well-structured for byte-level verification.
78-101: Robust lifecycle management with proper cleanup.The
hasStartedflag andstopWatchercleanup pattern properly prevents duplicate consumption and cleans up the watcher on unmount. The multiple guard conditions ensure streams are only consumed once and only when both are available.
158-182: Binary hint configuration is correct.Both
textDataandbinaryDataRawStreams are properly configured with{ hint: 'binary' }to test base64 encoding behavior.e2e/vue-start/basic/tests/raw-stream.spec.ts (4)
18-148: Comprehensive Client RPC test coverage.The tests thoroughly cover single streams, multiple streams, timing scenarios (JSON ends first, raw ends first), large binary data, and mixed streaming. Appropriate timeouts and hydration waits are used.
151-262: Well-structured SSR loader tests with proper skip conditions.Good use of
test.skip(isPrerender, ...)for tests that don't work in prerender mode. Both direct navigation and client-side navigation scenarios are covered.
486-553: Thorough multiplexing tests.The interleaved streams, burst-pause-burst, and three concurrent streams tests provide good coverage for the multiplexing protocol. The JSON parsing and individual stream verification is well done.
631-675: Good edge case coverage.Empty stream and error stream tests verify important boundary conditions. The error propagation test confirms that stream errors are correctly surfaced to the client.
e2e/vue-start/basic/src/raw-stream-fns.ts (4)
4-38: Well-designed stream creation utilities.
createDelayedStreamandcreateVariableDelayStreamprovide flexible timing control for tests. Theencodehelper is a clean abstraction over TextEncoder.
367-496: Robust stream consumption with proper resource management.The
getActualStreamhelper correctly handles bothRawStreamand plainReadableStreamtypes. The WeakMap caches prevent duplicate consumption, and all readers are properly released infinallyblocks.
498-532: Clear byte comparison semantics.
compareBytesreturns well-documented results:mismatchIndex: -1for length mismatch,nullfor full match, or the specific index for byte mismatch. This provides good debugging information for test failures.
335-365: Good edge case test handlers.
emptyStreamFntests zero-byte streams, anderrorStreamFntests mid-stream errors with propercontroller.error()usage. These cover important boundary conditions.
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.
Actionable comments posted: 0
♻️ Duplicate comments (3)
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
50-69: Same edge case consideration as ssr-mixed.tsx.If
rawDatais never available,isConsumingstaystrueindefinitely. Consider settingisConsuming.value = falsewhenrawDatais falsy for defensive handling.e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx (1)
58-76: Same edge case as other SSR routes.If either
firstorsecondstream is never available, the UI remains in a loading state indefinitely. For consistency with the pattern across these test routes, consider updating the loading state when streams are unavailable.e2e/vue-start/basic/tests/raw-stream.spec.ts (1)
14-16: Comment mentions React hydration in Vue test file.The comment on line 15 refers to "React hydration" but this is a Vue test suite. Update for accuracy.
🔎 Suggested fix
// Wait time for hydration to complete after page load -// This needs to be long enough for React hydration to attach event handlers +// This needs to be long enough for Vue hydration to attach event handlers const HYDRATION_WAIT = 1000
🧹 Nitpick comments (1)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (1)
57-76: Consider handling the edge case when rawData is never available.If
loaderData.value.rawDatais undefined on initial mount and never becomes truthy,isConsumingremainstrue(set at line 22), causing the UI to display "Loading..." indefinitely. While this shouldn't occur in normal operation, adding defensive handling improves robustness.🔎 Suggested improvement
onMounted(() => { stopWatcher = watch( () => loaderData.value.rawData, (rawData) => { - if (!rawData || rawData === lastRawData) { + if (!rawData) { + isConsuming.value = false + return + } + if (rawData === lastRawData) { return } lastRawData = rawData void consumeRawStream(rawData) }, { immediate: true }, )
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsxe2e/vue-start/basic/src/vite-env.d.tse2e/vue-start/basic/tests/raw-stream.spec.tse2e/vue-start/basic/vite.config.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/vite-env.d.tse2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/tests/raw-stream.spec.tse2e/vue-start/basic/vite.config.tse2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/vite-env.d.tse2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/tests/raw-stream.spec.tse2e/vue-start/basic/vite.config.tse2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx
🧠 Learnings (5)
📓 Common learnings
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsxe2e/vue-start/basic/tests/raw-stream.spec.tse2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsxe2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx
🧬 Code graph analysis (4)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (2)
e2e/solid-start/basic/src/routes/raw-stream/ssr-mixed.tsx (1)
Route(77-96)e2e/vue-start/basic/src/raw-stream-fns.ts (3)
createStreamConsumer(392-425)createDelayedStream(41-41)encode(41-41)
e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (1)
e2e/vue-start/basic/src/raw-stream-fns.ts (1)
createStreamConsumer(392-425)
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (1)
e2e/solid-start/basic/src/raw-stream-fns.ts (2)
collectBytes(418-444)compareBytes(447-480)
e2e/vue-start/basic/tests/raw-stream.spec.ts (1)
e2e/react-start/streaming-ssr/tests/fixtures.ts (1)
expect(90-90)
🪛 Biome (2.1.2)
e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx
[error] 101-101: Avoid passing children using a prop
The canonical way to pass children in React is to use JSX elements
(lint/correctness/noChildrenProp)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (19)
e2e/vue-start/basic/vite.config.ts (1)
36-38: LGTM!The
defineblock correctly injects the__TSR_PRERENDER__compile-time constant usingJSON.stringifyto ensure proper serialization. This pattern aligns with Vite's best practices for global constants.e2e/vue-start/basic/src/vite-env.d.ts (1)
12-13: LGTM!The ambient declaration correctly types
__TSR_PRERENDER__as a boolean, providing proper TypeScript support for the global constant injected via Vite'sdefineconfiguration.e2e/vue-start/basic/src/routes/raw-stream/ssr-mixed.tsx (3)
17-51: Race condition handling is well implemented.The
consumeRunIdpattern effectively prevents stale async updates from corrupting state when the stream changes or component remounts. Good error handling with proper state cleanup in both success and error paths.
96-106: Vue Suspense slot pattern is correct for JSX.The static analysis hint about
childrenprop is a false positive. In Vue JSX, theAwaitcomponent from@tanstack/vue-routeruses a render function pattern wherechildrenis passed as a prop. This differs from React's JSX children pattern and is the correct approach for Vue TSX.
130-150: Route configuration looks correct.The loader properly creates delayed streams, wraps them in RawStream, and returns mixed data types (immediate, deferred promise, rawData). The
shouldReload: __TSR_PRERENDER__configuration aligns with the Solid adapter pattern shown in the relevant code snippets.e2e/vue-start/basic/src/routes/raw-stream/ssr-single.tsx (2)
10-44: Stream consumption logic is well-structured.The
consumeRunIdpattern properly handles race conditions, and the error handling covers both success and failure paths with appropriate state updates.
119-133: LGTM!The loader configuration correctly creates a delayed stream with multiple chunks and returns metadata alongside the RawStream. The
shouldReload: __TSR_PRERENDER__flag ensures proper behavior during prerendering.e2e/vue-start/basic/src/routes/raw-stream/ssr-multiple.tsx (2)
20-47: Parallel stream consumption is well implemented.Using
Promise.allfor concurrent consumption of both streams is appropriate, and theconsumeRunIdpattern prevents race conditions when streams change.
133-151: LGTM!The loader correctly creates two independent delayed streams with different timing (30ms vs 50ms), demonstrating the multiplexing capability being tested.
e2e/vue-start/basic/src/routes/raw-stream/ssr-binary-hint.tsx (3)
12-35: Well-structured test data constants.Defining expected byte sequences at module level enables client-side verification against server-generated streams. The type definitions
TextMatchandBinaryMatchprovide clear contracts for the verification results.
46-85: Byte collection and comparison logic is correct.The
consumeHintStreamsfunction properly collects bytes from both streams, compares them against expected values, and decodes text content where applicable. The spread operator usage withcompareBytesresult is clean.
179-204: LGTM!The loader correctly demonstrates the binary hint feature by creating both text-based and pure binary streams, both configured with
{ hint: 'binary' }. This validates that the binary hint consistently uses base64 encoding regardless of content type.e2e/vue-start/basic/tests/raw-stream.spec.ts (4)
18-61: Client RPC tests are well-structured.Good coverage of single stream, multiple streams, and timing scenarios. The pattern of waiting for visibility, then hydration, then clicking is appropriate for e2e tests.
186-208: Good use of conditional test skip for prerender limitation.The comment clearly explains why the SSR mixed streaming test is skipped in prerender mode. The IIFE pattern
(isPrerender ? test.skip : test)(...)is a clean way to conditionally skip tests.
377-392: Byte-by-byte verification tests are thorough.Parsing the JSON result and asserting on individual match properties provides strong verification that the streaming and encoding work correctly at the byte level.
622-666: Edge case coverage is excellent.Testing empty streams (zero-byte) and error propagation ensures the RawStream implementation handles boundary conditions correctly. The assertions verify both the expected state and the error message content.
e2e/vue-start/basic/src/routes/raw-stream/ssr-text-hint.tsx (3)
12-47: Thorough test data setup for text hint validation.The three test cases (pure text, mixed content with invalid UTF-8, pure binary) comprehensively validate the text hint's behavior:
- UTF-8 encoding for valid text
- Base64 fallback for invalid UTF-8 sequences
The type definitions clearly distinguish between text matches (with
asText) and binary matches.
59-112: Stream consumption logic handles all three streams correctly.The parallel consumption via
Promise.allis appropriate, and the comparison logic properly handles each stream type with the correct expected bytes.
222-258: LGTM!The loader correctly demonstrates text hint behavior across three scenarios:
- Pure text - should use UTF-8 encoding
- Mixed content - UTF-8 for valid text, base64 for invalid UTF-8 chunks
- Pure binary - must fallback to base64 entirely
The comments clearly document the expected behavior for each stream.
Mirror tests from
To vue and solid
Summary by CodeRabbit
New Features
Tests
✏️ Tip: You can customize this high-level summary in your review settings.