update: add listen process

This commit is contained in:
2025-10-15 20:48:20 +08:00
parent 2483205a22
commit 10506503eb
3 changed files with 74 additions and 12 deletions

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://json.schemastore.org/package", "$schema": "https://json.schemastore.org/package",
"name": "@kevisual/router", "name": "@kevisual/router",
"version": "0.0.28", "version": "0.0.29",
"description": "", "description": "",
"type": "module", "type": "module",
"main": "./dist/router.js", "main": "./dist/router.js",
@@ -24,7 +24,7 @@
"@kevisual/local-proxy": "^0.0.6", "@kevisual/local-proxy": "^0.0.6",
"@kevisual/query": "^0.0.29", "@kevisual/query": "^0.0.29",
"@rollup/plugin-alias": "^5.1.1", "@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-node-resolve": "^16.0.3",
"@rollup/plugin-typescript": "^12.1.4", "@rollup/plugin-typescript": "^12.1.4",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",

View File

@@ -3,8 +3,9 @@ import { CustomError } from './result/error.ts';
import { Schema, Rule, createSchema } from './validator/index.ts'; import { Schema, Rule, createSchema } from './validator/index.ts';
import { pick } from './utils/pick.ts'; import { pick } from './utils/pick.ts';
import { get } from 'lodash-es'; 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<T = { code?: number }, S = any> = { export type RouteContext<T = { code?: number }, S = any> = {
// run first // run first
query?: { [key: string]: any }; query?: { [key: string]: any };
@@ -47,7 +48,7 @@ export type RouteContext<T = { code?: number }, S = any> = {
error?: any; error?: any;
/** 请求 route的返回结果包函ctx */ /** 请求 route的返回结果包函ctx */
call?: ( 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 }, ctx?: RouteContext & { [key: string]: any },
) => Promise<any>; ) => Promise<any>;
/** 请求 route的返回结果不包函ctx */ /** 请求 route的返回结果不包函ctx */
@@ -63,10 +64,10 @@ export type Run<T extends SimpleObject = {}> = (ctx: RouteContext<T>) => Promise
export type NextRoute = Pick<Route, 'id' | 'path' | 'key'>; export type NextRoute = Pick<Route, 'id' | 'path' | 'key'>;
export type RouteMiddleware = export type RouteMiddleware =
| { | {
path: string; path: string;
key?: string; key?: string;
id?: string; id?: string;
} }
| string; | string;
export type RouteOpts = { export type RouteOpts = {
path?: string; path?: string;
@@ -303,7 +304,7 @@ export class Route<U = { [key: string]: any }> {
} }
return this; 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); router.add(this);
} }
setData(data: any) { setData(data: any) {
@@ -608,7 +609,7 @@ export class QueryRouter {
* @description 这里的上下文是为了在handle函数中使用 * @description 这里的上下文是为了在handle函数中使用
* @param ctx * @param ctx
*/ */
setContext(ctx: RouteContext) { setContext(ctx: RouteContext) {
this.context = ctx; this.context = ctx;
} }
getList(): RouteInfo[] { getList(): RouteInfo[] {
@@ -620,7 +621,7 @@ export class QueryRouter {
* 获取handle函数, 这里会去执行parse函数 * 获取handle函数, 这里会去执行parse函数
*/ */
getHandle<T = any>(router: QueryRouter, wrapperFn?: HandleFn<T>, ctx?: RouteContext) { getHandle<T = any>(router: QueryRouter, wrapperFn?: HandleFn<T>, 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 { try {
const context = { ...ctx, ...handleContext }; const context = { ...ctx, ...handleContext };
const res = await router.parse(msg, context); const res = await router.parse(msg, context);
@@ -655,6 +656,17 @@ export class QueryRouter {
hasRoute(path: string, key: string = '') { hasRoute(path: string, key: string = '') {
return this.routes.find((r) => r.path === path && r.key === key); 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 = { type QueryRouterServerOpts = {
@@ -662,7 +674,7 @@ type QueryRouterServerOpts = {
context?: RouteContext; context?: RouteContext;
}; };
interface HandleFn<T = any> { interface HandleFn<T = any> {
(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<T>): any; (res: RouteContext<T>): any;
} }
/** /**

View File

@@ -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<any> => {
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)
}
}