Skip to content

Commit

Permalink
fix(wip): fix broken "use()" runtime handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito committed Feb 20, 2024
1 parent e89afa5 commit d23dd25
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 81 deletions.
9 changes: 2 additions & 7 deletions src/core/SetupApi.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { invariant } from 'outvariant'
import { EventMap, Emitter } from 'strict-event-emitter'
import {
RequestHandler,
RequestHandlerDefaultInfo,
} from './handlers/RequestHandler'
import { RequestHandler } from './handlers/RequestHandler'
import { LifeCycleEventEmitter } from './sharedOptions'
import { devUtils } from './utils/internal/devUtils'
import { pipeEvents } from './utils/internal/pipeEvents'
Expand Down Expand Up @@ -97,9 +94,7 @@ export abstract class SetupApi<EventsMap extends EventMap> extends Disposable {
this.handlersController.reset(nextHandlers)
}

public listHandlers(): ReadonlyArray<
RequestHandler<RequestHandlerDefaultInfo, any, any>
> {
public listHandlers(): ReadonlyArray<RequestHandler> {
return toReadonlyArray(this.handlersController.currentHandlers())
}

Expand Down
4 changes: 3 additions & 1 deletion src/core/handlers/RemoteRequestHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
serializeRequest,
deserializeResponse,
} from '../utils/request/serializeUtils'
import { passthrough } from '../passthrough'

