From 911f03b4bd14489571c29c4aaf6cb2b5e9d8afb6 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Sun, 25 Jan 2026 22:12:04 +0800 Subject: [PATCH] fix mini modules --- package.json | 2 +- src/browser.ts | 2 ++ src/index.ts | 2 ++ src/route.ts | 2 +- src/test/mini.ts | 14 ++++++++ src/test/run-mini.ts | 56 ++++++++++++++++++++++++++++++ src/utils/listen-process.ts | 69 +++++++++++++++++++++++++++++++------ 7 files changed, 134 insertions(+), 13 deletions(-) create mode 100644 src/test/mini.ts create mode 100644 src/test/run-mini.ts diff --git a/package.json b/package.json index 805250e..d86ca20 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package", "name": "@kevisual/router", - "version": "0.0.60", + "version": "0.0.61", "description": "", "type": "module", "main": "./dist/router.js", diff --git a/src/browser.ts b/src/browser.ts index 87a35cc..585b809 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -13,4 +13,6 @@ export { createSkill, tool } from './route.ts'; export { CustomError } from './result/error.ts'; export * from './router-define.ts'; + +export { MockProcess } from './utils/listen-process.ts' // --- 以上同步更新至 browser.ts --- \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index a3708d7..7fe8590 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,6 +13,8 @@ export { createSkill, tool } from './route.ts'; export { CustomError } from './result/error.ts'; export * from './router-define.ts'; + +export { MockProcess } from './utils/listen-process.ts' // --- 以上同步更新至 browser.ts --- export { ServerNode, handleServer } from './server/index.ts'; diff --git a/src/route.ts b/src/route.ts index bb7a9cd..51abbb5 100644 --- a/src/route.ts +++ b/src/route.ts @@ -632,7 +632,7 @@ export class QueryRouter { if (getList) { this.createRouteList(opts?.force ?? false, opts?.filter); } - return listenProcess({ app: this, params, ...opts }); + return listenProcess({ app: this as any, params, ...opts }); } } diff --git a/src/test/mini.ts b/src/test/mini.ts new file mode 100644 index 0000000..2ff1515 --- /dev/null +++ b/src/test/mini.ts @@ -0,0 +1,14 @@ +import { Mini } from "../route.ts"; + +const app = new Mini(); + +app.route({ + path: 'main' +}).define(async (ctx) => { + ctx.body = { + a: '123' + } +}).addTo(app) + + +app.wait() \ No newline at end of file diff --git a/src/test/run-mini.ts b/src/test/run-mini.ts new file mode 100644 index 0000000..a7c9196 --- /dev/null +++ b/src/test/run-mini.ts @@ -0,0 +1,56 @@ +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 +} +export const runCode = async (tsPath: string, params: RunCodeParams = {}): Promise => { + return new Promise((resolve, reject) => { + // 使用 Bun 的 fork 模式启动子进程 + const child = fork(tsPath) + + // 监听来自子进程的消息 + child.on('message', (msg: RunCode) => { + resolve(msg) + }) + + // child.on('exit', (code, signal) => { + // console.log('子进程已退出,退出码:', code, '信号:', signal) + // }) + + // child.on('close', (code, signal) => { + // console.log('子进程已关闭,退出码:', code, '信号:', signal) + // }) + + child.on('error', (error) => { + resolve({ + success: false, error: error?.message + }) + }) + + // 向子进程发送消息 + child.send(params) + }); +} +import path from 'node:path' +const res =await runCode(path.join(process.cwd(), './src/test/mini.ts'), { + // path: 'main' +}) + +console.log('res', res) \ No newline at end of file diff --git a/src/utils/listen-process.ts b/src/utils/listen-process.ts index 9963852..e3b52ad 100644 --- a/src/utils/listen-process.ts +++ b/src/utils/listen-process.ts @@ -1,23 +1,63 @@ +import { EventEmitter } from "eventemitter3"; +import { QueryRouterServer } from "../route.ts" +export class MockProcess { + emitter?: EventEmitter + process?: NodeJS.Process; + constructor(opts?: { emitter?: EventEmitter, isNode?: boolean }) { + this.emitter = opts?.emitter || new EventEmitter(); + const isNode = opts?.isNode ?? true; + if (isNode) { + this.process = globalThis?.process; + } + } + send(data?: any, callback?: (err?: Error) => void) { + if (this.process) { + this.process?.send?.(data, (err?: Error) => { + callback(err) + }) + } + this.emitter.emit('send', data) + } + exit(flag: number = 0) { + if (this.process) { + this.process?.exit?.(flag) + } + this.emitter.emit('exit', flag) + } + on(fn: (msg?: any) => any) { + if (this.process) { + this.process.on('message', fn) + } + this.emitter.on('message', fn) + } + desctroy() { + if (this.emitter) { + this.emitter = undefined; + } + this.process = undefined; + } +} export type ListenProcessOptions = { - app?: any; // 传入的应用实例 - emitter?: any; // 可选的事件发射器 + app?: QueryRouterServer; // 传入的应用实例 + mockProcess?: MockProcess; // 可选的事件发射器 params?: any; // 可选的参数 timeout?: number; // 可选的超时时间 (单位: 毫秒) 默认 10 分钟 }; -export const listenProcess = async ({ app, emitter, params, timeout = 10 * 60 * 60 * 1000 }: ListenProcessOptions) => { - const process = emitter || globalThis.process; +export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60 * 1000 }: ListenProcessOptions) => { + const process = mockProcess || new MockProcess(); let isEnd = false; const timer = setTimeout(() => { if (isEnd) return; isEnd = true; - process.send?.({ success: false, error: 'Timeout' }); - process.exit?.(1); + process.send?.({ success: false, error: 'Timeout' }, () => { + process.exit?.(1); + }); }, timeout); // 监听来自主进程的消息 const getParams = async (): Promise => { return new Promise((resolve) => { - process.on('message', (msg) => { + process.on((msg) => { if (isEnd) return; isEnd = true; clearTimeout(timer); @@ -27,10 +67,16 @@ export const listenProcess = async ({ app, emitter, params, timeout = 10 * 60 * } try { - const { path = 'main', payload = {}, ...rest + /** + * 如果不提供path,默认是main + */ + const { + path = 'main', + payload = {}, + ...rest } = await getParams() // 执行主要逻辑 - const result = await app.queryRoute({ path, ...params, ...rest, payload: { ...params.payload, ...payload } }) + const result = await app.run({ path, ...params, ...rest, payload: { ...params?.payload, ...payload } }) // 发送结果回主进程 const response = { success: true, @@ -38,14 +84,15 @@ export const listenProcess = async ({ app, emitter, params, timeout = 10 * 60 * timestamp: new Date().toISOString() } - process.send?.(response, (error) => { + process.send?.(response, () => { process.exit?.(0) }) } catch (error) { process.send?.({ success: false, error: error.message + }, () => { + process.exit?.(1) }) - process.exit?.(1) } } \ No newline at end of file