Skip to content

Conversation

@unnoq
Copy link
Member

@unnoq unnoq commented Nov 11, 2025

Summary by CodeRabbit

  • New Features
    • Configurable initial event comment (enable/disable + custom text).
  • Bug Fixes
    • Streaming/SSE responses now emit an initial keep‑alive heartbeat line before event data.
  • Documentation
    • Added HTTP Event Iterator configuration docs; removed several client/OpenAPI/RPC keep‑alive sections.
  • Tests
    • Expanded tests covering initial-comment and keep‑alive sequencing, timing, and stream consumption.

@unnoq unnoq requested a review from Copilot November 11, 2025 07:42
@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Nov 11, 2025
@vercel
Copy link

vercel bot commented Nov 11, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
orpc Ready Ready Preview Comment Nov 12, 2025 3:17am

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @unnoq, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a feature to optimize Server-Sent Events (SSE) streams by sending an immediate, empty comment. This ensures that HTTP response headers are flushed as soon as the stream starts, which can significantly improve the perceived responsiveness and connection establishment time for clients consuming the event stream. The change is reflected in both the core implementation and updated test cases.

Highlights

  • Initial Event Stream Comment: An empty comment (': \n\n') is now sent as the very first event in an event stream generated by toEventStream.
  • Header Flushing Optimization: This initial comment is specifically designed to immediately flush HTTP response headers, allowing clients to establish connections faster without waiting for the first meaningful event.
  • Test Coverage Update: Existing test cases for toEventStream have been updated to account for and verify the presence of this new initial comment in the event stream.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@unnoq unnoq changed the title Feat/standard server/send initial comment in event stream to flush response headers immediately feat(standard-server): send initial comment in event stream to flush response headers immediately Nov 11, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 11, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds optional initial SSE comment emission at stream start and emits a leading keep-alive prefix before event data; introduces two ToEventStream options (eventIteratorInitialCommentEnabled, eventIteratorInitialComment); updates tests across fetch/node/aws-lambda/fastify and augments/removes related docs.

Changes

Cohort / File(s) Summary
Fetch event stream implementation
packages/standard-server-fetch/src/event-iterator.ts
Add eventIteratorInitialCommentEnabled?: boolean and eventIteratorInitialComment?: string to ToEventStreamOptions; when enabled, toEventStream enqueues an initial comment frame at stream start.
Fetch event stream tests
packages/standard-server-fetch/src/event-iterator.test.ts
Reorganized tests for keep-alive and initial-comment enabled/disabled scenarios; removed explicit empty options in calls and updated reader timing/assertions and spy counts.
Fetch body & response tests
packages/standard-server-fetch/src/body.test.ts, packages/standard-server-fetch/src/response.test.ts
Tests updated to expect an initial keep-alive/initial-comment chunk (": \n\n" or ": <text>\n\n") as the first emitted stream chunk where applicable.
Node event/response/body tests
packages/standard-server-node/src/event-iterator.test.ts, packages/standard-server-node/src/response.test.ts, packages/standard-server-node/src/body.test.ts
Read/streaming tests updated to assert an initial ": \n\n" chunk emitted at stream start before event payloads.
AWS Lambda & Fastify response tests
packages/standard-server-aws-lambda/src/response.test.ts, packages/standard-server-fastify/src/response.test.ts
Streaming test expectations updated to include a leading keep-alive sequence (": \n\n") before the first event payload in streaming scenarios.
Docs — added HTTP handler/link options
apps/content/docs/adapters/http.md
Add Event Iterator Options docs (initial comment + keep-alive options), option tables, and examples showing eventIteratorInitialCommentEnabled and eventIteratorInitialComment.
Docs — removed keep-alive sections
apps/content/docs/client/rpc-link.md, apps/content/docs/openapi/client/openapi-link.md, apps/content/docs/openapi/openapi-handler.md, apps/content/docs/rpc-handler.md
Remove prior "Event Iterator Keep Alive" documentation sections and examples from several client and handler docs.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant Stream as ReadableStream
    participant Producer

    rect rgb(250,250,245)
    Note over Stream,Producer: Stream initialization — optional initial comment
    Client->>Stream: reader.read()
    Stream->>Producer: start(controller)
    alt initial comment enabled
        Producer->>Stream: enqueue(": <initial>\n\n")
        Stream-->>Client: ": <initial>\n\n"
    else initial comment disabled
        Producer->>Stream: (no initial comment)
    end
    end

    rect rgb(245,250,255)
    Note over Stream,Producer: Keep-alive (periodic) and event frames
    loop periodic
        alt keep-alive enabled
            Producer->>Stream: enqueue(": \n\n")
            Stream-->>Client: ": \n\n"
        end
        Producer->>Stream: enqueue("event: ...\ndata: ...\n\n")
        Stream-->>Client: "event/data frame"
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay extra attention to:
    • Exact byte formatting and newline counts of initial-comment vs keep-alive frames (": \n\n" vs ": <text>\n\n").
    • Timing-sensitive assertions and test windows in packages/standard-server-fetch/src/event-iterator.test.ts.
    • Interaction between new initial-comment options and existing keep-alive options/defaults.

Possibly related PRs

  • unnoq/orpc#560 — Related changes to toEventStream/toEventIterator behavior and option surface; touches same functions and option types.
  • unnoq/orpc#199 — Prior rename/adjustments of keep-alive/ping options and event-iterator surface that intersect these semantics.
  • unnoq/orpc#306 — Documentation changes around OpenAPILink and event-iterator/keep-alive behavior that overlap removed/edited docs here.

Poem

🐇 A tiny colon starts the stream tonight,
I hop the bytes to give the headers light,
First a whisper, then the pulses flow,
Events leap after the quiet hello,
I nibble timings, keep the heart aglow. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the main change: adding an initial comment to event streams to flush response headers immediately.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/standard-server/send-initial-comment-in-event-stream-to-flush-response-headers-immediately

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements a performance optimization for server-sent event (SSE) streams by sending an initial empty comment immediately when the stream starts. This causes response headers to flush immediately, allowing clients to establish connections earlier without waiting for the first actual event from the iterator.

  • Added initial empty comment (': \n\n') in the start() method of the ReadableStream
  • Updated all test cases to expect and consume the initial comment before subsequent events

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
packages/standard-server-fetch/src/event-iterator.ts Added logic to send an initial empty comment in the stream's start() method to flush response headers immediately
packages/standard-server-fetch/src/event-iterator.test.ts Updated all tests to expect the initial comment as the first chunk in event streams, ensuring test assertions align with the new behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a useful feature to immediately flush response headers for event streams by sending an initial comment. The implementation in toEventStream is straightforward and correct. The accompanying test updates are thorough, but I've identified a few minor inconsistencies in the testing style that could be improved for better maintainability and robustness. I've left specific suggestions in the comments below.

Copy link

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (1)
packages/standard-server-fetch/src/event-iterator.test.ts (1)

321-321: Consider adding assertions for consistency.

These lines correctly consume the initial empty-comment frame before testing cancellation scenarios. However, for consistency with other tests and explicit documentation of the behavior, consider asserting the value:

-    await reader.read()
+    expect((await reader.read())).toEqual({ done: false, value: ': \n\n' })

This makes it clearer that we're intentionally consuming the initial frame and maintains consistency with other test cases.

Also applies to: 351-351, 382-382

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ad5fd4 and 484a221.

📒 Files selected for processing (2)
  • packages/standard-server-fetch/src/event-iterator.test.ts (8 hunks)
  • packages/standard-server-fetch/src/event-iterator.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/standard-server-fetch/src/event-iterator.ts (2)
packages/shared/src/otel.ts (1)
  • startSpan (44-47)
packages/standard-server/src/event-iterator/encoder.ts (1)
  • encodeEventMessage (52-79)
⏰ 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). (3)
  • GitHub Check: lint
  • GitHub Check: publish-commit
  • GitHub Check: test
🔇 Additional comments (2)
packages/standard-server-fetch/src/event-iterator.ts (1)

154-164: LGTM! Excellent improvement for connection establishment.

