@kevisual/router 0.0.42 → 0.0.44

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
@@ -1,10 +1,12 @@
1
- import http$1, { IncomingMessage, ServerResponse } from 'node:http';
1
+ import * as http from 'node:http';
2
+ import http__default, { IncomingMessage, ServerResponse } from 'node:http';
2
3
  import https from 'node:https';
3
4
  import http2 from 'node:http2';
4
- import * as http from 'http';
5
- import { IncomingMessage as IncomingMessage$1, ServerResponse as ServerResponse$1 } from 'http';
5
+ import EventEmitter from 'node:events';
6
+ import { EventEmitter as EventEmitter$1 } from 'events';
6
7
  import { WebSocketServer, WebSocket } from 'ws';
7
8
  import { z } from 'zod';
9
+ import { IncomingMessage as IncomingMessage$1, ServerResponse as ServerResponse$1 } from 'http';
8
10
  import { RouteOpts as RouteOpts$1, QueryRouterServer as QueryRouterServer$1, RouteMiddleware as RouteMiddleware$1, Run as Run$1 } from '@kevisual/router';
9
11
  import { Query, DataOpts, Result } from '@kevisual/query/query';
10
12
 
@@ -383,14 +385,6 @@ declare class QueryConnect {
383
385
  }[];
384
386
  }
385
387
 
386
- type Listener$1 = {
387
- id?: string;
388
- io?: boolean;
389
- path?: string;
390
- fun: (...args: any[]) => Promise<void> | void;
391
- };
392
- type ListenerFun = (...args: any[]) => Promise<void> | void;
393
- type OnListener = Listener$1 | Listener$1[] | ListenerFun | ListenerFun[];
394
388
  type Cors$2 = {
395
389
  /**
396
390
  * @default '*''
@@ -432,18 +426,64 @@ interface ServerType {
432
426
  * @param listener
433
427
  */
434
428
  on(listener: OnListener): void;
435
- onWebSocket({ ws, message, pathname, token, id }: {
436
- ws: WS;
437
- message: string | Buffer;
438
- pathname: string;
439
- token?: string;
440
- id?: string;
441
- }): void;
429
+ onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): void;
442
430
  }
431
+ type OnWebSocketOptions = {
432
+ ws: WS;
433
+ message: string | Buffer;
434
+ pathname: string;
435
+ token?: string;
436
+ id?: string;
437
+ };
438
+ type OnWebSocketFn = (options: OnWebSocketOptions) => Promise<void> | void;
443
439
  type WS = {
444
440
  send: (data: any) => void;
445
- close: () => void;
441
+ close: (code?: number, reason?: string) => void;
442
+ };
443
+ type Listener$1 = {
444
+ id?: string;
445
+ io?: boolean;
446
+ path?: string;
447
+ fun: WebScoketListenerFun | HttpListenerFun;
448
+ };
449
+ type WebScoketListenerFun = (req: WebSocketReq, res: WebSocketRes) => Promise<void> | void;
450
+ type HttpListenerFun = (req: RouterReq, res: RouterRes) => Promise<void> | void;
451
+ type WebSocketReq = {
452
+ emitter?: EventEmitter;
453
+ ws: WS;
454
+ data: any;
455
+ pathname?: string;
456
+ token?: string;
457
+ id?: string;
446
458
  };
459
+ type WebSocketRes = {
460
+ end: (data: any) => void;
461
+ };
462
+ type ListenerFun = WebScoketListenerFun | HttpListenerFun;
463
+ type OnListener = Listener$1 | ListenerFun | (Listener$1 | ListenerFun)[];
464
+ type RouterReq<T = {}> = {
465
+ url: string;
466
+ method: string;
467
+ headers: Record<string, string>;
468
+ socket?: {
469
+ remoteAddress?: string;
470
+ remotePort?: number;
471
+ };
472
+ cookies?: Record<string, string>;
473
+ } & T;
474
+ type RouterRes<T = {}> = {
475
+ statusCode: number;
476
+ headersSent: boolean;
477
+ _headers: Record<string, string | string[]>;
478
+ _bodyChunks: any[];
479
+ writableEnded: boolean;
480
+ writeHead: (statusCode: number, headers?: Record<string, string>) => void;
481
+ setHeader: (name: string, value: string | string[]) => void;
482
+ cookie: (name: string, value: string, options?: any) => void;
483
+ write: (chunk: any) => void;
484
+ pipe: (stream: any) => void;
485
+ end: (data?: any) => void;
486
+ } & T;
447
487
 
