@orkestrel/router 0.0.13 → 0.0.14
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/README.md +14 -14
- package/dist/src/browser/index.d.ts +47 -29
- package/dist/src/browser/index.js +3 -2
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/core/index.cjs +44 -33
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +206 -108
- package/dist/src/core/index.d.ts +206 -108
- package/dist/src/core/index.js +44 -33
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +14 -5
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +17 -8
- package/dist/src/server/index.d.ts +17 -8
- package/dist/src/server/index.js +14 -5
- package/dist/src/server/index.js.map +1 -1
- package/package.json +10 -11
package/dist/src/core/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
2
|
-
import { EmitterHooks } from '@orkestrel/emitter';
|
|
3
|
-
import { EmitterInterface } from '@orkestrel/emitter';
|
|
1
|
+
import type { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
2
|
+
import type { EmitterHooks } from '@orkestrel/emitter';
|
|
3
|
+
import type { EmitterInterface } from '@orkestrel/emitter';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Represents the native-override seam — a predicate deciding whether an entry's
|
|
7
|
-
*
|
|
6
|
+
* Represents the native-override seam — a predicate deciding whether an entry's
|
|
7
|
+
* `meta` answers a given `match` call, beyond path matching.
|
|
8
8
|
*
|
|
9
9
|
* @typeParam Meta - The entry payload the predicate reads
|
|
10
10
|
*
|
|
@@ -19,7 +19,7 @@ import { EmitterInterface } from '@orkestrel/emitter';
|
|
|
19
19
|
export declare type AnswerHandler<Meta> = (meta: Meta) => boolean;
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Canonicalizes a route path for
|
|
22
|
+
* Canonicalizes a route path for registry identity — strips a single trailing
|
|
23
23
|
* slash, except the root `/` (and the empty pattern). The trailing-slash fold
|
|
24
24
|
* {@link compilePath} normalizes a pattern through, so identity agrees with the
|
|
25
25
|
* matcher.
|
|
@@ -45,11 +45,11 @@ export declare type AnswerHandler<Meta> = (meta: Meta) => boolean;
|
|
|
45
45
|
export declare function canonicalizePath(path: string): string;
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
* Classifies one path segment into its specificity
|
|
49
|
-
* {@link compilePath} rewrites: a syntactically valid `:name` head is a
|
|
50
|
-
* segment, a final `*name` is a
|
|
51
|
-
* literal segment that merely
|
|
52
|
-
*
|
|
48
|
+
* Classifies one path segment into its specificity tier — the same syntax
|
|
49
|
+
* {@link compilePath} rewrites: a syntactically valid `:name` head is a param
|
|
50
|
+
* segment, a final `*name` is a wildcard segment, and everything else (including a
|
|
51
|
+
* literal segment that merely contains a `:` mid-string, for example `a:b`) is a
|
|
52
|
+
* literal segment.
|
|
53
53
|
*
|
|
54
54
|
* @remarks
|
|
55
55
|
* This is the fix over the old engine's bug: the old classifier ranked any
|
|
@@ -77,7 +77,7 @@ export declare function canonicalizePath(path: string): string;
|
|
|
77
77
|
export declare function classifySegment(segment: string, isFinal: boolean): number;
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
|
-
* Compares two route paths by
|
|
80
|
+
* Compares two route paths by specificity — the comparator that picks the
|
|
81
81
|
* most-specific matching route (literal-over-param-over-wildcard,
|
|
82
82
|
* registration-order-independent).
|
|
83
83
|
*
|
|
@@ -168,7 +168,8 @@ export declare interface CompiledPath {
|
|
|
168
168
|
export declare function compilePath(path: string, sensitive?: boolean): CompiledPath;
|
|
169
169
|
|
|
170
170
|
/**
|
|
171
|
-
* Computes the registry key for a method-dimensioned
|
|
171
|
+
* Computes the canonical `METHOD /path` registry key for a method-dimensioned
|
|
172
|
+
* dispatcher route.
|
|
172
173
|
*
|
|
173
174
|
* @remarks
|
|
174
175
|
* Combines the route record's HTTP method with the outer entry's canonical
|
|
@@ -188,7 +189,7 @@ export declare interface CompiledPath {
|
|
|
188
189
|
}>): string;
|
|
189
190
|
|
|
190
191
|
/**
|
|
191
|
-
* Computes a route path's
|
|
192
|
+
* Computes a route path's specificity vector — the per-segment type ranking
|
|
192
193
|
* that breaks a tie when several registered routes match the same concrete
|
|
193
194
|
* pathname.
|
|
194
195
|
*
|
|
@@ -220,8 +221,8 @@ export declare interface CompiledPath {
|
|
|
220
221
|
export declare function computeSpecificity(path: string): readonly number[];
|
|
221
222
|
|
|
222
223
|
/**
|
|
223
|
-
* Creates a {@link DispatcherInterface} — the fetch-standard,
|
|
224
|
-
* dimensioned dispatch entity over one internal `Router<RouteRecord<TState>>`.
|
|
224
|
+
* Creates a {@link DispatcherInterface} — the fetch-standard,
|
|
225
|
+
* method-dimensioned dispatch entity over one internal `Router<RouteRecord<TState>>`.
|
|
225
226
|
*
|
|
226
227
|
* @remarks
|
|
227
228
|
* Prefer this over `new Dispatcher(...)` at call sites that only need the
|
|
@@ -262,19 +263,30 @@ export declare interface CompiledPath {
|
|
|
262
263
|
* (default `true`), and a `key` dedup identity function
|
|
263
264
|
* @returns A {@link RouterInterface}
|
|
264
265
|
*
|
|
265
|
-
* @example
|
|
266
|
+
* @example Register and match
|
|
266
267
|
* ```ts
|
|
267
|
-
* import { createRouter } from '@
|
|
268
|
+
* import { createDispatcher, createRouter } from '@orkestrel/router'
|
|
268
269
|
*
|
|
269
270
|
* const router = createRouter<{ readonly page: string }>()
|
|
270
271
|
* router.add({ path: '/users/:id', meta: { page: 'profile' } })
|
|
271
272
|
* router.match('/users/7') // { path: '/users/:id', params: { id: '7' }, meta: { page: 'profile' } }
|
|
273
|
+
*
|
|
274
|
+
* const dispatcher = createDispatcher<{ readonly userId: string }>({
|
|
275
|
+
* routes: [
|
|
276
|
+
* {
|
|
277
|
+
* method: 'GET',
|
|
278
|
+
* path: '/users/:id',
|
|
279
|
+
* handler: (_request, context) => Response.json(context.params),
|
|
280
|
+
* },
|
|
281
|
+
* ],
|
|
282
|
+
* })
|
|
283
|
+
* const response = await dispatcher.handle(new Request('http://x/users/7'), { userId: 'me' })
|
|
272
284
|
* ```
|
|
273
285
|
*/
|
|
274
286
|
export declare function createRouter<Meta>(options?: RouterOptions<Meta>): RouterInterface<Meta>;
|
|
275
287
|
|
|
276
288
|
/**
|
|
277
|
-
*
|
|
289
|
+
* Decodes one captured param value from a URL, tolerating a malformed percent-escape —
|
|
278
290
|
* the decode {@link matchPath} applies to each captured group.
|
|
279
291
|
*
|
|
280
292
|
* @remarks
|
|
@@ -296,8 +308,8 @@ export declare interface CompiledPath {
|
|
|
296
308
|
export declare function decodeParam(value: string): string;
|
|
297
309
|
|
|
298
310
|
/**
|
|
299
|
-
* Provides an identity pass-through for a {@link RouteInput} that pins its `Path`
|
|
300
|
-
* to the
|
|
311
|
+
* Provides an identity pass-through for a {@link RouteInput} that pins its `Path`
|
|
312
|
+
* generic to the literal registration-site string, so `context.params` types
|
|
301
313
|
* correctly through {@link PathParams} without an explicit type argument.
|
|
302
314
|
*
|
|
303
315
|
* @remarks
|
|
@@ -335,10 +347,10 @@ export declare interface CompiledPath {
|
|
|
335
347
|
export declare function defineRoute<const Path extends string, TState = undefined>(input: RouteInput<Path, TState>): RouteInput<Path, TState>;
|
|
336
348
|
|
|
337
349
|
/**
|
|
338
|
-
* Represents the fetch-standard, method-dimensioned dispatch entity — layers HTTP
|
|
339
|
-
* dispatch and web-standard `Request`/`Response` handling over one internal
|
|
340
|
-
* `Router<RouteRecord<TState>>`. The core machine the
|
|
341
|
-
*
|
|
350
|
+
* Represents the fetch-standard, method-dimensioned dispatch entity — layers HTTP
|
|
351
|
+
* method dispatch and web-standard `Request`/`Response` handling over one internal
|
|
352
|
+
* `Router<RouteRecord<TState>>`. The core machine the server face and any
|
|
353
|
+
* fetch-native runtime consume directly.
|
|
342
354
|
*
|
|
343
355
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
344
356
|
*
|
|
@@ -416,35 +428,50 @@ export declare interface CompiledPath {
|
|
|
416
428
|
* into every {@link RouteContext} (default `undefined` for stateless use)
|
|
417
429
|
*
|
|
418
430
|
* @remarks
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
* - `emitter` — the observable surface for {@link DispatcherEventMap}.
|
|
422
|
-
* - `add(input)` / `add(inputs)` — register ONE / MANY {@link RouteInput}s
|
|
423
|
-
* (batch registration); throws a `ContractError` on a malformed registration (a
|
|
424
|
-
* non-`/`-prefixed path, a non-function handler, or a method outside
|
|
425
|
-
* {@link import('./constants.js').METHODS}) — the construction/registration
|
|
426
|
-
* boundary guard; `match`/`handle` hot paths carry zero guards.
|
|
427
|
-
* - `group(prefix)` — a {@link DispatchGroupInterface} scoped under `prefix`.
|
|
428
|
-
* - `match(method, pathname)` — the raw {@link DispatchResult} for a method +
|
|
429
|
-
* pathname pair, with no `Request`/`Response` involvement — the pure
|
|
430
|
-
* decision `handle` builds its response from.
|
|
431
|
-
* - `handle(request, state)` — the full dispatch: parses `request.url`,
|
|
432
|
-
* calls `match`, and either invokes the winning handler (auto-stripping
|
|
433
|
-
* the body for a derived `HEAD`, auto-answering a derived `OPTIONS` with
|
|
434
|
-
* the `Allow` set), or invokes the `unmatched`/`unmethoded` responder.
|
|
435
|
-
* Emits `match`/`miss` accordingly. A handler throw propagates uncaught.
|
|
436
|
-
* - `destroy()` — tears down the `#emitter`; the underlying
|
|
437
|
-
* router is left registered (not cleared) so introspection remains valid
|
|
438
|
-
* after destroy.
|
|
431
|
+
* Registration is the guarded boundary: `add` throws on a malformed registration,
|
|
432
|
+
* while the `match` and `handle` hot paths carry no guard of their own.
|
|
439
433
|
*/
|
|
440
434
|
export declare interface DispatcherInterface<TState = undefined> {
|
|
435
|
+
/**
|
|
436
|
+
* Holds the underlying registry, exposed readonly for introspection — the same
|
|
437
|
+
* object `add`, `group`, and `match` operate on.
|
|
438
|
+
*/
|
|
441
439
|
readonly router: RouterInterface<RouteRecord<TState>>;
|
|
440
|
+
/** Holds the observable surface for {@link DispatcherEventMap}. */
|
|
442
441
|
readonly emitter: EmitterInterface<DispatcherEventMap>;
|
|
442
|
+
/**
|
|
443
|
+
* Registers one route input, or many in one call (batch registration); throws a
|
|
444
|
+
* `ContractError` on a malformed registration.
|
|
445
|
+
*
|
|
446
|
+
* @remarks
|
|
447
|
+
* A registration is malformed when its path is not `/`-prefixed, its handler is not
|
|
448
|
+
* a function, or its method sits outside {@link import('./constants.js').METHODS}.
|
|
449
|
+
* Path validation is delegated to the underlying router's own guard.
|
|
450
|
+
*/
|
|
443
451
|
add<Path extends string>(input: RouteInput<Path, TState>): void;
|
|
444
452
|
add(inputs: ReadonlyArray<RouteInput<string, TState>>): void;
|
|
453
|
+
/** Returns a prefix-scoped registration handle over this dispatcher. */
|
|
445
454
|
group(prefix: string): DispatchGroupInterface<TState>;
|
|
455
|
+
/**
|
|
456
|
+
* Decides the raw {@link DispatchResult} for a method and pathname pair, with no
|
|
457
|
+
* `Request` or `Response` involvement — the pure decision `handle` builds its
|
|
458
|
+
* response from.
|
|
459
|
+
*/
|
|
446
460
|
match(method: Method, pathname: string): DispatchResult<TState>;
|
|
461
|
+
/**
|
|
462
|
+
* Runs the full dispatch: parses the request URL, matches, and invokes either the
|
|
463
|
+
* winning handler or the `unmatched`/`unmethoded` responder.
|
|
464
|
+
*
|
|
465
|
+
* @remarks
|
|
466
|
+
* A derived `HEAD` runs the matching `GET` handler with the response body stripped,
|
|
467
|
+
* and a derived `OPTIONS` answers with the `Allow` set. Emits `match` or `miss`
|
|
468
|
+
* accordingly. A handler throw propagates uncaught.
|
|
469
|
+
*/
|
|
447
470
|
handle(request: Request, state: TState): Promise<Response>;
|
|
471
|
+
/**
|
|
472
|
+
* Tears down the emitter; the underlying router is left registered rather than
|
|
473
|
+
* cleared, so introspection stays valid afterwards.
|
|
474
|
+
*/
|
|
448
475
|
destroy(): void;
|
|
449
476
|
}
|
|
450
477
|
|
|
@@ -479,8 +506,8 @@ export declare interface CompiledPath {
|
|
|
479
506
|
|
|
480
507
|
/**
|
|
481
508
|
* Represents a prefix-scoped registration handle over a
|
|
482
|
-
* {@link import('./Dispatcher.js').Dispatcher} — the method-dimensioned
|
|
483
|
-
*
|
|
509
|
+
* {@link import('./Dispatcher.js').Dispatcher} — the method-dimensioned counterpart of
|
|
510
|
+
* `Group`.
|
|
484
511
|
*
|
|
485
512
|
* @typeParam TState - The consumer's opaque per-request state type, matching
|
|
486
513
|
* the owning dispatcher
|
|
@@ -517,25 +544,32 @@ export declare interface CompiledPath {
|
|
|
517
544
|
* the owning dispatcher
|
|
518
545
|
*
|
|
519
546
|
* @remarks
|
|
520
|
-
*
|
|
521
|
-
* registers (and to every nested group's own prefix).
|
|
522
|
-
* - `add(input)` / `add(inputs)` — register ONE / MANY {@link RouteInput}s on
|
|
523
|
-
* the OWNING dispatcher, each input's `path` composed as
|
|
524
|
-
* `prefix + input.path` (batch registration, mirroring
|
|
525
|
-
* {@link DispatcherInterface.add}).
|
|
526
|
-
* - `group(prefix)` — a nested group whose prefix is `this.prefix + prefix`.
|
|
547
|
+
* Nesting composes prefixes left to right with no depth limit.
|
|
527
548
|
*/
|
|
528
549
|
export declare interface DispatchGroupInterface<TState> {
|
|
550
|
+
/**
|
|
551
|
+
* Holds the path prefix this group prepends to every route it registers, and to
|
|
552
|
+
* every nested group's own prefix.
|
|
553
|
+
*/
|
|
529
554
|
readonly prefix: string;
|
|
555
|
+
/**
|
|
556
|
+
* Registers one route input, or many in one call, on the owning dispatcher with this
|
|
557
|
+
* group's prefix composed onto each path.
|
|
558
|
+
*
|
|
559
|
+
* @remarks
|
|
560
|
+
* Batch registration mirrors {@link DispatcherInterface.add}, and the owning
|
|
561
|
+
* dispatcher's own registration guard still applies.
|
|
562
|
+
*/
|
|
530
563
|
add<Path extends string>(input: RouteInput<Path, TState>): void;
|
|
531
564
|
add(inputs: ReadonlyArray<RouteInput<string, TState>>): void;
|
|
565
|
+
/** Returns a nested group whose prefix is this prefix followed by the given one. */
|
|
532
566
|
group(prefix: string): DispatchGroupInterface<TState>;
|
|
533
567
|
}
|
|
534
568
|
|
|
535
569
|
/**
|
|
536
|
-
* Represents the outcome of {@link DispatcherInterface.match} — a discriminated
|
|
537
|
-
* over the dispatch tiers: a full hit, a path
|
|
538
|
-
*
|
|
570
|
+
* Represents the outcome of {@link DispatcherInterface.match} — a discriminated
|
|
571
|
+
* union over the dispatch tiers: a full hit, a path that matches with no route for
|
|
572
|
+
* the method (405 territory), or nothing matched at all (404 territory).
|
|
539
573
|
*
|
|
540
574
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
541
575
|
*
|
|
@@ -616,33 +650,51 @@ export declare interface CompiledPath {
|
|
|
616
650
|
* @typeParam Meta - The entry payload type, matching the owning router
|
|
617
651
|
*
|
|
618
652
|
* @remarks
|
|
619
|
-
*
|
|
620
|
-
* registers (and to every nested group's own prefix).
|
|
621
|
-
* - `add(entry)` / `add(entries)` — register ONE / MANY entries on the
|
|
622
|
-
* OWNING router, each entry's `path` composed as `prefix + entry.path`
|
|
623
|
-
* (batch registration, mirroring {@link RouterInterface.add}).
|
|
624
|
-
* - `group(prefix)` — a nested group whose prefix is `this.prefix + prefix`;
|
|
625
|
-
* nesting composes prefixes left to right with no depth limit.
|
|
653
|
+
* Nesting composes prefixes left to right with no depth limit.
|
|
626
654
|
*/
|
|
627
655
|
export declare interface GroupInterface<Meta> {
|
|
656
|
+
/**
|
|
657
|
+
* Holds the path prefix this group prepends to every entry it registers, and to
|
|
658
|
+
* every nested group's own prefix.
|
|
659
|
+
*/
|
|
628
660
|
readonly prefix: string;
|
|
661
|
+
/**
|
|
662
|
+
* Registers one entry, or many in one call, on the owning router with this group's
|
|
663
|
+
* prefix composed onto each path.
|
|
664
|
+
*
|
|
665
|
+
* @remarks
|
|
666
|
+
* Batch registration mirrors {@link RouterInterface.add}, and the owning router's own
|
|
667
|
+
* registration guard still applies.
|
|
668
|
+
*/
|
|
629
669
|
add(entry: RouteEntry<Meta>): void;
|
|
630
670
|
add(entries: ReadonlyArray<RouteEntry<Meta>>): void;
|
|
671
|
+
/** Returns a nested group whose prefix is this prefix followed by the given one. */
|
|
631
672
|
group(prefix: string): GroupInterface<Meta>;
|
|
632
673
|
}
|
|
633
674
|
|
|
634
675
|
/**
|
|
635
|
-
* Names the identifier
|
|
676
|
+
* Names the identifier continuation characters after the first — mirrors the
|
|
636
677
|
* runtime classifier's `[A-Za-z0-9_]*` tail class.
|
|
637
678
|
*/
|
|
638
679
|
export declare type IdentifierChar = IdentifierStartChar | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
639
680
|
|
|
681
|
+
/**
|
|
682
|
+
* Captures the identifier at the front of a string literal, or an empty string when the
|
|
683
|
+
* literal does not begin with an identifier-start char.
|
|
684
|
+
*
|
|
685
|
+
* @typeParam S - The string literal to read the head from
|
|
686
|
+
*
|
|
687
|
+
* @remarks
|
|
688
|
+
* The type-level mirror of the runtime head match anchored on an identifier-start char:
|
|
689
|
+
* an {@link IdentifierStartChar} opens the run and {@link TakeIdentifierTail} consumes
|
|
690
|
+
* the rest of it.
|
|
691
|
+
*/
|
|
640
692
|
export declare type IdentifierHead<S extends string> = S extends `${infer Head}${infer Tail}` ? Head extends IdentifierStartChar ? TakeIdentifierTail<Tail, Head> : '' : '';
|
|
641
693
|
|
|
642
694
|
/**
|
|
643
|
-
* Names the identifier
|
|
644
|
-
*
|
|
645
|
-
*
|
|
695
|
+
* Names the identifier start characters an identifier-grammar param name may begin
|
|
696
|
+
* with — mirrors the runtime classifier's `[A-Za-z_]` head class, the one
|
|
697
|
+
* `classifySegment` and `compilePath` share.
|
|
646
698
|
*/
|
|
647
699
|
export declare type IdentifierStartChar = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '_';
|
|
648
700
|
|
|
@@ -700,9 +752,9 @@ export declare interface CompiledPath {
|
|
|
700
752
|
export declare function matchPath(compiled: CompiledPath, pathname: string): Readonly<Record<string, string>> | undefined;
|
|
701
753
|
|
|
702
754
|
/**
|
|
703
|
-
* Names the HTTP methods a {@link DispatcherInterface} dimensions dispatch
|
|
704
|
-
*
|
|
705
|
-
*
|
|
755
|
+
* Names the HTTP methods a {@link DispatcherInterface} dimensions dispatch over —
|
|
756
|
+
* derived from {@link import('./constants.js').METHOD_LIST}, whose membership
|
|
757
|
+
* counterpart is {@link import('./constants.js').METHODS}.
|
|
706
758
|
*
|
|
707
759
|
* @remarks
|
|
708
760
|
* Resolves to `'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' |
|
|
@@ -715,10 +767,10 @@ export declare interface CompiledPath {
|
|
|
715
767
|
export declare type Method = (typeof METHOD_LIST)[number];
|
|
716
768
|
|
|
717
769
|
/**
|
|
718
|
-
* Lists the HTTP methods a {@link import('./types.js').DispatcherInterface}
|
|
719
|
-
*
|
|
720
|
-
* {@link import('./types.js').Method} type, {@link METHODS}, and
|
|
721
|
-
*
|
|
770
|
+
* Lists the HTTP methods a {@link import('./types.js').DispatcherInterface} registers
|
|
771
|
+
* routes under, in canonical order — a frozen literal tuple, and the single source the
|
|
772
|
+
* {@link import('./types.js').Method} type, {@link METHODS}, and `parseMethod` are all
|
|
773
|
+
* derived from.
|
|
722
774
|
*
|
|
723
775
|
* @remarks
|
|
724
776
|
* A frozen tuple of the verbs: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`,
|
|
@@ -736,10 +788,9 @@ export declare interface CompiledPath {
|
|
|
736
788
|
export declare const METHOD_LIST: readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
|
|
737
789
|
|
|
738
790
|
/**
|
|
739
|
-
* Holds
|
|
740
|
-
*
|
|
741
|
-
*
|
|
742
|
-
* and the auto-`OPTIONS` `Allow` derivation.
|
|
791
|
+
* Holds every HTTP method a {@link import('./types.js').DispatcherInterface} registers
|
|
792
|
+
* routes under as a `ReadonlySet` — backs the registration guard (`add` rejects any
|
|
793
|
+
* `method` outside this set) and the auto-`OPTIONS` `Allow` derivation.
|
|
743
794
|
*
|
|
744
795
|
* @remarks
|
|
745
796
|
* A `ReadonlySet` built from {@link METHOD_LIST}, so it carries exactly the
|
|
@@ -920,9 +971,9 @@ export declare interface CompiledPath {
|
|
|
920
971
|
|
|
921
972
|
/**
|
|
922
973
|
* Represents the path-matching + registry engine — registers `{ path, meta, name? }`
|
|
923
|
-
* entries (compiling each path once) and resolves a concrete pathname to the
|
|
924
|
-
*
|
|
925
|
-
*
|
|
974
|
+
* entries (compiling each path once) and resolves a concrete pathname to the most
|
|
975
|
+
* specific matching entry. The shared machine both the `Navigator` (browser) and
|
|
976
|
+
* the `Dispatcher` (core, method-dimensioned) compose.
|
|
926
977
|
*
|
|
927
978
|
* @typeParam Meta - The opaque payload each entry carries and a match returns
|
|
928
979
|
*
|
|
@@ -981,47 +1032,66 @@ export declare interface CompiledPath {
|
|
|
981
1032
|
/**
|
|
982
1033
|
* Represents the path-matching + registry engine contract (the behavioral-interface
|
|
983
1034
|
* role for the one-class-per-file `Router`). Registers `{ path, meta, name? }`
|
|
984
|
-
* entries (compiling each path once) and resolves a concrete pathname to the
|
|
985
|
-
*
|
|
986
|
-
*
|
|
987
|
-
*
|
|
988
|
-
* (core, method-dimensioned) compose.
|
|
1035
|
+
* entries (compiling each path once) and resolves a concrete pathname to the most
|
|
1036
|
+
* specific matching entry — a literal segment beats a param beats a wildcard at the
|
|
1037
|
+
* earliest differing segment, registration-order-independent. The shared engine both
|
|
1038
|
+
* the `Navigator` (browser) and the `Dispatcher` (core, method-dimensioned) compose.
|
|
989
1039
|
*
|
|
990
1040
|
* @typeParam Meta - The opaque payload each entry carries and a match returns
|
|
991
1041
|
*
|
|
992
1042
|
* @remarks
|
|
993
|
-
*
|
|
994
|
-
*
|
|
995
|
-
* each path is compiled once here. When constructed with a `key` option,
|
|
996
|
-
* an entry whose key already exists replaces the prior one in place;
|
|
997
|
-
* otherwise every entry is kept, even duplicate paths.
|
|
998
|
-
* - `match(pathname, answers?)` — the MOST-SPECIFIC matching entry as a
|
|
999
|
-
* {@link RouterMatch} (its winning `path`, decoded `params`, `meta`, and
|
|
1000
|
-
* `name`), or `undefined`. The optional {@link AnswerHandler} predicate
|
|
1001
|
-
* filters candidates by `meta` first; omitted ⇒ every path match is
|
|
1002
|
-
* eligible.
|
|
1003
|
-
* - `entries()` — ALL registered entries in registration order.
|
|
1004
|
-
* - `entries(pathname)` — only entries whose path matches `pathname` (the
|
|
1005
|
-
* plural accessor's filtered form; backs a consumer's allow/405 set).
|
|
1006
|
-
* - `group(prefix)` — a {@link GroupInterface} scoped under `prefix`; entries
|
|
1007
|
-
* added through the group are registered on this same router with `prefix`
|
|
1008
|
-
* prepended to each path.
|
|
1009
|
-
* - `clear()` — drop every entry, leaving the router reusable.
|
|
1043
|
+
* Registration is the guarded boundary and matching is the hot path: `add` validates
|
|
1044
|
+
* each entry and throws, while `match` carries no guard of its own.
|
|
1010
1045
|
*/
|
|
1011
1046
|
export declare interface RouterInterface<Meta> {
|
|
1047
|
+
/** Holds the number of registered entries. */
|
|
1012
1048
|
readonly count: number;
|
|
1049
|
+
/**
|
|
1050
|
+
* Registers one entry, or many in one call (batch registration), compiling each path
|
|
1051
|
+
* once; throws a `ContractError` on a malformed path.
|
|
1052
|
+
*
|
|
1053
|
+
* @remarks
|
|
1054
|
+
* When the router was constructed with a `key` option, an entry whose key already
|
|
1055
|
+
* exists replaces the prior one in place; otherwise every entry is kept, even a
|
|
1056
|
+
* duplicate path.
|
|
1057
|
+
*/
|
|
1013
1058
|
add(entry: RouteEntry<Meta>): void;
|
|
1014
1059
|
add(entries: ReadonlyArray<RouteEntry<Meta>>): void;
|
|
1060
|
+
/**
|
|
1061
|
+
* Resolves the most-specific matching entry for a pathname, or `undefined` when
|
|
1062
|
+
* nothing matches.
|
|
1063
|
+
*
|
|
1064
|
+
* @remarks
|
|
1065
|
+
* A hit is a {@link RouterMatch} carrying the winning `path`, the decoded `params`,
|
|
1066
|
+
* the `meta` payload, and the optional `name`. The optional {@link AnswerHandler}
|
|
1067
|
+
* predicate filters candidates by `meta` first; omitted, every path match is eligible.
|
|
1068
|
+
*/
|
|
1015
1069
|
match(pathname: string, answers?: AnswerHandler<Meta>): RouterMatch<Meta> | undefined;
|
|
1070
|
+
/**
|
|
1071
|
+
* Lists every registered entry in registration order, or only those whose path
|
|
1072
|
+
* matches a given pathname.
|
|
1073
|
+
*
|
|
1074
|
+
* @remarks
|
|
1075
|
+
* The filtered form is the plural accessor's second shape, and it backs a consumer's
|
|
1076
|
+
* allow set for a 405 answer.
|
|
1077
|
+
*/
|
|
1016
1078
|
entries(): ReadonlyArray<RouteEntry<Meta>>;
|
|
1017
1079
|
entries(pathname: string): ReadonlyArray<RouteEntry<Meta>>;
|
|
1080
|
+
/**
|
|
1081
|
+
* Returns a prefix-scoped registration handle over this router.
|
|
1082
|
+
*
|
|
1083
|
+
* @remarks
|
|
1084
|
+
* Entries added through the group are registered on this same router with `prefix`
|
|
1085
|
+
* prepended to each path.
|
|
1086
|
+
*/
|
|
1018
1087
|
group(prefix: string): GroupInterface<Meta>;
|
|
1088
|
+
/** Drops every entry, leaving the router reusable. */
|
|
1019
1089
|
clear(): void;
|
|
1020
1090
|
}
|
|
1021
1091
|
|
|
1022
1092
|
/**
|
|
1023
|
-
* Represents one matched route — the winning entry's
|
|
1024
|
-
* payload, and optional `name`.
|
|
1093
|
+
* Represents one matched route — the winning entry's registered pattern, its decoded
|
|
1094
|
+
* params, its `meta` payload, and its optional `name`.
|
|
1025
1095
|
*
|
|
1026
1096
|
* @typeParam Meta - The payload the winning entry carries
|
|
1027
1097
|
*
|
|
@@ -1041,8 +1111,8 @@ export declare interface CompiledPath {
|
|
|
1041
1111
|
}
|
|
1042
1112
|
|
|
1043
1113
|
/**
|
|
1044
|
-
* Represents the options for `createRouter` — an optional initial entry set, the
|
|
1045
|
-
* sensitivity toggle, and the dedup identity function.
|
|
1114
|
+
* Represents the options for `createRouter` — an optional initial entry set, the
|
|
1115
|
+
* case-sensitivity toggle, and the dedup identity function.
|
|
1046
1116
|
*
|
|
1047
1117
|
* @typeParam Meta - The entry payload type
|
|
1048
1118
|
*
|
|
@@ -1065,12 +1135,40 @@ export declare interface CompiledPath {
|
|
|
1065
1135
|
readonly key?: (entry: RouteEntry<Meta>) => string;
|
|
1066
1136
|
}
|
|
1067
1137
|
|
|
1138
|
+
/**
|
|
1139
|
+
* Contributes one path segment's type-level param record — the type-level mirror of
|
|
1140
|
+
* the runtime `classifySegment` and `compilePath` segment parser.
|
|
1141
|
+
*
|
|
1142
|
+
* @typeParam Segment - One `/`-split path segment literal
|
|
1143
|
+
*
|
|
1144
|
+
* @remarks
|
|
1145
|
+
* A `:` head followed by an identifier captures that identifier, stopping at the first
|
|
1146
|
+
* non-identifier char, so `:name.json` captures only `name`. A segment whose `:` is not
|
|
1147
|
+
* at the segment start (`a:b`) is literal and captures nothing — the classification fix
|
|
1148
|
+
* this type mirrors. A `*name` segment, valid only as the grammar's final segment,
|
|
1149
|
+
* captures the identifier the same way. A non-capturing segment resolves to `unknown`
|
|
1150
|
+
* (the intersection identity) rather than `Record<string, never>` — an index-signature
|
|
1151
|
+
* type intersected with a later `{ id: string }` would otherwise conflict (`string` is
|
|
1152
|
+
* not assignable to the index signature's `never`); {@link PathParams} normalizes the
|
|
1153
|
+
* eventual `unknown` (parameterless) result down to a clean empty record.
|
|
1154
|
+
*/
|
|
1068
1155
|
export declare type SegmentParam<Segment extends string> = Segment extends `:${infer Rest}` ? IdentifierHead<Rest> extends infer Name extends string ? Name extends '' ? unknown : {
|
|
1069
1156
|
readonly [K in Name]: string;
|
|
1070
1157
|
} : unknown : Segment extends `*${infer Rest}` ? IdentifierHead<Rest> extends infer Name extends string ? Name extends '' ? unknown : {
|
|
1071
1158
|
readonly [K in Name]: string;
|
|
1072
1159
|
} : unknown : unknown;
|
|
1073
1160
|
|
|
1161
|
+
/**
|
|
1162
|
+
* Consumes the identifier-continuation run at the front of a string literal, char by
|
|
1163
|
+
* char, appending each onto the accumulator.
|
|
1164
|
+
*
|
|
1165
|
+
* @typeParam S - The string literal whose front is being consumed
|
|
1166
|
+
* @typeParam Acc - The identifier characters taken so far
|
|
1167
|
+
*
|
|
1168
|
+
* @remarks
|
|
1169
|
+
* Stops (returning `Acc` unchanged) at the first non-identifier char or at the end of
|
|
1170
|
+
* the string, so the accumulator holds exactly the leading {@link IdentifierChar} run.
|
|
1171
|
+
*/
|
|
1074
1172
|
export declare type TakeIdentifierTail<S extends string, Acc extends string> = S extends `${infer Head}${infer Tail}` ? Head extends IdentifierChar ? TakeIdentifierTail<Tail, `${Acc}${Head}`> : Acc : Acc;
|
|
1075
1173
|
|
|
1076
1174
|
/**
|