@kevisual/router 0.0.84 → 0.0.85
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/app.js +20 -7
- package/dist/opencode.d.ts +18 -1
- package/dist/router-browser.d.ts +1 -1
- package/dist/router-browser.js +4 -4
- package/dist/router-define.d.ts +1 -1
- package/dist/router.d.ts +20 -1
- package/dist/router.js +19 -6
- package/dist/ws.d.ts +18 -1
- package/package.json +7 -7
- package/src/route.ts +2 -12
- package/src/server/server-base.ts +4 -1
- package/src/server/server-bun.ts +6 -2
- package/src/server/server-type.ts +17 -0
- package/src/server/ws-server.ts +8 -1
package/dist/app.js
CHANGED
|
@@ -3091,7 +3091,7 @@ function pick(obj, keys) {
|
|
|
3091
3091
|
// node_modules/.pnpm/eventemitter3@5.0.4/node_modules/eventemitter3/index.mjs
|
|
3092
3092
|
var import__ = __toESM(require_eventemitter3(), 1);
|
|
3093
3093
|
|
|
3094
|
-
// node_modules/.pnpm/es-toolkit@1.
|
|
3094
|
+
// node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/predicate/isPlainObject.mjs
|
|
3095
3095
|
function isPlainObject(value) {
|
|
3096
3096
|
if (!value || typeof value !== "object") {
|
|
3097
3097
|
return false;
|
|
@@ -3104,12 +3104,12 @@ function isPlainObject(value) {
|
|
|
3104
3104
|
return Object.prototype.toString.call(value) === "[object Object]";
|
|
3105
3105
|
}
|
|
3106
3106
|
|
|
3107
|
-
// node_modules/.pnpm/es-toolkit@1.
|
|
3107
|
+
// node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/_internal/isUnsafeProperty.mjs
|
|
3108
3108
|
function isUnsafeProperty(key) {
|
|
3109
3109
|
return key === "__proto__";
|
|
3110
3110
|
}
|
|
3111
3111
|
|
|
3112
|
-
// node_modules/.pnpm/es-toolkit@1.
|
|
3112
|
+
// node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/object/merge.mjs
|
|
3113
3113
|
function merge(target, source) {
|
|
3114
3114
|
const sourceKeys = Object.keys(source);
|
|
3115
3115
|
for (let i = 0;i < sourceKeys.length; i++) {
|
|
@@ -16932,7 +16932,7 @@ class Route {
|
|
|
16932
16932
|
if (opts) {
|
|
16933
16933
|
this.id = opts.id || randomId(12, "rand-");
|
|
16934
16934
|
if (!opts.id && opts.idUsePath) {
|
|
16935
|
-
const delimiter = opts.delimiter ?? "
|
|
16935
|
+
const delimiter = opts.delimiter ?? "$$";
|
|
16936
16936
|
this.id = path + delimiter + key;
|
|
16937
16937
|
}
|
|
16938
16938
|
this.run = opts.run;
|
|
@@ -17914,7 +17914,7 @@ class ServerBase {
|
|
|
17914
17914
|
}
|
|
17915
17915
|
}
|
|
17916
17916
|
async onWsClose(ws) {
|
|
17917
|
-
const id = ws?.
|
|
17917
|
+
const id = ws?.wsId || "";
|
|
17918
17918
|
if (id) {
|
|
17919
17919
|
this.emitter.emit("close--" + id, { type: "close", ws, id });
|
|
17920
17920
|
setTimeout(() => {
|
|
@@ -17927,6 +17927,9 @@ class ServerBase {
|
|
|
17927
17927
|
if (this.showConnected)
|
|
17928
17928
|
ws.send(JSON.stringify({ type: "connected" }));
|
|
17929
17929
|
}
|
|
17930
|
+
createId() {
|
|
17931
|
+
return Math.random().toString(36).substring(2, 15);
|
|
17932
|
+
}
|
|
17930
17933
|
}
|
|
17931
17934
|
|
|
17932
17935
|
// node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/wrapper.mjs
|
|
@@ -17967,6 +17970,9 @@ class WsServerBase {
|
|
|
17967
17970
|
token,
|
|
17968
17971
|
id
|
|
17969
17972
|
};
|
|
17973
|
+
if (!ws.wsId) {
|
|
17974
|
+
ws.wsId = this.createId();
|
|
17975
|
+
}
|
|
17970
17976
|
ws.on("message", async (message) => {
|
|
17971
17977
|
await this.server.onWebSocket({ ws, message, pathname, token, id });
|
|
17972
17978
|
});
|
|
@@ -17977,6 +17983,9 @@ class WsServerBase {
|
|
|
17977
17983
|
});
|
|
17978
17984
|
});
|
|
17979
17985
|
}
|
|
17986
|
+
createId() {
|
|
17987
|
+
return Math.random().toString(36).substring(2, 15);
|
|
17988
|
+
}
|
|
17980
17989
|
}
|
|
17981
17990
|
|
|
17982
17991
|
class WsServer extends WsServerBase {
|
|
@@ -18292,10 +18301,14 @@ class BunServer extends ServerBase {
|
|
|
18292
18301
|
open: (ws) => {
|
|
18293
18302
|
this.sendConnected(ws);
|
|
18294
18303
|
},
|
|
18295
|
-
message: async (
|
|
18304
|
+
message: async (bunWs, message) => {
|
|
18305
|
+
const ws = bunWs;
|
|
18296
18306
|
const pathname = ws.data.pathname || "";
|
|
18297
18307
|
const token = ws.data.token || "";
|
|
18298
18308
|
const id = ws.data.id || "";
|
|
18309
|
+
if (!ws.wsId) {
|
|
18310
|
+
ws.wsId = this.createId();
|
|
18311
|
+
}
|
|
18299
18312
|
await this.onWebSocket({ ws, message, pathname, token, id });
|
|
18300
18313
|
},
|
|
18301
18314
|
close: (ws) => {
|
|
@@ -19562,7 +19575,7 @@ app
|
|
|
19562
19575
|
10. **中间件找不到会返回 404**,错误信息中会包含找不到的中间件列表。
|
|
19563
19576
|
`;
|
|
19564
19577
|
// package.json
|
|
19565
|
-
var version2 = "0.0.
|
|
19578
|
+
var version2 = "0.0.85";
|
|
19566
19579
|
|
|
19567
19580
|
// agent/routes/route-create.ts
|
|
19568
19581
|
app.route({
|
package/dist/opencode.d.ts
CHANGED
|
@@ -146,7 +146,7 @@ type RouteOpts<U = {}, T = SimpleObject> = {
|
|
|
146
146
|
description?: string;
|
|
147
147
|
metadata?: T;
|
|
148
148
|
middleware?: RouteMiddleware[];
|
|
149
|
-
type?: 'route' | 'middleware';
|
|
149
|
+
type?: 'route' | 'middleware' | 'compound';
|
|
150
150
|
/**
|
|
151
151
|
* $#$ will be used to split path and key
|
|
152
152
|
*/
|
|
@@ -503,15 +503,32 @@ type OnWebSocketOptions<T = {}> = {
|
|
|
503
503
|
message: string | Buffer;
|
|
504
504
|
pathname: string;
|
|
505
505
|
token?: string;
|
|
506
|
+
/** data 的id提取出来 */
|
|
506
507
|
id?: string;
|
|
507
508
|
};
|
|
508
509
|
type WS<T = {}> = {
|
|
509
510
|
send: (data: any) => void;
|
|
510
511
|
close: (code?: number, reason?: string) => void;
|
|
512
|
+
/**
|
|
513
|
+
* ws 自己生成的一个id,主要是为了区分不同的ws连接,方便在onWebSocket中使用
|
|
514
|
+
*/
|
|
515
|
+
wsId?: string;
|
|
511
516
|
data?: {
|
|
517
|
+
/**
|
|
518
|
+
* ws连接时的url,包含pathname和searchParams
|
|
519
|
+
*/
|
|
512
520
|
url: URL;
|
|
521
|
+
/**
|
|
522
|
+
* ws连接时的pathname
|
|
523
|
+
*/
|
|
513
524
|
pathname: string;
|
|
525
|
+
/**
|
|
526
|
+
* ws连接时的url中的token参数
|
|
527
|
+
*/
|
|
514
528
|
token?: string;
|
|
529
|
+
/**
|
|
530
|
+
* ws连接时的url中的id参数.
|
|
531
|
+
*/
|
|
515
532
|
id?: string;
|
|
516
533
|
/**
|
|
517
534
|
* 鉴权后的获取的信息
|
package/dist/router-browser.d.ts
CHANGED
|
@@ -187,7 +187,7 @@ type RouteOpts<U = {}, T = SimpleObject$1> = {
|
|
|
187
187
|
description?: string;
|
|
188
188
|
metadata?: T;
|
|
189
189
|
middleware?: RouteMiddleware[];
|
|
190
|
-
type?: 'route' | 'middleware';
|
|
190
|
+
type?: 'route' | 'middleware' | 'compound';
|
|
191
191
|
/**
|
|
192
192
|
* $#$ will be used to split path and key
|
|
193
193
|
*/
|
package/dist/router-browser.js
CHANGED
|
@@ -280,7 +280,7 @@ function pick(obj, keys) {
|
|
|
280
280
|
// node_modules/.pnpm/eventemitter3@5.0.4/node_modules/eventemitter3/index.mjs
|
|
281
281
|
var import__ = __toESM(require_eventemitter3(), 1);
|
|
282
282
|
|
|
283
|
-
// node_modules/.pnpm/es-toolkit@1.
|
|
283
|
+
// node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/predicate/isPlainObject.mjs
|
|
284
284
|
function isPlainObject(value) {
|
|
285
285
|
if (!value || typeof value !== "object") {
|
|
286
286
|
return false;
|
|
@@ -293,12 +293,12 @@ function isPlainObject(value) {
|
|
|
293
293
|
return Object.prototype.toString.call(value) === "[object Object]";
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
-
// node_modules/.pnpm/es-toolkit@1.
|
|
296
|
+
// node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/_internal/isUnsafeProperty.mjs
|
|
297
297
|
function isUnsafeProperty(key) {
|
|
298
298
|
return key === "__proto__";
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
-
// node_modules/.pnpm/es-toolkit@1.
|
|
301
|
+
// node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/object/merge.mjs
|
|
302
302
|
function merge(target, source) {
|
|
303
303
|
const sourceKeys = Object.keys(source);
|
|
304
304
|
for (let i = 0;i < sourceKeys.length; i++) {
|
|
@@ -14096,7 +14096,7 @@ class Route {
|
|
|
14096
14096
|
if (opts) {
|
|
14097
14097
|
this.id = opts.id || randomId(12, "rand-");
|
|
14098
14098
|
if (!opts.id && opts.idUsePath) {
|
|
14099
|
-
const delimiter = opts.delimiter ?? "
|
|
14099
|
+
const delimiter = opts.delimiter ?? "$$";
|
|
14100
14100
|
this.id = path + delimiter + key;
|
|
14101
14101
|
}
|
|
14102
14102
|
this.run = opts.run;
|
package/dist/router-define.d.ts
CHANGED
|
@@ -143,7 +143,7 @@ type RouteOpts<U = {}, T = SimpleObject$1> = {
|
|
|
143
143
|
description?: string;
|
|
144
144
|
metadata?: T;
|
|
145
145
|
middleware?: RouteMiddleware[];
|
|
146
|
-
type?: 'route' | 'middleware';
|
|
146
|
+
type?: 'route' | 'middleware' | 'compound';
|
|
147
147
|
/**
|
|
148
148
|
* $#$ will be used to split path and key
|
|
149
149
|
*/
|
package/dist/router.d.ts
CHANGED
|
@@ -193,7 +193,7 @@ type RouteOpts<U = {}, T = SimpleObject$1> = {
|
|
|
193
193
|
description?: string;
|
|
194
194
|
metadata?: T;
|
|
195
195
|
middleware?: RouteMiddleware[];
|
|
196
|
-
type?: 'route' | 'middleware';
|
|
196
|
+
type?: 'route' | 'middleware' | 'compound';
|
|
197
197
|
/**
|
|
198
198
|
* $#$ will be used to split path and key
|
|
199
199
|
*/
|
|
@@ -688,16 +688,33 @@ type OnWebSocketOptions<T = {}> = {
|
|
|
688
688
|
message: string | Buffer;
|
|
689
689
|
pathname: string;
|
|
690
690
|
token?: string;
|
|
691
|
+
/** data 的id提取出来 */
|
|
691
692
|
id?: string;
|
|
692
693
|
};
|
|
693
694
|
type OnWebSocketFn = (options: OnWebSocketOptions) => Promise<void> | void;
|
|
694
695
|
type WS<T = {}> = {
|
|
695
696
|
send: (data: any) => void;
|
|
696
697
|
close: (code?: number, reason?: string) => void;
|
|
698
|
+
/**
|
|
699
|
+
* ws 自己生成的一个id,主要是为了区分不同的ws连接,方便在onWebSocket中使用
|
|
700
|
+
*/
|
|
701
|
+
wsId?: string;
|
|
697
702
|
data?: {
|
|
703
|
+
/**
|
|
704
|
+
* ws连接时的url,包含pathname和searchParams
|
|
705
|
+
*/
|
|
698
706
|
url: URL;
|
|
707
|
+
/**
|
|
708
|
+
* ws连接时的pathname
|
|
709
|
+
*/
|
|
699
710
|
pathname: string;
|
|
711
|
+
/**
|
|
712
|
+
* ws连接时的url中的token参数
|
|
713
|
+
*/
|
|
700
714
|
token?: string;
|
|
715
|
+
/**
|
|
716
|
+
* ws连接时的url中的id参数.
|
|
717
|
+
*/
|
|
701
718
|
id?: string;
|
|
702
719
|
/**
|
|
703
720
|
* 鉴权后的获取的信息
|
|
@@ -916,6 +933,7 @@ declare class ServerBase implements ServerType {
|
|
|
916
933
|
*/
|
|
917
934
|
onWsClose(ws: WS): Promise<void>;
|
|
918
935
|
sendConnected(ws: WS): Promise<void>;
|
|
936
|
+
createId(): string;
|
|
919
937
|
}
|
|
920
938
|
|
|
921
939
|
type WsServerBaseOpts = {
|
|
@@ -928,6 +946,7 @@ declare class WsServerBase {
|
|
|
928
946
|
server: ServerType;
|
|
929
947
|
constructor(opts: WsServerBaseOpts);
|
|
930
948
|
listen(): void;
|
|
949
|
+
createId(): string;
|
|
931
950
|
}
|
|
932
951
|
declare class WsServer extends WsServerBase {
|
|
933
952
|
constructor(server: ServerType);
|
package/dist/router.js
CHANGED
|
@@ -3091,7 +3091,7 @@ function pick(obj, keys) {
|
|
|
3091
3091
|
// node_modules/.pnpm/eventemitter3@5.0.4/node_modules/eventemitter3/index.mjs
|
|
3092
3092
|
var import__ = __toESM(require_eventemitter3(), 1);
|
|
3093
3093
|
|
|
3094
|
-
// node_modules/.pnpm/es-toolkit@1.
|
|
3094
|
+
// node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/predicate/isPlainObject.mjs
|
|
3095
3095
|
function isPlainObject(value) {
|
|
3096
3096
|
if (!value || typeof value !== "object") {
|
|
3097
3097
|
return false;
|
|
@@ -3104,12 +3104,12 @@ function isPlainObject(value) {
|
|
|
3104
3104
|
return Object.prototype.toString.call(value) === "[object Object]";
|
|
3105
3105
|
}
|
|
3106
3106
|
|
|
3107
|
-
// node_modules/.pnpm/es-toolkit@1.
|
|
3107
|
+
// node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/_internal/isUnsafeProperty.mjs
|
|
3108
3108
|
function isUnsafeProperty(key) {
|
|
3109
3109
|
return key === "__proto__";
|
|
3110
3110
|
}
|
|
3111
3111
|
|
|
3112
|
-
// node_modules/.pnpm/es-toolkit@1.
|
|
3112
|
+
// node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/object/merge.mjs
|
|
3113
3113
|
function merge(target, source) {
|
|
3114
3114
|
const sourceKeys = Object.keys(source);
|
|
3115
3115
|
for (let i = 0;i < sourceKeys.length; i++) {
|
|
@@ -16929,7 +16929,7 @@ class Route {
|
|
|
16929
16929
|
if (opts) {
|
|
16930
16930
|
this.id = opts.id || randomId(12, "rand-");
|
|
16931
16931
|
if (!opts.id && opts.idUsePath) {
|
|
16932
|
-
const delimiter = opts.delimiter ?? "
|
|
16932
|
+
const delimiter = opts.delimiter ?? "$$";
|
|
16933
16933
|
this.id = path + delimiter + key;
|
|
16934
16934
|
}
|
|
16935
16935
|
this.run = opts.run;
|
|
@@ -18088,7 +18088,7 @@ class ServerBase {
|
|
|
18088
18088
|
}
|
|
18089
18089
|
}
|
|
18090
18090
|
async onWsClose(ws) {
|
|
18091
|
-
const id = ws?.
|
|
18091
|
+
const id = ws?.wsId || "";
|
|
18092
18092
|
if (id) {
|
|
18093
18093
|
this.emitter.emit("close--" + id, { type: "close", ws, id });
|
|
18094
18094
|
setTimeout(() => {
|
|
@@ -18101,6 +18101,9 @@ class ServerBase {
|
|
|
18101
18101
|
if (this.showConnected)
|
|
18102
18102
|
ws.send(JSON.stringify({ type: "connected" }));
|
|
18103
18103
|
}
|
|
18104
|
+
createId() {
|
|
18105
|
+
return Math.random().toString(36).substring(2, 15);
|
|
18106
|
+
}
|
|
18104
18107
|
}
|
|
18105
18108
|
|
|
18106
18109
|
// node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/wrapper.mjs
|
|
@@ -18141,6 +18144,9 @@ class WsServerBase {
|
|
|
18141
18144
|
token,
|
|
18142
18145
|
id
|
|
18143
18146
|
};
|
|
18147
|
+
if (!ws.wsId) {
|
|
18148
|
+
ws.wsId = this.createId();
|
|
18149
|
+
}
|
|
18144
18150
|
ws.on("message", async (message) => {
|
|
18145
18151
|
await this.server.onWebSocket({ ws, message, pathname, token, id });
|
|
18146
18152
|
});
|
|
@@ -18151,6 +18157,9 @@ class WsServerBase {
|
|
|
18151
18157
|
});
|
|
18152
18158
|
});
|
|
18153
18159
|
}
|
|
18160
|
+
createId() {
|
|
18161
|
+
return Math.random().toString(36).substring(2, 15);
|
|
18162
|
+
}
|
|
18154
18163
|
}
|
|
18155
18164
|
|
|
18156
18165
|
class WsServer extends WsServerBase {
|
|
@@ -18465,10 +18474,14 @@ class BunServer extends ServerBase {
|
|
|
18465
18474
|
open: (ws) => {
|
|
18466
18475
|
this.sendConnected(ws);
|
|
18467
18476
|
},
|
|
18468
|
-
message: async (
|
|
18477
|
+
message: async (bunWs, message) => {
|
|
18478
|
+
const ws = bunWs;
|
|
18469
18479
|
const pathname = ws.data.pathname || "";
|
|
18470
18480
|
const token = ws.data.token || "";
|
|
18471
18481
|
const id = ws.data.id || "";
|
|
18482
|
+
if (!ws.wsId) {
|
|
18483
|
+
ws.wsId = this.createId();
|
|
18484
|
+
}
|
|
18472
18485
|
await this.onWebSocket({ ws, message, pathname, token, id });
|
|
18473
18486
|
},
|
|
18474
18487
|
close: (ws) => {
|
package/dist/ws.d.ts
CHANGED
|
@@ -193,7 +193,7 @@ type RouteOpts<U = {}, T = SimpleObject> = {
|
|
|
193
193
|
description?: string;
|
|
194
194
|
metadata?: T;
|
|
195
195
|
middleware?: RouteMiddleware[];
|
|
196
|
-
type?: 'route' | 'middleware';
|
|
196
|
+
type?: 'route' | 'middleware' | 'compound';
|
|
197
197
|
/**
|
|
198
198
|
* $#$ will be used to split path and key
|
|
199
199
|
*/
|
|
@@ -550,15 +550,32 @@ type OnWebSocketOptions<T = {}> = {
|
|
|
550
550
|
message: string | Buffer;
|
|
551
551
|
pathname: string;
|
|
552
552
|
token?: string;
|
|
553
|
+
/** data 的id提取出来 */
|
|
553
554
|
id?: string;
|
|
554
555
|
};
|
|
555
556
|
type WS<T = {}> = {
|
|
556
557
|
send: (data: any) => void;
|
|
557
558
|
close: (code?: number, reason?: string) => void;
|
|
559
|
+
/**
|
|
560
|
+
* ws 自己生成的一个id,主要是为了区分不同的ws连接,方便在onWebSocket中使用
|
|
561
|
+
*/
|
|
562
|
+
wsId?: string;
|
|
558
563
|
data?: {
|
|
564
|
+
/**
|
|
565
|
+
* ws连接时的url,包含pathname和searchParams
|
|
566
|
+
*/
|
|
559
567
|
url: URL;
|
|
568
|
+
/**
|
|
569
|
+
* ws连接时的pathname
|
|
570
|
+
*/
|
|
560
571
|
pathname: string;
|
|
572
|
+
/**
|
|
573
|
+
* ws连接时的url中的token参数
|
|
574
|
+
*/
|
|
561
575
|
token?: string;
|
|
576
|
+
/**
|
|
577
|
+
* ws连接时的url中的id参数.
|
|
578
|
+
*/
|
|
562
579
|
id?: string;
|
|
563
580
|
/**
|
|
564
581
|
* 鉴权后的获取的信息
|
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.
|
|
4
|
+
"version": "0.0.85",
|
|
5
5
|
"description": "",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/router.js",
|
|
@@ -27,17 +27,17 @@
|
|
|
27
27
|
"@kevisual/dts": "^0.0.4",
|
|
28
28
|
"@kevisual/js-filter": "^0.0.5",
|
|
29
29
|
"@kevisual/local-proxy": "^0.0.8",
|
|
30
|
-
"@kevisual/query": "^0.0.
|
|
30
|
+
"@kevisual/query": "^0.0.52",
|
|
31
31
|
"@kevisual/use-config": "^1.0.30",
|
|
32
|
-
"@opencode-ai/plugin": "^1.2.
|
|
33
|
-
"@types/bun": "^1.3.
|
|
34
|
-
"@types/node": "^25.3.
|
|
32
|
+
"@opencode-ai/plugin": "^1.2.16",
|
|
33
|
+
"@types/bun": "^1.3.10",
|
|
34
|
+
"@types/node": "^25.3.3",
|
|
35
35
|
"@types/send": "^1.2.1",
|
|
36
36
|
"@types/ws": "^8.18.1",
|
|
37
37
|
"@types/xml2js": "^0.4.14",
|
|
38
38
|
"eventemitter3": "^5.0.4",
|
|
39
39
|
"fast-glob": "^3.3.3",
|
|
40
|
-
"hono": "^4.12.
|
|
40
|
+
"hono": "^4.12.5",
|
|
41
41
|
"nanoid": "^5.1.6",
|
|
42
42
|
"path-to-regexp": "^8.3.0",
|
|
43
43
|
"send": "^1.2.1",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"url": "git+https://github.com/abearxiong/kevisual-router.git"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"es-toolkit": "^1.
|
|
54
|
+
"es-toolkit": "^1.45.1"
|
|
55
55
|
},
|
|
56
56
|
"publishConfig": {
|
|
57
57
|
"access": "public"
|
package/src/route.ts
CHANGED
|
@@ -7,14 +7,6 @@ import * as schema from './validator/schema.ts';
|
|
|
7
7
|
|
|
8
8
|
export type RouterContextT = { code?: number;[key: string]: any };
|
|
9
9
|
|
|
10
|
-
type ExtractArgs<A> = A extends z.ZodTypeAny ? z.infer<A> : A;
|
|
11
|
-
|
|
12
|
-
type OptionalKeys<T> = {
|
|
13
|
-
[K in keyof T]-?: {} extends Pick<T, K> ? K : never;
|
|
14
|
-
}[keyof T];
|
|
15
|
-
|
|
16
|
-
type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
17
|
-
|
|
18
10
|
type BuildRouteContext<M, U> = M extends { args?: infer A }
|
|
19
11
|
? A extends z.ZodObject<any>
|
|
20
12
|
? RouteContext<{ args?: z.infer<A> }, U>
|
|
@@ -103,7 +95,7 @@ export type RouteOpts<U = {}, T = SimpleObject> = {
|
|
|
103
95
|
description?: string;
|
|
104
96
|
metadata?: T;
|
|
105
97
|
middleware?: RouteMiddleware[]; // middleware
|
|
106
|
-
type?: 'route' | 'middleware';
|
|
98
|
+
type?: 'route' | 'middleware' | 'compound'; // compound表示这个 route 作为一个聚合体,没有实际的 run,而是一个 router 的聚合列表
|
|
107
99
|
/**
|
|
108
100
|
* $#$ will be used to split path and key
|
|
109
101
|
*/
|
|
@@ -146,8 +138,6 @@ export const createSkill = <T = SimpleObject>(skill: Skill<T>): Skill<T> => {
|
|
|
146
138
|
|
|
147
139
|
export type RouteInfo = Pick<Route, (typeof pickValue)[number]>;
|
|
148
140
|
|
|
149
|
-
type ExtractMetadata<M> = M extends { metadata?: infer Meta } ? Meta extends SimpleObject ? Meta : SimpleObject : SimpleObject;
|
|
150
|
-
|
|
151
141
|
/**
|
|
152
142
|
* @M 是 route的 metadate的类型,默认是 SimpleObject
|
|
153
143
|
* @U 是 RouteContext 里 state的类型
|
|
@@ -183,7 +173,7 @@ export class Route<M extends SimpleObject = SimpleObject, U extends SimpleObject
|
|
|
183
173
|
if (opts) {
|
|
184
174
|
this.id = opts.id || randomId(12, 'rand-');
|
|
185
175
|
if (!opts.id && opts.idUsePath) {
|
|
186
|
-
const delimiter = opts.delimiter ?? '
|
|
176
|
+
const delimiter = opts.delimiter ?? '$$';
|
|
187
177
|
this.id = path + delimiter + key;
|
|
188
178
|
}
|
|
189
179
|
this.run = opts.run as Run<BuildRouteContext<M, U>>;
|
|
@@ -284,7 +284,7 @@ export class ServerBase implements ServerType {
|
|
|
284
284
|
* @param ws
|
|
285
285
|
*/
|
|
286
286
|
async onWsClose(ws: WS) {
|
|
287
|
-
const id = ws?.
|
|
287
|
+
const id = ws?.wsId || '';
|
|
288
288
|
if (id) {
|
|
289
289
|
this.emitter.emit('close--' + id, { type: 'close', ws, id });
|
|
290
290
|
setTimeout(() => {
|
|
@@ -298,4 +298,7 @@ export class ServerBase implements ServerType {
|
|
|
298
298
|
if (this.showConnected)
|
|
299
299
|
ws.send(JSON.stringify({ type: 'connected' }));
|
|
300
300
|
}
|
|
301
|
+
createId() {
|
|
302
|
+
return Math.random().toString(36).substring(2, 15);
|
|
303
|
+
}
|
|
301
304
|
}
|
package/src/server/server-bun.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @tags bun, server, websocket, http
|
|
5
5
|
* @createdAt 2025-12-20
|
|
6
6
|
*/
|
|
7
|
-
import { ServerType, type ServerOpts, type Cors, RouterRes, RouterReq } from './server-type.ts';
|
|
7
|
+
import { ServerType, type ServerOpts, type Cors, RouterRes, RouterReq, WS } from './server-type.ts';
|
|
8
8
|
import { ServerBase } from './server-base.ts';
|
|
9
9
|
|
|
10
10
|
export class BunServer extends ServerBase implements ServerType {
|
|
@@ -264,10 +264,14 @@ export class BunServer extends ServerBase implements ServerType {
|
|
|
264
264
|
open: (ws: any) => {
|
|
265
265
|
this.sendConnected(ws);
|
|
266
266
|
},
|
|
267
|
-
message: async (
|
|
267
|
+
message: async (bunWs: any, message: string | Buffer) => {
|
|
268
|
+
const ws = bunWs as WS;
|
|
268
269
|
const pathname = ws.data.pathname || '';
|
|
269
270
|
const token = ws.data.token || '';
|
|
270
271
|
const id = ws.data.id || '';
|
|
272
|
+
if (!ws.wsId) {
|
|
273
|
+
ws.wsId = this.createId();
|
|
274
|
+
}
|
|
271
275
|
await this.onWebSocket({ ws, message, pathname, token, id });
|
|
272
276
|
},
|
|
273
277
|
close: (ws: any) => {
|
|
@@ -49,16 +49,33 @@ export type OnWebSocketOptions<T = {}> = {
|
|
|
49
49
|
message: string | Buffer;
|
|
50
50
|
pathname: string,
|
|
51
51
|
token?: string,
|
|
52
|
+
/** data 的id提取出来 */
|
|
52
53
|
id?: string,
|
|
53
54
|
}
|
|
54
55
|
export type OnWebSocketFn = (options: OnWebSocketOptions) => Promise<void> | void;
|
|
55
56
|
export type WS<T = {}> = {
|
|
56
57
|
send: (data: any) => void;
|
|
57
58
|
close: (code?: number, reason?: string) => void;
|
|
59
|
+
/**
|
|
60
|
+
* ws 自己生成的一个id,主要是为了区分不同的ws连接,方便在onWebSocket中使用
|
|
61
|
+
*/
|
|
62
|
+
wsId?: string;
|
|
58
63
|
data?: {
|
|
64
|
+
/**
|
|
65
|
+
* ws连接时的url,包含pathname和searchParams
|
|
66
|
+
*/
|
|
59
67
|
url: URL;
|
|
68
|
+
/**
|
|
69
|
+
* ws连接时的pathname
|
|
70
|
+
*/
|
|
60
71
|
pathname: string;
|
|
72
|
+
/**
|
|
73
|
+
* ws连接时的url中的token参数
|
|
74
|
+
*/
|
|
61
75
|
token?: string;
|
|
76
|
+
/**
|
|
77
|
+
* ws连接时的url中的id参数.
|
|
78
|
+
*/
|
|
62
79
|
id?: string;
|
|
63
80
|
/**
|
|
64
81
|
* 鉴权后的获取的信息
|
package/src/server/ws-server.ts
CHANGED
|
@@ -56,6 +56,11 @@ export class WsServerBase {
|
|
|
56
56
|
token,
|
|
57
57
|
id,
|
|
58
58
|
}
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
if (!ws.wsId) {
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
ws.wsId = this.createId();
|
|
63
|
+
}
|
|
59
64
|
ws.on('message', async (message: string | Buffer) => {
|
|
60
65
|
await this.server.onWebSocket({ ws, message, pathname, token, id });
|
|
61
66
|
});
|
|
@@ -66,7 +71,9 @@ export class WsServerBase {
|
|
|
66
71
|
this.server.onWsClose(ws);
|
|
67
72
|
});
|
|
68
73
|
});
|
|
69
|
-
|
|
74
|
+
}
|
|
75
|
+
createId() {
|
|
76
|
+
return Math.random().toString(36).substring(2, 15);
|
|
70
77
|
}
|
|
71
78
|
}
|
|
72
79
|
// TODO: ws handle and path and routerContext
|