Skip to content

Comments

feat(experimental): migrate to the network source architecture (defineNetwork)#2650

Draft
kettanaito wants to merge 71 commits intomainfrom
fix/define-network
Draft

feat(experimental): migrate to the network source architecture (defineNetwork)#2650
kettanaito wants to merge 71 commits intomainfrom
fix/define-network

Conversation

@kettanaito
Copy link
Member

@kettanaito kettanaito commented Jan 10, 2026

Changes

  • Rewrites the way the SetupApi behaves by introducing: network frames, sources, controllers, and defineNetwork.
  • Handlers are now stored in a kind-based map. This should improve the performance during handler lookup since it becomes O(1).
  • Fixes an issue where a WebSocket connection would be logged in the console even when there are no matching event handlers for it.

Usage

The introduces APIs are meant to be used from the explicit msw/future export path. The path itself isn't documented as the APIs are considered experimental until the next major release.

Roadmap

  • Ensure the changes are backward-compatible
    • I removed HandlersKind and just inlined them in the handler classes.
    • I removed __kind private field from handler classes and made kind public. This is a safe change as nobody should be using these fields.
  • Passing handlers as both handlers and the constructor argument for the handlers controller seems odd. Choose just one?
    • Merged two into a single handlers option. After all, handlers are only needed as the input to the controller.
  • Consider higher-level utilities to create things like custom setupServer. The defineNetwork API is rather low-level. Export NetowrkOptions to the user can just override some of them?
import { defineNetwork } from 'msw'
import { defaultNetwork } from 'msw/node'

// Create a custom "setup*" wrapper.
function setupCustomApi(...handlers) {
  return defineNetwork({
    ...defaultNetwork,
    ...customizations,
    handlers,
  })
}

// Use it as you normally would use "setup*" APIs.
const network = setupCustomApi(...handlers)
network.enable()
  • Export createSetupServerCommonApi or its alternative. That's a crucial part of extending the default behaviors.
    • I'll hold on regarding this. Let the userland decide what utilities are missing. The common SetuApi isn't that difficult to implement by hand.
  • Fix the issue where onUnhandledFrame couldn't affect the request resolution because it's called after frame.resolve() is finished.
  • Add a test for onUnhandledRequest: 'error' to ensure that the request is errored (not bypassed). There's currently a bug since onUnhandledFrame is called after frame.resolve(), which always calls passthrough() before the unhandled frame callback.
  • Add a test for multiple WebSocket handlers that match the same URL. Make the first throw an error intentionally. Make sure that the next two still fire off. I suspect due to the algo change in WebSocketNetworkFrame, that won't happen (exception in one handler will short-circuit the entire loop).
    • ⚠️ The handler lookup must short-circuit. This is how HTTP behaves, this is how WebSocket should behave to remain predictable.
  • Unit tests for the introduced functionality.

@kettanaito kettanaito changed the title feat: add the defineNetwork API feat: migrate to the defineNetwork API Jan 11, 2026
@kettanaito kettanaito changed the title feat: migrate to the defineNetwork API feat: implement the defineNetwork API Jan 14, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 14, 2026

Open in StackBlitz

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

commit: 901f76f

@kettanaito kettanaito changed the title feat: implement the defineNetwork API feat(experimental): migrate to the network source architecture (defineNetwork) Feb 16, 2026
@christoph-fricke
Copy link
Contributor

Hey @kettanaito 👋
I saw your request for adventures preview testers on Bluesky. I gave this PR a spin in four different projects, which all use MSW differently. I checked static code analysis and test runs in each of them.

  1. OpenAPI-MSW: Uses exported types and getResponse in tests. Only uses HTTP handlers.
    • Everything looks good. No errors.
  2. Project that uses setupWorker and setupServer in JSDOM. Only uses HTTP handlers.
    • All tests passed.
    • Initial handlers array is explicitly types as RequestHandler[]. Caused an error when passed to setupWorker: "Argument of type 'RequestHandler<RequestHandlerDefaultInfo, any, any, RequestHandlerOptions>' is not assignable to parameter of type 'AnyHandler'"
    • I don't think the type error is big deal. Fixing it is trivial.
  3. Project that uses setupWorker in Playwright test processes to mock network requests for a react-router server started in the same process, and getResponse in a mock backend server for local development. Only uses HTTP handlers.
    • No type problems reported
    • Tests passed just fine
    • Project has the most initial handers (42). Maybe the Playwright tests performance is slightly better (~4s) from a total 44s to 49s for 179 tests. Not completely sure as I no longer actively work on that project.
  4. Project that uses MSW with @msw/playwright - obviously in a Playwright test setup. Mostly uses HTTP handlers and one Noop WebSocket handler.
    • No type errors reported
    • Tests failed with a runtime error: "TypeError: this.handlersController.currentHandlers is not a function". Error originated from @msw/playwright L. 104

Please let me now if you need further testing. Happy to help.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants