k99 0.8.0 → 0.9.1

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/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * k99 v0.8.0
2
+ * k99 v0.9.1
3
3
  * (c) 2019-2026 猛火Fierflame
4
4
  * @license MIT
5
5
  */
@@ -407,7 +407,7 @@ function main(request, getHandler, {
407
407
  if (result instanceof Response) { return result; }
408
408
  const headers = new Headers(context.responseHeaders);
409
409
  const { status } = context;
410
- if (!result) { return new Response(null, { status, headers }); }
410
+ if (!result == null) { return new Response(null, { status, headers }); }
411
411
  const body = toBody(result, headers, replacer, aborted);
412
412
  return new Response(body, { status, headers });
413
413
  }).then(response => {
@@ -426,40 +426,151 @@ function main(request, getHandler, {
426
426
  return exec(request);
427
427
  }
428
428
 
429
- /** @import { FindHandler, Options } from './main/types' */
429
+ /** @import { Method, Params } from './main/types' */
430
430
 
431
431
  /**
432
- *
433
- * @param {FindHandler} getHandler
434
- * @param {Options} options
435
- * @returns {(request: Request) => Promise<Response | null>}
432
+ * @template {Function} T
433
+ * @typedef {[T | T[] | Router<T>, Record<string | symbol, any>, string[]]} FindItem
436
434
  */
437
- function make(getHandler, options) {
438
- return r => main(r, getHandler, options);
435
+ /**
436
+ * @template {Function} T
437
+ * @callback Finder
438
+ * @this {Router<T>}
439
+ * @param {Method} method
440
+ * @param {string[]} path
441
+ * @returns {AsyncIterable<FindItem<T>> | Iterable<FindItem<T>>}
442
+ */
443
+
444
+ /**
445
+ * @abstract
446
+ * @template {Function} T
447
+ */
448
+ class Router {
449
+ disabled = false;
450
+ /**
451
+ *
452
+ * @template {Function} T
453
+ * @param {Router<T> | T[] | T} route
454
+ * @param {Method} method
455
+ * @param {string[]} path
456
+ * @param {Params} params
457
+ * @param {AbortSignal?} [signal]
458
+ * @param {((v: Params) => void)?} [setParams]
459
+ * @returns {Promise<T[] | null>}
460
+ */
461
+ static async #find(route, method, path, params, signal, setParams) {
462
+ if (!(route instanceof Router)) {
463
+ if (typeof setParams === 'function') { setParams(params); }
464
+ // @ts-ignore
465
+ return [route].flat();
466
+ }
467
+ if (route.disabled) { return null; }
468
+ if (signal?.aborted) { return null; }
469
+ for await (const [r, result, p] of route.find(method, path)) {
470
+ if (signal?.aborted) { return null; }
471
+ const res = await Router.#find(r, method, p, { ...params, ...result }, signal, setParams);
472
+ if (res) { return [...route.#guards, ...res]; }
473
+ }
474
+ return null;
475
+ }
476
+ /**
477
+ *
478
+ * @template {Function} T
479
+ * @param {Router<T>[]} routers
480
+ * @param {Method} method
481
+ * @param {string[]} path
482
+ * @param {AbortSignal?} [signal]
483
+ * @param {((v: Params) => void)?} [setParams]
484
+ * @returns {Promise<T[] | null>}
485
+ */
486
+ static async find(routers, method, path, signal, setParams) {
487
+ const m = `${method}`.toUpperCase();
488
+ for (const route of routers.flat()) {
489
+ const res = await Router.#find(route, m, path, {}, signal, setParams);
490
+ if (res) { return res; }
491
+ }
492
+ return null;
493
+ }
494
+ /**
495
+ * @abstract
496
+ * @param {Method} method
497
+ * @param {string[]} path
498
+ * @returns {AsyncIterable<FindItem<T>> | Iterable<FindItem<T>>}
499
+ */
500
+ find(method, path) { return []; }
501
+
502
+
503
+ /** @type {T[]} */
504
+ #guards = [];
505
+ /**
506
+ *
507
+ * @param {...T | T[]} guards
508
+ */
509
+ guard(...guards) {
510
+ const list = this.#guards;
511
+ for (const guard of guards.flat()) {
512
+ if (typeof guard !== 'function') { continue; }
513
+ // @ts-ignore
514
+ list.push(guard);
515
+ }
516
+ }
517
+
518
+ /**
519
+ *
520
+ * @template {Function} T
521
+ * @param {Finder<T>} find
522
+ * @returns {Router<T>}
523
+ */
524
+ static create(find) {
525
+ return Object.defineProperties(new Router(), {
526
+ 'find': { configurable: true, value: find, writable: true },
527
+ });
528
+ }
439
529
  }
440
530
 
441
- /** @import { Context, Handler, HandlerResult } from './main/types' */
531
+ /** @import { FindHandler, Handler, Options } from './main/types' */
532
+
533
+ /**
534
+ *
535
+ * @param {string} t
536
+ * @returns
537
+ */
538
+ function uriDecode(t) {
539
+ try {
540
+ return decodeURIComponent(t);
541
+ } catch {
542
+ return t;
543
+ }
544
+ }
442
545
  /**
443
546
  *
444
- * @param {Context} context
445
- * @param {Handler[]} handlers
446
- * @returns {Promise<HandlerResult>}
547
+ * @param {Router<Handler> | Router<Handler>[] | FindHandler} routers
548
+ * @param {Options} options
549
+ * @returns {(request: Request) => Promise<Response | null>}
447
550
  */
448
- async function runHandles(context, handlers) {
449
- for (const handle of handlers) {
450
- const result = await handle(context);
451
- if (result === undefined) { continue; }
452
- return result;
551
+ function make(routers, options) {
552
+ if (typeof routers === 'function') {
553
+ return r => main(r, routers, options);
453
554
  }
555
+ const list = [routers].flat();
556
+ /** @type {FindHandler} */
557
+ const getHandler = (ctx, setParams) => {
558
+ const path = ctx.url.pathname.split('/').filter(Boolean).map(uriDecode);
559
+ return Router.find(list, ctx.method, path, ctx.signal, setParams);
560
+ };
561
+ return r => main(r, getHandler, options);
454
562
  }
455
563
 
564
+ /** @import { FindHandler, Options } from './main/types' */
565
+
456
566
  /**
457
567
  *
458
- * @param {...(Handler | Handler[])} handlers
459
- * @returns {Handler}
568
+ * @param {FindHandler} getHandler
569
+ * @param {Options} options
570
+ * @returns {(request: Request) => Promise<Response | null>}
460
571
  */
461
- function merge(...handlers) {
462
- return ctx => runHandles(ctx, handlers.flat());
572
+ function bind$1(getHandler, options) {
573
+ return r => main(r, getHandler, options);
463
574
  }
464
575
 
465
576
  /** @import { Context, Service } from './main/types' */
@@ -641,151 +752,6 @@ function storeService(destroy, exec, options) {
641
752
  return service;
642
753
  }
643
754
 
644
- /** @import { Handler } from './main/types' */
645
- /** @import { Onionskin } from './onionskin.mjs' */
646
- /**
647
- * @callback Packer
648
- * @param {Handler | Handler[]} handler
649
- * @returns {Handler | Handler[]}
650
- */
651
-
652
-
653
- /** @type {Packer} */
654
- const noop$1 = h => h;
655
- /**
656
- *
657
- * @param {Onionskin} onionskin
658
- * @param {Packer} [packer]
659
- * @returns {Packer}
660
- */
661
- function packer(onionskin, packer = noop$1) {
662
- return h => {
663
- const handler = packer(h);
664
- return async (ctx) => onionskin(ctx, async () => runHandles(ctx, [handler].flat()));
665
- };
666
- }
667
-
668
- /** @import { Context, FindHandler, Handler, Method, Params } from './main/types' */
669
- /** @import { Onionskin } from './onionskin.mjs' */
670
-
671
- /**
672
- * @callback Guard
673
- * @param {Context} ctx
674
- * @returns {PromiseLike<boolean | Handler | void> | boolean | Handler | void}
675
- */
676
- /**
677
- * @typedef {[Handler | Handler[] | Router, Record<string | symbol, any>, string[]]} FindItem
678
- */
679
- /**
680
- * @callback Finder
681
- * @this {Router}
682
- * @param {Method} method
683
- * @param {string[]} path
684
- * @param {Context} ctx
685
- * @returns {AsyncIterable<FindItem> | Iterable<FindItem>}
686
- */
687
-
688
-
689
- /**
690
- *
691
- * @param {string} t
692
- * @returns
693
- */
694
- function uriDecode(t) {
695
- try {
696
- return decodeURIComponent(t);
697
- } catch {
698
- return t;
699
- }
700
- }
701
- /**
702
- * @abstract
703
- */
704
- class Router {
705
- disabled = false;
706
- /**
707
- *
708
- * @param {Router | Handler[] | Handler} route
709
- * @param {string[]} path
710
- * @param {Context} ctx
711
- * @param {(v: Params) => void} setParams
712
- * @param {Params} params
713
- * @returns {Promise<Handler[] | null>}
714
- */
715
- static async #find(route, path, ctx, setParams, params) {
716
- if (!(route instanceof Router)) {
717
- setParams(params);
718
- return [route].flat();
719
- }
720
- if (route.disabled) { return null; }
721
- if (ctx.destroyed) { return null; }
722
- for await (const [r, result, p] of route.find(ctx.method, path, ctx)) {
723
- if (ctx.destroyed) { return null; }
724
- const res = await Router.#find(r, p, ctx, setParams, { ...params, ...result });
725
- if (res) { return [route.#guards, route.#onionskin(res)].flat(); }
726
- }
727
- return null;
728
- }
729
- /**
730
- * @abstract
731
- * @param {Method} method
732
- * @param {string[]} path
733
- * @param {Context} ctx
734
- * @returns {AsyncIterable<FindItem> | Iterable<FindItem>}
735
- */
736
- find(method, path, ctx) { return []; }
737
- /**
738
- *
739
- * @param {Router[]} routers
740
- * @returns {FindHandler}
741
- */
742
- static make(routers) {
743
- return async (ctx, setParams) => {
744
- const list = routers.flat();
745
- const path = ctx.url.pathname.split('/').filter(Boolean).map(uriDecode);
746
- for (const route of list) {
747
- const res = await Router.#find(route, path, ctx, setParams, {});
748
- if (res) { return res; }
749
- }
750
- return null;
751
- };
752
- }
753
-
754
-
755
- /** @type {Handler[]} */
756
- #guards = [];
757
- /**
758
- *
759
- * @param {...Handler | Handler[]} guards
760
- */
761
- guard(...guards) {
762
- const list =this.#guards;
763
- for (const guard of guards.flat()) {
764
- if (typeof guard !== 'function') { continue; }
765
- list.push(guard);
766
- }
767
- }
768
-
769
- /**
770
- *
771
- * @param {Finder} find
772
- * @returns {Router}
773
- */
774
- static create(find) {
775
- return Object.defineProperties(new Router(), {
776
- 'find': { configurable: true, value: find, writable: true },
777
- });
778
- }
779
- /**
780
- *
781
- * @param {Handler | Handler[]} h
782
- * @returns {Handler | Handler[]}
783
- */
784
- #onionskin = (h) => h;
785
- /** @param {Onionskin} os */
786
- onionskin(os) { this.#onionskin = packer(os, this.#onionskin); }
787
- }
788
-
789
755
  /** @import { Match } from './index.mjs' */
790
756
  /** @import { Params } from '../main/types.js' */
791
757
  /**
@@ -968,19 +934,20 @@ function toMatch(path, end) {
968
934
  return path => exec(list, path, end);
969
935
  }
970
936
 
971
- /** @import { Handler, Method } from '../main/types' */
937
+ /** @import { Method } from '../main/types' */
972
938
  /** @import { Binder, Match, Route, RouterRoute } from './index.mjs' */
973
939
 
974
940
  /**
975
941
  *
976
- * @param {(Route | RouterRoute)[]} routes
942
+ * @template {Function} T
943
+ * @param {(Route<T> | RouterRoute<T>)[]} routes
977
944
  * @param {Set<Method>} methods
978
945
  * @param {Match | undefined} match
979
- * @param {Handler[]} handlers
946
+ * @param {T[]} handlers
980
947
  * @returns {() => void}
981
948
  */
982
949
  function bind(routes, methods, match, handlers) {
983
- /** @type {Route} */
950
+ /** @type {Route<T>} */
984
951
  const route = { match, methods, handlers: handlers };
985
952
  routes.push(route);
986
953
  let removed = false;
@@ -992,45 +959,45 @@ function bind(routes, methods, match, handlers) {
992
959
  routes.splice(index, 1);
993
960
  };
994
961
  }
995
- /** @type {(v: any) => v is Handler} */
962
+ /** @type {(v: any) => v is Function} */
996
963
  const findHandler = v => typeof v === 'function';
997
964
  /**
998
965
  *
999
- * @param {(Route | RouterRoute)[]} routes
966
+ * @template {Function} T
967
+ * @param {(Route<T> | RouterRoute<T>)[]} routes
1000
968
  * @param {Iterable<Method>} methods
1001
969
  * @param {any[]} p
1002
- * @returns {Binder | (() => void)}
970
+ * @returns {Binder<T> | (() => void)}
1003
971
  */
1004
972
  function verb(routes, methods, p) {
1005
973
  const methodSet = new Set(methods);
1006
974
  if (!p.length) {
1007
975
  const match = undefined;
1008
- /** @type {Binder} */
976
+ /** @type {Binder<T>} */
1009
977
  return (...handlers) => bind(routes, methodSet, match, handlers);
1010
978
  }
1011
979
  const [path] = p;
1012
980
  if (path && typeof path === 'object') {
1013
981
  const match = toMatch([path, p.slice(1)], true);
1014
- /** @type {Binder} */
982
+ /** @type {Binder<T>} */
1015
983
  return (...handlers) => bind(routes, methodSet, match, handlers);
1016
984
  }
1017
985
  const match = toMatch(typeof path === 'string' ? path : '', true);
1018
986
  const handlers = p.filter(findHandler);
1019
987
  if (!handlers.length) {
1020
- /** @type {Binder} */
988
+ /** @type {Binder<T>} */
1021
989
  return (...handlers) => bind(routes, methodSet, match, handlers);
1022
990
  }
1023
991
  return bind(routes, methodSet, match, handlers);
1024
992
  }
1025
993
 
1026
994
  /** @import { Method } from '../main/types' */
1027
- const methods = new Set(['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS']);
1028
995
  /**
1029
996
  *
1030
997
  * @param {any} v
1031
998
  * @returns {v is Method}
1032
999
  */
1033
- function isMethod(v) { return methods.has(v); }
1000
+ function isMethod(v) { return Boolean(v); }
1034
1001
  /**
1035
1002
  *
1036
1003
  * @param {Method | Iterable<Method> | ArrayLike<Method>} [methods]
@@ -1048,7 +1015,7 @@ function getMethods(methods) {
1048
1015
  .filter(isMethod);
1049
1016
  }
1050
1017
 
1051
- /** @import { Context, Handler, Method, Params } from '../main/types' */
1018
+ /** @import { Handler, Method, Params } from '../main/types' */
1052
1019
  /** @import { Finder, FindItem } from '../Router.mjs' */
1053
1020
 
1054
1021
  /**
@@ -1057,78 +1024,125 @@ function getMethods(methods) {
1057
1024
  * @returns {[Params, string[]] | undefined}
1058
1025
  */
1059
1026
 
1060
- /** @typedef {(handler: Handler, ...handlers: Handler[]) => () => void} Binder */
1027
+ /**
1028
+ * @template {Function} T
1029
+ * @typedef {(handler: T, ...handlers: T[]) => () => void} Binder
1030
+ */
1031
+
1061
1032
 
1062
1033
  /**
1034
+ * @template {Function} T
1035
+ * @callback Verb1
1036
+ * @param {T} handler 要注册的处理函数
1037
+ * @param {...T} handlers 要注册的处理函数
1038
+ * @returns {() => void}
1039
+ */
1040
+ /**
1041
+ * @template {Function} T
1042
+ * @callback Verb2
1043
+ * @param {string} path 要注册的路径
1044
+ * @param {T} handler 要注册的处理函数
1045
+ * @param {...T} handlers 要注册的处理函数
1046
+ * @returns {() => void}
1047
+ */
1048
+ /**
1049
+ * @template {Function} T
1050
+ * @callback Verb3
1051
+ * @param {string} path 要注册的路径
1052
+ * @returns {Binder<T>}
1053
+ */
1054
+ /**
1055
+ * @template {Function} T
1056
+ * @callback Verb4
1057
+ * @param {TemplateStringsArray} template 要注册的路径模板
1058
+ * @param {...any} substitutions 要注册的路径模板代替内容
1059
+ * @returns {Binder<T>}
1060
+ */
1061
+ /**
1062
+ * @template {Function} T
1063
+ * @typedef {Verb1<T> & Verb2<T> & Verb3<T> & Verb4<T>} Verb
1064
+ */
1065
+
1066
+ /**
1067
+ * @template {Function} T
1063
1068
  * @typedef {object} Route
1064
1069
  * @property {Match} [match] 路径匹配
1065
1070
  * @property {null} [router]
1066
- * @property {Handler[]} handlers 处理函数
1071
+ * @property {T[]} handlers 处理函数
1067
1072
  * @property {Set<Method>} methods 方法列表
1068
1073
  */
1069
1074
 
1070
1075
  /**
1076
+ * @template {Function} T
1071
1077
  * @typedef {object} RouterRoute
1072
1078
  * @property {Match} [match] 路径匹配
1073
- * @property {Router} router
1079
+ * @property {Router<T>} router
1074
1080
  */
1075
1081
 
1076
1082
 
1077
1083
  /**
1078
- * @template {Router | Finder} [T=ApiRouter]
1084
+ * @template {Function} T
1085
+ * @template {Router<T> | Finder<T>} [P=MapRouter<T>]
1079
1086
  * @callback RouteBinder
1080
- * @param {T} [router] 要注册的子路由或子路由的 Finder
1081
- * @returns {T extends Finder ? Router : T}
1087
+ * @param {P} [router] 要注册的子路由或子路由的 Finder<T>
1088
+ * @returns {P extends Finder<T> ? Router<T> : P}
1082
1089
  */
1083
1090
  /**
1084
1091
  *
1085
- * @param {(Route | RouterRoute)[]} routes
1092
+ * @template {Function} T
1093
+ * @param {(Route<T> | RouterRoute<T>)[]} routes
1086
1094
  * @param {string | [string[], any[]]} path
1087
- * @param {Router | Finder} [r]
1088
- * @returns {Router}
1095
+ * @param {Router<T> | Finder<T>} [r]
1096
+ * @returns {Router<T>}
1089
1097
  */
1090
1098
  function bindRouter(routes, path, r) {
1099
+ /** @type {Router<T>} */
1091
1100
  const router = r instanceof Router ? r
1092
1101
  : typeof r === 'function' ? Router.create(r)
1093
- : new ApiRouter();
1102
+ : new MapRouter();
1094
1103
  routes.push({ match: toMatch(path, false), router });
1095
1104
  return router;
1096
1105
  }
1097
- class ApiRouter extends Router {
1098
- /** @readonly @type {(Route | RouterRoute)[]} 路由列表 */
1106
+ /**
1107
+ *
1108
+ * @template {Function} T
1109
+ * @extends {Router<T>}
1110
+ */
1111
+ class MapRouter extends Router {
1112
+ /** @readonly @type {(Route<T> | RouterRoute<T>)[]} 路由列表 */
1099
1113
  #routes = [];
1100
1114
  /**
1101
1115
  * 添加子路由
1102
- * @template {Router | Finder} [T=ApiRouter]
1116
+ * @template {Router<T> | Finder<T>} [P=MapRouter<T>]
1103
1117
  * @overload
1104
- * @param {T} [router] 要注册的子路由或子路由的 Finder
1105
- * @returns {T extends Finder ? Router : T}
1118
+ * @param {P} [router] 要注册的子路由或子路由的 Finder<T>
1119
+ * @returns {P extends Finder<T> ? Router<T> : P}
1106
1120
  */
1107
1121
  /**
1108
1122
  * 添加子路由
1109
- * @template {Router | Finder} [T=ApiRouter]
1123
+ * @template {Router<T> | Finder<T>} [P=MapRouter<T>]
1110
1124
  * @overload
1111
1125
  * @param {string} path 要注册的路径
1112
- * @param {T} [router] 要注册的子路由或子路由的 Finder
1113
- * @returns {T extends Finder ? Router : T}
1126
+ * @param {P} [router] 要注册的子路由或子路由的 Finder<T>
1127
+ * @returns {P extends Finder<T> ? Router<T> : P}
1114
1128
  */
1115
1129
  /**
1116
1130
  * 添加子路由
1117
1131
  * @overload
1118
1132
  * @param {TemplateStringsArray} template 要注册的路径模板
1119
1133
  * @param {...any} substitutions 要注册的路径模板代替内容
1120
- * @returns {RouteBinder}
1134
+ * @returns {RouteBinder<T>}
1121
1135
  */
1122
1136
  /**
1123
1137
  * 添加子路由
1124
1138
  * @param {...any} p 要注册的路径
1125
- * @returns {Router | RouteBinder}
1139
+ * @returns {Router<T> | RouteBinder<T>}
1126
1140
  */
1127
1141
  route(...p) {
1128
1142
  const [a] = p;
1129
1143
  if (a && typeof a === 'object' && !(a instanceof Router)) {
1130
1144
  /**
1131
- * @param { Finder | Router} [r];
1145
+ * @param { Finder<T> | Router<T>} [r];
1132
1146
  * @returns {any}
1133
1147
  */
1134
1148
  return r => bindRouter(this.#routes, [a, p.slice(1)], r);
@@ -1141,10 +1155,9 @@ class ApiRouter extends Router {
1141
1155
  *
1142
1156
  * @param {Method} method
1143
1157
  * @param {string[]} path
1144
- * @param {Context} ctx
1145
- * @returns {Iterable<FindItem>}
1158
+ * @returns {Iterable<FindItem<T>>}
1146
1159
  */
1147
- *find(method, path, ctx) {
1160
+ *find(method, path) {
1148
1161
  for (const route of Array.from(this.#routes)) {
1149
1162
  if (!route.router && !route.methods.has(method)) { continue; }
1150
1163
  const {match} = route;
@@ -1164,7 +1177,7 @@ class ApiRouter extends Router {
1164
1177
  * 注册处理函数
1165
1178
  * @overload
1166
1179
  * @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
1167
- * @param {Handler} handler 要注册的处理函数
1180
+ * @param {T} handler 要注册的处理函数
1168
1181
  * @returns {() => void}
1169
1182
  */
1170
1183
  /**
@@ -1172,7 +1185,7 @@ class ApiRouter extends Router {
1172
1185
  * @overload
1173
1186
  * @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
1174
1187
  * @param {string} path 要注册的路径
1175
- * @param {Handler} handler 要注册的处理函数
1188
+ * @param {T} handler 要注册的处理函数
1176
1189
  * @returns {() => void}
1177
1190
  */
1178
1191
  /**
@@ -1180,48 +1193,58 @@ class ApiRouter extends Router {
1180
1193
  * @overload
1181
1194
  * @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
1182
1195
  * @param {string} path 要注册的路径
1183
- * @returns {Binder}
1196
+ * @returns {Binder<T>}
1184
1197
  */
1185
1198
  /**
1186
1199
  * @param {Method | Iterable<Method> | ArrayLike<Method>} methods
1187
- * @param {string| Handler} [path]
1188
- * @param {...Handler} handler
1189
- * @returns {Binder | (() => void)}
1200
+ * @param {string| T} [path]
1201
+ * @param {...T} handler
1202
+ * @returns {Binder<T> | (() => void)}
1190
1203
  */
1191
1204
  verb(methods, path, ...handler) {
1192
1205
  const allMethods = getMethods(methods);
1193
1206
  if (!allMethods.length) { return () => {}; }
1194
1207
  return verb(this.#routes, allMethods, [path, ...handler]);
1195
1208
  }
1209
+
1210
+ /**
1211
+ * @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
1212
+ * @returns {Verb<T>}
1213
+ */
1214
+ method(method) {
1215
+ const methods = getMethods(method);
1216
+ // @ts-ignore
1217
+ return (...p) => verb(this.#routes, methods, p);
1218
+ }
1196
1219
  /**
1197
1220
  * 注册 HTTP GET/POST/PUT/DELETE 处理函数
1198
1221
  * @overload
1199
- * @param {...Handler} handlers 要注册的处理函数
1222
+ * @param {...T} handlers 要注册的处理函数
1200
1223
  * @returns {() => void}
1201
1224
  */
1202
1225
  /**
1203
1226
  * 注册处理函数
1204
1227
  * @overload
1205
1228
  * @param {string} path 要注册的路径
1206
- * @param {...Handler} handlers 要注册的处理函数
1229
+ * @param {...T} handlers 要注册的处理函数
1207
1230
  * @returns {() => void}
1208
1231
  */
1209
1232
  /**
1210
1233
  * 注册 HTTP GET/POST/PUT/DELETE 处理函数
1211
1234
  * @overload
1212
1235
  * @param {string} path 要注册的路径
1213
- * @returns {Binder}
1236
+ * @returns {Binder<T>}
1214
1237
  */
1215
1238
  /**
1216
1239
  * 注册 HTTP GET/POST/PUT/DELETE 处理函数
1217
1240
  * @overload
1218
1241
  * @param {TemplateStringsArray} template 要注册的路径模板
1219
1242
  * @param {...any} substitutions 要注册的路径模板代替内容
1220
- * @returns {Binder}
1243
+ * @returns {Binder<T>}
1221
1244
  */
1222
1245
  /**
1223
1246
  * @param {...any} p 要注册的路径
1224
- * @returns {Binder | (() => void)}
1247
+ * @returns {Binder<T> | (() => void)}
1225
1248
  */
1226
1249
  match(...p) {
1227
1250
  return verb(this.#routes, ['GET', 'POST', 'PUT', 'DELETE'], p);
@@ -1243,18 +1266,18 @@ class ApiRouter extends Router {
1243
1266
  * 注册 HTTP GET 处理函数
1244
1267
  * @overload
1245
1268
  * @param {string} path 要注册的路径
1246
- * @returns {Binder}
1269
+ * @returns {Binder<T>}
1247
1270
  */
1248
1271
  /**
1249
1272
  * 注册 HTTP GET 处理函数
1250
1273
  * @overload
1251
1274
  * @param {TemplateStringsArray} template 要注册的路径模板
1252
1275
  * @param {...any} substitutions 要注册的路径模板代替内容
1253
- * @returns {Binder}
1276
+ * @returns {Binder<T>}
1254
1277
  */
1255
1278
  /**
1256
1279
  * @param {...any} p 要注册的路径
1257
- * @returns {Binder | (() => void)}
1280
+ * @returns {Binder<T> | (() => void)}
1258
1281
  */
1259
1282
  get(...p) { return verb(this.#routes, ['GET'], p); }
1260
1283
  /**
@@ -1274,18 +1297,18 @@ class ApiRouter extends Router {
1274
1297
  * 注册 HTTP POST 处理函数
1275
1298
  * @overload
1276
1299
  * @param {string} path 要注册的路径
1277
- * @returns {Binder}
1300
+ * @returns {Binder<T>}
1278
1301
  */
1279
1302
  /**
1280
1303
  * 注册 HTTP POST 处理函数
1281
1304
  * @overload
1282
1305
  * @param {TemplateStringsArray} template 要注册的路径模板
1283
1306
  * @param {...any} substitutions 要注册的路径模板代替内容
1284
- * @returns {Binder}
1307
+ * @returns {Binder<T>}
1285
1308
  */
1286
1309
  /**
1287
1310
  * @param {...any} p 要注册的路径
1288
- * @returns {Binder | (() => void)}
1311
+ * @returns {Binder<T> | (() => void)}
1289
1312
  */
1290
1313
  post(...p) { return verb(this.#routes, ['POST'], p); }
1291
1314
  /**
@@ -1305,18 +1328,18 @@ class ApiRouter extends Router {
1305
1328
  * 注册 HTTP PUT 处理函数
1306
1329
  * @overload
1307
1330
  * @param {string} path 要注册的路径
1308
- * @returns {Binder}
1331
+ * @returns {Binder<T>}
1309
1332
  */
1310
1333
  /**
1311
1334
  * 注册 HTTP PUT 处理函数
1312
1335
  * @overload
1313
1336
  * @param {TemplateStringsArray} template 要注册的路径模板
1314
1337
  * @param {...any} substitutions 要注册的路径模板代替内容
1315
- * @returns {Binder}
1338
+ * @returns {Binder<T>}
1316
1339
  */
1317
1340
  /**
1318
1341
  * @param {...any} p 要注册的路径
1319
- * @returns {Binder | (() => void)}
1342
+ * @returns {Binder<T> | (() => void)}
1320
1343
  */
1321
1344
  put(...p) { return verb(this.#routes, ['PUT'], p); }
1322
1345
  /**
@@ -1336,18 +1359,18 @@ class ApiRouter extends Router {
1336
1359
  * 注册 HTTP DELETE 处理函数
1337
1360
  * @overload
1338
1361
  * @param {string} path 要注册的路径
1339
- * @returns {Binder}
1362
+ * @returns {Binder<T>}
1340
1363
  */
1341
1364
  /**
1342
1365
  * 注册 HTTP DELETE 处理函数
1343
1366
  * @overload
1344
1367
  * @param {TemplateStringsArray} template 要注册的路径模板
1345
1368
  * @param {...any} substitutions 要注册的路径模板代替内容
1346
- * @returns {Binder}
1369
+ * @returns {Binder<T>}
1347
1370
  */
1348
1371
  /**
1349
1372
  * @param {...any} p 要注册的路径
1350
- * @returns {Binder | (() => void)}
1373
+ * @returns {Binder<T> | (() => void)}
1351
1374
  */
1352
1375
  delete(...p) { return verb(this.#routes, ['DELETE'], p); }
1353
1376
  /**
@@ -1367,18 +1390,18 @@ class ApiRouter extends Router {
1367
1390
  * 注册 HTTP HEAD 处理函数
1368
1391
  * @overload
1369
1392
  * @param {string} path 要注册的路径
1370
- * @returns {Binder}
1393
+ * @returns {Binder<T>}
1371
1394
  */
1372
1395
  /**
1373
1396
  * 注册 HTTP HEAD 处理函数
1374
1397
  * @overload
1375
1398
  * @param {TemplateStringsArray} template 要注册的路径模板
1376
1399
  * @param {...any} substitutions 要注册的路径模板代替内容
1377
- * @returns {Binder}
1400
+ * @returns {Binder<T>}
1378
1401
  */
1379
1402
  /**
1380
1403
  * @param {...any} p 要注册的路径
1381
- * @returns {Binder | (() => void)}
1404
+ * @returns {Binder<T> | (() => void)}
1382
1405
  */
1383
1406
  head(...p) { return verb(this.#routes, ['HEAD'], p); }
1384
1407
  /**
@@ -1398,18 +1421,18 @@ class ApiRouter extends Router {
1398
1421
  * 注册 HTTP OPTIONS 处理函数
1399
1422
  * @overload
1400
1423
  * @param {string} path 要注册的路径
1401
- * @returns {Binder}
1424
+ * @returns {Binder<T>}
1402
1425
  */
1403
1426
  /**
1404
1427
  * 注册 HTTP OPTIONS 处理函数
1405
1428
  * @overload
1406
1429
  * @param {TemplateStringsArray} template 要注册的路径模板
1407
1430
  * @param {...any} substitutions 要注册的路径模板代替内容
1408
- * @returns {Binder}
1431
+ * @returns {Binder<T>}
1409
1432
  */
1410
1433
  /**
1411
1434
  * @param {...any} p 要注册的路径
1412
- * @returns {Binder | (() => void)}
1435
+ * @returns {Binder<T> | (() => void)}
1413
1436
  */
1414
1437
  options(...p) { return verb(this.#routes, ['OPTIONS'], p); }
1415
1438
  }
@@ -1437,30 +1460,6 @@ function createFetch(run, notFound) {
1437
1460
  };
1438
1461
  }
1439
1462
 
1440
- /** @import { Context, Handler, HandlerResult } from './main/types' */
1441
- /**
1442
- * @callback Onionskin
1443
- * @param {Context} ctx
1444
- * @param {() => Promise<HandlerResult>} next
1445
- * @returns {PromiseLike<HandlerResult> | HandlerResult}
1446
- */
1447
-
1448
- const noop = () => {};
1449
- /**
1450
- *
1451
- * @param {...(Onionskin | Onionskin[])} handlers
1452
- * @returns {Handler}
1453
- */
1454
- function onionskin(...handlers) {
1455
- /** @type {Handler} */
1456
- let handler = noop;
1457
- for (const os of handlers.flat()) {
1458
- const currentHandler = handler;
1459
- handler = async ctx => os(ctx, async () => currentHandler(ctx));
1460
- }
1461
- return handler;
1462
- }
1463
-
1464
1463
  /** @import { Context } from './main/types.js' */
1465
1464
  class Param {
1466
1465
  #symbol = Symbol();
@@ -1497,4 +1496,4 @@ class Param {
1497
1496
  }
1498
1497
  }
1499
1498
 
1500
- export { ApiRouter, Param, Router, createFetch, main, make, merge, onionskin, packer, service, stateService, storeService };
1499
+ export { MapRouter, Param, Router, bind$1 as bind, createFetch, main, make, service, stateService, storeService };