@kevisual/router 0.0.45 → 0.0.47

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.
package/dist/router.d.ts CHANGED
@@ -4,7 +4,7 @@ import https from 'node:https';
4
4
  import http2 from 'node:http2';
5
5
  import EventEmitter from 'node:events';
6
6
  import { EventEmitter as EventEmitter$1 } from 'events';
7
- import { WebSocketServer, WebSocket } from 'ws';
7
+ import { WebSocketServer } from 'ws';
8
8
  import { z } from 'zod';
9
9
  import { IncomingMessage as IncomingMessage$1, ServerResponse as ServerResponse$1 } from 'http';
10
10
  import { RouteOpts as RouteOpts$1, QueryRouterServer as QueryRouterServer$1, RouteMiddleware as RouteMiddleware$1, Run as Run$1 } from '@kevisual/router';
@@ -411,7 +411,7 @@ interface ServerType {
411
411
  server?: any;
412
412
  handle: ServerOpts['handle'];
413
413
  setHandle(handle?: any): void;
414
- listeners: Listener$1[];
414
+ listeners: Listener[];
415
415
  listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
416
416
  listen(port: number, hostname?: string, listeningListener?: () => void): void;
417
417
  listen(port: number, backlog?: number, listeningListener?: () => void): void;
@@ -427,6 +427,7 @@ interface ServerType {
427
427
  */
428
428
  on(listener: OnListener): void;
429
429
  onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): void;
430
+ onWsClose(ws: WS): void;
430
431
  }