448
488
  interface StringifyOptions {
449
489
  /**
@@ -565,6 +605,7 @@ declare class ServerBase implements ServerType {
565
605
  _callback: any;
566
606
  cors: Cors$1;
567
607
  listeners: Listener$1[];
608
+ emitter: EventEmitter$1<any>;
568
609
  constructor(opts?: ServerOpts);
569
610
  listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
570
611
  listen(port: number, hostname?: string, listeningListener?: () => void): void;
@@ -590,13 +631,7 @@ declare class ServerBase implements ServerType {
590
631
  */
591
632
  createCallback(): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
592
633
  on(listener: OnListener): void;
593
- onWebSocket({ ws, message, pathname, token, id }: {
594
- ws: any;
595
- message: any;
596
- pathname: any;
597
- token: any;
598
- id: any;
599
- }): Promise<void>;
634
+ onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): Promise<void>;
600
635
  }
601
636
 
602
637
  type WsServerBaseOpts = {
@@ -638,7 +673,7 @@ type ServerNodeOpts = ServerOpts<{
638
673
  httpsCert?: string;
639
674
  }>;
640
675
  declare class ServerNode extends ServerBase implements ServerType {
641
- _server: http$1.Server | https.Server | http2.Http2SecureServer;
676
+ _server: http__default.Server | https.Server | http2.Http2SecureServer;
642
677
  _callback: any;
643
678
  cors: Cors;
644
679
  private httpType;
@@ -647,7 +682,7 @@ declare class ServerNode extends ServerBase implements ServerType {
647
682
  io: WsServer | undefined;
648
683
  constructor(opts?: ServerNodeOpts);
649
684
  customListen(...args: any[]): void;
650
- createServer(): http$1.Server<typeof http$1.IncomingMessage, typeof http$1.ServerResponse> | http2.Http2SecureServer<typeof http$1.IncomingMessage, typeof http$1.ServerResponse, typeof http2.Http2ServerRequest, typeof http2.Http2ServerResponse>;
685
+ createServer(): http__default.Server<typeof http__default.IncomingMessage, typeof http__default.ServerResponse> | http2.Http2SecureServer<typeof http__default.IncomingMessage, typeof http__default.ServerResponse, typeof http2.Http2ServerRequest, typeof http2.Http2ServerResponse>;
651
686
  }
652
687
 
653
688
  /**
@@ -889,4 +924,4 @@ declare class App<U = {}> {
889
924
  }
890
925
 
891
926
  export { App, Connect, CustomError, Mini, QueryConnect, QueryRouter, QueryRouterServer, QueryUtil, Route, ServerNode, createSchema, define, handleServer, util };
892
- export type { RouteArray, RouteContext, RouteMiddleware, RouteObject, RouteOpts, Rule, Run, Schema };
927
+ export type { OnWebSocketFn, RouteArray, RouteContext, RouteMiddleware, RouteObject, RouteOpts, RouterReq, RouterRes, Rule, Run, Schema };
package/dist/router.js CHANGED
@@ -3,7 +3,7 @@ import require$$2 from 'node:http';
3
3
  import require$$1$1 from 'node:https';
4
4
  import http2 from 'node:http2';
5
5
  import url from 'node:url';
6
- import require$$0$3 from 'node:events';
6
+ import require$$0$3, { EventEmitter } from 'node:events';
7
7
  import require$$3 from 'node:net';
8
8
  import require$$4 from 'node:tls';
9
9
  import require$$0$2 from 'node:stream';
@@ -1214,6 +1214,7 @@ class ServerBase {
1214
1214
  _callback;
1215
1215
  cors;
1216
1216
  listeners = [];
1217
+ emitter = new EventEmitter();
1217
1218
  constructor(opts) {
1218
1219
  this.path = opts?.path || '/api/router';
1219
1220
  this.handle = opts?.handle;
@@ -1348,6 +1349,7 @@ class ServerBase {
1348
1349
  ws.send(JSON.stringify(data));
1349
1350
  };
1350
1351
  listener.fun({
1352
+ emitter: this.emitter,
1351
1353
  data,
1352
1354
  token,
1353
1355
  id,
@@ -6498,6 +6500,7 @@ class BunServer extends ServerBase {
6498
6500
  idleTimeout: 0, // 4 minutes idle timeout (max 255 seconds)
6499
6501
  fetch: async (request, server) => {
6500
6502
  const host = request.headers.get('host') || 'localhost';
6503
+ const clientInfo = server.requestIP(request); // 返回 { address: string, port: number } 或 null
6501
6504
  const url = new URL(request.url, `http://${host}`);
6502
6505
  // 处理 WebSocket 升级请求
6503
6506
  if (request.headers.get('upgrade') === 'websocket') {
@@ -6520,12 +6523,18 @@ class BunServer extends ServerBase {
6520
6523
  url: url.pathname + url.search,
6521
6524
  method: request.method,
6522
6525
  headers: Object.fromEntries(request.headers.entries()),
6526
+ socket: {
6527
+ // @ts-ignore
6528
+ remoteAddress: request?.remoteAddress || request?.ip || clientInfo?.address || '',
6529
+ remotePort: clientInfo?.port || 0,
6530
+ }
6523
6531
  };
6524
6532
  const res = {
6525
6533
  statusCode: 200,
6526
6534
  headersSent: false,
6527
6535
  writableEnded: false,
6528
6536
  _headers: {},
6537
+ _bodyChunks: [],
6529
6538
  writeHead(statusCode, headers) {
6530
6539
  this.statusCode = statusCode;
6531
6540
  for (const key in headers) {
@@ -6563,9 +6572,79 @@ class BunServer extends ServerBase {
6563
6572
  }
6564
6573
  this.setHeader('Set-Cookie', cookieString);
6565
6574
  },
6575
+ write(chunk, encoding, callback) {
6576
+ if (typeof encoding === 'function') {
6577
+ callback = encoding;
6578
+ encoding = 'utf8';
6579
+ }
6580
+ if (!this._bodyChunks) {
6581
+ this._bodyChunks = [];
6582
+ }
6583
+ this._bodyChunks.push(chunk);
6584
+ if (callback)
6585
+ callback();
6586
+ return true;
6587
+ },
6588
+ pipe(stream) {
6589
+ this.writableEnded = true;
6590
+ // 如果是 ReadableStream,直接使用
6591
+ if (stream instanceof ReadableStream) {
6592
+ resolve(new Response(stream, {
6593
+ status: this.statusCode,
6594
+ headers: this._headers,
6595
+ }));
6596
+ return;
6597
+ }
6598
+ // 如果是 Node.js 流,转换为 ReadableStream
6599
+ const readableStream = new ReadableStream({
6600
+ start(controller) {
6601
+ stream.on('data', (chunk) => {
6602
+ controller.enqueue(chunk);
6603
+ });
6604
+ stream.on('end', () => {
6605
+ controller.close();
6606
+ });
6607
+ stream.on('error', (err) => {
6608
+ controller.error(err);
6609
+ });
6610
+ },
6611
+ cancel() {
6612
+ if (stream.destroy) {
6613
+ stream.destroy();
6614
+ }
6615
+ }
6616
+ });
6617
+ resolve(new Response(readableStream, {
6618
+ status: this.statusCode,
6619
+ headers: this._headers,
6620
+ }));
6621
+ },
6566
6622
  end(data) {
6567
6623
  this.writableEnded = true;
6568
- resolve(new Response(data, {
6624
+ // 合并所有写入的数据块
6625
+ let responseData = data;
6626
+ if (this._bodyChunks && this._bodyChunks.length > 0) {
6627
+ if (data)
6628
+ this._bodyChunks.push(data);
6629
+ // 处理 Buffer 和字符串混合的情况
6630
+ const hasBuffer = this._bodyChunks.some(chunk => chunk instanceof Buffer || chunk instanceof Uint8Array);
6631
+ if (hasBuffer) {
6632
+ // 如果有 Buffer,转换所有内容为 Buffer 后合并
6633
+ const buffers = this._bodyChunks.map(chunk => {
6634
+ if (chunk instanceof Buffer)
6635
+ return chunk;
6636
+ if (chunk instanceof Uint8Array)
6637
+ return Buffer.from(chunk);
6638
+ return Buffer.from(String(chunk));
6639
+ });
6640
+ responseData = Buffer.concat(buffers);
6641
+ }
6642
+ else {
6643
+ // 纯字符串,直接拼接
6644
+ responseData = this._bodyChunks.map(chunk => String(chunk)).join('');
6645
+ }
6646
+ }
6647
+ resolve(new Response(responseData, {
6569
6648
  status: this.statusCode,
6570
6649
  headers: this._headers,
6571
6650
  }));
@@ -6585,7 +6664,7 @@ class BunServer extends ServerBase {
6585
6664
  },
6586
6665
  websocket: {
6587
6666
  open: (ws) => {
6588
- ws.send('connected');
6667
+ ws.send({ type: 'connected' });
6589
6668
  },
6590
6669
  message: async (ws, message) => {
6591
6670
  const pathname = ws.data.pathname || '';
@@ -6595,6 +6674,14 @@ class BunServer extends ServerBase {
6595
6674
  },
6596
6675
  close: (ws) => {
6597
6676
  // WebSocket 连接关闭
6677
+ const id = ws?.data?.id || '';
6678
+ if (id) {
6679
+ this.emitter.emit(id, { type: 'close', ws, id });
6680
+ setTimeout(() => {
6681
+ // 关闭后 5 秒清理监听器, 避免内存泄漏, 理论上原本的自己就应该被清理掉了,这里是保险起见
6682
+ this.emitter.removeAllListeners(id);
6683
+ }, 5000);
6684
+ }
6598
6685
  },
6599
6686
  },
6600
6687
  });
@@ -11081,7 +11168,7 @@ class App {
11081
11168
  }
11082
11169
  this.server.on({
11083
11170
  id: 'app-request-listener',
11084
- fun: fn
11171
+ fun: fn,
11085
11172
  });
11086
11173
  }
11087
11174
  }
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.42",
4
+ "version": "0.0.44",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "main": "./dist/router.js",
package/src/app.ts CHANGED
@@ -134,7 +134,7 @@ export class App<U = {}> {
134
134
  }
135
135
  this.server.on({
136
136
  id: 'app-request-listener',
137
- fun: fn
137
+ fun: fn as any,
138
138
  });
139
139
  }
140
140
  }
package/src/index.ts CHANGED
@@ -18,3 +18,6 @@ export type { Rule, Schema, } from './validator/index.ts';
18
18
  export { App } from './app.ts';
19
19
 
20
20
  export * from './router-define.ts';
21
+
22
+
23
+ export { RouterReq, RouterRes, OnWebSocketFn } from './server/server-type.ts';
@@ -1,9 +1,9 @@
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 } from './server-type.ts';
4
+ import { ServerType, Listener, OnListener, ServerOpts, OnWebSocketOptions, OnWebSocketFn, WebScoketListenerFun, ListenerFun, HttpListenerFun } 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;
8
8
 
9
9
  export type HandleCtx = {
@@ -63,6 +63,7 @@ export class ServerBase implements ServerType {
63
63
  _callback: any;
64
64
  cors: Cors;
65
65
  listeners: Listener[] = [];
66
+ emitter = new EventEmitter();
66
67
  constructor(opts?: ServerOpts) {
67
68
  this.path = opts?.path || '/api/router';
68
69
  this.handle = opts?.handle;
@@ -118,7 +119,7 @@ export class ServerBase implements ServerType {
118
119
  }
119
120
  const listeners = that.listeners || [];
120
121
  for (const item of listeners) {
121
- const fun = item.fun;
122
+ const fun = item.fun as any;
122
123
  if (typeof fun === 'function' && !item.io) {
123
124
  await fun(req, res);
124
125
  }
@@ -193,7 +194,7 @@ export class ServerBase implements ServerType {
193
194
  this.listeners.push(listener);
194
195
  }
195
196
  }
196
- async onWebSocket({ ws, message, pathname, token, id }) {
197
+ async onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions) {
197
198
  const listener = this.listeners.find((item) => item.path === pathname && item.io);
198
199
  const data: any = parseIfJson(message);
199
200
 
@@ -201,7 +202,8 @@ export class ServerBase implements ServerType {
201
202
  const end = (data: any) => {
202
203
  ws.send(JSON.stringify(data));
203
204
  }
204
- listener.fun({
205
+ (listener.fun as WebScoketListenerFun)({
206
+ emitter: this.emitter,
205
207
  data,
206
208
  token,
207
209
  id,
@@ -4,19 +4,8 @@
4
4
  * @tags bun, server, websocket, http
5
5
  * @createdAt 2025-12-20
6
6
  */
7
- import type { IncomingMessage, ServerResponse } from 'node:http';
8
- import { ServerType, type ServerOpts, type Cors, Listener } from './server-type.ts';
9
- import { handleServer } from './handle-server.ts';
7
+ import { ServerType, type ServerOpts, type Cors, RouterRes, RouterReq } from './server-type.ts';
10
8
  import { ServerBase } from './server-base.ts';
11
- import { parseIfJson } from '../utils/parse.ts';
12
-
13
- const resultError = (error: string, code = 500) => {
14
- const r = {
15
- code: code,
16
- message: error,
17
- };
18
- return JSON.stringify(r);
19
- };
20
9
 
21
10
  export class BunServer extends ServerBase implements ServerType {
22
11
  declare _server: any;
@@ -54,15 +43,16 @@ export class BunServer extends ServerBase implements ServerType {
54
43
  }
55
44
  }
56
45
 
57
- const requestCallback = this.createCallback();
46
+ const requestCallback = this.createCallback() as unknown as (req: RouterReq, res: RouterRes) => void;
58
47
  const wsPath = this.path;
59
48
  // @ts-ignore
60
49
  this._server = Bun.serve({
61
50
  port,
62
51
  hostname,
63
52
  idleTimeout: 0, // 4 minutes idle timeout (max 255 seconds)
64
- fetch: async (request: Request, server: any) => {
53
+ fetch: async (request: Bun.BunRequest, server: any) => {
65
54
  const host = request.headers.get('host') || 'localhost';
55
+ const clientInfo = server.requestIP(request); // 返回 { address: string, port: number } 或 null
66
56
  const url = new URL(request.url, `http://${host}`);
67
57
  // 处理 WebSocket 升级请求
68
58
  if (request.headers.get('upgrade') === 'websocket') {
@@ -82,17 +72,23 @@ export class BunServer extends ServerBase implements ServerType {
82
72
 
83
73
  // 将 Bun 的 Request 转换为 Node.js 风格的 req/res
84
74
  return new Promise((resolve) => {
85
- const req: any = {
75
+ const req: RouterReq = {
86
76
  url: url.pathname + url.search,
87
77
  method: request.method,
88
78
  headers: Object.fromEntries(request.headers.entries()),
79
+ socket: {
80
+ // @ts-ignore
81
+ remoteAddress: request?.remoteAddress || request?.ip || clientInfo?.address || '',
82
+ remotePort: clientInfo?.port || 0,
83
+ }
89
84
  };
90
85
 
91
- const res: any = {
86
+ const res: RouterRes = {
92
87
  statusCode: 200,
93
88
  headersSent: false,
94
89
  writableEnded: false,
95
90
  _headers: {} as Record<string, string | string[]>,
91
+ _bodyChunks: [] as any[],
96
92
  writeHead(statusCode: number, headers: Record<string, string | string[]>) {
97
93
  this.statusCode = statusCode;
98
94
  for (const key in headers) {
@@ -130,10 +126,84 @@ export class BunServer extends ServerBase implements ServerType {
130
126
  }
131
127
  this.setHeader('Set-Cookie', cookieString);
132
128
  },
129
+ write(chunk: any, encoding?: string | Function, callback?: Function) {
130
+ if (typeof encoding === 'function') {
131
+ callback = encoding;
132
+ encoding = 'utf8';
133
+ }
134
+ if (!this._bodyChunks) {
135
+ this._bodyChunks = [];
136
+ }
137
+ this._bodyChunks.push(chunk);
138
+ if (callback) callback();
139
+ return true;
140
+ },
141
+ pipe(stream: any) {
142
+ this.writableEnded = true;
143
+
144
+ // 如果是 ReadableStream,直接使用
145
+ if (stream instanceof ReadableStream) {
146
+ resolve(
147
+ new Response(stream, {
148
+ status: this.statusCode,
149
+ headers: this._headers as any,
150
+ })
151
+ );
152
+ return;
153
+ }
154
+
155
+ // 如果是 Node.js 流,转换为 ReadableStream
156
+ const readableStream = new ReadableStream({
157
+ start(controller) {
158
+ stream.on('data', (chunk: any) => {
159
+ controller.enqueue(chunk);
160
+ });
161
+ stream.on('end', () => {
162
+ controller.close();
163
+ });
164
+ stream.on('error', (err: any) => {
165
+ controller.error(err);
166
+ });
167
+ },
168
+ cancel() {
169
+ if (stream.destroy) {
170
+ stream.destroy();
171
+ }
172
+ }
173
+ });
174
+
175
+ resolve(
176
+ new Response(readableStream, {
177
+ status: this.statusCode,
178
+ headers: this._headers as any,
179
+ })
180
+ );
181
+ },
133
182
  end(data?: string) {
134
183
  this.writableEnded = true;
184
+
185
+ // 合并所有写入的数据块
186
+ let responseData: string | Buffer = data;
187
+ if (this._bodyChunks && this._bodyChunks.length > 0) {
188
+ if (data) this._bodyChunks.push(data);
189
+ // 处理 Buffer 和字符串混合的情况
190
+ const hasBuffer = this._bodyChunks.some(chunk => chunk instanceof Buffer || chunk instanceof Uint8Array);
191
+ if (hasBuffer) {
192
+ // 如果有 Buffer,转换所有内容为 Buffer 后合并
193
+ const buffers = this._bodyChunks.map(chunk => {
194
+ if (chunk instanceof Buffer) return chunk;
195
+ if (chunk instanceof Uint8Array) return Buffer.from(chunk);
196
+ return Buffer.from(String(chunk));
197
+ });
198
+ responseData = Buffer.concat(buffers);
199
+ } else {
200
+ // 纯字符串,直接拼接
201
+ responseData = this._bodyChunks.map(chunk => String(chunk)).join('');
202
+ }
203
+ }
204
+
135
205
  resolve(
136
- new Response(data, {
206
+ new Response(responseData as any, {
137
207
  status: this.statusCode,
138
208
  headers: this._headers as any,
139
209
  })
@@ -153,7 +223,7 @@ export class BunServer extends ServerBase implements ServerType {
153
223
  },
154
224
  websocket: {
155
225
  open: (ws: any) => {
156
- ws.send('connected');
226
+ ws.send({ type: 'connected' });
157
227
  },
158
228
  message: async (ws: any, message: string | Buffer) => {
159
229
  const pathname = ws.data.pathname || '';
@@ -163,6 +233,14 @@ export class BunServer extends ServerBase implements ServerType {
163
233
  },
164
234
  close: (ws: any) => {
165
235
  // WebSocket 连接关闭
236
+ const id = ws?.data?.id || '';
237
+ if (id) {
238
+ this.emitter.emit(id, { type: 'close', ws, id });
239
+ setTimeout(() => {
240
+ // 关闭后 5 秒清理监听器, 避免内存泄漏, 理论上原本的自己就应该被清理掉了,这里是保险起见
241
+ this.emitter.removeAllListeners(id);
242
+ }, 5000);
243
+ }
166
244
  },
167
245
  },
168
246
  });
@@ -1,13 +1,7 @@
1
- import * as http from 'http';
1
+ import EventEmitter from 'node:events';
2
+ import * as http from 'node:http';
3
+
2
4
 
3
- export type Listener = {
4
- id?: string;
5
- io?: boolean;
6
- path?: string;
7
- fun: (...args: any[]) => Promise<void> | void;
8
- }
9
- export type ListenerFun = (...args: any[]) => Promise<void> | void;
10
- export type OnListener = Listener | Listener[] | ListenerFun | ListenerFun[];
11
5
  export type Cors = {
12
6
  /**
13
7
  * @default '*''
@@ -44,27 +38,59 @@ export interface ServerType {
44
38
  * @param listener
45
39
  */
46
40
  on(listener: OnListener): void;
47
- onWebSocket({ ws, message, pathname, token, id }: { ws: WS; message: string | Buffer; pathname: string, token?: string, id?: string }): void;
41
+ onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): void;
48
42
  }
49
43
 
44
+ export type OnWebSocketOptions = { ws: WS; message: string | Buffer; pathname: string, token?: string, id?: string }
45
+ export type OnWebSocketFn = (options: OnWebSocketOptions) => Promise<void> | void;
50
46
  type WS = {
51
47
  send: (data: any) => void;
52
- close: () => void;
48
+ close: (code?: number, reason?: string) => void;
49
+ }
50
+ export type Listener = {
51
+ id?: string;
52
+ io?: boolean;
53
+ path?: string;
54
+ fun: WebScoketListenerFun | HttpListenerFun;
53
55
  }
54
56
 
55
- export type CommonReq = {
57
+ export type WebScoketListenerFun = (req: WebSocketReq, res: WebSocketRes) => Promise<void> | void;
58
+ export type HttpListenerFun = (req: RouterReq, res: RouterRes) => Promise<void> | void;
59
+
60
+ export type WebSocketReq = {
61
+ emitter?: EventEmitter;
62
+ ws: WS;
63
+ data: any;
64
+ pathname?: string;
65
+ token?: string;
66
+ id?: string;
67
+ }
68
+ export type WebSocketRes = {
69
+ end: (data: any) => void;
70
+ }
71
+ export type ListenerFun = WebScoketListenerFun | HttpListenerFun;;
72
+ export type OnListener = Listener | ListenerFun | (Listener | ListenerFun)[];
73
+ export type RouterReq<T = {}> = {
56
74
  url: string;
57
75
  method: string;
58
76
  headers: Record<string, string>;
59
- [key: string]: any;
60
- }
77
+ socket?: {
78
+ remoteAddress?: string;
79
+ remotePort?: number;
80
+ };
81
+ cookies?: Record<string, string>;
82
+ } & T;
61
83
 
62
- export type CommonRes = {
84
+ export type RouterRes<T = {}> = {
63
85
  statusCode: number;
86
+ headersSent: boolean;
87
+ _headers: Record<string, string | string[]>;
88
+ _bodyChunks: any[];
64
89
  writableEnded: boolean;
65
90
  writeHead: (statusCode: number, headers?: Record<string, string>) => void;
66
91
  setHeader: (name: string, value: string | string[]) => void;
67
92
  cookie: (name: string, value: string, options?: any) => void;
93
+ write: (chunk: any) => void;
94
+ pipe: (stream: any) => void;
68
95
  end: (data?: any) => void;
69
- [key: string]: any;
70
- }
96
+ } & T;