diff --git a/package.json b/package.json index 4114843..2501dda 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package", "name": "@kevisual/router", - "version": "0.0.69", + "version": "0.0.70", "description": "", "type": "module", "main": "./dist/router.js", @@ -29,7 +29,7 @@ "@kevisual/local-proxy": "^0.0.8", "@kevisual/query": "^0.0.39", "@kevisual/use-config": "^1.0.30", - "@opencode-ai/plugin": "^1.1.48", + "@opencode-ai/plugin": "^1.1.49", "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-commonjs": "29.0.0", "@rollup/plugin-node-resolve": "^16.0.3", @@ -41,6 +41,7 @@ "@types/xml2js": "^0.4.14", "eventemitter3": "^5.0.4", "fast-glob": "^3.3.3", + "hono": "^4.11.7", "nanoid": "^5.1.6", "path-to-regexp": "^8.3.0", "rollup": "^4.57.1", @@ -53,14 +54,15 @@ "typescript": "^5.9.3", "ws": "npm:@kevisual/ws", "xml2js": "^0.6.2", - "zod": "^4.3.6", - "hono": "^4.11.7" + "zod": "^4.3.6" }, "repository": { "type": "git", "url": "git+https://github.com/abearxiong/kevisual-router.git" }, - "dependencies": {}, + "dependencies": { + "es-toolkit": "^1.44.0" + }, "publishConfig": { "access": "public" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89e6abe..0cbea2b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,10 @@ settings: importers: .: + dependencies: + es-toolkit: + specifier: ^1.44.0 + version: 1.44.0 devDependencies: '@kevisual/context': specifier: ^0.0.4 @@ -775,6 +779,9 @@ packages: es-module-lexer@2.0.0: resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + es-toolkit@1.44.0: + resolution: {integrity: sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==} + esbuild@0.27.2: resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} engines: {node: '>=18'} @@ -1725,6 +1732,8 @@ snapshots: es-module-lexer@2.0.0: {} + es-toolkit@1.44.0: {} + esbuild@0.27.2: optionalDependencies: '@esbuild/aix-ppc64': 0.27.2 diff --git a/src/browser.ts b/src/browser.ts index cbbce03..3bdacb7 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -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 --- \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 830d0bc..faa2d6c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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'; diff --git a/src/route.ts b/src/route.ts index 6ca8db0..e86d68d 100644 --- a/src/route.ts +++ b/src/route.ts @@ -61,7 +61,7 @@ export type RouteContext = { } & T; export type SimpleObject = Record; export type Run = (ctx: Required>) => Promise; - +export type RunMessage = { path?: string; key?: string; id?: string; payload?: any; }; export type NextRoute = Pick; 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 = { diff --git a/src/test/run-mini.ts b/src/test/run-mini.ts index 68682a1..0f24625 100644 --- a/src/test/run-mini.ts +++ b/src/test/run-mini.ts @@ -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 => { 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) \ No newline at end of file +console.log('success', res) +console.log('res', res.data?.data?.list) \ No newline at end of file diff --git a/src/test/ws.ts b/src/test/ws.ts index 397da04..86ecfef 100644 --- a/src/test/ws.ts +++ b/src/test/ws.ts @@ -1,7 +1,6 @@ import { App } from "../app.ts"; const app = new App({ - io: true }); app diff --git a/src/utils/listen-process.ts b/src/utils/listen-process.ts index 038f217..df31a77 100644 --- a/src/utils/listen-process.ts +++ b/src/utils/listen-process.ts @@ -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 => { 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