export class RemoteRequestHandler extends HttpHandler {
constructor(args: { socket: Socket<SyncServerEventsMap> }) {
Expand All @@ -25,12 +26,13 @@ export class RemoteRequestHandler extends HttpHandler {
// aren't considered unhandled.
if (request.headers.get('x-msw-request-type') === 'internal-request') {
console.log('[msw] INTERNAL SOCKET REQUEST, IGNORE!')
return
return passthrough()
}

console.log('[msw] regular request, continue...')

console.log('[msw] emitting "request" ws event')

socket.emit('request', {
requestId,
serializedRequest: await serializeRequest(request),
Expand Down
80 changes: 34 additions & 46 deletions src/node/SetupServerApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ 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 { SetupServer } from './glossary'
import type { ListenOptions, SetupServer } from './glossary'
import { SetupServerCommonApi } from './SetupServerCommonApi'
import { Socket } from 'socket.io-client'
import { SyncServerEventsMap, createSyncClient } from './setupRemoteServer'
Expand Down Expand Up @@ -67,7 +67,6 @@ export class SetupServerApi
)

this.handlersController = new AsyncHandlersController(handlers)
this.initRemoteServer()
}

public boundary<Fn extends (...args: Array<any>) => unknown>(
Expand All @@ -90,59 +89,48 @@ export class SetupServerApi
store.disable()
}

private async initRemoteServer() {
const { remotePort } = this.resolvedOptions
public listen(options?: Partial<ListenOptions>): void {
super.listen(options)

if (remotePort == null) {
return
}
if (this.resolvedOptions.remotePort != null) {
this.mapRequestHandlers = async (handlers) => {
const { socket } = this

const { socket } = this
if (typeof socket === 'undefined') {
this.socket = await createSyncClient(this.resolvedOptions.remotePort)
}

if (typeof socket === 'undefined') {
this.socket = await createSyncClient(remotePort)
} else {
this.handlersController.currentHandlers = new Proxy(
this.handlersController.currentHandlers,
{
get: (target, property, value) => {
const handlers = Reflect.get(
target,
property,
value,
) as Array<RequestHandler>

return Array.prototype.concat(
new RemoteRequestHandler({
socket,
}),
handlers,
)
},
},
)
if (typeof socket !== 'undefined') {
return Array.prototype.concat(
new RemoteRequestHandler({ socket }),
handlers,
)
}

return handlers
}
}
this.forwardLifeCycleEvents()
}

private async forwardLifeCycleEvents() {
onAnyEvent(this.emitter, async (eventName, listenerArgs) => {
const { socket } = this
const { request } = listenerArgs

if (socket) {
const forwardLifeCycleEvent = async () => {
const args = await serializeEventPayload(listenerArgs)
socket.emit(
'lifeCycleEventForward',
/**
* @todo Annotating serialized/desirialized mirror channels is tough.
*/
eventName,
args as any,
)
}

if (request.headers.get('x-msw-request-type') !== 'internal-request') {
forwardLifeCycleEvent()
}
if (
socket &&
request.headers.get('x-msw-request-type') !== 'internal-request'
) {
const args = await serializeEventPayload(listenerArgs)
socket.emit(
'lifeCycleEventForward',
/**
* @todo Annotating serialized/desirialized mirror channels is tough.
*/
eventName,
args as any,
)
}
})
}
Expand Down
10 changes: 9 additions & 1 deletion src/node/SetupServerCommonApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ export class SetupServerCommonApi
this.init()
}

protected async mapRequestHandlers(
handlers: Array<RequestHandler>,
): Promise<Array<RequestHandler>> {
return handlers
}

/**
* Subscribe to all requests that are using the interceptor object
*/
Expand All @@ -56,7 +62,9 @@ export class SetupServerCommonApi
const response = await handleRequest(
request,
requestId,
this.handlersController.currentHandlers(),
await this.mapRequestHandlers(
this.handlersController.currentHandlers(),
),
this.resolvedOptions,
this.emitter,
)
Expand Down
36 changes: 11 additions & 25 deletions src/node/setupRemoteServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ import { Server as WebSocketServer } from 'socket.io'
import { Socket, io } from 'socket.io-client'
import { Emitter } from 'strict-event-emitter'
import { DeferredPromise } from '@open-draft/deferred-promise'
import {
LifeCycleEventsMap,
RequestHandler,
SetupApi,
handleRequest,
} from '~/core'
import { SetupApi } from '~/core/SetupApi'
import { RequestHandler } from '~/core/handlers/RequestHandler'
import { handleRequest } from '~/core/utils/handleRequest'
import {
SerializedRequest,
SerializedResponse,
deserializeRequest,
serializeResponse,
} from '~/core/utils/request/serializeUtils'
import { LifeCycleEventEmitter } from '~/core/sharedOptions'
import { LifeCycleEventEmitter, LifeCycleEventsMap } from '~/core/sharedOptions'
import { devUtils } from '~/core/utils/internal/devUtils'
import {
SerializedLifeCycleEventsMap,
Expand All @@ -28,7 +25,9 @@ const kSyncServer = Symbol('kSyncServer')
/**
* Enables API mocking in a remote Node.js process.
*/
export function setupRemoteServer(...handlers: Array<RequestHandler>) {
export function setupRemoteServer(
...handlers: Array<RequestHandler>
): SetupRemoteServerApi {
return new SetupRemoteServerApi(...handlers)
}

Expand Down Expand Up @@ -82,6 +81,8 @@ export class SetupRemoteServerApi
.on('SIGINT', () => closeSyncServer(server))

server.on('connection', (socket) => {
console.log('[remote] connection!')

socket.on('request', async ({ requestId, serializedRequest }) => {
const request = deserializeRequest(serializedRequest)
const response = await handleRequest(
Expand All @@ -108,23 +109,6 @@ export class SetupRemoteServerApi
})
}

public printHandlers() {
const handlers = this.listHandlers()

handlers.forEach((handler) => {
const { header, callFrame } = handler.info

const pragma = handler.info.hasOwnProperty('operationType')
? '[graphql]'
: '[rest]'

console.log(`\
${`${pragma} ${header}`}
Declaration: ${callFrame}
`)
})
}

public async close(): Promise<void> {
const { [kSyncServer]: syncServer } = globalThis

Expand Down Expand Up @@ -165,6 +149,8 @@ async function createSyncServer(
},
})

console.log('Creating a WS server...')

httpServer.listen(+url.port, url.hostname, () => {
globalThis[kSyncServer] = ws
serverReadyPromise.resolve(ws)
Expand Down
4 changes: 3 additions & 1 deletion test/node/msw-api/setup-remote-server/use.app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ const server = setupServer(
}),
)

server.listen()
server.listen({
remotePort: 56789,
})

// Spawn a Node.js application.
const app = express()
Expand Down

0 comments on commit d23dd25

Please sign in to comment.