431
432
  type OnWebSocketOptions = {
432
433
  ws: WS;
@@ -439,14 +440,24 @@ type OnWebSocketFn = (options: OnWebSocketOptions) => Promise<void> | void;
439
440
  type WS = {
440
441
  send: (data: any) => void;
441
442
  close: (code?: number, reason?: string) => void;
443
+ data?: {
444
+ url: URL;
445
+ pathname: string;
446
+ token?: string;
447
+ id?: string;
448
+ /**
449
+ * 鉴权后的获取的信息
450
+ */
451
+ userApp?: string;
452
+ };
442
453
  };
443
- type Listener$1 = {
454
+ type Listener = {
444
455
  id?: string;
445
456
  io?: boolean;
446
457
  path?: string;
447
- fun: WebScoketListenerFun | HttpListenerFun;
458
+ func: WebSocketListenerFun | HttpListenerFun;
448
459
  };
449
- type WebScoketListenerFun = (req: WebSocketReq, res: WebSocketRes) => Promise<void> | void;
460
+ type WebSocketListenerFun = (req: WebSocketReq, res: WebSocketRes) => Promise<void> | void;
450
461
  type HttpListenerFun = (req: RouterReq, res: RouterRes) => Promise<void> | void;
451
462
  type WebSocketReq = {
452
463
  emitter?: EventEmitter;
@@ -459,8 +470,8 @@ type WebSocketReq = {
459
470
  type WebSocketRes = {
460
471
  end: (data: any) => void;
461
472
  };
462
- type ListenerFun = WebScoketListenerFun | HttpListenerFun;
463
- type OnListener = Listener$1 | ListenerFun | (Listener$1 | ListenerFun)[];
473
+ type ListenerFun = WebSocketListenerFun | HttpListenerFun;
474
+ type OnListener = Listener | ListenerFun | (Listener | ListenerFun)[];
464
475
  type RouterReq<T = {}> = {
465
476
  url: string;
466
477
  method: string;
@@ -604,7 +615,7 @@ declare class ServerBase implements ServerType {
604
615
  handle: ServerOpts['handle'];
605
616
  _callback: any;
606
617
  cors: Cors$1;
607
- listeners: Listener$1[];
618
+ listeners: Listener[];
608
619
  emitter: EventEmitter$1<any>;
609
620
  constructor(opts?: ServerOpts);
610
621
  listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
@@ -632,25 +643,15 @@ declare class ServerBase implements ServerType {
632
643
  createCallback(): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
633
644
  on(listener: OnListener): void;
634
645
  onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): Promise<void>;
646
+ onWsClose(ws: WS): Promise<void>;
635
647
  }
636
648
 
637
649
  type WsServerBaseOpts = {
638
650
  wss?: WebSocketServer | null;
639
651
  path?: string;
640
652
  };
641
- type ListenerFn = (message: {
642
- data: Record<string, any>;
643
- ws: WebSocket;
644
- end: (data: any) => any;
645
- }) => Promise<any>;
646
- type Listener<T = 'router' | 'chat' | 'ai'> = {
647
- type: T;
648
- path?: string;
649
- listener: ListenerFn;
650
- };
651
653
  declare class WsServerBase {
652
654
  wss: WebSocketServer | null;
653
- listeners: Listener[];
654
655
  listening: boolean;
655
656
  server: ServerType;
656
657
  constructor(opts: WsServerBaseOpts);
@@ -677,7 +678,7 @@ declare class ServerNode extends ServerBase implements ServerType {
677
678
  _callback: any;
678
679
  cors: Cors;
679
680
  private httpType;
680
- listeners: Listener$1[];
681
+ listeners: Listener[];
681
682
  private options;
682
683
  io: WsServer | undefined;
683
684
  constructor(opts?: ServerNodeOpts);
@@ -924,4 +925,4 @@ declare class App<U = {}> {
924
925
  }
925
926
 
926
927
  export { App, Connect, CustomError, Mini, QueryConnect, QueryRouter, QueryRouterServer, QueryUtil, Route, ServerNode, createSchema, define, handleServer, util };
927
- export type { OnWebSocketFn, RouteArray, RouteContext, RouteMiddleware, RouteObject, RouteOpts, RouterReq, RouterRes, Rule, Run, Schema };
928
+ export type { HttpListenerFun, Listener, OnListener, OnWebSocketFn, RouteArray, RouteContext, RouteMiddleware, RouteObject, RouteOpts, RouterReq, RouterRes, Rule, Run, Schema, WS, WebSocketListenerFun, WebSocketReq, WebSocketRes };
package/dist/router.js CHANGED
@@ -1261,9 +1261,9 @@ class ServerBase {
1261
1261
  }
1262
1262
  const listeners = that.listeners || [];
1263
1263
  for (const item of listeners) {
1264
- const fun = item.fun;
1265
- if (typeof fun === 'function' && !item.io) {
1266
- await fun(req, res);
1264
+ const func = item.func;
1265
+ if (typeof func === 'function' && !item.io) {
1266
+ await func(req, res);
1267
1267
  }
1268
1268
  }
1269
1269
  if (res.headersSent) {
@@ -1324,13 +1324,13 @@ class ServerBase {
1324
1324
  on(listener) {
1325
1325
  this.listeners = [];
1326
1326
  if (typeof listener === 'function') {
1327
- this.listeners.push({ fun: listener });
1327
+ this.listeners.push({ func: listener });
1328
1328
  return;
1329
1329
  }
1330
1330
  if (Array.isArray(listener)) {
1331
1331
  for (const item of listener) {
1332
1332
  if (typeof item === 'function') {
1333
- this.listeners.push({ fun: item });
1333
+ this.listeners.push({ func: item });
1334
1334
  }
1335
1335
  else {
1336
1336
  this.listeners.push(item);
@@ -1348,7 +1348,7 @@ class ServerBase {
1348
1348
  const end = (data) => {
1349
1349
  ws.send(JSON.stringify(data));
1350
1350
  };
1351
- listener.fun({
1351
+ listener.func({
1352
1352
  emitter: this.emitter,
1353
1353
  data,
1354
1354
  token,
@@ -1408,6 +1408,17 @@ class ServerBase {
1408
1408
  end({ code: 500, message: `${type} server is error` });
1409
1409
  }
1410
1410
  }
1411
+ async onWsClose(ws) {
1412
+ const id = ws?.data?.id || '';
1413
+ if (id) {
1414
+ this.emitter.emit('close--' + id, { type: 'close', ws, id });
1415
+ setTimeout(() => {
1416
+ // 关闭后 5 秒清理监听器, 避免内存泄漏, 理论上原本的自己就应该被清理掉了,这里是保险起见
1417
+ this.emitter.removeAllListeners('close--' + id);
1418
+ this.emitter.removeAllListeners(id);
1419
+ }, 5000);
1420
+ }
1421
+ }
1411
1422
  }
1412
1423
 
1413
1424
  function getDefaultExportFromCjs (x) {
@@ -6329,7 +6340,6 @@ var WebSocketServer = /*@__PURE__*/getDefaultExportFromCjs(websocketServerExport
6329
6340
  // @ts-type=ws
6330
6341
  class WsServerBase {
6331
6342
  wss;
6332
- listeners = [];
6333
6343
  listening = false;
6334
6344
  server;
6335
6345
  constructor(opts) {
@@ -6353,10 +6363,20 @@ class WsServerBase {
6353
6363
  const pathname = url.pathname;
6354
6364
  const token = url.searchParams.get('token') || '';
6355
6365
  const id = url.searchParams.get('id') || '';
6366
+ // @ts-ignore
6367
+ ws.data = {
6368
+ url: url,
6369
+ pathname,
6370
+ token,
6371
+ id,
6372
+ };
6356
6373
  ws.on('message', async (message) => {
6357
6374
  await this.server.onWebSocket({ ws, message, pathname, token, id });
6358
6375
  });
6359
- ws.send('connected');
6376
+ ws.send(JSON.stringify({ type: 'connected' }));
6377
+ this.wss.on('close', () => {
6378
+ this.server.onWsClose(ws);
6379
+ });
6360
6380
  });
6361
6381
  }
6362
6382
  }
@@ -6674,15 +6694,7 @@ class BunServer extends ServerBase {
6674
6694
  },
6675
6695
  close: (ws) => {
6676
6696
  // WebSocket 连接关闭
6677
- const id = ws?.data?.id || '';
6678
- if (id) {
6679
- this.emitter.emit('close--' + id, { type: 'close', ws, id });
6680
- setTimeout(() => {
6681
- // 关闭后 5 秒清理监听器, 避免内存泄漏, 理论上原本的自己就应该被清理掉了,这里是保险起见
6682
- this.emitter.removeAllListeners('close--' + id);
6683
- this.emitter.removeAllListeners(id);
6684
- }, 5000);
6685
- }
6697
+ this.onWsClose(ws);
6686
6698
  },
6687
6699
  },
6688
6700
  });
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.45",
4
+ "version": "0.0.47",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "main": "./dist/router.js",
package/src/index.ts CHANGED
@@ -20,4 +20,15 @@ export { App } from './app.ts';
20
20
  export * from './router-define.ts';
21
21
 
22
22
 
23
- export { RouterReq, RouterRes, OnWebSocketFn } from './server/server-type.ts';
23
+ export {
24
+ RouterReq,
25
+ RouterRes,
26
+ OnWebSocketFn,
27
+ WS,
28
+ WebSocketReq,
29
+ WebSocketRes,
30
+ Listener,
31
+ WebSocketListenerFun,
32
+ HttpListenerFun,
33
+ OnListener,
34
+ } from './server/server-type.ts';
@@ -1,7 +1,7 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
2
  import { handleServer } from './handle-server.ts';
3
3
  import * as cookie from './cookie.ts';
4
- import { ServerType, Listener, OnListener, ServerOpts, OnWebSocketOptions, OnWebSocketFn, WebScoketListenerFun, ListenerFun, HttpListenerFun } from './server-type.ts';
4
+ import { ServerType, Listener, OnListener, ServerOpts, OnWebSocketOptions, OnWebSocketFn, WebScoketListenerFun, ListenerFun, HttpListenerFun, WS } from './server-type.ts';
5
5
  import { parseIfJson } from '../utils/parse.ts';
6
6
  import { EventEmitter } from 'events';
7
7
  type CookieFn = (name: string, value: string, options?: cookie.SerializeOptions, end?: boolean) => void;
@@ -119,9 +119,9 @@ export class ServerBase implements ServerType {
119
119
  }
120
120
  const listeners = that.listeners || [];
121
121
  for (const item of listeners) {
122
- const fun = item.fun as any;
123
- if (typeof fun === 'function' && !item.io) {
124
- await fun(req, res);
122
+ const func = item.func as any;
123
+ if (typeof func === 'function' && !item.io) {
124
+ await func(req, res);
125
125
  }
126
126
  }
127
127
  if (res.headersSent) {
@@ -179,13 +179,13 @@ export class ServerBase implements ServerType {
179
179
  on(listener: OnListener) {
180
180
  this.listeners = [];
181
181
  if (typeof listener === 'function') {
182
- this.listeners.push({ fun: listener });
182
+ this.listeners.push({ func: listener });
183
183
  return;
184
184
  }
185
185
  if (Array.isArray(listener)) {
186
186
  for (const item of listener) {
187
187
  if (typeof item === 'function') {
188
- this.listeners.push({ fun: item });
188
+ this.listeners.push({ func: item });
189
189
  } else {
190
190
  this.listeners.push(item);
191
191
  }
@@ -202,7 +202,7 @@ export class ServerBase implements ServerType {
202
202
  const end = (data: any) => {
203
203
  ws.send(JSON.stringify(data));
204
204
  }
205
- (listener.fun as WebScoketListenerFun)({
205
+ (listener.func as WebScoketListenerFun)({
206
206
  emitter: this.emitter,
207
207
  data,
208
208
  token,
@@ -264,4 +264,15 @@ export class ServerBase implements ServerType {
264
264
  end({ code: 500, message: `${type} server is error` });
265
265
  }
266
266
  }
267
+ async onWsClose(ws: WS) {
268
+ const id = ws?.data?.id || '';
269
+ if (id) {
270
+ this.emitter.emit('close--' + id, { type: 'close', ws, id });
271
+ setTimeout(() => {
272
+ // 关闭后 5 秒清理监听器, 避免内存泄漏, 理论上原本的自己就应该被清理掉了,这里是保险起见
273
+ this.emitter.removeAllListeners('close--' + id);
274
+ this.emitter.removeAllListeners(id);
275
+ }, 5000);
276
+ }
277
+ }
267
278
  }
@@ -233,15 +233,7 @@ export class BunServer extends ServerBase implements ServerType {
233
233
  },
234
234
  close: (ws: any) => {
235
235
  // WebSocket 连接关闭
236
- const id = ws?.data?.id || '';
237
- if (id) {
238
- this.emitter.emit('close--' + id, { type: 'close', ws, id });
239
- setTimeout(() => {
240
- // 关闭后 5 秒清理监听器, 避免内存泄漏, 理论上原本的自己就应该被清理掉了,这里是保险起见
241
- this.emitter.removeAllListeners('close--' + id);
242
- this.emitter.removeAllListeners(id);
243
- }, 5000);
244
- }
236
+ this.onWsClose(ws);
245
237
  },
246
238
  },
247
239
  });
@@ -39,22 +39,33 @@ export interface ServerType {
39
39
  */
40
40
  on(listener: OnListener): void;
41
41
  onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): void;
42
+ onWsClose(ws: WS): void;
42
43
  }
43
44
 
44
45
  export type OnWebSocketOptions = { ws: WS; message: string | Buffer; pathname: string, token?: string, id?: string }
45
46
  export type OnWebSocketFn = (options: OnWebSocketOptions) => Promise<void> | void;
46
- type WS = {
47
+ export type WS = {
47
48
  send: (data: any) => void;
48
49
  close: (code?: number, reason?: string) => void;
50
+ data?: {
51
+ url: URL;
52
+ pathname: string;
53
+ token?: string;
54
+ id?: string;
55
+ /**
56
+ * 鉴权后的获取的信息
57
+ */
58
+ userApp?: string;
59
+ }
49
60
  }
50
61
  export type Listener = {
51
62
  id?: string;
52
63
  io?: boolean;
53
64
  path?: string;
54
- fun: WebScoketListenerFun | HttpListenerFun;
65
+ func: WebSocketListenerFun | HttpListenerFun;
55
66
  }
56
67
 
57
- export type WebScoketListenerFun = (req: WebSocketReq, res: WebSocketRes) => Promise<void> | void;
68
+ export type WebSocketListenerFun = (req: WebSocketReq, res: WebSocketRes) => Promise<void> | void;
58
69
  export type HttpListenerFun = (req: RouterReq, res: RouterRes) => Promise<void> | void;
59
70
 
60
71
  export type WebSocketReq = {
@@ -68,7 +79,7 @@ export type WebSocketReq = {
68
79
  export type WebSocketRes = {
69
80
  end: (data: any) => void;
70
81
  }
71
- export type ListenerFun = WebScoketListenerFun | HttpListenerFun;;
82
+ export type ListenerFun = WebSocketListenerFun | HttpListenerFun;;
72
83
  export type OnListener = Listener | ListenerFun | (Listener | ListenerFun)[];
73
84
  export type RouterReq<T = {}> = {
74
85
  url: string;
@@ -24,7 +24,6 @@ export type Listener<T = 'router' | 'chat' | 'ai'> = {
24
24
 
25
25
  export class WsServerBase {
26
26
  wss: WebSocketServer | null;
27
- listeners: Listener[] = [];
28
27
  listening: boolean = false;
29
28
  server: ServerType;
30
29
 
@@ -51,11 +50,22 @@ export class WsServerBase {
51
50
  const pathname = url.pathname;
52
51
  const token = url.searchParams.get('token') || '';
53
52
  const id = url.searchParams.get('id') || '';
53
+ // @ts-ignore
54
+ ws.data = {
55
+ url: url,
56
+ pathname,
57
+ token,
58
+ id,
59
+ }
54
60
  ws.on('message', async (message: string | Buffer) => {
55
61
  await this.server.onWebSocket({ ws, message, pathname, token, id });
56
62
  });
57
- ws.send('connected');
63
+ ws.send(JSON.stringify({ type: 'connected' }));
64
+ this.wss.on('close', () => {
65
+ this.server.onWsClose(ws);
66
+ });
58
67
  });
68
+
59
69
  }
60
70
  }
61
71
  // TODO: ws handle and path and routerContext