k99 0.7.1 → 0.8.0

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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * k99 v0.7.1
3
- * (c) 2019-2025 猛火Fierflame
2
+ * k99 v0.8.0
3
+ * (c) 2019-2026 猛火Fierflame
4
4
  * @license MIT
5
5
  */
6
6
  (function (global, factory) {
@@ -12,9 +12,10 @@
12
12
  /**
13
13
  *
14
14
  * @param {string} str
15
- * @returns {Uint8Array}
15
+ * @returns {Uint8Array<ArrayBuffer>}
16
16
  */
17
17
  function str2utf8bin(str) {
18
+ // @ts-ignore
18
19
  return new TextEncoder().encode(str);
19
20
  }
20
21
  /**
@@ -53,26 +54,15 @@
53
54
  }
54
55
  }
55
56
 
56
- /**
57
- *
58
- * @param {any} k
59
- * @param {any} v
60
- * @returns {any}
61
- */
62
- function replacer(k, v) {
63
- if (typeof v === 'bigint') {
64
- return String(v);
65
- }
66
- return v;
67
- }
68
57
 
69
58
  /**
70
59
  *
71
60
  * @param {any} result
61
+ * @param {(this: any, key: string, value: any) => any} replacer
72
62
  * @param {Promise<never>} [aborted]
73
63
  * @returns {[BodyInit, number, string] | null}
74
64
  */
75
- function toBodyData(result, aborted) {
65
+ function toBodyData(result, replacer, aborted) {
76
66
  if (result instanceof ReadableStream) {
77
67
  return [result, 0, ''];
78
68
  }
@@ -86,11 +76,16 @@
86
76
  return [result, 0, ''];
87
77
  }
88
78
  if (ArrayBuffer.isView(result) || result instanceof ArrayBuffer) {
79
+ // @ts-ignore
89
80
  return [result, result.byteLength, ''];
90
81
  }
91
82
  if (typeof result === 'string') {
92
83
  const body = str2utf8bin(result);
93
- return [body, body.byteLength, ''];
84
+ return [body, body.byteLength, 'text/plain'];
85
+ }
86
+ if (['bigint', 'boolean', 'number'].includes(typeof result)) {
87
+ const body = str2utf8bin(JSON.stringify(result, replacer));
88
+ return [body, body.byteLength, 'application/json'];
94
89
  }
95
90
  if (typeof result !== 'object') {
96
91
  return null;
@@ -117,11 +112,12 @@
117
112
  *
118
113
  * @param {any} result
119
114
  * @param {Headers} headers
115
+ * @param {(this: any, key: string, value: any) => any} replacer
120
116
  * @param {Promise<never>} [aborted]
121
117
  * @returns
122
118
  */
123
- function toBody(result, headers, aborted) {
124
- const bodyData = toBodyData(result, aborted);
119
+ function toBody(result, headers, replacer, aborted) {
120
+ const bodyData = toBodyData(result, replacer, aborted);
125
121
  if (!bodyData) { return null; }
126
122
  const [body, size, type] = bodyData;
127
123
  if (type && !headers.get('Content-Type')) {
@@ -215,7 +211,7 @@
215
211
  }
216
212
  }
217
213
 
218
- /** @import { Context, Cookie, CookieOption, FindHandler, Method, Options, Params, Service } from './types' */
214
+ /** @import { Context, Cookie, CookieOption, FindHandler, HandlerResult, Method, Options, Params, Service } from './types' */
219
215
 
220
216
 
221
217
  const noBodyMethods = new Set(['GET', 'OPTIONS']);
@@ -268,6 +264,18 @@
268
264
  }
269
265
  return /** @type {Method} */(methodStr.toUpperCase());
270
266
  }
267
+ /**
268
+ *
269
+ * @param {any} k
270
+ * @param {any} v
271
+ * @returns {any}
272
+ */
273
+ function defaultReplacer(k, v) {
274
+ if (typeof v === 'bigint') {
275
+ return String(v);
276
+ }
277
+ return v;
278
+ }
271
279
  /**
272
280
  *
273
281
  * @param {Request} request
@@ -275,10 +283,15 @@
275
283
  * @param {Options} [options]
276
284
  * @returns {Promise<Response | null>}
277
285
  */
278
- function main(
279
- request, getHandler,
280
- { runner, error: echoError, catch: catchError, method: toMethod, environment } = {},
281
- ) {
286
+ function main(request, getHandler, {
287
+ runner,
288
+ error: echoError,
289
+ catch: catchError,
290
+ method: toMethod,
291
+ environment,
292
+ replacer: JSONReplacer,
293
+ } = {}) {
294
+ const replacer = typeof JSONReplacer === 'function' ? JSONReplacer : defaultReplacer;
282
295
  /**
283
296
  *
284
297
  * @param {Request} request
@@ -302,12 +315,12 @@
302
315
  /** @type {any} */
303
316
  let error = null;
304
317
 
305
- let resolve = () => {};
318
+ let resolve = () => { };
306
319
  /** @type {(error: unknown) => void} */
307
- let reject = () => {};
320
+ let reject = () => { };
308
321
  /** @type {Promise<void>} */
309
322
  const donePromise = new Promise((a, b) => { resolve = a; reject = b; });
310
- donePromise.catch(() => {});
323
+ donePromise.catch(() => { });
311
324
 
312
325
  /** @type {Params} */
313
326
  let params = {};
@@ -325,7 +338,7 @@
325
338
  if (!data || noBodyMethods.has(method.toUpperCase())) {
326
339
  return exec(new Request(fetchUrl, { method, headers, signal }), context);
327
340
  }
328
- const body = toBody(data, headers);
341
+ const body = toBody(data, headers, replacer);
329
342
  return exec(new Request(fetchUrl, { method, headers, signal, body }), context);
330
343
  },
331
344
  done(onfulfilled, onrejected) {
@@ -370,7 +383,7 @@
370
383
  set responseType(type) { setHeader(responseHeaders, 'content-type', type); },
371
384
  getCookie(name) { return getCookie(sentCookies, name); },
372
385
  setCookie(name, value, { expire, domain, path, secure, httpOnly } = {}) {
373
- sentCookies.push({name, value, expire, domain, path, secure, httpOnly});
386
+ sentCookies.push({ name, value, expire, domain, path, secure, httpOnly });
374
387
  setCookiesHeader(responseHeaders, sentCookies);
375
388
  },
376
389
  /**
@@ -388,16 +401,22 @@
388
401
  return Promise.race([
389
402
  aborted,
390
403
  Promise.resolve().then(() => getHandler(context, v => { params = v; })),
391
- ]).then(handler => handler ? Promise.race([aborted, handler(context)]).then(result => {
392
- if (result instanceof Response) {
393
- return result;
404
+ ]).then(async handlers => {
405
+ const allHandlers = [handlers].flat().filter(h => typeof h === 'function');
406
+ if (!allHandlers.length) { return null; }
407
+ /** @type {HandlerResult?} */
408
+ let result;
409
+ for (const handle of allHandlers) {
410
+ result = await Promise.race([aborted, handle(context)]);
411
+ if (result !== undefined) { break; }
394
412
  }
413
+ if (result instanceof Response) { return result; }
395
414
  const headers = new Headers(context.responseHeaders);
396
415
  const { status } = context;
397
416
  if (!result) { return new Response(null, { status, headers }); }
398
- const body = toBody(result, headers, aborted);
417
+ const body = toBody(result, headers, replacer, aborted);
399
418
  return new Response(body, { status, headers });
400
- }) : null).then(response => {
419
+ }).then(response => {
401
420
  destroyed = true;
402
421
  resolve();
403
422
  return response;
@@ -425,12 +444,12 @@
425
444
  return r => main(r, getHandler, options);
426
445
  }
427
446
 
428
- /** @import { Context, Handler } from './main/types' */
447
+ /** @import { Context, Handler, HandlerResult } from './main/types' */
429
448
  /**
430
449
  *
431
450
  * @param {Context} context
432
451
  * @param {Handler[]} handlers
433
- * @returns {Promise<string | boolean | object | undefined>}
452
+ * @returns {Promise<HandlerResult>}
434
453
  */
435
454
  async function runHandles(context, handlers) {
436
455
  for (const handle of handlers) {
@@ -632,9 +651,11 @@
632
651
  /** @import { Onionskin } from './onionskin.mjs' */
633
652
  /**
634
653
  * @callback Packer
635
- * @param {Handler} handler
636
- * @returns {Handler}
654
+ * @param {Handler | Handler[]} handler
655
+ * @returns {Handler | Handler[]}
637
656
  */
657
+
658
+
638
659
  /** @type {Packer} */
639
660
  const noop$1 = h => h;
640
661
  /**
@@ -646,7 +667,7 @@
646
667
  function packer(onionskin, packer = noop$1) {
647
668
  return h => {
648
669
  const handler = packer(h);
649
- return async (ctx) => onionskin(ctx, async () => handler(ctx));
670
+ return async (ctx) => onionskin(ctx, async () => runHandles(ctx, [handler].flat()));
650
671
  };
651
672
  }
652
673
 
@@ -659,7 +680,7 @@
659
680
  * @returns {PromiseLike<boolean | Handler | void> | boolean | Handler | void}
660
681
  */
661
682
  /**
662
- * @typedef {[Handler | Router, Record<string | symbol, any>, string[]]} FindItem
683
+ * @typedef {[Handler | Handler[] | Router, Record<string | symbol, any>, string[]]} FindItem
663
684
  */
664
685
  /**
665
686
  * @callback Finder
@@ -670,55 +691,6 @@
670
691
  * @returns {AsyncIterable<FindItem> | Iterable<FindItem>}
671
692
  */
672
693
 
673
- /**
674
- *
675
- * @param {Set<Guard>} guards
676
- * @param {Context} ctx
677
- * @param {(v: any) => void} setParams
678
- * @param {object} params
679
- * @returns {Promise<boolean | Handler>}
680
- */
681
- async function execGuard(guards, ctx, setParams, params) {
682
- if (!guards.size) { return true; }
683
- setParams(params);
684
- for (const guard of guards) {
685
- if (ctx.destroyed) { return false; }
686
- const ret = await guard(Object.create(ctx, {
687
- params: { value: { ...params } },
688
- }));
689
- if (ret === false) { return false; }
690
- // @ts-ignore
691
- if (typeof ret === 'function') { return ret; }
692
- }
693
- return true;
694
- }
695
-
696
- /**
697
- *
698
- * @param {Router | Handler} route
699
- * @param {string[]} path
700
- * @param {Context} ctx
701
- * @param {(v: Params) => void} setParams
702
- * @param {Params} params
703
- * @returns {Promise<Handler | null>}
704
- */
705
- async function find(route, path, ctx, setParams, params) {
706
- if (!(route instanceof Router)) {
707
- setParams(params);
708
- return route;
709
- }
710
- if (route.disabled) { return null; }
711
- const guardResult = await execGuard(route.guards, ctx, setParams, params);
712
- if (!guardResult) { return null; }
713
- if (typeof guardResult === 'function') { return guardResult; }
714
- if (ctx.destroyed) { return null; }
715
- for await (const [r, result, p] of route.find(ctx.method, path, ctx)) {
716
- if (ctx.destroyed) { return null; }
717
- const res = await find(r, p, ctx, setParams, { ...params, ...result });
718
- if (res) { return route.__onionskin(res); }
719
- }
720
- return null;
721
- }
722
694
 
723
695
  /**
724
696
  *
@@ -737,6 +709,29 @@
737
709
  */
738
710
  class Router {
739
711
  disabled = false;
712
+ /**
713
+ *
714
+ * @param {Router | Handler[] | Handler} route
715
+ * @param {string[]} path
716
+ * @param {Context} ctx
717
+ * @param {(v: Params) => void} setParams
718
+ * @param {Params} params
719
+ * @returns {Promise<Handler[] | null>}
720
+ */
721
+ static async #find(route, path, ctx, setParams, params) {
722
+ if (!(route instanceof Router)) {
723
+ setParams(params);
724
+ return [route].flat();
725
+ }
726
+ if (route.disabled) { return null; }
727
+ if (ctx.destroyed) { return null; }
728
+ for await (const [r, result, p] of route.find(ctx.method, path, ctx)) {
729
+ if (ctx.destroyed) { return null; }
730
+ const res = await Router.#find(r, p, ctx, setParams, { ...params, ...result });
731
+ if (res) { return [route.#guards, route.#onionskin(res)].flat(); }
732
+ }
733
+ return null;
734
+ }
740
735
  /**
741
736
  * @abstract
742
737
  * @param {Method} method
@@ -755,13 +750,28 @@
755
750
  const list = routers.flat();
756
751
  const path = ctx.url.pathname.split('/').filter(Boolean).map(uriDecode);
757
752
  for (const route of list) {
758
- const res = await find(route, path, ctx, setParams, {});
753
+ const res = await Router.#find(route, path, ctx, setParams, {});
759
754
  if (res) { return res; }
760
755
  }
761
756
  return null;
762
757
  };
763
758
  }
764
759
 
760
+
761
+ /** @type {Handler[]} */
762
+ #guards = [];
763
+ /**
764
+ *
765
+ * @param {...Handler | Handler[]} guards
766
+ */
767
+ guard(...guards) {
768
+ const list =this.#guards;
769
+ for (const guard of guards.flat()) {
770
+ if (typeof guard !== 'function') { continue; }
771
+ list.push(guard);
772
+ }
773
+ }
774
+
765
775
  /**
766
776
  *
767
777
  * @param {Finder} find
@@ -772,16 +782,14 @@
772
782
  'find': { configurable: true, value: find, writable: true },
773
783
  });
774
784
  }
775
- /** @readonly @type {Set<Guard>} */
776
- guards = new Set();
777
785
  /**
778
786
  *
779
- * @param {Handler} h
780
- * @returns {Handler}
787
+ * @param {Handler | Handler[]} h
788
+ * @returns {Handler | Handler[]}
781
789
  */
782
- __onionskin = (h) => h;
790
+ #onionskin = (h) => h;
783
791
  /** @param {Onionskin} os */
784
- onionskin(os) { this.__onionskin = packer(os, this.__onionskin); }
792
+ onionskin(os) { this.#onionskin = packer(os, this.#onionskin); }
785
793
  }
786
794
 
787
795
  /** @import { Match } from './index.mjs' */
@@ -979,7 +987,7 @@
979
987
  */
980
988
  function bind(routes, methods, match, handlers) {
981
989
  /** @type {Route} */
982
- const route = { match, methods, handler: ctx => runHandles(ctx, handlers) };
990
+ const route = { match, methods, handlers: handlers };
983
991
  routes.push(route);
984
992
  let removed = false;
985
993
  return () => {
@@ -1061,8 +1069,7 @@
1061
1069
  * @typedef {object} Route
1062
1070
  * @property {Match} [match] 路径匹配
1063
1071
  * @property {null} [router]
1064
- * @property {string} [plugin] 所属插件
1065
- * @property {Handler} handler 处理函数
1072
+ * @property {Handler[]} handlers 处理函数
1066
1073
  * @property {Set<Method>} methods 方法列表
1067
1074
  */
1068
1075
 
@@ -1149,14 +1156,14 @@
1149
1156
  const {match} = route;
1150
1157
  if (!match) {
1151
1158
  if (route.router || !path.length) {
1152
- yield [route.router || route.handler, {}, path];
1159
+ yield [route.router || route.handlers, {}, path];
1153
1160
  }
1154
1161
  continue;
1155
1162
  }
1156
1163
  if (!path.length) { continue; }
1157
1164
  const result = match(path);
1158
1165
  if (!result) { continue; }
1159
- yield [route.router || route.handler, ...result];
1166
+ yield [route.router || route.handlers, ...result];
1160
1167
  }
1161
1168
  }
1162
1169
  /**
@@ -1184,25 +1191,25 @@
1184
1191
  /**
1185
1192
  * @param {Method | Iterable<Method> | ArrayLike<Method>} methods
1186
1193
  * @param {string| Handler} [path]
1187
- * @param {Handler} [handler]
1194
+ * @param {...Handler} handler
1188
1195
  * @returns {Binder | (() => void)}
1189
1196
  */
1190
- verb(methods, path, handler) {
1197
+ verb(methods, path, ...handler) {
1191
1198
  const allMethods = getMethods(methods);
1192
1199
  if (!allMethods.length) { return () => {}; }
1193
- return verb(this.#routes, allMethods, [path, handler]);
1200
+ return verb(this.#routes, allMethods, [path, ...handler]);
1194
1201
  }
1195
1202
  /**
1196
1203
  * 注册 HTTP GET/POST/PUT/DELETE 处理函数
1197
1204
  * @overload
1198
- * @param {Handler} handler 要注册的处理函数
1205
+ * @param {...Handler} handlers 要注册的处理函数
1199
1206
  * @returns {() => void}
1200
1207
  */
1201
1208
  /**
1202
1209
  * 注册处理函数
1203
1210
  * @overload
1204
1211
  * @param {string} path 要注册的路径
1205
- * @param {Handler} handler 要注册的处理函数
1212
+ * @param {...Handler} handlers 要注册的处理函数
1206
1213
  * @returns {() => void}
1207
1214
  */
1208
1215
  /**
@@ -1228,14 +1235,14 @@
1228
1235
  /**
1229
1236
  * 注册 HTTP GET 处理函数
1230
1237
  * @overload
1231
- * @param {Handler} handler 要注册的处理函数
1238
+ * @param {...Handler} handlers 要注册的处理函数
1232
1239
  * @returns {() => void}
1233
1240
  */
1234
1241
  /**
1235
1242
  * 注册 HTTP GET 处理函数
1236
1243
  * @overload
1237
1244
  * @param {string} path 要注册的路径
1238
- * @param {Handler} handler 要注册的处理函数
1245
+ * @param {...Handler} handlers 要注册的处理函数
1239
1246
  * @returns {() => void}
1240
1247
  */
1241
1248
  /**
@@ -1259,14 +1266,14 @@
1259
1266
  /**
1260
1267
  * 注册 HTTP POST 处理函数
1261
1268
  * @overload
1262
- * @param {Handler} handler 要注册的处理函数
1269
+ * @param {...Handler} handlers 要注册的处理函数
1263
1270
  * @returns {() => void}
1264
1271
  */
1265
1272
  /**
1266
1273
  * 注册 HTTP POST 处理函数
1267
1274
  * @overload
1268
1275
  * @param {string} path 要注册的路径
1269
- * @param {Handler} handler 要注册的处理函数
1276
+ * @param {...Handler} handlers 要注册的处理函数
1270
1277
  * @returns {() => void}
1271
1278
  */
1272
1279
  /**
@@ -1290,14 +1297,14 @@
1290
1297
  /**
1291
1298
  * 注册 HTTP PUT 处理函数
1292
1299
  * @overload
1293
- * @param {Handler} handler 要注册的处理函数
1300
+ * @param {...Handler} handlers 要注册的处理函数
1294
1301
  * @returns {() => void}
1295
1302
  */
1296
1303
  /**
1297
1304
  * 注册 HTTP PUT 处理函数
1298
1305
  * @overload
1299
1306
  * @param {string} path 要注册的路径
1300
- * @param {Handler} handler 要注册的处理函数
1307
+ * @param {...Handler} handlers 要注册的处理函数
1301
1308
  * @returns {() => void}
1302
1309
  */
1303
1310
  /**
@@ -1321,14 +1328,14 @@
1321
1328
  /**
1322
1329
  * 注册 HTTP DELETE 处理函数
1323
1330
  * @overload
1324
- * @param {Handler} handler 要注册的处理函数
1331
+ * @param {...Handler} handlers 要注册的处理函数
1325
1332
  * @returns {() => void}
1326
1333
  */
1327
1334
  /**
1328
1335
  * 注册 HTTP DELETE 处理函数
1329
1336
  * @overload
1330
1337
  * @param {string} path 要注册的路径
1331
- * @param {Handler} handler 要注册的处理函数
1338
+ * @param {...Handler} handlers 要注册的处理函数
1332
1339
  * @returns {() => void}
1333
1340
  */
1334
1341
  /**
@@ -1352,14 +1359,14 @@
1352
1359
  /**
1353
1360
  * 注册 HTTP HEAD 处理函数
1354
1361
  * @overload
1355
- * @param {Handler} handler 要注册的处理函数
1362
+ * @param {...Handler} handlers 要注册的处理函数
1356
1363
  * @returns {() => void}
1357
1364
  */
1358
1365
  /**
1359
1366
  * 注册 HTTP HEAD 处理函数
1360
1367
  * @overload
1361
1368
  * @param {string} path 要注册的路径
1362
- * @param {Handler} handler 要注册的处理函数
1369
+ * @param {...Handler} handlers 要注册的处理函数
1363
1370
  * @returns {() => void}
1364
1371
  */
1365
1372
  /**
@@ -1383,14 +1390,14 @@
1383
1390
  /**
1384
1391
  * 注册 HTTP OPTIONS 处理函数
1385
1392
  * @overload
1386
- * @param {Handler} handler 要注册的处理函数
1393
+ * @param {...Handler} handlers 要注册的处理函数
1387
1394
  * @returns {() => void}
1388
1395
  */
1389
1396
  /**
1390
1397
  * 注册 HTTP OPTIONS 处理函数
1391
1398
  * @overload
1392
1399
  * @param {string} path 要注册的路径
1393
- * @param {Handler} handler 要注册的处理函数
1400
+ * @param {...Handler} handlers 要注册的处理函数
1394
1401
  * @returns {() => void}
1395
1402
  */
1396
1403
  /**
package/index.min.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * k99 v0.7.1
3
- * (c) 2019-2025 猛火Fierflame
2
+ * k99 v0.8.0
3
+ * (c) 2019-2026 猛火Fierflame
4
4
  * @license MIT
5
5
  */
6
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).k99={})}(this,(function(t){"use strict";function e(t){return(new TextEncoder).encode(t)}function n(t){return Symbol.asyncIterator in t||Symbol.iterator in t}async function r(t,o){if("string"==typeof o)return t.write(e(o));if("object"==typeof o){if(ArrayBuffer.isView(o))return t.write(new Uint8Array(o.buffer,o.byteOffset,o.byteLength));if(o instanceof ArrayBuffer)return t.write(new Uint8Array(o));if(n(o))for await(const e of o)e&&await r(t,e)}}function o(t,e){return"bigint"==typeof e?String(e):e}function s(t,s,i){const c=function(t,s){if(t instanceof ReadableStream)return[t,0,""];if(t instanceof URLSearchParams)return[t,0,""];if(t instanceof Blob)return[t,t.size,t.type];if(t instanceof FormData)return[t,0,""];if(ArrayBuffer.isView(t)||t instanceof ArrayBuffer)return[t,t.byteLength,""];if("string"==typeof t){const n=e(t);return[n,n.byteLength,""]}if("object"!=typeof t)return null;if(Array.isArray(t)||!n(t)){const n=e(JSON.stringify(t,o));return[n,n.byteLength,"application/json"]}const{writable:i,readable:c}=new TransformStream,u=i.getWriter();return s?.catch((t=>{i.abort(t||new DOMException("The user aborted a request.")).catch((()=>{}))})),(async()=>{for await(const e of t)e&&await r(u,e)})().then((()=>i.close()),(t=>i.abort(t))).catch((()=>{})),[c,0,""]}(t,i);if(!c)return null;const[u,a,f]=c;return f&&!s.get("Content-Type")&&s.set("Content-Type",f),a>0&&!s.get("Content-Length")&&s.set("Content-Length",String(a)),u}function i(t,e){t.delete("set-cookie");for(const{name:n,value:r,expire:o,domain:s,path:i,secure:c,httpOnly:u}of e)n&&t.append("set-cookie",[`${encodeURI(n)}=${encodeURI(r||"")}`,o&&`Expires=${o}`,s&&`Domain=${encodeURI(s)}`,i&&`Path=${encodeURI(i)}`,c&&"Secure",u&&"HttpOnly"].filter(Boolean).join("; "))}const c=new Set(["GET","OPTIONS"]);function u(t,e,n){n?t.set(e,n):t.delete(e)}function a(t,e,{runner:n,error:r,catch:o,method:a,environment:f}={}){return function t(l,p){const h=function(t,e){let n="";return"string"==typeof e?n=e:"function"==typeof e&&(n=e(t)),n&&"string"==typeof n||(n=t.method||"GET"),n.toUpperCase()}(l,a),y=new URL(l.url),{signal:d,headers:g}=l,m=function(t){return new Promise(((e,n)=>{if(t.aborted)return n(t.reason);t.addEventListener("abort",(()=>n(t.reason)),{once:!0})}))}(d),b=new Map,w=function(t){let e={};for(const n of t.replace(/\s/g,"").split(";")){const t=n.split("=");e[decodeURIComponent(t.shift())]=decodeURIComponent(t.join("="))}return e}(g.get("cookie")||""),O=[],T=new Headers,E=p?.root;let j=200,R=!1,S=null,A=()=>{},P=()=>{};const U=new Promise(((t,e)=>{A=t,P=e}));U.catch((()=>{}));let v={};const k={environment:f,parent:p,get error(){return S},get root(){return E||this},signal:d,url:y,fetch(e,{method:n="get",signal:r,body:o,headers:i}={}){const u=new URL(e,y),a=new Headers(i||{});if(!o||c.has(n.toUpperCase()))return t(new Request(u,{method:n,headers:a,signal:r}),k);const f=s(o,a);return t(new Request(u,{method:n,headers:a,signal:r,body:f}),k)},done(t,e){if(R)return null;const n=U.then(t,e);return n.catch(r),n},service(t,...e){if(t.rootOnly&&E)return E.service(t,...e);let n=b.get(t);if(!n){if(n=t(k),"function"!=typeof n)return;b.set(t,n)}return n(...e)},method:h,get params(){return v},requestHeaders:g,requestType:g.get("content-type")||"",referer:g.get("referer")||"",userAgent:g.get("user-agent")||"",accept:(g.get("accept")||"").split(/,\s*/).filter(Boolean),acceptLanguage:(g.get("accept-language")||"").split(/,\s*/).filter(Boolean),cookies:w,request:l,get destroyed(){return R},get status(){return j},set status(t){j=t},responseHeaders:T,get location(){return T.get("location")||""},set location(t){u(T,"location",t)},get responseType(){return T.get("content-type")||""},set responseType(t){u(T,"content-type",t)},getCookie:t=>function*(t,e){const n=t;for(const t of n)e&&t.name!==e||(yield{...t})}(O,t),setCookie(t,e,{expire:n,domain:r,path:o,secure:s,httpOnly:c}={}){O.push({name:t,value:e,expire:n,domain:r,path:o,secure:s,httpOnly:c}),i(T,O)},clearCookie(t,e){!function(t,e,n,r){let o="Fri, 31 Dec 1999 16:00:00 GMT";if("string"==typeof n){if(!n)return;const{domain:e,path:s,secure:i,httpOnly:c}=!0!==r&&r||{};t.push({name:n,value:"delete",expire:o,domain:e,path:s,secure:i,httpOnly:c})}else{const{domain:s,path:i,secure:c,httpOnly:u}=n||{};if(t.length=0,r)for(let n in e)t.push({name:n,value:"delete",expire:o,domain:s,path:i,secure:c,httpOnly:u})}}(O,w,t,e),i(T,O)}};function x(){return Promise.race([m,Promise.resolve().then((()=>e(k,(t=>{v=t}))))]).then((t=>t?Promise.race([m,t(k)]).then((t=>{if(t instanceof Response)return t;const e=new Headers(k.responseHeaders),{status:n}=k;if(!t)return new Response(null,{status:n,headers:e});const r=s(t,e,m);return new Response(r,{status:n,headers:e})})):null)).then((t=>(R=!0,A(),t)),(t=>(R=!0,S=t||!0,P(S),Promise.reject(t)))).catch(o)}return n?n(k,x):x()}(t)}async function f(t,e){for(const n of e){const e=await n(t);if(void 0!==e)return e}}const l=t=>t;function p(t,e=l){return n=>{const r=e(n);return async e=>t(e,(async()=>r(e)))}}async function h(t,e,n,r,o){if(!(t instanceof d))return r(o),t;if(t.disabled)return null;const s=await async function(t,e,n,r){if(!t.size)return!0;n(r);for(const n of t){if(e.destroyed)return!1;const t=await n(Object.create(e,{params:{value:{...r}}}));if(!1===t)return!1;if("function"==typeof t)return t}return!0}(t.guards,n,r,o);if(!s)return null;if("function"==typeof s)return s;if(n.destroyed)return null;for await(const[s,i,c]of t.find(n.method,e,n)){if(n.destroyed)return null;const e=await h(s,c,n,r,{...o,...i});if(e)return t.__onionskin(e)}return null}function y(t){try{return decodeURIComponent(t)}catch{return t}}class d{disabled=!1;find(t,e,n){return[]}static make(t){return async(e,n)=>{const r=t.flat(),o=e.url.pathname.split("/").filter(Boolean).map(y);for(const t of r){const r=await h(t,o,e,n,{});if(r)return r}return null}}static create(t){return Object.defineProperties(new d,{find:{configurable:!0,value:t,writable:!0}})}guards=new Set;__onionskin=t=>t;onionskin(t){this.__onionskin=p(t,this.__onionskin)}}const g=/^:([a-zA-Z][a-zA-Z0-9]*)(?:\((.+)\))?([ius]+)?([?+*]?)$/;function m(t){const e=g.exec(t);if(!e)return t;const[,n,r=".*",o,s]=e;if(!r)return{name:n,pattern:new RegExp("^.*$",o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s};let i=0,c=0;const u=["^(?:"];for(;i<r.length;){const e=r[i++];if(u.push(e),"\\"!==e)if(")"!==e)if("["!==e){if("("===e&&(c++,"?"===r[i]&&(i+=2,":"!==r[i-1])))return t}else for(;i<r.length;){const t=r[i++];if(u.push(t),"]"===t)break;"\\"===t&&u.push(r[i++])}else{if(0===c)return t;c--}else u.push(r[i++])}return c?t:(u.push(")$"),{name:n,pattern:new RegExp(u.join(""),o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s})}function b(t,e){const n=[];if("string"==typeof t)for(const e of t.split("/"))e&&!/^\.+$/.test(e)&&n.push(m(e));else for(const[e,r]of function*([...t],[...e]){let n=(t.shift()||"").split("/"),r=[n.pop()||""];for(const t of n)yield[[t],[]];for(const n of t){const t=n.split("/");if(t.length<=1){r.push(n);continue}const o=e.splice(0,r.length);r.push(t.shift()||""),yield[r,o],r=[t.pop()||""];for(const e of t)yield[[e],[]]}yield[r,e]}(...t)){if(2===e.length&&!e[0]){const t=e[1];if(["","?","+","*"].includes(t)){const e=r[0];if("symbol"==typeof e){n.push({name:e,pattern:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}if(e&&"object"==typeof e){const{name:r,pattern:o}=e;if("symbol"==typeof r){n.push({name:r,pattern:o instanceof RegExp?o:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}}}}const t=e.pop()||"",o=e.map(((t,e)=>[t,r[e]])).flat();o.push(t);const s=o.join("");s&&!/^\.+$/.test(s)&&n.push(m(s))}if(n.length)return t=>function(t,e,n){const r={};for(let n=0;n<t.length;n++){const o=t[n],s=e[n];if(o!==s){if("string"==typeof o)return;if(!s)return o.optional?[r,[]]:void 0;if(!o.pattern.test(s))return;r[o.name]=s}}if(!n)return[r,e.slice(t.length)];if(e.length<=t.length)return[r,[]];const o=t[t.length-1];if("string"!=typeof o&&(o.many||!(e.length>t.length))){for(let n=t.length;n<e.length;n++)if(!o.pattern.test(e[n]))return;return r[o.name]=e.slice(t.length-1),[r,[]]}}(n,t,e)}function w(t,e,n,r){const o={match:n,methods:e,handler:t=>f(t,r)};t.push(o);let s=!1;return()=>{if(s)return;s=!0;const e=t.indexOf(o);e<0||t.splice(e,1)}}const O=t=>"function"==typeof t;function T(t,e,n){const r=new Set(e);if(!n.length){const e=void 0;return(...n)=>w(t,r,e,n)}const[o]=n;if(o&&"object"==typeof o){const e=b([o,n.slice(1)],!0);return(...n)=>w(t,r,e,n)}const s=b("string"==typeof o?o:"",!0),i=n.filter(O);return i.length?w(t,r,s,i):(...e)=>w(t,r,s,e)}const E=new Set(["GET","POST","PUT","DELETE","HEAD","OPTIONS"]);function j(t){return E.has(t)}function R(t,e,n){const r=n instanceof d?n:"function"==typeof n?d.create(n):new S;return t.push({match:b(e,!1),router:r}),r}class S extends d{#t=[];route(...t){const[e]=t;if(e&&"object"==typeof e&&!(e instanceof d))return n=>R(this.#t,[e,t.slice(1)],n);const n="string"==typeof e?e:"",r="string"==typeof e?t[1]:e;return R(this.#t,n,r)}*find(t,e,n){for(const n of Array.from(this.#t)){if(!n.router&&!n.methods.has(t))continue;const{match:r}=n;if(!r){!n.router&&e.length||(yield[n.router||n.handler,{},e]);continue}if(!e.length)continue;const o=r(e);o&&(yield[n.router||n.handler,...o])}}verb(t,e,n){const r=function(t){return t?"string"==typeof t?[t.toUpperCase()].filter(j):Array.from(t).map((t=>"string"==typeof t&&t.toUpperCase())).filter(j):["GET","POST","PUT","DELETE"]}(t);return r.length?T(this.#t,r,[e,n]):()=>{}}match(...t){return T(this.#t,["GET","POST","PUT","DELETE"],t)}get(...t){return T(this.#t,["GET"],t)}post(...t){return T(this.#t,["POST"],t)}put(...t){return T(this.#t,["PUT"],t)}delete(...t){return T(this.#t,["DELETE"],t)}head(...t){return T(this.#t,["HEAD"],t)}options(...t){return T(this.#t,["OPTIONS"],t)}}const A=()=>{};t.ApiRouter=S,t.Param=class{#e=Symbol();get name(){return this.#e}#n;get pattern(){return this.#n}constructor(t){this.#n=t}param(t){const e=t.params[this.#e];return Array.isArray(e)?e[0]??null:e??null}params(t){const e=t.params[this.#e];return"string"==typeof e?[e]:Array.isArray(e)?e:null}},t.Router=d,t.createFetch=function(t,e){return async function(n,r){const o=new Request(n,r),{signal:s}=o;s.throwIfAborted();const i=await t(o);return i||("function"==typeof e?e(o):new Response(null,{status:404}))}},t.main=a,t.make=function(t,e){return n=>a(n,t,e)},t.merge=function(...t){return e=>f(e,t.flat())},t.onionskin=function(...t){let e=A;for(const n of t.flat()){const t=e;e=async e=>n(e,(async()=>t(e)))}return e},t.packer=p,t.service=function(t,e,n){const r=function(n){return"function"==typeof e&&n.done((()=>e(n)),(t=>e(n,t))),(...e)=>t(n,...e)},{rootOnly:o}="object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r},t.stateService=function(t,e,n,r){const o=function(r){const o=t(r)||{};return"function"==typeof e&&r.done((()=>e(o,r)),(t=>e(o,r,t))),"function"!=typeof n?()=>o:()=>(n(o,r),o)},{rootOnly:s}="object"==typeof e&&e||"object"==typeof n&&n||"object"==typeof r&&r||{};return Object.assign(o,{rootOnly:Boolean(s)}),o},t.storeService=function(t,e,n){const r=function(n){let r;return"function"==typeof t&&n.done((()=>t(r,n)),(e=>t(r,n,e))),"function"!=typeof e?(...t)=>(t.length&&([r]=t),r):(...t)=>(t.length&&([r]=t,e(r,n)),r)},{rootOnly:o}="object"==typeof t&&t||"object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r}}));
6
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).k99={})}(this,(function(t){"use strict";function e(t){return(new TextEncoder).encode(t)}function n(t){return Symbol.asyncIterator in t||Symbol.iterator in t}async function r(t,o){if("string"==typeof o)return t.write(e(o));if("object"==typeof o){if(ArrayBuffer.isView(o))return t.write(new Uint8Array(o.buffer,o.byteOffset,o.byteLength));if(o instanceof ArrayBuffer)return t.write(new Uint8Array(o));if(n(o))for await(const e of o)e&&await r(t,e)}}function o(t,o,s,i){const c=function(t,o,s){if(t instanceof ReadableStream)return[t,0,""];if(t instanceof URLSearchParams)return[t,0,""];if(t instanceof Blob)return[t,t.size,t.type];if(t instanceof FormData)return[t,0,""];if(ArrayBuffer.isView(t)||t instanceof ArrayBuffer)return[t,t.byteLength,""];if("string"==typeof t){const n=e(t);return[n,n.byteLength,"text/plain"]}if(["bigint","boolean","number"].includes(typeof t)){const n=e(JSON.stringify(t,o));return[n,n.byteLength,"application/json"]}if("object"!=typeof t)return null;if(Array.isArray(t)||!n(t)){const n=e(JSON.stringify(t,o));return[n,n.byteLength,"application/json"]}const{writable:i,readable:c}=new TransformStream,f=i.getWriter();return s?.catch((t=>{i.abort(t||new DOMException("The user aborted a request.")).catch((()=>{}))})),(async()=>{for await(const e of t)e&&await r(f,e)})().then((()=>i.close()),(t=>i.abort(t))).catch((()=>{})),[c,0,""]}(t,s,i);if(!c)return null;const[f,a,u]=c;return u&&!o.get("Content-Type")&&o.set("Content-Type",u),a>0&&!o.get("Content-Length")&&o.set("Content-Length",String(a)),f}function s(t,e){t.delete("set-cookie");for(const{name:n,value:r,expire:o,domain:s,path:i,secure:c,httpOnly:f}of e)n&&t.append("set-cookie",[`${encodeURI(n)}=${encodeURI(r||"")}`,o&&`Expires=${o}`,s&&`Domain=${encodeURI(s)}`,i&&`Path=${encodeURI(i)}`,c&&"Secure",f&&"HttpOnly"].filter(Boolean).join("; "))}const i=new Set(["GET","OPTIONS"]);function c(t,e,n){n?t.set(e,n):t.delete(e)}function f(t,e){return"bigint"==typeof e?String(e):e}function a(t,e,{runner:n,error:r,catch:a,method:u,environment:l,replacer:p}={}){const h="function"==typeof p?p:f;return function t(f,p){const y=function(t,e){let n="";return"string"==typeof e?n=e:"function"==typeof e&&(n=e(t)),n&&"string"==typeof n||(n=t.method||"GET"),n.toUpperCase()}(f,u),d=new URL(f.url),{signal:g,headers:m}=f,b=function(t){return new Promise(((e,n)=>{if(t.aborted)return n(t.reason);t.addEventListener("abort",(()=>n(t.reason)),{once:!0})}))}(g),w=new Map,O=function(t){let e={};for(const n of t.replace(/\s/g,"").split(";")){const t=n.split("=");e[decodeURIComponent(t.shift())]=decodeURIComponent(t.join("="))}return e}(m.get("cookie")||""),T=[],E=new Headers,j=p?.root;let R=200,S=!1,A=null,P=()=>{},U=()=>{};const k=new Promise(((t,e)=>{P=t,U=e}));k.catch((()=>{}));let v={};const x={environment:l,parent:p,get error(){return A},get root(){return j||this},signal:g,url:d,fetch(e,{method:n="get",signal:r,body:s,headers:c}={}){const f=new URL(e,d),a=new Headers(c||{});if(!s||i.has(n.toUpperCase()))return t(new Request(f,{method:n,headers:a,signal:r}),x);const u=o(s,a,h);return t(new Request(f,{method:n,headers:a,signal:r,body:u}),x)},done(t,e){if(S)return null;const n=k.then(t,e);return n.catch(r),n},service(t,...e){if(t.rootOnly&&j)return j.service(t,...e);let n=w.get(t);if(!n){if(n=t(x),"function"!=typeof n)return;w.set(t,n)}return n(...e)},method:y,get params(){return v},requestHeaders:m,requestType:m.get("content-type")||"",referer:m.get("referer")||"",userAgent:m.get("user-agent")||"",accept:(m.get("accept")||"").split(/,\s*/).filter(Boolean),acceptLanguage:(m.get("accept-language")||"").split(/,\s*/).filter(Boolean),cookies:O,request:f,get destroyed(){return S},get status(){return R},set status(t){R=t},responseHeaders:E,get location(){return E.get("location")||""},set location(t){c(E,"location",t)},get responseType(){return E.get("content-type")||""},set responseType(t){c(E,"content-type",t)},getCookie:t=>function*(t,e){const n=t;for(const t of n)e&&t.name!==e||(yield{...t})}(T,t),setCookie(t,e,{expire:n,domain:r,path:o,secure:i,httpOnly:c}={}){T.push({name:t,value:e,expire:n,domain:r,path:o,secure:i,httpOnly:c}),s(E,T)},clearCookie(t,e){!function(t,e,n,r){let o="Fri, 31 Dec 1999 16:00:00 GMT";if("string"==typeof n){if(!n)return;const{domain:e,path:s,secure:i,httpOnly:c}=!0!==r&&r||{};t.push({name:n,value:"delete",expire:o,domain:e,path:s,secure:i,httpOnly:c})}else{const{domain:s,path:i,secure:c,httpOnly:f}=n||{};if(t.length=0,r)for(let n in e)t.push({name:n,value:"delete",expire:o,domain:s,path:i,secure:c,httpOnly:f})}}(T,O,t,e),s(E,T)}};function L(){return Promise.race([b,Promise.resolve().then((()=>e(x,(t=>{v=t}))))]).then((async t=>{const e=[t].flat().filter((t=>"function"==typeof t));if(!e.length)return null;let n;for(const t of e)if(n=await Promise.race([b,t(x)]),void 0!==n)break;if(n instanceof Response)return n;const r=new Headers(x.responseHeaders),{status:s}=x;if(!n)return new Response(null,{status:s,headers:r});const i=o(n,r,h,b);return new Response(i,{status:s,headers:r})})).then((t=>(S=!0,P(),t)),(t=>(S=!0,A=t||!0,U(A),Promise.reject(t)))).catch(a)}return n?n(x,L):L()}(t)}async function u(t,e){for(const n of e){const e=await n(t);if(void 0!==e)return e}}const l=t=>t;function p(t,e=l){return n=>{const r=e(n);return async e=>t(e,(async()=>u(e,[r].flat())))}}function h(t){try{return decodeURIComponent(t)}catch{return t}}class y{disabled=!1;static async#t(t,e,n,r,o){if(!(t instanceof y))return r(o),[t].flat();if(t.disabled)return null;if(n.destroyed)return null;for await(const[s,i,c]of t.find(n.method,e,n)){if(n.destroyed)return null;const e=await y.#t(s,c,n,r,{...o,...i});if(e)return[t.#e,t.#n(e)].flat()}return null}find(t,e,n){return[]}static make(t){return async(e,n)=>{const r=t.flat(),o=e.url.pathname.split("/").filter(Boolean).map(h);for(const t of r){const r=await y.#t(t,o,e,n,{});if(r)return r}return null}}#e=[];guard(...t){const e=this.#e;for(const n of t.flat())"function"==typeof n&&e.push(n)}static create(t){return Object.defineProperties(new y,{find:{configurable:!0,value:t,writable:!0}})}#n=t=>t;onionskin(t){this.#n=p(t,this.#n)}}const d=/^:([a-zA-Z][a-zA-Z0-9]*)(?:\((.+)\))?([ius]+)?([?+*]?)$/;function g(t){const e=d.exec(t);if(!e)return t;const[,n,r=".*",o,s]=e;if(!r)return{name:n,pattern:new RegExp("^.*$",o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s};let i=0,c=0;const f=["^(?:"];for(;i<r.length;){const e=r[i++];if(f.push(e),"\\"!==e)if(")"!==e)if("["!==e){if("("===e&&(c++,"?"===r[i]&&(i+=2,":"!==r[i-1])))return t}else for(;i<r.length;){const t=r[i++];if(f.push(t),"]"===t)break;"\\"===t&&f.push(r[i++])}else{if(0===c)return t;c--}else f.push(r[i++])}return c?t:(f.push(")$"),{name:n,pattern:new RegExp(f.join(""),o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s})}function m(t,e){const n=[];if("string"==typeof t)for(const e of t.split("/"))e&&!/^\.+$/.test(e)&&n.push(g(e));else for(const[e,r]of function*([...t],[...e]){let n=(t.shift()||"").split("/"),r=[n.pop()||""];for(const t of n)yield[[t],[]];for(const n of t){const t=n.split("/");if(t.length<=1){r.push(n);continue}const o=e.splice(0,r.length);r.push(t.shift()||""),yield[r,o],r=[t.pop()||""];for(const e of t)yield[[e],[]]}yield[r,e]}(...t)){if(2===e.length&&!e[0]){const t=e[1];if(["","?","+","*"].includes(t)){const e=r[0];if("symbol"==typeof e){n.push({name:e,pattern:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}if(e&&"object"==typeof e){const{name:r,pattern:o}=e;if("symbol"==typeof r){n.push({name:r,pattern:o instanceof RegExp?o:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}}}}const t=e.pop()||"",o=e.map(((t,e)=>[t,r[e]])).flat();o.push(t);const s=o.join("");s&&!/^\.+$/.test(s)&&n.push(g(s))}if(n.length)return t=>function(t,e,n){const r={};for(let n=0;n<t.length;n++){const o=t[n],s=e[n];if(o!==s){if("string"==typeof o)return;if(!s)return o.optional?[r,[]]:void 0;if(!o.pattern.test(s))return;r[o.name]=s}}if(!n)return[r,e.slice(t.length)];if(e.length<=t.length)return[r,[]];const o=t[t.length-1];if("string"!=typeof o&&(o.many||!(e.length>t.length))){for(let n=t.length;n<e.length;n++)if(!o.pattern.test(e[n]))return;return r[o.name]=e.slice(t.length-1),[r,[]]}}(n,t,e)}function b(t,e,n,r){const o={match:n,methods:e,handlers:r};t.push(o);let s=!1;return()=>{if(s)return;s=!0;const e=t.indexOf(o);e<0||t.splice(e,1)}}const w=t=>"function"==typeof t;function O(t,e,n){const r=new Set(e);if(!n.length){const e=void 0;return(...n)=>b(t,r,e,n)}const[o]=n;if(o&&"object"==typeof o){const e=m([o,n.slice(1)],!0);return(...n)=>b(t,r,e,n)}const s=m("string"==typeof o?o:"",!0),i=n.filter(w);return i.length?b(t,r,s,i):(...e)=>b(t,r,s,e)}const T=new Set(["GET","POST","PUT","DELETE","HEAD","OPTIONS"]);function E(t){return T.has(t)}function j(t,e,n){const r=n instanceof y?n:"function"==typeof n?y.create(n):new R;return t.push({match:m(e,!1),router:r}),r}class R extends y{#r=[];route(...t){const[e]=t;if(e&&"object"==typeof e&&!(e instanceof y))return n=>j(this.#r,[e,t.slice(1)],n);const n="string"==typeof e?e:"",r="string"==typeof e?t[1]:e;return j(this.#r,n,r)}*find(t,e,n){for(const n of Array.from(this.#r)){if(!n.router&&!n.methods.has(t))continue;const{match:r}=n;if(!r){!n.router&&e.length||(yield[n.router||n.handlers,{},e]);continue}if(!e.length)continue;const o=r(e);o&&(yield[n.router||n.handlers,...o])}}verb(t,e,...n){const r=function(t){return t?"string"==typeof t?[t.toUpperCase()].filter(E):Array.from(t).map((t=>"string"==typeof t&&t.toUpperCase())).filter(E):["GET","POST","PUT","DELETE"]}(t);return r.length?O(this.#r,r,[e,...n]):()=>{}}match(...t){return O(this.#r,["GET","POST","PUT","DELETE"],t)}get(...t){return O(this.#r,["GET"],t)}post(...t){return O(this.#r,["POST"],t)}put(...t){return O(this.#r,["PUT"],t)}delete(...t){return O(this.#r,["DELETE"],t)}head(...t){return O(this.#r,["HEAD"],t)}options(...t){return O(this.#r,["OPTIONS"],t)}}const S=()=>{};t.ApiRouter=R,t.Param=class{#o=Symbol();get name(){return this.#o}#s;get pattern(){return this.#s}constructor(t){this.#s=t}param(t){const e=t.params[this.#o];return Array.isArray(e)?e[0]??null:e??null}params(t){const e=t.params[this.#o];return"string"==typeof e?[e]:Array.isArray(e)?e:null}},t.Router=y,t.createFetch=function(t,e){return async function(n,r){const o=new Request(n,r),{signal:s}=o;s.throwIfAborted();const i=await t(o);return i||("function"==typeof e?e(o):new Response(null,{status:404}))}},t.main=a,t.make=function(t,e){return n=>a(n,t,e)},t.merge=function(...t){return e=>u(e,t.flat())},t.onionskin=function(...t){let e=S;for(const n of t.flat()){const t=e;e=async e=>n(e,(async()=>t(e)))}return e},t.packer=p,t.service=function(t,e,n){const r=function(n){return"function"==typeof e&&n.done((()=>e(n)),(t=>e(n,t))),(...e)=>t(n,...e)},{rootOnly:o}="object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r},t.stateService=function(t,e,n,r){const o=function(r){const o=t(r)||{};return"function"==typeof e&&r.done((()=>e(o,r)),(t=>e(o,r,t))),"function"!=typeof n?()=>o:()=>(n(o,r),o)},{rootOnly:s}="object"==typeof e&&e||"object"==typeof n&&n||"object"==typeof r&&r||{};return Object.assign(o,{rootOnly:Boolean(s)}),o},t.storeService=function(t,e,n){const r=function(n){let r;return"function"==typeof t&&n.done((()=>t(r,n)),(e=>t(r,n,e))),"function"!=typeof e?(...t)=>(t.length&&([r]=t),r):(...t)=>(t.length&&([r]=t,e(r,n)),r)},{rootOnly:o}="object"==typeof t&&t||"object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r}}));
package/index.min.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * k99 v0.7.1
3
- * (c) 2019-2025 猛火Fierflame
2
+ * k99 v0.8.0
3
+ * (c) 2019-2026 猛火Fierflame
4
4
  * @license MIT
5
5
  */
6
- function t(t){return(new TextEncoder).encode(t)}function e(t){return Symbol.asyncIterator in t||Symbol.iterator in t}async function n(r,o){if("string"==typeof o)return r.write(t(o));if("object"==typeof o){if(ArrayBuffer.isView(o))return r.write(new Uint8Array(o.buffer,o.byteOffset,o.byteLength));if(o instanceof ArrayBuffer)return r.write(new Uint8Array(o));if(e(o))for await(const t of o)t&&await n(r,t)}}function r(t,e){return"bigint"==typeof e?String(e):e}function o(o,s,i){const c=function(o,s){if(o instanceof ReadableStream)return[o,0,""];if(o instanceof URLSearchParams)return[o,0,""];if(o instanceof Blob)return[o,o.size,o.type];if(o instanceof FormData)return[o,0,""];if(ArrayBuffer.isView(o)||o instanceof ArrayBuffer)return[o,o.byteLength,""];if("string"==typeof o){const e=t(o);return[e,e.byteLength,""]}if("object"!=typeof o)return null;if(Array.isArray(o)||!e(o)){const e=t(JSON.stringify(o,r));return[e,e.byteLength,"application/json"]}const{writable:i,readable:c}=new TransformStream,u=i.getWriter();return s?.catch((t=>{i.abort(t||new DOMException("The user aborted a request.")).catch((()=>{}))})),(async()=>{for await(const t of o)t&&await n(u,t)})().then((()=>i.close()),(t=>i.abort(t))).catch((()=>{})),[c,0,""]}(o,i);if(!c)return null;const[u,a,f]=c;return f&&!s.get("Content-Type")&&s.set("Content-Type",f),a>0&&!s.get("Content-Length")&&s.set("Content-Length",String(a)),u}function s(t,e){t.delete("set-cookie");for(const{name:n,value:r,expire:o,domain:s,path:i,secure:c,httpOnly:u}of e)n&&t.append("set-cookie",[`${encodeURI(n)}=${encodeURI(r||"")}`,o&&`Expires=${o}`,s&&`Domain=${encodeURI(s)}`,i&&`Path=${encodeURI(i)}`,c&&"Secure",u&&"HttpOnly"].filter(Boolean).join("; "))}const i=new Set(["GET","OPTIONS"]);function c(t,e,n){n?t.set(e,n):t.delete(e)}function u(t,e,{runner:n,error:r,catch:u,method:a,environment:f}={}){return function t(l,p){const h=function(t,e){let n="";return"string"==typeof e?n=e:"function"==typeof e&&(n=e(t)),n&&"string"==typeof n||(n=t.method||"GET"),n.toUpperCase()}(l,a),y=new URL(l.url),{signal:d,headers:g}=l,m=function(t){return new Promise(((e,n)=>{if(t.aborted)return n(t.reason);t.addEventListener("abort",(()=>n(t.reason)),{once:!0})}))}(d),b=new Map,w=function(t){let e={};for(const n of t.replace(/\s/g,"").split(";")){const t=n.split("=");e[decodeURIComponent(t.shift())]=decodeURIComponent(t.join("="))}return e}(g.get("cookie")||""),O=[],T=new Headers,E=p?.root;let j=200,R=!1,S=null,A=()=>{},P=()=>{};const U=new Promise(((t,e)=>{A=t,P=e}));U.catch((()=>{}));let v={};const x={environment:f,parent:p,get error(){return S},get root(){return E||this},signal:d,url:y,fetch(e,{method:n="get",signal:r,body:s,headers:c}={}){const u=new URL(e,y),a=new Headers(c||{});if(!s||i.has(n.toUpperCase()))return t(new Request(u,{method:n,headers:a,signal:r}),x);const f=o(s,a);return t(new Request(u,{method:n,headers:a,signal:r,body:f}),x)},done(t,e){if(R)return null;const n=U.then(t,e);return n.catch(r),n},service(t,...e){if(t.rootOnly&&E)return E.service(t,...e);let n=b.get(t);if(!n){if(n=t(x),"function"!=typeof n)return;b.set(t,n)}return n(...e)},method:h,get params(){return v},requestHeaders:g,requestType:g.get("content-type")||"",referer:g.get("referer")||"",userAgent:g.get("user-agent")||"",accept:(g.get("accept")||"").split(/,\s*/).filter(Boolean),acceptLanguage:(g.get("accept-language")||"").split(/,\s*/).filter(Boolean),cookies:w,request:l,get destroyed(){return R},get status(){return j},set status(t){j=t},responseHeaders:T,get location(){return T.get("location")||""},set location(t){c(T,"location",t)},get responseType(){return T.get("content-type")||""},set responseType(t){c(T,"content-type",t)},getCookie:t=>function*(t,e){const n=t;for(const t of n)e&&t.name!==e||(yield{...t})}(O,t),setCookie(t,e,{expire:n,domain:r,path:o,secure:i,httpOnly:c}={}){O.push({name:t,value:e,expire:n,domain:r,path:o,secure:i,httpOnly:c}),s(T,O)},clearCookie(t,e){!function(t,e,n,r){let o="Fri, 31 Dec 1999 16:00:00 GMT";if("string"==typeof n){if(!n)return;const{domain:e,path:s,secure:i,httpOnly:c}=!0!==r&&r||{};t.push({name:n,value:"delete",expire:o,domain:e,path:s,secure:i,httpOnly:c})}else{const{domain:s,path:i,secure:c,httpOnly:u}=n||{};if(t.length=0,r)for(let n in e)t.push({name:n,value:"delete",expire:o,domain:s,path:i,secure:c,httpOnly:u})}}(O,w,t,e),s(T,O)}};function L(){return Promise.race([m,Promise.resolve().then((()=>e(x,(t=>{v=t}))))]).then((t=>t?Promise.race([m,t(x)]).then((t=>{if(t instanceof Response)return t;const e=new Headers(x.responseHeaders),{status:n}=x;if(!t)return new Response(null,{status:n,headers:e});const r=o(t,e,m);return new Response(r,{status:n,headers:e})})):null)).then((t=>(R=!0,A(),t)),(t=>(R=!0,S=t||!0,P(S),Promise.reject(t)))).catch(u)}return n?n(x,L):L()}(t)}function a(t,e){return n=>u(n,t,e)}async function f(t,e){for(const n of e){const e=await n(t);if(void 0!==e)return e}}function l(...t){return e=>f(e,t.flat())}function p(t,e,n){const r=function(n){return"function"==typeof e&&n.done((()=>e(n)),(t=>e(n,t))),(...e)=>t(n,...e)},{rootOnly:o}="object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r}function h(t,e,n,r){const o=function(r){const o=t(r)||{};return"function"==typeof e&&r.done((()=>e(o,r)),(t=>e(o,r,t))),"function"!=typeof n?()=>o:()=>(n(o,r),o)},{rootOnly:s}="object"==typeof e&&e||"object"==typeof n&&n||"object"==typeof r&&r||{};return Object.assign(o,{rootOnly:Boolean(s)}),o}function y(t,e,n){const r=function(n){let r;return"function"==typeof t&&n.done((()=>t(r,n)),(e=>t(r,n,e))),"function"!=typeof e?(...t)=>(t.length&&([r]=t),r):(...t)=>(t.length&&([r]=t,e(r,n)),r)},{rootOnly:o}="object"==typeof t&&t||"object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r}const d=t=>t;function g(t,e=d){return n=>{const r=e(n);return async e=>t(e,(async()=>r(e)))}}async function m(t,e,n,r,o){if(!(t instanceof w))return r(o),t;if(t.disabled)return null;const s=await async function(t,e,n,r){if(!t.size)return!0;n(r);for(const n of t){if(e.destroyed)return!1;const t=await n(Object.create(e,{params:{value:{...r}}}));if(!1===t)return!1;if("function"==typeof t)return t}return!0}(t.guards,n,r,o);if(!s)return null;if("function"==typeof s)return s;if(n.destroyed)return null;for await(const[s,i,c]of t.find(n.method,e,n)){if(n.destroyed)return null;const e=await m(s,c,n,r,{...o,...i});if(e)return t.__onionskin(e)}return null}function b(t){try{return decodeURIComponent(t)}catch{return t}}class w{disabled=!1;find(t,e,n){return[]}static make(t){return async(e,n)=>{const r=t.flat(),o=e.url.pathname.split("/").filter(Boolean).map(b);for(const t of r){const r=await m(t,o,e,n,{});if(r)return r}return null}}static create(t){return Object.defineProperties(new w,{find:{configurable:!0,value:t,writable:!0}})}guards=new Set;__onionskin=t=>t;onionskin(t){this.__onionskin=g(t,this.__onionskin)}}const O=/^:([a-zA-Z][a-zA-Z0-9]*)(?:\((.+)\))?([ius]+)?([?+*]?)$/;function T(t){const e=O.exec(t);if(!e)return t;const[,n,r=".*",o,s]=e;if(!r)return{name:n,pattern:new RegExp("^.*$",o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s};let i=0,c=0;const u=["^(?:"];for(;i<r.length;){const e=r[i++];if(u.push(e),"\\"!==e)if(")"!==e)if("["!==e){if("("===e&&(c++,"?"===r[i]&&(i+=2,":"!==r[i-1])))return t}else for(;i<r.length;){const t=r[i++];if(u.push(t),"]"===t)break;"\\"===t&&u.push(r[i++])}else{if(0===c)return t;c--}else u.push(r[i++])}return c?t:(u.push(")$"),{name:n,pattern:new RegExp(u.join(""),o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s})}function E(t,e){const n=[];if("string"==typeof t)for(const e of t.split("/"))e&&!/^\.+$/.test(e)&&n.push(T(e));else for(const[e,r]of function*([...t],[...e]){let n=(t.shift()||"").split("/"),r=[n.pop()||""];for(const t of n)yield[[t],[]];for(const n of t){const t=n.split("/");if(t.length<=1){r.push(n);continue}const o=e.splice(0,r.length);r.push(t.shift()||""),yield[r,o],r=[t.pop()||""];for(const e of t)yield[[e],[]]}yield[r,e]}(...t)){if(2===e.length&&!e[0]){const t=e[1];if(["","?","+","*"].includes(t)){const e=r[0];if("symbol"==typeof e){n.push({name:e,pattern:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}if(e&&"object"==typeof e){const{name:r,pattern:o}=e;if("symbol"==typeof r){n.push({name:r,pattern:o instanceof RegExp?o:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}}}}const t=e.pop()||"",o=e.map(((t,e)=>[t,r[e]])).flat();o.push(t);const s=o.join("");s&&!/^\.+$/.test(s)&&n.push(T(s))}if(n.length)return t=>function(t,e,n){const r={};for(let n=0;n<t.length;n++){const o=t[n],s=e[n];if(o!==s){if("string"==typeof o)return;if(!s)return o.optional?[r,[]]:void 0;if(!o.pattern.test(s))return;r[o.name]=s}}if(!n)return[r,e.slice(t.length)];if(e.length<=t.length)return[r,[]];const o=t[t.length-1];if("string"!=typeof o&&(o.many||!(e.length>t.length))){for(let n=t.length;n<e.length;n++)if(!o.pattern.test(e[n]))return;return r[o.name]=e.slice(t.length-1),[r,[]]}}(n,t,e)}function j(t,e,n,r){const o={match:n,methods:e,handler:t=>f(t,r)};t.push(o);let s=!1;return()=>{if(s)return;s=!0;const e=t.indexOf(o);e<0||t.splice(e,1)}}const R=t=>"function"==typeof t;function S(t,e,n){const r=new Set(e);if(!n.length){const e=void 0;return(...n)=>j(t,r,e,n)}const[o]=n;if(o&&"object"==typeof o){const e=E([o,n.slice(1)],!0);return(...n)=>j(t,r,e,n)}const s=E("string"==typeof o?o:"",!0),i=n.filter(R);return i.length?j(t,r,s,i):(...e)=>j(t,r,s,e)}const A=new Set(["GET","POST","PUT","DELETE","HEAD","OPTIONS"]);function P(t){return A.has(t)}function U(t,e,n){const r=n instanceof w?n:"function"==typeof n?w.create(n):new v;return t.push({match:E(e,!1),router:r}),r}class v extends w{#t=[];route(...t){const[e]=t;if(e&&"object"==typeof e&&!(e instanceof w))return n=>U(this.#t,[e,t.slice(1)],n);const n="string"==typeof e?e:"",r="string"==typeof e?t[1]:e;return U(this.#t,n,r)}*find(t,e,n){for(const n of Array.from(this.#t)){if(!n.router&&!n.methods.has(t))continue;const{match:r}=n;if(!r){!n.router&&e.length||(yield[n.router||n.handler,{},e]);continue}if(!e.length)continue;const o=r(e);o&&(yield[n.router||n.handler,...o])}}verb(t,e,n){const r=function(t){return t?"string"==typeof t?[t.toUpperCase()].filter(P):Array.from(t).map((t=>"string"==typeof t&&t.toUpperCase())).filter(P):["GET","POST","PUT","DELETE"]}(t);return r.length?S(this.#t,r,[e,n]):()=>{}}match(...t){return S(this.#t,["GET","POST","PUT","DELETE"],t)}get(...t){return S(this.#t,["GET"],t)}post(...t){return S(this.#t,["POST"],t)}put(...t){return S(this.#t,["PUT"],t)}delete(...t){return S(this.#t,["DELETE"],t)}head(...t){return S(this.#t,["HEAD"],t)}options(...t){return S(this.#t,["OPTIONS"],t)}}function x(t,e){return async function(n,r){const o=new Request(n,r),{signal:s}=o;s.throwIfAborted();const i=await t(o);return i||("function"==typeof e?e(o):new Response(null,{status:404}))}}const L=()=>{};function k(...t){let e=L;for(const n of t.flat()){const t=e;e=async e=>n(e,(async()=>t(e)))}return e}class C{#e=Symbol();get name(){return this.#e}#n;get pattern(){return this.#n}constructor(t){this.#n=t}param(t){const e=t.params[this.#e];return Array.isArray(e)?e[0]??null:e??null}params(t){const e=t.params[this.#e];return"string"==typeof e?[e]:Array.isArray(e)?e:null}}export{v as ApiRouter,C as Param,w as Router,x as createFetch,u as main,a as make,l as merge,k as onionskin,g as packer,p as service,h as stateService,y as storeService};
6
+ function t(t){return(new TextEncoder).encode(t)}function e(t){return Symbol.asyncIterator in t||Symbol.iterator in t}async function n(r,o){if("string"==typeof o)return r.write(t(o));if("object"==typeof o){if(ArrayBuffer.isView(o))return r.write(new Uint8Array(o.buffer,o.byteOffset,o.byteLength));if(o instanceof ArrayBuffer)return r.write(new Uint8Array(o));if(e(o))for await(const t of o)t&&await n(r,t)}}function r(r,o,s,i){const c=function(r,o,s){if(r instanceof ReadableStream)return[r,0,""];if(r instanceof URLSearchParams)return[r,0,""];if(r instanceof Blob)return[r,r.size,r.type];if(r instanceof FormData)return[r,0,""];if(ArrayBuffer.isView(r)||r instanceof ArrayBuffer)return[r,r.byteLength,""];if("string"==typeof r){const e=t(r);return[e,e.byteLength,"text/plain"]}if(["bigint","boolean","number"].includes(typeof r)){const e=t(JSON.stringify(r,o));return[e,e.byteLength,"application/json"]}if("object"!=typeof r)return null;if(Array.isArray(r)||!e(r)){const e=t(JSON.stringify(r,o));return[e,e.byteLength,"application/json"]}const{writable:i,readable:c}=new TransformStream,u=i.getWriter();return s?.catch((t=>{i.abort(t||new DOMException("The user aborted a request.")).catch((()=>{}))})),(async()=>{for await(const t of r)t&&await n(u,t)})().then((()=>i.close()),(t=>i.abort(t))).catch((()=>{})),[c,0,""]}(r,s,i);if(!c)return null;const[u,a,f]=c;return f&&!o.get("Content-Type")&&o.set("Content-Type",f),a>0&&!o.get("Content-Length")&&o.set("Content-Length",String(a)),u}function o(t,e){t.delete("set-cookie");for(const{name:n,value:r,expire:o,domain:s,path:i,secure:c,httpOnly:u}of e)n&&t.append("set-cookie",[`${encodeURI(n)}=${encodeURI(r||"")}`,o&&`Expires=${o}`,s&&`Domain=${encodeURI(s)}`,i&&`Path=${encodeURI(i)}`,c&&"Secure",u&&"HttpOnly"].filter(Boolean).join("; "))}const s=new Set(["GET","OPTIONS"]);function i(t,e,n){n?t.set(e,n):t.delete(e)}function c(t,e){return"bigint"==typeof e?String(e):e}function u(t,e,{runner:n,error:u,catch:a,method:f,environment:l,replacer:p}={}){const h="function"==typeof p?p:c;return function t(c,p){const y=function(t,e){let n="";return"string"==typeof e?n=e:"function"==typeof e&&(n=e(t)),n&&"string"==typeof n||(n=t.method||"GET"),n.toUpperCase()}(c,f),d=new URL(c.url),{signal:g,headers:m}=c,b=function(t){return new Promise(((e,n)=>{if(t.aborted)return n(t.reason);t.addEventListener("abort",(()=>n(t.reason)),{once:!0})}))}(g),w=new Map,O=function(t){let e={};for(const n of t.replace(/\s/g,"").split(";")){const t=n.split("=");e[decodeURIComponent(t.shift())]=decodeURIComponent(t.join("="))}return e}(m.get("cookie")||""),T=[],E=new Headers,j=p?.root;let R=200,S=!1,A=null,P=()=>{},U=()=>{};const v=new Promise(((t,e)=>{P=t,U=e}));v.catch((()=>{}));let x={};const L={environment:l,parent:p,get error(){return A},get root(){return j||this},signal:g,url:d,fetch(e,{method:n="get",signal:o,body:i,headers:c}={}){const u=new URL(e,d),a=new Headers(c||{});if(!i||s.has(n.toUpperCase()))return t(new Request(u,{method:n,headers:a,signal:o}),L);const f=r(i,a,h);return t(new Request(u,{method:n,headers:a,signal:o,body:f}),L)},done(t,e){if(S)return null;const n=v.then(t,e);return n.catch(u),n},service(t,...e){if(t.rootOnly&&j)return j.service(t,...e);let n=w.get(t);if(!n){if(n=t(L),"function"!=typeof n)return;w.set(t,n)}return n(...e)},method:y,get params(){return x},requestHeaders:m,requestType:m.get("content-type")||"",referer:m.get("referer")||"",userAgent:m.get("user-agent")||"",accept:(m.get("accept")||"").split(/,\s*/).filter(Boolean),acceptLanguage:(m.get("accept-language")||"").split(/,\s*/).filter(Boolean),cookies:O,request:c,get destroyed(){return S},get status(){return R},set status(t){R=t},responseHeaders:E,get location(){return E.get("location")||""},set location(t){i(E,"location",t)},get responseType(){return E.get("content-type")||""},set responseType(t){i(E,"content-type",t)},getCookie:t=>function*(t,e){const n=t;for(const t of n)e&&t.name!==e||(yield{...t})}(T,t),setCookie(t,e,{expire:n,domain:r,path:s,secure:i,httpOnly:c}={}){T.push({name:t,value:e,expire:n,domain:r,path:s,secure:i,httpOnly:c}),o(E,T)},clearCookie(t,e){!function(t,e,n,r){let o="Fri, 31 Dec 1999 16:00:00 GMT";if("string"==typeof n){if(!n)return;const{domain:e,path:s,secure:i,httpOnly:c}=!0!==r&&r||{};t.push({name:n,value:"delete",expire:o,domain:e,path:s,secure:i,httpOnly:c})}else{const{domain:s,path:i,secure:c,httpOnly:u}=n||{};if(t.length=0,r)for(let n in e)t.push({name:n,value:"delete",expire:o,domain:s,path:i,secure:c,httpOnly:u})}}(T,O,t,e),o(E,T)}};function k(){return Promise.race([b,Promise.resolve().then((()=>e(L,(t=>{x=t}))))]).then((async t=>{const e=[t].flat().filter((t=>"function"==typeof t));if(!e.length)return null;let n;for(const t of e)if(n=await Promise.race([b,t(L)]),void 0!==n)break;if(n instanceof Response)return n;const o=new Headers(L.responseHeaders),{status:s}=L;if(!n)return new Response(null,{status:s,headers:o});const i=r(n,o,h,b);return new Response(i,{status:s,headers:o})})).then((t=>(S=!0,P(),t)),(t=>(S=!0,A=t||!0,U(A),Promise.reject(t)))).catch(a)}return n?n(L,k):k()}(t)}function a(t,e){return n=>u(n,t,e)}async function f(t,e){for(const n of e){const e=await n(t);if(void 0!==e)return e}}function l(...t){return e=>f(e,t.flat())}function p(t,e,n){const r=function(n){return"function"==typeof e&&n.done((()=>e(n)),(t=>e(n,t))),(...e)=>t(n,...e)},{rootOnly:o}="object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r}function h(t,e,n,r){const o=function(r){const o=t(r)||{};return"function"==typeof e&&r.done((()=>e(o,r)),(t=>e(o,r,t))),"function"!=typeof n?()=>o:()=>(n(o,r),o)},{rootOnly:s}="object"==typeof e&&e||"object"==typeof n&&n||"object"==typeof r&&r||{};return Object.assign(o,{rootOnly:Boolean(s)}),o}function y(t,e,n){const r=function(n){let r;return"function"==typeof t&&n.done((()=>t(r,n)),(e=>t(r,n,e))),"function"!=typeof e?(...t)=>(t.length&&([r]=t),r):(...t)=>(t.length&&([r]=t,e(r,n)),r)},{rootOnly:o}="object"==typeof t&&t||"object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r}const d=t=>t;function g(t,e=d){return n=>{const r=e(n);return async e=>t(e,(async()=>f(e,[r].flat())))}}function m(t){try{return decodeURIComponent(t)}catch{return t}}class b{disabled=!1;static async#t(t,e,n,r,o){if(!(t instanceof b))return r(o),[t].flat();if(t.disabled)return null;if(n.destroyed)return null;for await(const[s,i,c]of t.find(n.method,e,n)){if(n.destroyed)return null;const e=await b.#t(s,c,n,r,{...o,...i});if(e)return[t.#e,t.#n(e)].flat()}return null}find(t,e,n){return[]}static make(t){return async(e,n)=>{const r=t.flat(),o=e.url.pathname.split("/").filter(Boolean).map(m);for(const t of r){const r=await b.#t(t,o,e,n,{});if(r)return r}return null}}#e=[];guard(...t){const e=this.#e;for(const n of t.flat())"function"==typeof n&&e.push(n)}static create(t){return Object.defineProperties(new b,{find:{configurable:!0,value:t,writable:!0}})}#n=t=>t;onionskin(t){this.#n=g(t,this.#n)}}const w=/^:([a-zA-Z][a-zA-Z0-9]*)(?:\((.+)\))?([ius]+)?([?+*]?)$/;function O(t){const e=w.exec(t);if(!e)return t;const[,n,r=".*",o,s]=e;if(!r)return{name:n,pattern:new RegExp("^.*$",o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s};let i=0,c=0;const u=["^(?:"];for(;i<r.length;){const e=r[i++];if(u.push(e),"\\"!==e)if(")"!==e)if("["!==e){if("("===e&&(c++,"?"===r[i]&&(i+=2,":"!==r[i-1])))return t}else for(;i<r.length;){const t=r[i++];if(u.push(t),"]"===t)break;"\\"===t&&u.push(r[i++])}else{if(0===c)return t;c--}else u.push(r[i++])}return c?t:(u.push(")$"),{name:n,pattern:new RegExp(u.join(""),o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s})}function T(t,e){const n=[];if("string"==typeof t)for(const e of t.split("/"))e&&!/^\.+$/.test(e)&&n.push(O(e));else for(const[e,r]of function*([...t],[...e]){let n=(t.shift()||"").split("/"),r=[n.pop()||""];for(const t of n)yield[[t],[]];for(const n of t){const t=n.split("/");if(t.length<=1){r.push(n);continue}const o=e.splice(0,r.length);r.push(t.shift()||""),yield[r,o],r=[t.pop()||""];for(const e of t)yield[[e],[]]}yield[r,e]}(...t)){if(2===e.length&&!e[0]){const t=e[1];if(["","?","+","*"].includes(t)){const e=r[0];if("symbol"==typeof e){n.push({name:e,pattern:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}if(e&&"object"==typeof e){const{name:r,pattern:o}=e;if("symbol"==typeof r){n.push({name:r,pattern:o instanceof RegExp?o:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}}}}const t=e.pop()||"",o=e.map(((t,e)=>[t,r[e]])).flat();o.push(t);const s=o.join("");s&&!/^\.+$/.test(s)&&n.push(O(s))}if(n.length)return t=>function(t,e,n){const r={};for(let n=0;n<t.length;n++){const o=t[n],s=e[n];if(o!==s){if("string"==typeof o)return;if(!s)return o.optional?[r,[]]:void 0;if(!o.pattern.test(s))return;r[o.name]=s}}if(!n)return[r,e.slice(t.length)];if(e.length<=t.length)return[r,[]];const o=t[t.length-1];if("string"!=typeof o&&(o.many||!(e.length>t.length))){for(let n=t.length;n<e.length;n++)if(!o.pattern.test(e[n]))return;return r[o.name]=e.slice(t.length-1),[r,[]]}}(n,t,e)}function E(t,e,n,r){const o={match:n,methods:e,handlers:r};t.push(o);let s=!1;return()=>{if(s)return;s=!0;const e=t.indexOf(o);e<0||t.splice(e,1)}}const j=t=>"function"==typeof t;function R(t,e,n){const r=new Set(e);if(!n.length){const e=void 0;return(...n)=>E(t,r,e,n)}const[o]=n;if(o&&"object"==typeof o){const e=T([o,n.slice(1)],!0);return(...n)=>E(t,r,e,n)}const s=T("string"==typeof o?o:"",!0),i=n.filter(j);return i.length?E(t,r,s,i):(...e)=>E(t,r,s,e)}const S=new Set(["GET","POST","PUT","DELETE","HEAD","OPTIONS"]);function A(t){return S.has(t)}function P(t,e,n){const r=n instanceof b?n:"function"==typeof n?b.create(n):new U;return t.push({match:T(e,!1),router:r}),r}class U extends b{#r=[];route(...t){const[e]=t;if(e&&"object"==typeof e&&!(e instanceof b))return n=>P(this.#r,[e,t.slice(1)],n);const n="string"==typeof e?e:"",r="string"==typeof e?t[1]:e;return P(this.#r,n,r)}*find(t,e,n){for(const n of Array.from(this.#r)){if(!n.router&&!n.methods.has(t))continue;const{match:r}=n;if(!r){!n.router&&e.length||(yield[n.router||n.handlers,{},e]);continue}if(!e.length)continue;const o=r(e);o&&(yield[n.router||n.handlers,...o])}}verb(t,e,...n){const r=function(t){return t?"string"==typeof t?[t.toUpperCase()].filter(A):Array.from(t).map((t=>"string"==typeof t&&t.toUpperCase())).filter(A):["GET","POST","PUT","DELETE"]}(t);return r.length?R(this.#r,r,[e,...n]):()=>{}}match(...t){return R(this.#r,["GET","POST","PUT","DELETE"],t)}get(...t){return R(this.#r,["GET"],t)}post(...t){return R(this.#r,["POST"],t)}put(...t){return R(this.#r,["PUT"],t)}delete(...t){return R(this.#r,["DELETE"],t)}head(...t){return R(this.#r,["HEAD"],t)}options(...t){return R(this.#r,["OPTIONS"],t)}}function v(t,e){return async function(n,r){const o=new Request(n,r),{signal:s}=o;s.throwIfAborted();const i=await t(o);return i||("function"==typeof e?e(o):new Response(null,{status:404}))}}const x=()=>{};function L(...t){let e=x;for(const n of t.flat()){const t=e;e=async e=>n(e,(async()=>t(e)))}return e}class k{#o=Symbol();get name(){return this.#o}#s;get pattern(){return this.#s}constructor(t){this.#s=t}param(t){const e=t.params[this.#o];return Array.isArray(e)?e[0]??null:e??null}params(t){const e=t.params[this.#o];return"string"==typeof e?[e]:Array.isArray(e)?e:null}}export{U as ApiRouter,k as Param,b as Router,v as createFetch,u as main,a as make,l as merge,L as onionskin,g as packer,p as service,h as stateService,y as storeService};