The implementation correctly sends an initial SSE comment event to flush response headers immediately. This is a well-established pattern in server-sent events that ensures clients can establish the connection without waiting for the first data event.

The use of encodeEventMessage({ comments: [''] }) produces the valid SSE format : \n\n (comment line + blank line terminator), which complies with the SSE specification.

packages/standard-server-fetch/src/event-iterator.test.ts (1)

225-225: LGTM! Test assertions correctly verify the initial frame.

The tests properly assert that the initial empty-comment frame (: \n\n) is sent before any data events across various scenarios (with/without return, error cases, keep-alive). This ensures the implementation behavior is well-tested.

Also applies to: 247-247, 269-269, 291-291, 415-415

@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:S This PR changes 10-29 lines, ignoring generated files. labels Nov 11, 2025
@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 11, 2025

More templates

@orpc/ai-sdk

npm i https://pkg.pr.new/@orpc/ai-sdk@1204

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@1204

@orpc/client

npm i https://pkg.pr.new/@orpc/client@1204

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@1204

@orpc/experimental-durable-iterator

npm i https://pkg.pr.new/@orpc/experimental-durable-iterator@1204

@orpc/hey-api

npm i https://pkg.pr.new/@orpc/hey-api@1204

@orpc/interop

npm i https://pkg.pr.new/@orpc/interop@1204

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@1204

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@1204

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@1204

@orpc/openapi-client

npm i https://pkg.pr.new/@orpc/openapi-client@1204

@orpc/otel

npm i https://pkg.pr.new/@orpc/otel@1204

@orpc/experimental-pino

npm i https://pkg.pr.new/@orpc/experimental-pino@1204

@orpc/experimental-publisher

npm i https://pkg.pr.new/@orpc/experimental-publisher@1204

@orpc/experimental-ratelimit

npm i https://pkg.pr.new/@orpc/experimental-ratelimit@1204

@orpc/react

npm i https://pkg.pr.new/@orpc/react@1204

@orpc/react-query

npm i https://pkg.pr.new/@orpc/react-query@1204

@orpc/experimental-react-swr

npm i https://pkg.pr.new/@orpc/experimental-react-swr@1204

@orpc/server

npm i https://pkg.pr.new/@orpc/server@1204

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@1204

@orpc/solid-query

npm i https://pkg.pr.new/@orpc/solid-query@1204

@orpc/standard-server

npm i https://pkg.pr.new/@orpc/standard-server@1204

@orpc/standard-server-aws-lambda

npm i https://pkg.pr.new/@orpc/standard-server-aws-lambda@1204

@orpc/standard-server-fastify

npm i https://pkg.pr.new/@orpc/standard-server-fastify@1204

@orpc/standard-server-fetch

npm i https://pkg.pr.new/@orpc/standard-server-fetch@1204

@orpc/standard-server-node

npm i https://pkg.pr.new/@orpc/standard-server-node@1204

@orpc/standard-server-peer

npm i https://pkg.pr.new/@orpc/standard-server-peer@1204

@orpc/svelte-query

npm i https://pkg.pr.new/@orpc/svelte-query@1204

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@1204

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@1204

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@1204

@orpc/vue-colada

npm i https://pkg.pr.new/@orpc/vue-colada@1204

@orpc/vue-query

npm i https://pkg.pr.new/@orpc/vue-query@1204

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@1204

commit: 4549064

@codecov
Copy link

codecov bot commented Nov 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…response headers immediately

Adds an initial empty comment (': \n\n') in the `start()` method of `toEventStream`
to immediately flush response headers to the client. This ensures the connection is
established without waiting for others events
@unnoq unnoq force-pushed the feat/standard-server/send-initial-comment-in-event-stream-to-flush-response-headers-immediately branch from f1b55ce to dafdae4 Compare November 12, 2025 02:31
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Nov 12, 2025
Copy link

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (2)
packages/standard-server-node/src/event-iterator.test.ts (1)

35-35: Consider adding test coverage for disabled keep-alive behavior.

While this test correctly validates the default behavior (initial keep-alive chunk : \n\n), consider adding a companion test case that explicitly disables the keep-alive to ensure both code paths are covered. Other test files in this PR pass explicit options like eventIteratorKeepAliveEnabled: false.

For example, add a test case like:

it('toEventStream without keep-alive', async () => {
  async function* gen() {
    yield 1
    yield 2
  }

  const reader = Readable.toWeb(toEventStream(gen(), { eventIteratorKeepAliveEnabled: false }))
    .pipeThrough(new TextDecoderStream())
    .getReader()

  // Should NOT have initial keep-alive chunk
  expect((await reader.read())).toEqual({ done: false, value: 'event: message\ndata: 1\n\n' })
  expect((await reader.read())).toEqual({ done: false, value: 'event: message\ndata: 2\n\n' })
  expect((await reader.read())).toEqual({ done: true, value: undefined })
})
apps/content/docs/adapters/http.md (1)

250-298: Well-documented feature addition!

The new Event Iterator Configuration section clearly documents the initial comment and keep-alive options. The structure with separate subsections, option tables, and usage examples is easy to follow.

Minor suggestion: Consider expanding the warning at lines 278-279 to clarify when link-side event iterator options would be useful (e.g., "only when your client is sending an event stream to the server, which is uncommon in most applications").

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f1b55ce and dafdae4.

📒 Files selected for processing (14)
  • apps/content/docs/adapters/http.md (1 hunks)
  • apps/content/docs/client/rpc-link.md (0 hunks)
  • apps/content/docs/openapi/client/openapi-link.md (0 hunks)
  • apps/content/docs/openapi/openapi-handler.md (0 hunks)
  • apps/content/docs/rpc-handler.md (0 hunks)
  • packages/standard-server-aws-lambda/src/response.test.ts (3 hunks)
  • packages/standard-server-fastify/src/response.test.ts (1 hunks)
  • packages/standard-server-fetch/src/body.test.ts (1 hunks)
  • packages/standard-server-fetch/src/event-iterator.test.ts (9 hunks)
  • packages/standard-server-fetch/src/event-iterator.ts (2 hunks)
  • packages/standard-server-fetch/src/response.test.ts (1 hunks)
  • packages/standard-server-node/src/body.test.ts (1 hunks)
  • packages/standard-server-node/src/event-iterator.test.ts (1 hunks)
  • packages/standard-server-node/src/response.test.ts (3 hunks)
💤 Files with no reviewable changes (4)
  • apps/content/docs/rpc-handler.md
  • apps/content/docs/client/rpc-link.md
  • apps/content/docs/openapi/openapi-handler.md
  • apps/content/docs/openapi/client/openapi-link.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/standard-server-fetch/src/event-iterator.ts
  • packages/standard-server-node/src/body.test.ts
  • packages/standard-server-fetch/src/event-iterator.test.ts
  • packages/standard-server-fetch/src/response.test.ts
  • packages/standard-server-fastify/src/response.test.ts
⏰ 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). (3)
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: publish-commit
🔇 Additional comments (7)
packages/standard-server-aws-lambda/src/response.test.ts (3)

96-139: LGTM! Initial comment chunk properly tested.

The test correctly verifies that an initial keep-alive comment (Buffer.from(': \n\n')) is emitted before the event data chunks, ensuring headers are flushed immediately when streaming begins.


141-195: LGTM! Stream cancellation with initial comment tested.

The test properly verifies that the initial comment chunk is sent before event data even in the error/cancellation scenario, and that cleanup occurs correctly when the stream is destroyed.


197-251: LGTM! Stream cancellation without error properly tested.

The test correctly handles the initial comment emission and stream cancellation without error, verifying proper cleanup behavior.

packages/standard-server-node/src/response.test.ts (3)

120-161: LGTM! Async generator streaming test properly updated.

The test correctly verifies that the response text begins with the initial comment (': \n\n') followed by the event data. The full-text assertion approach is appropriate for the node adapter's response handling.


163-219: LGTM! Stream destruction with error properly tested.

The test correctly verifies initial comment emission and proper cleanup when the stream is destroyed with an error.


221-277: LGTM! Stream destruction without error properly tested.

The test correctly verifies initial comment emission and proper cleanup when the stream is destroyed gracefully.

packages/standard-server-fetch/src/body.test.ts (1)

280-302: Verify test configuration for initial comment behavior.

The test sets eventIteratorKeepAliveEnabled: false (line 285) but still expects an initial ': \n\n' chunk (line 299). This appears to be testing that the initial comment is emitted even when periodic keep-alive is disabled, which aligns with the feature design where initial comments and keep-alive are separate options.

However, the test doesn't explicitly set eventIteratorInitialCommentEnabled. If the default is true (as documented), this test is implicitly relying on that default.

Consider explicitly setting eventIteratorInitialCommentEnabled: true in the options to make the test's intent clearer:

-    const options = { eventIteratorKeepAliveEnabled: false }
+    const options = { eventIteratorKeepAliveEnabled: false, eventIteratorInitialCommentEnabled: true }

Alternatively, if this test is specifically meant to verify the default behavior, add a comment explaining that.

Additionally, verify that there's test coverage for when eventIteratorInitialCommentEnabled: false to ensure the initial comment can be disabled:

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@coderabbitai coderabbitai bot left a 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 (1)
packages/standard-server-fetch/src/event-iterator.test.ts (1)

247-255: Inconsistent assertion patterns across tests.

Lines 247-251 check both done and value properties, while lines 270-272 and 292-295 only check .value. For improved robustness and consistency, consider standardizing on checking both properties throughout the test suite, especially for the assertions following the initial comment check.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dafdae4 and 9770032.

📒 Files selected for processing (2)
  • apps/content/docs/adapters/http.md (1 hunks)
  • packages/standard-server-fetch/src/event-iterator.test.ts (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/content/docs/adapters/http.md
🧰 Additional context used
🧬 Code graph analysis (1)
packages/standard-server-fetch/src/event-iterator.test.ts (1)
packages/standard-server-fetch/src/event-iterator.ts (2)
  • toEventStream (156-262)
  • start (171-179)
⏰ 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). (3)
  • GitHub Check: publish-commit
  • GitHub Check: lint
  • GitHub Check: test
🔇 Additional comments (4)
packages/standard-server-fetch/src/event-iterator.test.ts (4)

221-234: LGTM! Initial comment assertion added correctly.

The test properly accounts for the new initial comment behavior, checking for ': \n\n' as the first read value before subsequent messages.


317-322: LGTM! Extra read correctly accounts for initial comment.

The additional await reader.read() at line 321 properly consumes the initial comment before canceling, maintaining the test's intent to cancel after reading actual data.


396-432: Comprehensive keep-alive test coverage.

The test correctly validates keep-alive behavior with appropriate timing expectations. The logic is sound: with a 40ms interval and 100ms generator delay, two keep-alive pings should be sent before each message.


468-511: Excellent test coverage for initial comment feature.

The tests properly validate both enabled and disabled states of the initial comment feature, with clear timing expectations to verify immediate delivery when enabled (< 10ms) versus waiting for the first actual message when disabled (>= 50ms).

Copy link

@coderabbitai coderabbitai bot left a 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 (4)
packages/standard-server-fetch/src/event-iterator.test.ts (4)

269-273: Assertion style inconsistency remains unaddressed.

As previously noted, line 269 checks both done and value properties while lines 270-272 only check .value. This inconsistency affects test robustness. Consider standardizing to always check both properties.


291-295: Assertion style inconsistency remains unaddressed.

Similar to the previous test, line 291 checks both done and value while lines 292-295 only check .value. Standardizing the assertion pattern would improve test consistency.


416-439: Timing assertions remain potentially flaky (unresolved from previous review).

The tight timing windows (e.g., < 50ms, < 100ms, < 130ms) throughout this test could still fail in resource-constrained CI environments. As previously suggested, consider:

  • Widening upper bounds (e.g., < 150ms instead of < 130ms)
  • Using vi.waitFor with timing predicates instead of single point-in-time checks

464-471: Tight timing windows in disabled test may also be flaky.

