import { observable } from '@trpc/server/observable'; import { z } from 'zod'; import type { CommonRouter } from '../trpc'; import { logger } from '../logger'; import { clearMappedFunctions } from '../fnMap'; import { clearMappedPromises } from '../promiseMap'; import type { InstanceManager } from '../instanceManager'; import { getClientFunctionCallEventSubject, clearClientFunctionCallEventSubjects, clientFunctionReturnEventSubject } from '../subjects'; import { router, publicProcedure } from '../utils'; /** * Create common router. * @param instanceManager * @returns Common router. */ export function createCommonRouter(instanceManager: InstanceManager) { return router({ /** * It is used for rpc client to subscribe to rpc server when websocket is connected. */ event: publicProcedure.subscription(({ ctx }) => { return observable((emit) => { const subject = getClientFunctionCallEventSubject(ctx.socketId); subject.subscribe({ next(value) { emit.next(value); } }); return () => { const { socketId } = ctx; if (!socketId) { return; } logger.debug(`common.event clear map: ${socketId}`); clearClientFunctionCallEventSubjects(socketId); instanceManager.clearAllInstances(socketId); clearMappedFunctions(socketId); clearMappedPromises(socketId); }; }); }), /** * It is used for rpc client to send the result of client function call back to the server. */ returnCallbackValue: publicProcedure.input(z.any()).mutation(({ input, ctx }) => { clientFunctionReturnEventSubject.next({ ...input, socketId: ctx.socketId }); }) }); }