Compare commits
5 Commits
2483205a22
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 87068cd626 | |||
| ac32ff9d4a | |||
| cc74dc6803 | |||
| 24166f9899 | |||
| 10506503eb |
28
demo/simple/src/nopath.ts
Normal file
28
demo/simple/src/nopath.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { Route, App } from '@kevisual/router/src/index.ts';
|
||||||
|
|
||||||
|
|
||||||
|
const app = new App();
|
||||||
|
|
||||||
|
app.route({
|
||||||
|
description: 'sdf'
|
||||||
|
}).define(async (ctx) => {
|
||||||
|
ctx.body = 'this is no path fns';
|
||||||
|
return ctx;
|
||||||
|
}).addTo(app);
|
||||||
|
|
||||||
|
|
||||||
|
let id = ''
|
||||||
|
console.log('routes', app.router.routes.map(item => {
|
||||||
|
id = item.id;
|
||||||
|
return {
|
||||||
|
path: item.path,
|
||||||
|
key: item.key,
|
||||||
|
id: item.id,
|
||||||
|
description: item.description
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
app.call({id: id}).then(res => {
|
||||||
|
console.log('id', id);
|
||||||
|
console.log('res', res);
|
||||||
|
})
|
||||||
10
package.json
10
package.json
@@ -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.31",
|
||||||
"description": "",
|
"description": "",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/router.js",
|
"main": "./dist/router.js",
|
||||||
@@ -24,18 +24,18 @@
|
|||||||
"@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.8",
|
||||||
"@rollup/plugin-node-resolve": "^16.0.3",
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||||
"@rollup/plugin-typescript": "^12.1.4",
|
"@rollup/plugin-typescript": "^12.3.0",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^24.7.2",
|
"@types/node": "^24.9.1",
|
||||||
"@types/send": "^1.2.0",
|
"@types/send": "^1.2.0",
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
"@types/xml2js": "^0.4.14",
|
"@types/xml2js": "^0.4.14",
|
||||||
"cookie": "^1.0.2",
|
"cookie": "^1.0.2",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"nanoid": "^5.1.6",
|
"nanoid": "^5.1.6",
|
||||||
"rollup": "^4.52.4",
|
"rollup": "^4.52.5",
|
||||||
"rollup-plugin-dts": "^6.2.3",
|
"rollup-plugin-dts": "^6.2.3",
|
||||||
"ts-loader": "^9.5.4",
|
"ts-loader": "^9.5.4",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
|
|||||||
17
src/app.ts
17
src/app.ts
@@ -5,7 +5,7 @@ import { CustomError } from './result/error.ts';
|
|||||||
import { handleServer } from './server/handle-server.ts';
|
import { handleServer } from './server/handle-server.ts';
|
||||||
import { IncomingMessage, ServerResponse } from 'http';
|
import { IncomingMessage, ServerResponse } from 'http';
|
||||||
|
|
||||||
type RouterHandle = (msg: { path: string; [key: string]: any }) => { code: string; data?: any; message?: string; [key: string]: any };
|
type RouterHandle = (msg: { path: string;[key: string]: any }) => { code: string; data?: any; message?: string;[key: string]: any };
|
||||||
type AppOptions<T = {}> = {
|
type AppOptions<T = {}> = {
|
||||||
router?: QueryRouter;
|
router?: QueryRouter;
|
||||||
server?: Server;
|
server?: Server;
|
||||||
@@ -82,7 +82,20 @@ export class App<T = {}, U = AppReqRes> {
|
|||||||
}
|
}
|
||||||
return new Route(path, key, opts);
|
return new Route(path, key, opts);
|
||||||
}
|
}
|
||||||
async call(message: { path: string; key?: string; payload?: any }, ctx?: RouteContext & { [key: string]: any }) {
|
prompt(description: string): Route<Required<RouteContext>>;
|
||||||
|
prompt(description: Function): Route<Required<RouteContext>>;
|
||||||
|
prompt(...args: any[]) {
|
||||||
|
const [desc] = args;
|
||||||
|
let description = ''
|
||||||
|
if (typeof desc === 'string') {
|
||||||
|
description = desc;
|
||||||
|
} else if (typeof desc === 'function') {
|
||||||
|
description = desc() || ''; // 如果是Promise,需要addTo App之前就要获取应有的函数了。
|
||||||
|
}
|
||||||
|
return new Route('', '', { description });
|
||||||
|
}
|
||||||
|
|
||||||
|
async call(message: { id?: string, path?: string; key?: string; payload?: any }, ctx?: RouteContext & { [key: string]: any }) {
|
||||||
const router = this.router;
|
const router = this.router;
|
||||||
return await router.call(message, ctx);
|
return await router.call(message, ctx);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export { Route, QueryRouter, QueryRouterServer } from './route.ts';
|
export { Route, QueryRouter, QueryRouterServer, Mini } from './route.ts';
|
||||||
|
|
||||||
export type { Rule, Schema } from './validator/index.ts';
|
export type { Rule, Schema } from './validator/index.ts';
|
||||||
|
|
||||||
|
|||||||
40
src/chat.ts
Normal file
40
src/chat.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { QueryRouter } from "./route.ts";
|
||||||
|
|
||||||
|
type RouterChatOptions = {
|
||||||
|
router?: QueryRouter;
|
||||||
|
}
|
||||||
|
export class RouterChat {
|
||||||
|
router: QueryRouter;
|
||||||
|
prompt: string = '';
|
||||||
|
constructor(opts?: RouterChatOptions) {
|
||||||
|
this.router = opts?.router || new QueryRouter();
|
||||||
|
}
|
||||||
|
prefix(wrapperFn?: (routes: any[]) => string) {
|
||||||
|
if (this.prompt) {
|
||||||
|
return this.prompt;
|
||||||
|
}
|
||||||
|
let _prompt = `你是一个调用函数工具的助手,当用户询问时,如果拥有工具,请返回 JSON 数据,数据的值的内容是 id 和 payload 。如果有参数,请放到 payload 当中。
|
||||||
|
|
||||||
|
下面是你可以使用的工具列表:
|
||||||
|
|
||||||
|
`;
|
||||||
|
if (!wrapperFn) {
|
||||||
|
_prompt += this.router.routes.map(r => `工具名称: ${r.id}\n描述: ${r.description}\n`).join('\n');
|
||||||
|
} else {
|
||||||
|
_prompt += wrapperFn(this.router.exportRoutes());
|
||||||
|
}
|
||||||
|
_prompt += `当你需要使用工具时,请严格按照以下格式返回:
|
||||||
|
{
|
||||||
|
"id": "工具名称",
|
||||||
|
"payload": {
|
||||||
|
// 参数列表
|
||||||
|
}
|
||||||
|
}
|
||||||
|
如果你不需要使用工具,直接返回用户想要的内容即可,不要返回任何多余的信息。`;
|
||||||
|
return _prompt;
|
||||||
|
}
|
||||||
|
chat() {
|
||||||
|
const prompt = this.prefix();
|
||||||
|
return prompt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
export { Route, QueryRouter, QueryRouterServer } from './route.ts';
|
export { Route, QueryRouter, QueryRouterServer, Mini } from './route.ts';
|
||||||
export { Connect, QueryConnect } from './connect.ts';
|
export { Connect, QueryConnect } from './connect.ts';
|
||||||
|
|
||||||
export type { RouteContext, RouteOpts, RouteMiddleware } from './route.ts';
|
export type { RouteContext, RouteOpts, RouteMiddleware } from './route.ts';
|
||||||
@@ -11,7 +11,9 @@ export { Server, handleServer } from './server/index.ts';
|
|||||||
*/
|
*/
|
||||||
export { CustomError } from './result/error.ts';
|
export { CustomError } from './result/error.ts';
|
||||||
|
|
||||||
export { Rule, Schema, createSchema } from './validator/index.ts';
|
export { createSchema } from './validator/index.ts';
|
||||||
|
|
||||||
|
export type { Rule, Schema, } from './validator/index.ts';
|
||||||
|
|
||||||
export { App } from './app.ts';
|
export { App } from './app.ts';
|
||||||
|
|
||||||
|
|||||||
107
src/route.ts
107
src/route.ts
@@ -1,10 +1,11 @@
|
|||||||
import { nanoid } from 'nanoid';
|
import { nanoid, random } from 'nanoid';
|
||||||
import { CustomError } from './result/error.ts';
|
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;
|
||||||
@@ -87,7 +88,7 @@ export type RouteOpts = {
|
|||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
validator?: { [key: string]: Rule };
|
validator?: { [key: string]: Rule };
|
||||||
schema?: { [key: string]: Schema<any> };
|
schema?: { [key: string]: any };
|
||||||
isVerify?: boolean;
|
isVerify?: boolean;
|
||||||
verify?: (ctx?: RouteContext, dev?: boolean) => boolean;
|
verify?: (ctx?: RouteContext, dev?: boolean) => boolean;
|
||||||
verifyKey?: (key: string, ctx?: RouteContext, dev?: boolean) => boolean;
|
verifyKey?: (key: string, ctx?: RouteContext, dev?: boolean) => boolean;
|
||||||
@@ -102,7 +103,7 @@ export type RouteOpts = {
|
|||||||
isDebug?: boolean;
|
isDebug?: boolean;
|
||||||
};
|
};
|
||||||
export type DefineRouteOpts = Omit<RouteOpts, 'idUsePath' | 'verify' | 'verifyKey' | 'nextRoute'>;
|
export type DefineRouteOpts = Omit<RouteOpts, 'idUsePath' | 'verify' | 'verifyKey' | 'nextRoute'>;
|
||||||
const pickValue = ['path', 'key', 'id', 'description', 'type', 'validator', 'middleware'] as const;
|
const pickValue = ['path', 'key', 'id', 'description', 'type', 'validator', 'middleware', 'metadata'] as const;
|
||||||
export type RouteInfo = Pick<Route, (typeof pickValue)[number]>;
|
export type RouteInfo = Pick<Route, (typeof pickValue)[number]>;
|
||||||
export class Route<U = { [key: string]: any }> {
|
export class Route<U = { [key: string]: any }> {
|
||||||
/**
|
/**
|
||||||
@@ -122,7 +123,7 @@ export class Route<U = { [key: string]: any }> {
|
|||||||
middleware?: RouteMiddleware[]; // middleware
|
middleware?: RouteMiddleware[]; // middleware
|
||||||
type? = 'route';
|
type? = 'route';
|
||||||
private _validator?: { [key: string]: Rule };
|
private _validator?: { [key: string]: Rule };
|
||||||
schema?: { [key: string]: Schema<any> };
|
schema?: { [key: string]: any };
|
||||||
data?: any;
|
data?: any;
|
||||||
/**
|
/**
|
||||||
* 是否需要验证
|
* 是否需要验证
|
||||||
@@ -132,7 +133,10 @@ export class Route<U = { [key: string]: any }> {
|
|||||||
* 是否开启debug,开启后会打印错误信息
|
* 是否开启debug,开启后会打印错误信息
|
||||||
*/
|
*/
|
||||||
isDebug?: boolean;
|
isDebug?: boolean;
|
||||||
constructor(path: string, key: string = '', opts?: RouteOpts) {
|
constructor(path: string = '', key: string = '', opts?: RouteOpts) {
|
||||||
|
if (!path) {
|
||||||
|
path = nanoid(8)
|
||||||
|
}
|
||||||
path = path.trim();
|
path = path.trim();
|
||||||
key = key.trim();
|
key = key.trim();
|
||||||
this.path = path;
|
this.path = path;
|
||||||
@@ -260,6 +264,17 @@ export class Route<U = { [key: string]: any }> {
|
|||||||
this.validator = validator;
|
this.validator = validator;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
prompt(description: string): this;
|
||||||
|
prompt(description: Function): this;
|
||||||
|
prompt(...args: any[]) {
|
||||||
|
const [description] = args;
|
||||||
|
if (typeof description === 'string') {
|
||||||
|
this.description = description;
|
||||||
|
} else if (typeof description === 'function') {
|
||||||
|
this.description = description() || ''; // 如果是Promise,需要addTo App之前就要获取应有的函数了。
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
define<T extends { [key: string]: any } = RouterContextT>(opts: DefineRouteOpts): this;
|
define<T extends { [key: string]: any } = RouterContextT>(opts: DefineRouteOpts): this;
|
||||||
define<T extends { [key: string]: any } = RouterContextT>(fn: Run<T & U>): this;
|
define<T extends { [key: string]: any } = RouterContextT>(fn: Run<T & U>): this;
|
||||||
define<T extends { [key: string]: any } = RouterContextT>(key: string, fn: Run<T & U>): this;
|
define<T extends { [key: string]: any } = RouterContextT>(key: string, fn: Run<T & U>): this;
|
||||||
@@ -303,7 +318,28 @@ export class Route<U = { [key: string]: any }> {
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
addTo(router: QueryRouter | { add: (route: Route) => void; [key: string]: any }) {
|
|
||||||
|
update(opts: DefineRouteOpts, checkList?: string[]): this {
|
||||||
|
const keys = Object.keys(opts);
|
||||||
|
const defaultCheckList = ['path', 'key', 'run', 'nextRoute', 'description', 'metadata', 'middleware', 'type', 'validator', 'isVerify', 'isDebug'];
|
||||||
|
checkList = checkList || defaultCheckList;
|
||||||
|
for (let item of keys) {
|
||||||
|
if (!checkList.includes(item)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (item === 'validator') {
|
||||||
|
this.validator = opts[item];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (item === 'middleware') {
|
||||||
|
this.middleware = this.middleware.concat(opts[item]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this[item] = opts[item];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
addTo(router: QueryRouter | { add: (route: Route) => void;[key: string]: any }) {
|
||||||
router.add(this);
|
router.add(this);
|
||||||
}
|
}
|
||||||
setData(data: any) {
|
setData(data: any) {
|
||||||
@@ -582,8 +618,9 @@ export class QueryRouter {
|
|||||||
} else {
|
} else {
|
||||||
return { code: 404, body: null, message: 'Not found route' };
|
return { code: 404, body: null, message: 'Not found route' };
|
||||||
}
|
}
|
||||||
|
return await this.parse({ ...message, path, key }, { ...this.context, ...ctx });
|
||||||
} else if (path) {
|
} else if (path) {
|
||||||
return await this.parse({ ...message, path }, { ...this.context, ...ctx });
|
return await this.parse({ ...message, path, key }, { ...this.context, ...ctx });
|
||||||
} else {
|
} else {
|
||||||
return { code: 404, body: null, message: 'Not found path' };
|
return { code: 404, body: null, message: 'Not found path' };
|
||||||
}
|
}
|
||||||
@@ -595,7 +632,7 @@ export class QueryRouter {
|
|||||||
* @param ctx
|
* @param ctx
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async queryRoute(message: { path: string; key?: string; payload?: any }, ctx?: RouteContext & { [key: string]: any }) {
|
async queryRoute(message: { id?: string; path: string; key?: string; payload?: any }, ctx?: RouteContext & { [key: string]: any }) {
|
||||||
const res = await this.parse(message, { ...this.context, ...ctx });
|
const res = await this.parse(message, { ...this.context, ...ctx });
|
||||||
return {
|
return {
|
||||||
code: res.code,
|
code: res.code,
|
||||||
@@ -608,7 +645,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,9 +657,19 @@ 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: { id?: string; path?: string; key?: string;[key: string]: any }, handleContext?: RouteContext) => {
|
||||||
try {
|
try {
|
||||||
const context = { ...ctx, ...handleContext };
|
const context = { ...ctx, ...handleContext };
|
||||||
|
if (msg.id) {
|
||||||
|
const route = router.routes.find((r) => r.id === msg.id);
|
||||||
|
if (route) {
|
||||||
|
msg.path = route.path;
|
||||||
|
msg.key = route.key;
|
||||||
|
} else {
|
||||||
|
return { code: 404, message: 'Not found route' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
const res = await router.parse(msg, context);
|
const res = await router.parse(msg, context);
|
||||||
if (wrapperFn) {
|
if (wrapperFn) {
|
||||||
res.data = res.body;
|
res.data = res.body;
|
||||||
@@ -655,6 +702,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 +720,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;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -709,6 +767,18 @@ export class QueryRouterServer extends QueryRouter {
|
|||||||
}
|
}
|
||||||
return new Route(path, key, opts);
|
return new Route(path, key, opts);
|
||||||
}
|
}
|
||||||
|
prompt(description: string): Route<Required<RouteContext>>;
|
||||||
|
prompt(description: Function): Route<Required<RouteContext>>;
|
||||||
|
prompt(...args: any[]) {
|
||||||
|
const [desc] = args;
|
||||||
|
let description = ''
|
||||||
|
if (typeof desc === 'string') {
|
||||||
|
description = desc;
|
||||||
|
} else if (typeof desc === 'function') {
|
||||||
|
description = desc() || ''; // 如果是Promise,需要addTo App之前就要获取应有的函数了。
|
||||||
|
}
|
||||||
|
return new Route('', '', { description });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 等于queryRoute,但是调用了handle
|
* 等于queryRoute,但是调用了handle
|
||||||
@@ -739,3 +809,6 @@ export class QueryRouterServer extends QueryRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const Mini = QueryRouterServer
|
||||||
17
src/test/chat.ts
Normal file
17
src/test/chat.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { App } from '../app.ts'
|
||||||
|
import { RouterChat } from '@/chat.ts';
|
||||||
|
|
||||||
|
const app = new App();
|
||||||
|
|
||||||
|
app.prompt(`获取时间的工具`).define(async (ctx) => {
|
||||||
|
ctx.body = '123'
|
||||||
|
}).addTo(app);
|
||||||
|
|
||||||
|
app.prompt('获取天气的工具。\n参数是 city 为对应的城市').define(async (ctx) => {
|
||||||
|
ctx.body = '晴天'
|
||||||
|
}).addTo(app);
|
||||||
|
|
||||||
|
|
||||||
|
export const chat = new RouterChat({ router: app.router });
|
||||||
|
|
||||||
|
console.log(chat.chat());
|
||||||
50
src/utils/listen-process.ts
Normal file
50
src/utils/listen-process.ts
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user