@kevisual/router 0.0.69 → 0.0.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,4 @@
1
1
  import { EventEmitter } from 'eventemitter3';
2
- import { z } from 'zod';
3
2
  import * as http from 'node:http';
4
3
  import { IncomingMessage, ServerResponse } from 'node:http';
5
4
  import { IncomingMessage as IncomingMessage$1, ServerResponse as ServerResponse$1 } from 'http';
@@ -95,6 +94,12 @@ type RouteContext<T = {
95
94
  } & T;
96
95
  type SimpleObject = Record<string, any>;
97
96
  type Run<T extends SimpleObject = {}> = (ctx: Required<RouteContext<T>>) => Promise<typeof ctx | null | void>;
97
+ type RunMessage = {
98
+ path?: string;
99
+ key?: string;
100
+ id?: string;
101
+ payload?: any;
102
+ };
98
103
  type NextRoute = Pick<Route, 'id' | 'path' | 'key'>;
99
104
  type RouteMiddleware = {
100
105
  path: string;
@@ -328,9 +333,7 @@ declare class QueryRouter {
328
333
  * -- .send
329
334
  */
330
335
  wait(params?: {
331
- path?: string;
332
- key?: string;
333
- payload?: any;
336
+ message: RunMessage;
334
337
  }, opts?: {
335
338
  mockProcess?: MockProcess;
336
339
  timeout?: number;
@@ -338,10 +341,8 @@ declare class QueryRouter {
338
341
  force?: boolean;
339
342
  filter?: (route: Route) => boolean;
340
343
  }): Promise<void>;
341
- static toJSONSchema: (route: RouteInfo) => Pick<RouteInfo, "path" | "key" | "id" | "description" | "type" | "middleware" | "metadata">;
342
- static fromJSONSchema: (route: RouteInfo) => {
343
- [key: string]: z.ZodTypeAny;
344
- };
344
+ toJSONSchema: (route: RouteInfo) => Pick<RouteInfo, "path" | "key" | "id" | "description" | "type" | "middleware" | "metadata">;
345
+ fromJSONSchema: (route: RouteInfo) => RouteInfo;
345
346
  }
346
347
  type QueryRouterServerOpts = {
347
348
  handleFn?: HandleFn;
@@ -15,6 +15,22 @@ declare class MockProcess {
15
15
  on(fn: (msg?: any) => any): void;
16
16
  desctroy(): void;
17
17
  }
18
+ type ListenProcessParams = {
19
+ message?: RunMessage;
20
+ context?: any;
21
+ };
22
+ type ListenProcessResponse = {
23
+ success?: boolean;
24
+ data?: {
25
+ code?: number;
26
+ data?: any;
27
+ message?: string;
28
+ [key: string]: any;
29
+ };
30
+ error?: any;
31
+ timestamp?: string;
32
+ [key: string]: any;
33
+ };
18
34
 
19
35
  type RouterContextT = {
20
36
  code?: number;
@@ -93,6 +109,12 @@ type RouteContext<T = {
93
109
  } & T;
94
110
  type SimpleObject$1 = Record<string, any>;
95
111
  type Run<T extends SimpleObject$1 = {}> = (ctx: Required<RouteContext<T>>) => Promise<typeof ctx | null | void>;
112
+ type RunMessage = {
113
+ path?: string;
114
+ key?: string;
115
+ id?: string;
116
+ payload?: any;
117
+ };
96
118
  type NextRoute = Pick<Route, 'id' | 'path' | 'key'>;
97
119
  type RouteMiddleware = {
98
120
  path: string;
@@ -182,9 +204,7 @@ declare class Route<U = {
182
204
  throw(code?: number | string, message?: string, tips?: string): void;
183
205
  }
184
206
  declare const toJSONSchema: (route: RouteInfo) => Pick<RouteInfo, "path" | "key" | "id" | "description" | "type" | "middleware" | "metadata">;
185
- declare const fromJSONSchema: (route: RouteInfo) => {
186
- [key: string]: z.ZodTypeAny;
187
- };
207
+ declare const fromJSONSchema: (route: RouteInfo) => RouteInfo;
188
208
  /**
189
209
  * @parmas overwrite 是否覆盖已存在的route,默认true
190
210
  */
@@ -343,9 +363,7 @@ declare class QueryRouter {
343
363
  * -- .send
344
364
  */
345
365
  wait(params?: {
346
- path?: string;
347
- key?: string;
348
- payload?: any;
366
+ message: RunMessage;
349
367
  }, opts?: {
350
368
  mockProcess?: MockProcess;
351
369
  timeout?: number;
@@ -353,10 +371,8 @@ declare class QueryRouter {
353
371
  force?: boolean;
354
372
  filter?: (route: Route) => boolean;
355
373
  }): Promise<void>;
356
- static toJSONSchema: (route: RouteInfo) => Pick<RouteInfo, "path" | "key" | "id" | "description" | "type" | "middleware" | "metadata">;
357
- static fromJSONSchema: (route: RouteInfo) => {
358
- [key: string]: z.ZodTypeAny;
359
- };
374
+ toJSONSchema: (route: RouteInfo) => Pick<RouteInfo, "path" | "key" | "id" | "description" | "type" | "middleware" | "metadata">;
375
+ fromJSONSchema: (route: RouteInfo) => RouteInfo;
360
376
  }
361
377
  type QueryRouterServerOpts = {
362
378
  handleFn?: HandleFn;
@@ -546,4 +562,4 @@ declare class QueryUtil<T extends RouteObject = RouteObject> {
546
562
  declare const App: typeof QueryRouterServer;
547
563
 
548
564
  export { App, CustomError, Mini, MockProcess, QueryRouter, QueryRouterServer, QueryUtil, Route, createSchema, createSkill, define, fromJSONSchema, toJSONSchema, tool, util };
549
- export type { RouteArray, RouteContext, RouteMiddleware, RouteObject, RouteOpts, Rule, Run, Schema, Skill };
565
+ export type { ListenProcessParams, ListenProcessResponse, RouteArray, RouteContext, RouteMiddleware, RouteObject, RouteOpts, Rule, Run, Schema, Skill };
@@ -453,6 +453,52 @@ function requireEventemitter3 () {
453
453
  var eventemitter3Exports = requireEventemitter3();
454
454
  var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
455
455
 
456
+ function isPlainObject$1(value) {
457
+ if (!value || typeof value !== 'object') {
458
+ return false;
459
+ }
460
+ const proto = Object.getPrototypeOf(value);
461
+ const hasObjectPrototype = proto === null ||
462
+ proto === Object.prototype ||
463
+ Object.getPrototypeOf(proto) === null;
464
+ if (!hasObjectPrototype) {
465
+ return false;
466
+ }
467
+ return Object.prototype.toString.call(value) === '[object Object]';
468
+ }
469
+
470
+ function isUnsafeProperty(key) {
471
+ return key === '__proto__';
472
+ }
473
+
474
+ function merge$1(target, source) {
475
+ const sourceKeys = Object.keys(source);
476
+ for (let i = 0; i < sourceKeys.length; i++) {
477
+ const key = sourceKeys[i];
478
+ if (isUnsafeProperty(key)) {
479
+ continue;
480
+ }
481
+ const sourceValue = source[key];
482
+ const targetValue = target[key];
483
+ if (isMergeableValue(sourceValue) && isMergeableValue(targetValue)) {
484
+ target[key] = merge$1(targetValue, sourceValue);
485
+ }
486
+ else if (Array.isArray(sourceValue)) {
487
+ target[key] = merge$1([], sourceValue);
488
+ }
489
+ else if (isPlainObject$1(sourceValue)) {
490
+ target[key] = merge$1({}, sourceValue);
491
+ }
492
+ else if (targetValue === undefined || sourceValue !== undefined) {
493
+ target[key] = sourceValue;
494
+ }
495
+ }
496
+ return target;
497
+ }
498
+ function isMergeableValue(value) {
499
+ return isPlainObject$1(value) || Array.isArray(value);
500
+ }
501
+
456
502
  class MockProcess {
457
503
  emitter;
458
504
  process;
@@ -490,7 +536,7 @@ class MockProcess {
490
536
  this.process = undefined;
491
537
  }
492
538
  }
493
- const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60 * 1000 }) => {
539
+ const listenProcess = async ({ app, mockProcess, params = {}, timeout = 10 * 60 * 60 * 1000 }) => {
494
540
  const process = mockProcess || new MockProcess();
495
541
  let isEnd = false;
496
542
  const timer = setTimeout(() => {
@@ -504,12 +550,12 @@ const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60
504
550
  // 监听来自主进程的消息
505
551
  const getParams = async () => {
506
552
  return new Promise((resolve) => {
507
- process.on((msg) => {
553
+ process.on((params) => {
508
554
  if (isEnd)
509
555
  return;
510
556
  isEnd = true;
511
557
  clearTimeout(timer);
512
- resolve(msg);
558
+ resolve(params || {});
513
559
  });
514
560
  });
515
561
  };
@@ -517,8 +563,10 @@ const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60
517
563
  /**
518
564
  * 如果不提供path,默认是main
519
565
  */
520
- const { payload = {}, ...rest } = await getParams();
521
- const msg = { ...params, ...rest, payload: { ...params?.payload, ...payload } };
566
+ const _params = await getParams();
567
+ const mergeParams = merge$1(params, _params);
568
+ const msg = mergeParams?.message || {};
569
+ const ctx = mergeParams?.context || {};
522
570
  /**
523
571
  * 如果没有提供path和id,默认取第一个路由, 而且路由path不是router的
524
572
  */
@@ -527,7 +575,7 @@ const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60
527
575
  msg.id = route?.id;
528
576
  }
529
577
  // 执行主要逻辑
530
- const result = await app.run(msg);
578
+ const result = await app.run(msg, ctx);
531
579
  // 发送结果回主进程
532
580
  const response = {
533
581
  success: true,
@@ -539,6 +587,7 @@ const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60
539
587
  });
540
588
  }
541
589
  catch (error) {
590
+ console.error('Error in listenProcess:', error);
542
591
  process.send?.({
543
592
  success: false,
544
593
  error: error.message
@@ -15064,14 +15113,17 @@ const toJSONSchema = (route) => {
15064
15113
  return pickValues;
15065
15114
  };
15066
15115
  const fromJSONSchema = (route) => {
15067
- const args = route?.metadata?.args || {};
15116
+ const args = route?.metadata?.args;
15117
+ if (!args)
15118
+ return route;
15068
15119
  const keys = Object.keys(args);
15069
15120
  const newArgs = {};
15070
15121
  for (let key of keys) {
15071
15122
  const item = args[key];
15072
15123
  newArgs[key] = fromJSONSchema$1(item);
15073
15124
  }
15074
- return newArgs;
15125
+ route.metadata.args = newArgs;
15126
+ return route;
15075
15127
  };
15076
15128
  class QueryRouter {
15077
15129
  appId = '';
@@ -15494,8 +15546,8 @@ class QueryRouter {
15494
15546
  }
15495
15547
  return listenProcess({ app: this, params, ...opts });
15496
15548
  }
15497
- static toJSONSchema = toJSONSchema;
15498
- static fromJSONSchema = fromJSONSchema;
15549
+ toJSONSchema = toJSONSchema;
15550
+ fromJSONSchema = fromJSONSchema;
15499
15551
  }
15500
15552
  /**
15501
15553
  * QueryRouterServer
package/dist/router.d.ts CHANGED
@@ -21,6 +21,22 @@ declare class MockProcess {
21
21
  on(fn: (msg?: any) => any): void;
22
22
  desctroy(): void;
23
23
  }
24
+ type ListenProcessParams = {
25
+ message?: RunMessage;
26
+ context?: any;
27
+ };
28
+ type ListenProcessResponse = {
29
+ success?: boolean;
30
+ data?: {
31
+ code?: number;
32
+ data?: any;
33
+ message?: string;
34
+ [key: string]: any;
35
+ };
36
+ error?: any;
37
+ timestamp?: string;
38
+ [key: string]: any;
39
+ };
24
40
 
25
41
  type RouterContextT = {
26
42
  code?: number;
@@ -99,6 +115,12 @@ type RouteContext<T = {
99
115
  } & T;
100
116
  type SimpleObject$1 = Record<string, any>;
101
117
  type Run<T extends SimpleObject$1 = {}> = (ctx: Required<RouteContext<T>>) => Promise<typeof ctx | null | void>;
118
+ type RunMessage = {
119
+ path?: string;
120
+ key?: string;
121
+ id?: string;
122
+ payload?: any;
123
+ };
102
124
  type NextRoute = Pick<Route, 'id' | 'path' | 'key'>;
103
125
  type RouteMiddleware = {
104
126
  path: string;
@@ -188,9 +210,7 @@ declare class Route<U = {
188
210
  throw(code?: number | string, message?: string, tips?: string): void;
189
211
  }
190
212
  declare const toJSONSchema: (route: RouteInfo) => Pick<RouteInfo, "path" | "key" | "id" | "description" | "type" | "middleware" | "metadata">;
191
- declare const fromJSONSchema: (route: RouteInfo) => {
192
- [key: string]: z.ZodTypeAny;
193
- };
213
+ declare const fromJSONSchema: (route: RouteInfo) => RouteInfo;
194
214
  /**
195
215
  * @parmas overwrite 是否覆盖已存在的route,默认true
196
216
  */
@@ -349,9 +369,7 @@ declare class QueryRouter {
349
369
  * -- .send
350
370
  */
351
371
  wait(params?: {
352
- path?: string;
353
- key?: string;
354
- payload?: any;
372
+ message: RunMessage;
355
373
  }, opts?: {
356
374
  mockProcess?: MockProcess;
357
375
  timeout?: number;
@@ -359,10 +377,8 @@ declare class QueryRouter {
359
377
  force?: boolean;
360
378
  filter?: (route: Route) => boolean;
361
379
  }): Promise<void>;
362
- static toJSONSchema: (route: RouteInfo) => Pick<RouteInfo, "path" | "key" | "id" | "description" | "type" | "middleware" | "metadata">;
363
- static fromJSONSchema: (route: RouteInfo) => {
364
- [key: string]: z.ZodTypeAny;
365
- };
380
+ toJSONSchema: (route: RouteInfo) => Pick<RouteInfo, "path" | "key" | "id" | "description" | "type" | "middleware" | "metadata">;
381
+ fromJSONSchema: (route: RouteInfo) => RouteInfo;
366
382
  }
367
383
  type QueryRouterServerOpts = {
368
384
  handleFn?: HandleFn;
@@ -959,4 +975,4 @@ declare class App<U = {}> extends QueryRouter {
959
975
  }
960
976
 
961
977
  export { App, CustomError, Mini, MockProcess, QueryRouter, QueryRouterServer, QueryUtil, Route, ServerNode, createSchema, createSkill, define, fromJSONSchema, handleServer, toJSONSchema, tool, util };
962
- export type { HttpListenerFun, Listener, OnListener, OnWebSocketFn, RouteArray, RouteContext, RouteMiddleware, RouteObject, RouteOpts, RouterReq, RouterRes, Rule, Run, Schema, Skill, WS, WebSocketListenerFun, WebSocketReq, WebSocketRes };
978
+ export type { HttpListenerFun, ListenProcessParams, ListenProcessResponse, Listener, OnListener, OnWebSocketFn, RouteArray, RouteContext, RouteMiddleware, RouteObject, RouteOpts, RouterReq, RouterRes, Rule, Run, Schema, Skill, WS, WebSocketListenerFun, WebSocketReq, WebSocketRes };
package/dist/router.js CHANGED
@@ -477,6 +477,52 @@ function requireEventemitter3 () {
477
477
  var eventemitter3Exports = requireEventemitter3();
478
478
  var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
479
479
 
480
+ function isPlainObject$1(value) {
481
+ if (!value || typeof value !== 'object') {
482
+ return false;
483
+ }
484
+ const proto = Object.getPrototypeOf(value);
485
+ const hasObjectPrototype = proto === null ||
486
+ proto === Object.prototype ||
487
+ Object.getPrototypeOf(proto) === null;
488
+ if (!hasObjectPrototype) {
489
+ return false;
490
+ }
491
+ return Object.prototype.toString.call(value) === '[object Object]';
492
+ }
493
+
494
+ function isUnsafeProperty(key) {
495
+ return key === '__proto__';
496
+ }
497
+
498
+ function merge$1(target, source) {
499
+ const sourceKeys = Object.keys(source);
500
+ for (let i = 0; i < sourceKeys.length; i++) {
501
+ const key = sourceKeys[i];
502
+ if (isUnsafeProperty(key)) {
503
+ continue;
504
+ }
505
+ const sourceValue = source[key];
506
+ const targetValue = target[key];
507
+ if (isMergeableValue(sourceValue) && isMergeableValue(targetValue)) {
508
+ target[key] = merge$1(targetValue, sourceValue);
509
+ }
510
+ else if (Array.isArray(sourceValue)) {
511
+ target[key] = merge$1([], sourceValue);
512
+ }
513
+ else if (isPlainObject$1(sourceValue)) {
514
+ target[key] = merge$1({}, sourceValue);
515
+ }
516
+ else if (targetValue === undefined || sourceValue !== undefined) {
517
+ target[key] = sourceValue;
518
+ }
519
+ }
520
+ return target;
521
+ }
522
+ function isMergeableValue(value) {
523
+ return isPlainObject$1(value) || Array.isArray(value);
524
+ }
525
+
480
526
  class MockProcess {
481
527
  emitter;
482
528
  process;
@@ -514,7 +560,7 @@ class MockProcess {
514
560
  this.process = undefined;
515
561
  }
516
562
  }
517
- const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60 * 1000 }) => {
563
+ const listenProcess = async ({ app, mockProcess, params = {}, timeout = 10 * 60 * 60 * 1000 }) => {
518
564
  const process = mockProcess || new MockProcess();
519
565
  let isEnd = false;
520
566
  const timer = setTimeout(() => {
@@ -528,12 +574,12 @@ const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60
528
574
  // 监听来自主进程的消息
529
575
  const getParams = async () => {
530
576
  return new Promise((resolve) => {
531
- process.on((msg) => {
577
+ process.on((params) => {
532
578
  if (isEnd)
533
579
  return;
534
580
  isEnd = true;
535
581
  clearTimeout(timer);
536
- resolve(msg);
582
+ resolve(params || {});
537
583
  });
538
584
  });
539
585
  };
@@ -541,8 +587,10 @@ const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60
541
587
  /**
542
588
  * 如果不提供path,默认是main
543
589
  */
544
- const { payload = {}, ...rest } = await getParams();
545
- const msg = { ...params, ...rest, payload: { ...params?.payload, ...payload } };
590
+ const _params = await getParams();
591
+ const mergeParams = merge$1(params, _params);
592
+ const msg = mergeParams?.message || {};
593
+ const ctx = mergeParams?.context || {};
546
594
  /**
547
595
  * 如果没有提供path和id,默认取第一个路由, 而且路由path不是router的
548
596
  */
@@ -551,7 +599,7 @@ const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60
551
599
  msg.id = route?.id;
552
600
  }
553
601
  // 执行主要逻辑
554
- const result = await app.run(msg);
602
+ const result = await app.run(msg, ctx);
555
603
  // 发送结果回主进程
556
604
  const response = {
557
605
  success: true,
@@ -563,6 +611,7 @@ const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60
563
611
  });
564
612
  }
565
613
  catch (error) {
614
+ console.error('Error in listenProcess:', error);
566
615
  process.send?.({
567
616
  success: false,
568
617
  error: error.message
@@ -15088,14 +15137,17 @@ const toJSONSchema = (route) => {
15088
15137
  return pickValues;
15089
15138
  };
15090
15139
  const fromJSONSchema = (route) => {
15091
- const args = route?.metadata?.args || {};
15140
+ const args = route?.metadata?.args;
15141
+ if (!args)
15142
+ return route;
15092
15143
  const keys = Object.keys(args);
15093
15144
  const newArgs = {};
15094
15145
  for (let key of keys) {
15095
15146
  const item = args[key];
15096
15147
  newArgs[key] = fromJSONSchema$1(item);
15097
15148
  }
15098
- return newArgs;
15149
+ route.metadata.args = newArgs;
15150
+ return route;
15099
15151
  };
15100
15152
  class QueryRouter {
15101
15153
  appId = '';
@@ -15518,8 +15570,8 @@ class QueryRouter {
15518
15570
  }
15519
15571
  return listenProcess({ app: this, params, ...opts });
15520
15572
  }
15521
- static toJSONSchema = toJSONSchema;
15522
- static fromJSONSchema = fromJSONSchema;
15573
+ toJSONSchema = toJSONSchema;
15574
+ fromJSONSchema = fromJSONSchema;
15523
15575
  }
15524
15576
  /**
15525
15577
  * QueryRouterServer
package/dist/ws.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { EventEmitter } from 'eventemitter3';
2
- import { z } from 'zod';
3
2
  import * as http from 'node:http';
4
3
  import { IncomingMessage, ServerResponse } from 'node:http';
5
4
  import { IncomingMessage as IncomingMessage$1, ServerResponse as ServerResponse$1 } from 'http';
@@ -142,6 +141,12 @@ type RouteContext<T = {
142
141
  } & T;
143
142
  type SimpleObject = Record<string, any>;
144
143
  type Run<T extends SimpleObject = {}> = (ctx: Required<RouteContext<T>>) => Promise<typeof ctx | null | void>;
144
+ type RunMessage = {
145
+ path?: string;
146
+ key?: string;
147
+ id?: string;
148
+ payload?: any;
149
+ };
145
150
  type NextRoute = Pick<Route, 'id' | 'path' | 'key'>;
146
151
  type RouteMiddleware = {
147
152
  path: string;
@@ -375,9 +380,7 @@ declare class QueryRouter {
375
380
  * -- .send
376
381
  */
377
382
  wait(params?: {
378
- path?: string;
379
- key?: string;
380
- payload?: any;
383
+ message: RunMessage;
381
384
  }, opts?: {
382
385
  mockProcess?: MockProcess;
383
386
  timeout?: number;
@@ -385,10 +388,8 @@ declare class QueryRouter {
385
388
  force?: boolean;
386
389
  filter?: (route: Route) => boolean;
387
390
  }): Promise<void>;
388
- static toJSONSchema: (route: RouteInfo) => Pick<RouteInfo, "key" | "path" | "id" | "description" | "type" | "middleware" | "metadata">;
389
- static fromJSONSchema: (route: RouteInfo) => {
390
- [key: string]: z.ZodTypeAny;
391
- };
391
+ toJSONSchema: (route: RouteInfo) => Pick<RouteInfo, "path" | "key" | "id" | "description" | "type" | "middleware" | "metadata">;
392
+ fromJSONSchema: (route: RouteInfo) => RouteInfo;
392
393
  }
393
394
  interface HandleFn<T = any> {
394
395
  (msg: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@kevisual/router",
4
- "version": "0.0.69",
4
+ "version": "0.0.70",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "main": "./dist/router.js",
@@ -29,7 +29,7 @@
29
29
  "@kevisual/local-proxy": "^0.0.8",
30
30
  "@kevisual/query": "^0.0.39",
31
31
  "@kevisual/use-config": "^1.0.30",
32
- "@opencode-ai/plugin": "^1.1.48",
32
+ "@opencode-ai/plugin": "^1.1.49",
33
33
  "@rollup/plugin-alias": "^6.0.0",
34
34
  "@rollup/plugin-commonjs": "29.0.0",
35
35
  "@rollup/plugin-node-resolve": "^16.0.3",
@@ -41,6 +41,7 @@
41
41
  "@types/xml2js": "^0.4.14",
42
42
  "eventemitter3": "^5.0.4",
43
43
  "fast-glob": "^3.3.3",
44
+ "hono": "^4.11.7",
44
45
  "nanoid": "^5.1.6",
45
46
  "path-to-regexp": "^8.3.0",
46
47
  "rollup": "^4.57.1",
@@ -53,14 +54,15 @@
53
54
  "typescript": "^5.9.3",
54
55
  "ws": "npm:@kevisual/ws",
55
56
  "xml2js": "^0.6.2",
56
- "zod": "^4.3.6",
57
- "hono": "^4.11.7"
57
+ "zod": "^4.3.6"
58
58
  },
59
59
  "repository": {
60
60
  "type": "git",
61
61
  "url": "git+https://github.com/abearxiong/kevisual-router.git"
62
62
  },
63
- "dependencies": {},
63
+ "dependencies": {
64
+ "es-toolkit": "^1.44.0"
65
+ },
64
66
  "publishConfig": {
65
67
  "access": "public"
66
68
  },
package/src/browser.ts CHANGED
@@ -14,5 +14,5 @@ export { CustomError } from './result/error.ts';
14
14
 
15
15
  export * from './router-define.ts';
16
16
 
17
- export { MockProcess } from './utils/listen-process.ts'
17
+ export { MockProcess, type ListenProcessParams, type ListenProcessResponse } from './utils/listen-process.ts'
18
18
  // --- 以上同步更新至 browser.ts ---
package/src/index.ts CHANGED
@@ -14,7 +14,7 @@ export { CustomError } from './result/error.ts';
14
14
 
15
15
  export * from './router-define.ts';
16
16
 
17
- export { MockProcess } from './utils/listen-process.ts'
17
+ export { MockProcess, type ListenProcessParams, type ListenProcessResponse } from './utils/listen-process.ts'
18
18
  // --- 以上同步更新至 browser.ts ---
19
19
 
20
20
  export { ServerNode, handleServer } from './server/index.ts';
package/src/route.ts CHANGED
@@ -61,7 +61,7 @@ export type RouteContext<T = { code?: number }, S = any> = {
61
61
  } & T;
62
62
  export type SimpleObject = Record<string, any>;
63
63
  export type Run<T extends SimpleObject = {}> = (ctx: Required<RouteContext<T>>) => Promise<typeof ctx | null | void>;
64
-
64
+ export type RunMessage = { path?: string; key?: string; id?: string; payload?: any; };
65
65
  export type NextRoute = Pick<Route, 'id' | 'path' | 'key'>;
66
66
  export type RouteMiddleware =
67
67
  | {
@@ -262,17 +262,17 @@ export const toJSONSchema = (route: RouteInfo) => {
262
262
  return pickValues;
263
263
  }
264
264
 
265
- export const fromJSONSchema = (route: RouteInfo): {
266
- [key: string]: z.ZodTypeAny
267
- } => {
268
- const args = route?.metadata?.args || {};
265
+ export const fromJSONSchema = (route: RouteInfo): RouteInfo => {
266
+ const args = route?.metadata?.args;
267
+ if (!args) return route;
269
268
  const keys = Object.keys(args);
270
269
  const newArgs: { [key: string]: any } = {};
271
270
  for (let key of keys) {
272
271
  const item = args[key];
273
272
  newArgs[key] = z.fromJSONSchema(item);
274
273
  }
275
- return newArgs;
274
+ route.metadata.args = newArgs;
275
+ return route;
276
276
  }
277
277
 
278
278
  /**
@@ -680,7 +680,7 @@ export class QueryRouter {
680
680
  * -- .on
681
681
  * -- .send
682
682
  */
683
- wait(params?: { path?: string; key?: string; payload?: any }, opts?: {
683
+ wait(params?: { message: RunMessage }, opts?: {
684
684
  mockProcess?: MockProcess,
685
685
  timeout?: number,
686
686
  getList?: boolean
@@ -693,8 +693,8 @@ export class QueryRouter {
693
693
  }
694
694
  return listenProcess({ app: this as any, params, ...opts });
695
695
  }
696
- static toJSONSchema = toJSONSchema;
697
- static fromJSONSchema = fromJSONSchema;
696
+ toJSONSchema = toJSONSchema;
697
+ fromJSONSchema = fromJSONSchema;
698
698
  }
699
699
 
700
700
  type QueryRouterServerOpts = {
@@ -1,25 +1,7 @@
1
1
  import { fork } from 'child_process'
2
-
3
- export type RunCodeParams = {
4
- path?: string;
5
- key?: string;
6
- payload?: string;
7
- [key: string]: any
8
- }
9
- type RunCode = {
10
- // 调用进程的功能
11
- success?: boolean
12
- data?: {
13
- // 调用router的结果
14
- code?: number
15
- data?: any
16
- message?: string
17
- [key: string]: any
18
- };
19
- error?: any
20
- timestamp?: string
21
- [key: string]: any
22
- }
2
+ import { ListenProcessParams, ListenProcessResponse } from '@/utils/listen-process.ts';
3
+ export type RunCodeParams = ListenProcessParams
4
+ export type RunCode = ListenProcessResponse
23
5
  export const runCode = async (tsPath: string, params: RunCodeParams = {}): Promise<RunCode> => {
24
6
  return new Promise((resolve, reject) => {
25
7
  // 使用 Bun 的 fork 模式启动子进程
@@ -52,8 +34,11 @@ import path from 'node:path'
52
34
  const res = await runCode(path.join(process.cwd(), './src/test/mini.ts'), {
53
35
  // path: 'main'
54
36
  // id: 'abc'
55
- path: 'router',
56
- key: 'list'
37
+ message: {
38
+ path: 'router',
39
+ key: 'list'
40
+ }
57
41
  })
58
42
 
59
- console.log('res', res.data.data.list)
43
+ console.log('success', res)
44
+ console.log('res', res.data?.data?.list)
package/src/test/ws.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { App } from "../app.ts";
2
2
 
3
3
  const app = new App({
4
- io: true
5
4
  });
6
5
 
7
6
  app
@@ -1,5 +1,6 @@
1
1
  import { EventEmitter } from "eventemitter3";
2
- import { QueryRouterServer } from "../route.ts"
2
+ import { QueryRouterServer, RouterContextT, RunMessage } from "../route.ts"
3
+ import { merge } from 'es-toolkit'
3
4
  export class MockProcess {
4
5
  emitter?: EventEmitter
5
6
  process?: NodeJS.Process;
@@ -37,13 +38,31 @@ export class MockProcess {
37
38
  this.process = undefined;
38
39
  }
39
40
  }
41
+ export type ListenProcessParams = {
42
+ message?: RunMessage,
43
+ context?: any
44
+ }
45
+ export type ListenProcessResponse = {
46
+ // 调用进程的功能
47
+ success?: boolean
48
+ data?: {
49
+ // 调用router的结果
50
+ code?: number
51
+ data?: any
52
+ message?: string
53
+ [key: string]: any
54
+ };
55
+ error?: any
56
+ timestamp?: string
57
+ [key: string]: any
58
+ }
40
59
  export type ListenProcessOptions = {
41
60
  app?: QueryRouterServer; // 传入的应用实例
42
61
  mockProcess?: MockProcess; // 可选的事件发射器
43
- params?: any; // 可选的参数
62
+ params?: ListenProcessParams; // 可选的参数
44
63
  timeout?: number; // 可选的超时时间 (单位: 毫秒) 默认 10 分钟
45
64
  };
46
- export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60 * 1000 }: ListenProcessOptions) => {
65
+ export const listenProcess = async ({ app, mockProcess, params = {}, timeout = 10 * 60 * 60 * 1000 }: ListenProcessOptions) => {
47
66
  const process = mockProcess || new MockProcess();
48
67
  let isEnd = false;
49
68
  const timer = setTimeout(() => {
@@ -57,11 +76,11 @@ export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 6
57
76
  // 监听来自主进程的消息
58
77
  const getParams = async (): Promise<any> => {
59
78
  return new Promise((resolve) => {
60
- process.on((msg) => {
79
+ process.on((params) => {
61
80
  if (isEnd) return;
62
81
  isEnd = true;
63
82
  clearTimeout(timer);
64
- resolve(msg)
83
+ resolve(params || {})
65
84
  })
66
85
  })
67
86
  }
@@ -70,11 +89,11 @@ export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 6
70
89
  /**
71
90
  * 如果不提供path,默认是main
72
91
  */
73
- const {
74
- payload = {},
75
- ...rest
76
- } = await getParams()
77
- const msg = { ...params, ...rest, payload: { ...params?.payload, ...payload } }
92
+ const _params = await getParams()
93
+ const mergeParams = merge(params, _params)
94
+
95
+ const msg = mergeParams?.message || {};
96
+ const ctx: RouterContextT = mergeParams?.context || {}
78
97
  /**
79
98
  * 如果没有提供path和id,默认取第一个路由, 而且路由path不是router的
80
99
  */
@@ -83,7 +102,7 @@ export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 6
83
102
  msg.id = route?.id
84
103
  }
85
104
  // 执行主要逻辑
86
- const result = await app.run(msg)
105
+ const result = await app.run(msg, ctx);
87
106
  // 发送结果回主进程
88
107
  const response = {
89
108
  success: true,
@@ -95,6 +114,7 @@ export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 6
95
114
  process.exit?.(0)
96
115
  })
97
116
  } catch (error) {
117
+ console.error('Error in listenProcess:', error);
98
118
  process.send?.({
99
119
  success: false,
100
120
  error: error.message