Spaces:
Paused
Paused
| import { AsyncLocalStorage } from 'node:async_hooks' | |
| import { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest' | |
| import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest' | |
| import { FetchInterceptor } from '@mswjs/interceptors/fetch' | |
| import { HandlersController } from '~/core/SetupApi' | |
| import type { RequestHandler } from '~/core/handlers/RequestHandler' | |
| import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler' | |
| import type { SetupServer } from './glossary' | |
| import { SetupServerCommonApi } from './SetupServerCommonApi' | |
| const store = new AsyncLocalStorage<RequestHandlersContext>() | |
| type RequestHandlersContext = { | |
| initialHandlers: Array<RequestHandler | WebSocketHandler> | |
| handlers: Array<RequestHandler | WebSocketHandler> | |
| } | |
| /** | |
| * A handlers controller that utilizes `AsyncLocalStorage` in Node.js | |
| * to prevent the request handlers list from being a shared state | |
| * across mutliple tests. | |
| */ | |
| class AsyncHandlersController implements HandlersController { | |
| private rootContext: RequestHandlersContext | |
| constructor(initialHandlers: Array<RequestHandler | WebSocketHandler>) { | |
| this.rootContext = { initialHandlers, handlers: [] } | |
| } | |
| get context(): RequestHandlersContext { | |
| return store.getStore() || this.rootContext | |
| } | |
| public prepend(runtimeHandlers: Array<RequestHandler | WebSocketHandler>) { | |
| this.context.handlers.unshift(...runtimeHandlers) | |
| } | |
| public reset(nextHandlers: Array<RequestHandler | WebSocketHandler>) { | |
| const context = this.context | |
| context.handlers = [] | |
| context.initialHandlers = | |
| nextHandlers.length > 0 ? nextHandlers : context.initialHandlers | |
| } | |
| public currentHandlers(): Array<RequestHandler | WebSocketHandler> { | |
| const { initialHandlers, handlers } = this.context | |
| return handlers.concat(initialHandlers) | |
| } | |
| } | |
| export class SetupServerApi | |
| extends SetupServerCommonApi | |
| implements SetupServer | |
| { | |
| constructor(handlers: Array<RequestHandler | WebSocketHandler>) { | |
| super( | |
| [ClientRequestInterceptor, XMLHttpRequestInterceptor, FetchInterceptor], | |
| handlers, | |
| ) | |
| this.handlersController = new AsyncHandlersController(handlers) | |
| } | |
| public boundary<Args extends Array<any>, R>( | |
| callback: (...args: Args) => R, | |
| ): (...args: Args) => R { | |
| return (...args: Args): R => { | |
| return store.run<any, any>( | |
| { | |
| initialHandlers: this.handlersController.currentHandlers(), | |
| handlers: [], | |
| }, | |
| callback, | |
| ...args, | |
| ) | |
| } | |
| } | |
| public close(): void { | |
| super.close() | |
| store.disable() | |
| } | |
| } | |