diff --git a/package.json b/package.json index 2d7a8d6..4b914a8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package", "name": "@kevisual/router", - "version": "0.0.28", + "version": "0.0.29", "description": "", "type": "module", "main": "./dist/router.js", @@ -24,7 +24,7 @@ "@kevisual/local-proxy": "^0.0.6", "@kevisual/query": "^0.0.29", "@rollup/plugin-alias": "^5.1.1", - "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-commonjs": "28.0.6", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-typescript": "^12.1.4", "@types/lodash-es": "^4.17.12", diff --git a/src/route.ts b/src/route.ts index 007a656..5ff284b 100644 --- a/src/route.ts +++ b/src/route.ts @@ -3,8 +3,9 @@ import { CustomError } from './result/error.ts'; import { Schema, Rule, createSchema } from './validator/index.ts'; import { pick } from './utils/pick.ts'; import { get } from 'lodash-es'; +import { listenProcess } from './utils/listen-process.ts'; -export type RouterContextT = { code?: number; [key: string]: any }; +export type RouterContextT = { code?: number;[key: string]: any }; export type RouteContext = { // run first query?: { [key: string]: any }; @@ -47,7 +48,7 @@ export type RouteContext = { error?: any; /** 请求 route的返回结果,包函ctx */ call?: ( - message: { path: string; key?: string; payload?: any; [key: string]: any } | { id: string; apyload?: any; [key: string]: any }, + message: { path: string; key?: string; payload?: any;[key: string]: any } | { id: string; apyload?: any;[key: string]: any }, ctx?: RouteContext & { [key: string]: any }, ) => Promise; /** 请求 route的返回结果,不包函ctx */ @@ -63,10 +64,10 @@ export type Run = (ctx: RouteContext) => Promise export type NextRoute = Pick; export type RouteMiddleware = | { - path: string; - key?: string; - id?: string; - } + path: string; + key?: string; + id?: string; + } | string; export type RouteOpts = { path?: string; @@ -303,7 +304,7 @@ export class Route { } return this; } - addTo(router: QueryRouter | { add: (route: Route) => void; [key: string]: any }) { + addTo(router: QueryRouter | { add: (route: Route) => void;[key: string]: any }) { router.add(this); } setData(data: any) { @@ -608,7 +609,7 @@ export class QueryRouter { * @description 这里的上下文是为了在handle函数中使用 * @param ctx */ - setContext(ctx: RouteContext) { + setContext(ctx: RouteContext) { this.context = ctx; } getList(): RouteInfo[] { @@ -620,7 +621,7 @@ export class QueryRouter { * 获取handle函数, 这里会去执行parse函数 */ getHandle(router: QueryRouter, wrapperFn?: HandleFn, ctx?: RouteContext) { - return async (msg: { path: string; key?: string; [key: string]: any }, handleContext?: RouteContext) => { + return async (msg: { path: string; key?: string;[key: string]: any }, handleContext?: RouteContext) => { try { const context = { ...ctx, ...handleContext }; const res = await router.parse(msg, context); @@ -655,6 +656,17 @@ export class QueryRouter { hasRoute(path: string, key: string = '') { return this.routes.find((r) => r.path === path && r.key === key); } + /** + * 等待程序运行, 获取到message的数据,就执行 + * + * emitter = process + * -- .exit + * -- .on + * -- .send + */ + wait(params?: { path?: string; key?: string; payload?: any }, opts?: { emitter?: any, timeout?: number }) { + return listenProcess({ app: this, params, ...opts }); + } } type QueryRouterServerOpts = { @@ -662,7 +674,7 @@ type QueryRouterServerOpts = { context?: RouteContext; }; interface HandleFn { - (msg: { path: string; [key: string]: any }, ctx?: any): { code: string; data?: any; message?: string; [key: string]: any }; + (msg: { path: string;[key: string]: any }, ctx?: any): { code: string; data?: any; message?: string;[key: string]: any }; (res: RouteContext): any; } /** diff --git a/src/utils/listen-process.ts b/src/utils/listen-process.ts new file mode 100644 index 0000000..b08d568 --- /dev/null +++ b/src/utils/listen-process.ts @@ -0,0 +1,50 @@ +export type ListenProcessOptions = { + app?: any; // 传入的应用实例 + emitter?: any; // 可选的事件发射器 + params?: any; // 可选的参数 + timeout?: number; // 可选的超时时间 (单位: 毫秒) +}; +export const listenProcess = async ({ app, emitter, params, timeout = 10 * 60 * 60 * 1000 }: ListenProcessOptions) => { + const process = emitter || globalThis.process; + let isEnd = false; + const timer = setTimeout(() => { + if (isEnd) return; + isEnd = true; + process.send?.({ success: false, error: 'Timeout' }); + process.exit?.(1); + }, timeout); + + // 监听来自主进程的消息 + const getParams = async (): Promise => { + return new Promise((resolve) => { + process.on('message', (msg) => { + if (isEnd) return; + isEnd = true; + clearTimeout(timer); + resolve(msg) + }) + }) + } + + try { + const { path = 'main', ...rest } = await getParams() + // 执行主要逻辑 + const result = await app.queryRoute({ path, ...rest, ...params }) + // 发送结果回主进程 + const response = { + success: true, + data: result, + timestamp: new Date().toISOString() + } + + process.send?.(response, (error) => { + process.exit?.(0) + }) + } catch (error) { + process.send?.({ + success: false, + error: error.message + }) + process.exit?.(1) + } +} \ No newline at end of file