Skip to content

feat: use the network source architecture (defineNetwork)#2650

Open
kettanaito wants to merge 98 commits intomainfrom
fix/define-network
Open

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

Conversation

@kettanaito
Copy link
Copy Markdown
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.
  • Handlers filtering no longer uses instanceof check. Instead, the kind property of the handler is used.

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)
await 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.
  • Check if unhandled frame logic and exception try/catch in WebSocketInterceptor aren't fighting each other. I suspect since we catch exceptions, they never surface to the interceptor and it never properly translates them to socket error + closure.
  • Consider a new API to replace server.boundary() to establish ASL boundaries for Node.js tests. The NetworkApi must remain the same across environments. Environment-specific APIs must come from the environment entrypoints (msw/node) and applied explicitly.
    • Consider AsyncHandlersController.boundary() instead of the boundary() method in setup-server.ts.
  • Introduce readyState to NetworkApi so implementers don't have to introduce it themselves (e.g. remove isStarted from setup-worker.ts and use a network.readyState check).

@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
@felmonon
Copy link
Copy Markdown
Contributor

Opened #2676 as a focused follow-up for the RequestHandler[] compatibility issue reported in testing on this PR.

It widens the shared AnyHandler type to RequestHandler | WebSocketHandler and adds regression coverage for both setupWorker and setupServer.

Verified with:

  • pnpm build
  • pnpm test:ts
  • pnpm test:unit -- --run src/core/experimental/handlers-controller.test.ts test/node/msw-api/setup-server/listHandlers.node.test.ts
  • pnpm lint

Co-authored-by: Felmon Fekadu <felmonon@gmail.com>
Co-authored-by: Artem Zakharchenko <kettanaito@gmail.com>
@kettanaito kettanaito added this to the 3.0 milestone Mar 20, 2026
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.

3 participants