Skip to content

Add SseDecoder to decode Server-Sent Events from any readable stream - #52

Merged
clue merged 2 commits into
clue:1.xfrom
clue-labs:sse-decoder
Sep 17, 2026
Merged

clue merged 2 commits into
clue:1.xfrom
clue-labs:sse-decoder

Conversation

@clue

@clue clue commented Sep 17, 2026

Copy link
Copy Markdown
Owner

This changeset adds a new SseDecoder class that decodes the Server-Sent Events (SSE) wire protocol from any readable byte stream.

Unlike the EventSource class which implements the higher-level HTML5 EventSource API (HTTP GET request, automatic reconnection, readyState and Last-Event-ID handling), this class only decodes the text/event-stream wire protocol. This makes it reusable whenever you already have a readable stream of SSE data, such as a streaming HTTP response to a custom request. This is common for LLM streaming APIs that return SSE over an HTTP POST request:

$browser = new React\Http\Browser();

$response = await($browser->requestStreaming(
    'POST',
    'https://api.example.com/v1/messages',
    $headers,
    $body
));
assert($response instanceof Psr\Http\Message\ResponseInterface);

$stream = $response->getBody();
assert($stream instanceof React\Stream\ReadableStreamInterface);

$sse = new Clue\React\EventSource\SseDecoder($stream);
$sse->on('data', function (Clue\React\EventSource\MessageEvent $message) {
    $data = json_decode($message->data);

    if ($data?->type === 'content_block_delta') {
        echo $data->delta->text;
    }
});

The second commit updates EventSource to use this class internally without changing its behavior. All existing EventSource tests continue to pass unchanged and the test suite ensures 100% code coverage across all supported environments, so this should be safe. Limiting the buffer size for the parser remains out of scope, see #34.

Builds on top of #36 and #41
Refs #34

@clue clue added this to the v1.5.0 milestone Sep 17, 2026
@clue clue added the new feature New feature or request label Sep 17, 2026
@clue
clue requested a lite review from Copilot September 17, 2026 13:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new README examples/signature include PHP syntax and formatting errors that conflict with the project’s declared PHP compatibility and should be corrected before merge.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR introduces a reusable SseDecoder that decodes the text/event-stream (SSE wire protocol) from any ReadableStreamInterface, and refactors EventSource to use this decoder internally while preserving reconnection behavior.

Changes:

  • Add new Clue\React\EventSource\SseDecoder stream decoder and a dedicated test suite for SSE parsing behavior.
  • Refactor EventSource parsing to delegate SSE framing/parsing to SseDecoder, and extend reconnection tests for Last-Event-ID and retry.
  • Document SseDecoder usage in the README and add an explicit runtime dependency on react/stream.
File summaries
File Description
src/SseDecoder.php New decoder that buffers and parses SSE frames from any readable stream.
src/EventSource.php Uses SseDecoder internally and persists id/retry across reconnects.
tests/SseDecoderTest.php New unit tests covering SSE decoding, buffering, and close/error semantics.
tests/EventSourceTest.php Adds reconnection regression tests for Last-Event-ID and retry persistence.
README.md Adds SseDecoder documentation and examples.
composer.json Adds explicit react/stream dependency required by SseDecoder.
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread README.md
Comment thread README.md Outdated
Comment thread README.md
@clue
clue merged commit d31d455 into clue:1.x Sep 17, 2026
14 checks passed
@clue
clue deleted the sse-decoder branch September 17, 2026 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants