Skip to content

Conversation

@kettanaito
Copy link
Member

@kettanaito kettanaito commented Sep 30, 2024

Todo

  • Accept an OutgoingEvents type argument at sse() to make type-safe event property on the mock payload.
  • Support passthrough(). How do you intercept an EventSource, interact with it from the mock, and then passthrough after that?
  • Support event augmentation. How do you listen to the actual server's events, modify them, and send them back to the client?
  • Add test for withCredentials affecting the request cookies propagation.
  • How to handle passthrough()? What if I want to let the EventSource receive whichever events the actual server sends from now on? Still manual?
  • Add tests for .use() with sse().
  • Support retry
  • Add an invariant for typeof EventSource !== 'undefined' to let the developer know when they are using sse() in the environment that doesn't support it.
  • Fix the [Error [TypeError]: Failed to fetch] error during test/browser/sse-api/sse.server.connect.test.ts tests. It seems to be originating from the actual fetch() in the Service Worker (the scenarios call server.connect() on the SSE).
    • This is caused by the missing logger!
  • Finish sse.client.send.test.ts (the last test case is unfinished).
  • ⚠️ Consider exporting sse from msw root. While EventSource doesn't exist in Node.js, it exists in Deno. It might also be added to Node.js in the future. Afaik, there's nothing specific to browsers in our implementation. Keep the global check, export from the root for consistency.
  • Support writing to the stream from extraneous sources (e.g. pubsub). Something similar to GraphQL subscriptions. client.from()?
    • Excessively complicated and not needed. DYI. Will show an example of that in the docs.
  • Documentation (document server-sent events mswjs.io#470)

References

@kettanaito
Copy link
Member Author

Augmenting actual server-sent events

sse(url, ({ source, server }) => {
  // This creates a new EventSource request
  // and propagates all the events from here
  // to the underlying pending stream for `source`.
  server.connect()
})

Modifying the event is similar to that in WebSockets: prevent its default and send a new event:

sse(url, ({ source, server }) => {
  server.connect()

  server.addEventListener('message', (event) => {
    // Prevent this server event from reaching the client.
    event.preventDefault()
    const newEvent = modify(event.data)
    source.send(newEvent)
  })
})

May be a good idea to rename source to client and have a consistent SSE/WebSocket experience.

@kettanaito
Copy link
Member Author

kettanaito commented Oct 2, 2024

The tests are failing likely due to Node.js bump to v20 in CI.

Edit: Looks like an issue specific to a particular version of Node.js. Reported here: nodejs/undici#3676

@kettanaito kettanaito changed the title feat: support server-sent events feat: support server-sent events (SSE) Dec 5, 2024
@kettanaito
Copy link
Member Author

kettanaito commented Feb 21, 2025

Test update

I've resolved the infinite request issue that failed the majority of SSE tests (was using legacy passthrough header; migrating to accept: msw/passthrough + respecting that later on helped).

Two tests are still failing, both seem to be related to errors.

There's an odd rogue TypeError: Network error being thrown right when the Playwright window closes. Odd. The SSE request is not considered a network error from what I can tell. The error test case also fails. Maybe the two are related?

* Determines if the given value is an object.
*/
export function isObject(value: any): boolean {
export function isObject(value: any): value is Record<string, any> {
Copy link
Contributor

Choose a reason for hiding this comment

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

fwiw, this isn't exactly type-safe in a way you'd assume: TS playground

Copy link
Member Author

Choose a reason for hiding this comment

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

Ouch.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jun 5, 2025

Open in StackBlitz

npm i https://pkg.pr.new/msw@2299

commit: 591b493

@kettanaito
Copy link
Member Author

[Error [TypeError]: Failed to fetch] error

Root cause

The log method of the HttpHandler class that SSE is extending was consuming the response body in await serializeResponse(args.response), which resulted in the said error. The body of the SSE cannot be consumed since it's being streamed and it incomplete.

Solution

The SSE handler must implement its own logger to solve this issue and also be more contextual.

@kettanaito kettanaito marked this pull request as ready for review July 12, 2025 10:40
@kettanaito
Copy link
Member Author

Update

The sse API is ready. You can install a preview release by following the instructions here. I will let the folks use it and share their feedback for a bit and then merge it.

@zeroregard
Copy link

Just wanna prefix this by saying, thanks a lot for introducing this and we are enjoying using it!!

Tip/note to other potential PNPM users for when you are using https://pkg.pr.new/msw@2299 (or other PR identifiers for other bleeding-edge MSW versions, it's not exclusive to this branch), since it's not versioned per se, you will run into an issue like

ERR_PNPM_UNEXPECTED_PKG_CONTENT_IN_STOREPackage name mismatch found while reading {"tarball":"https://pkg.pr.new/msw@2299"} from the store.

This means that either the lockfile is broken or the package metadata (name and version) inside the package's package.json file doesn't match the metadata in the registry. 
Expected package: msw@2.11.0. 
Actual package in the store with the given integrity: msw@2.10.4.

The workaround is that you can use the specific commit version like https://pkg.pr.new/mswjs/msw/msw@ad82c8e to lock yourself in, otherwise your CI builds might fail suddenly.

@kettanaito
Copy link
Member Author

Thanks, @zeroregard. Let me know if you have some suggestions around this API or some use cases that you think it doesn't cover.

The feature is complete and tested, and I plan on releasing it later this month. It's a great chance to share early feedback until then so we could address potentially breaking changes before they are locked up until the next major release. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

First-class Server-Sent Events (SSE) API

3 participants