Similar to the enabled test, lines 466-467 and 470-471 use tight timing assertions (< 110ms, < 220ms) that could fail under CI load. Consider relaxing these bounds for better reliability.

🧹 Nitpick comments (2)
packages/standard-server-fetch/src/event-iterator.test.ts (2)

478-501: Initial comment test logic is sound, but consider relaxing timing bounds.

The test correctly verifies that:

  • Initial comment is sent immediately on stream start (line 496-497)
  • Custom comment text is used (line 487)
  • Keep-alive is properly isolated (line 488)

However, lines 499-500 use a tight upper bound (< 60ms) that could be relaxed to < 80ms for better CI reliability.


503-522: Disabled test correctly verifies absence of initial comment.

The test properly confirms that when eventIteratorInitialCommentEnabled: false, no initial comment is sent and the first read directly receives the message event. Consider widening line 521's upper bound to < 80ms for CI robustness.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9770032 and 0657f12.

📒 Files selected for processing (1)
  • packages/standard-server-fetch/src/event-iterator.test.ts (9 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/standard-server-fetch/src/event-iterator.test.ts (2)
packages/standard-server-fetch/src/event-iterator.ts (2)
  • toEventStream (156-262)
  • start (171-179)
packages/standard-server-node/src/event-iterator.ts (1)
  • toEventStream (22-27)
⏰ 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). (3)
  • GitHub Check: lint
  • GitHub Check: publish-commit
  • GitHub Check: test
🔇 Additional comments (3)
packages/standard-server-fetch/src/event-iterator.test.ts (3)

221-230: LGTM! Tests correctly updated for initial comment default behavior.

The removal of the explicit empty options object is cleaner, and the new assertion on line 225 correctly verifies that the initial comment (: \n\n) is sent as the first value when using default options.


317-322: LGTM! Correctly adapted for initial comment.

The additional reader.read() call on line 321 is necessary to consume the initial comment before testing cancellation behavior. This ensures the test logic remains correct with the new default behavior.


530-540: LGTM! Enhanced roundtrip test with keep-alive interaction.

The increased delay (50ms on line 532) and addition of eventIteratorKeepAliveInterval: 10 (line 535) improves test coverage by exercising the interaction between keep-alive messages and actual events in the roundtrip scenario.

Copy link

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (1)
apps/content/docs/adapters/http.md (1)

273-279: Minor clarity suggestion: Clarify the initial comment's primary use case.

The warning at lines 277–279 correctly notes that link options apply to client-to-server streaming. However, since the initial comment feature is primarily designed for server-to-client event streaming (to flush response headers), it might be helpful to add a brief note clarifying that eventIteratorInitialCommentEnabled and eventIteratorInitialComment on links are typically not needed in common patterns.

Consider updating the warning to explicitly mention that initial comment options on links are rarely needed:

::: warning
-Link options apply when streaming from **client to server**, not server to client (as with handlers). In most cases, you don't need to configure these on the link.
+Link options apply when streaming from **client to server**, not server to client (as with handlers). In most cases, you don't need to configure these on the link. Note: `eventIteratorInitialComment*` options are typically only relevant for handlers, not links.
:::
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0657f12 and 4549064.

📒 Files selected for processing (2)
  • apps/content/docs/adapters/http.md (1 hunks)
  • packages/standard-server-fetch/src/event-iterator.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/standard-server-fetch/src/event-iterator.ts
⏰ 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). (3)
  • GitHub Check: publish-commit
  • GitHub Check: test
  • GitHub Check: lint
🔇 Additional comments (1)
apps/content/docs/adapters/http.md (1)

250-289: Documentation defaults are accurate and consistent with implementation.

Verification confirms all documented Event Iterator Options defaults match the actual implementation in packages/standard-server-fetch/src/event-iterator.ts:

  • eventIteratorInitialCommentEnabled: true
  • eventIteratorInitialComment: ''
  • eventIteratorKeepAliveEnabled: true
  • eventIteratorKeepAliveInterval: 5000
  • eventIteratorKeepAliveComment: ''

The documentation is well-structured, accurate, and complete.

@unnoq unnoq merged commit 91ac36a into main Nov 12, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants