perf: 优化监听进程

This commit is contained in:
2026-02-04 02:36:12 +08:00
parent 08696dedd8
commit 15db8515d6
8 changed files with 67 additions and 52 deletions

View File

@@ -14,5 +14,5 @@ export { CustomError } from './result/error.ts';
export * from './router-define.ts';
export { MockProcess } from './utils/listen-process.ts'
export { MockProcess, type ListenProcessParams, type ListenProcessResponse } from './utils/listen-process.ts'
// --- 以上同步更新至 browser.ts ---

View File

@@ -14,7 +14,7 @@ export { CustomError } from './result/error.ts';
export * from './router-define.ts';
export { MockProcess } from './utils/listen-process.ts'
export { MockProcess, type ListenProcessParams, type ListenProcessResponse } from './utils/listen-process.ts'
// --- 以上同步更新至 browser.ts ---
export { ServerNode, handleServer } from './server/index.ts';

View File

@@ -61,7 +61,7 @@ export type RouteContext<T = { code?: number }, S = any> = {
} & T;
export type SimpleObject = Record<string, any>;
export type Run<T extends SimpleObject = {}> = (ctx: Required<RouteContext<T>>) => Promise<typeof ctx | null | void>;
export type RunMessage = { path?: string; key?: string; id?: string; payload?: any; };
export type NextRoute = Pick<Route, 'id' | 'path' | 'key'>;
export type RouteMiddleware =
| {
@@ -262,17 +262,17 @@ export const toJSONSchema = (route: RouteInfo) => {
return pickValues;
}
export const fromJSONSchema = (route: RouteInfo): {
[key: string]: z.ZodTypeAny
} => {
const args = route?.metadata?.args || {};
export const fromJSONSchema = (route: RouteInfo): RouteInfo => {
const args = route?.metadata?.args;
if (!args) return route;
const keys = Object.keys(args);
const newArgs: { [key: string]: any } = {};
for (let key of keys) {
const item = args[key];
newArgs[key] = z.fromJSONSchema(item);
}
return newArgs;
route.metadata.args = newArgs;
return route;
}
/**
@@ -680,7 +680,7 @@ export class QueryRouter {
* -- .on
* -- .send
*/
wait(params?: { path?: string; key?: string; payload?: any }, opts?: {
wait(params?: { message: RunMessage }, opts?: {
mockProcess?: MockProcess,
timeout?: number,
getList?: boolean
@@ -693,8 +693,8 @@ export class QueryRouter {
}
return listenProcess({ app: this as any, params, ...opts });
}
static toJSONSchema = toJSONSchema;
static fromJSONSchema = fromJSONSchema;
toJSONSchema = toJSONSchema;
fromJSONSchema = fromJSONSchema;
}
type QueryRouterServerOpts = {

View File

@@ -1,25 +1,7 @@
import { fork } from 'child_process'
export type RunCodeParams = {
path?: string;
key?: string;
payload?: string;
[key: string]: any
}
type RunCode = {
// 调用进程的功能
success?: boolean
data?: {
// 调用router的结果
code?: number
data?: any
message?: string
[key: string]: any
};
error?: any
timestamp?: string
[key: string]: any
}
import { ListenProcessParams, ListenProcessResponse } from '@/utils/listen-process.ts';
export type RunCodeParams = ListenProcessParams
export type RunCode = ListenProcessResponse
export const runCode = async (tsPath: string, params: RunCodeParams = {}): Promise<RunCode> => {
return new Promise((resolve, reject) => {
// 使用 Bun 的 fork 模式启动子进程
@@ -52,8 +34,11 @@ import path from 'node:path'
const res = await runCode(path.join(process.cwd(), './src/test/mini.ts'), {
// path: 'main'
// id: 'abc'
path: 'router',
key: 'list'
message: {
path: 'router',
key: 'list'
}
})
console.log('res', res.data.data.list)
console.log('success', res)
console.log('res', res.data?.data?.list)

View File

@@ -1,7 +1,6 @@
import { App } from "../app.ts";
const app = new App({
io: true
});
app

View File

@@ -1,5 +1,6 @@
import { EventEmitter } from "eventemitter3";
import { QueryRouterServer } from "../route.ts"
import { QueryRouterServer, RouterContextT, RunMessage } from "../route.ts"
import { merge } from 'es-toolkit'
export class MockProcess {
emitter?: EventEmitter
process?: NodeJS.Process;
@@ -37,13 +38,31 @@ export class MockProcess {
this.process = undefined;
}
}
export type ListenProcessParams = {
message?: RunMessage,
context?: any
}
export type ListenProcessResponse = {
// 调用进程的功能
success?: boolean
data?: {
// 调用router的结果
code?: number
data?: any
message?: string
[key: string]: any
};
error?: any
timestamp?: string
[key: string]: any
}
export type ListenProcessOptions = {
app?: QueryRouterServer; // 传入的应用实例
mockProcess?: MockProcess; // 可选的事件发射器
params?: any; // 可选的参数
params?: ListenProcessParams; // 可选的参数
timeout?: number; // 可选的超时时间 (单位: 毫秒) 默认 10 分钟
};
export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60 * 1000 }: ListenProcessOptions) => {
export const listenProcess = async ({ app, mockProcess, params = {}, timeout = 10 * 60 * 60 * 1000 }: ListenProcessOptions) => {
const process = mockProcess || new MockProcess();
let isEnd = false;
const timer = setTimeout(() => {
@@ -57,11 +76,11 @@ export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 6
// 监听来自主进程的消息
const getParams = async (): Promise<any> => {
return new Promise((resolve) => {
process.on((msg) => {
process.on((params) => {
if (isEnd) return;
isEnd = true;
clearTimeout(timer);
resolve(msg)
resolve(params || {})
})
})
}
@@ -70,11 +89,11 @@ export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 6
/**
* 如果不提供path默认是main
*/
const {
payload = {},
...rest
} = await getParams()
const msg = { ...params, ...rest, payload: { ...params?.payload, ...payload } }
const _params = await getParams()
const mergeParams = merge(params, _params)
const msg = mergeParams?.message || {};
const ctx: RouterContextT = mergeParams?.context || {}
/**
* 如果没有提供path和id默认取第一个路由, 而且路由path不是router的
*/
@@ -83,7 +102,7 @@ export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 6
msg.id = route?.id
}
// 执行主要逻辑
const result = await app.run(msg)
const result = await app.run(msg, ctx);
// 发送结果回主进程
const response = {
success: true,
@@ -95,6 +114,7 @@ export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 6
process.exit?.(0)
})
} catch (error) {
console.error('Error in listenProcess:', error);
process.send?.({
success: false,
error: error.message