UNPKG

1.58 kBPlain TextView Raw
1/** @format */
2
3import { Middleware, MiddlewareObj } from './middleware'
4import Composer from './composer'
5import Context from './context'
6
7type NonemptyReadonlyArray<T> = readonly [T, ...T[]]
8
9type RouteFn<TContext extends Context> = (ctx: TContext) => {
10 route: string
11 context?: Partial<TContext>
12 state?: Partial<TContext['state']>
13} | null
14
15/** @deprecated in favor of {@link Composer.dispatch} */
16export class Router<C extends Context> implements MiddlewareObj<C> {
17 private otherwiseHandler: Middleware<C> = Composer.passThru()
18
19 constructor(
20 private readonly routeFn: RouteFn<C>,
21 public handlers = new Map<string, Middleware<C>>()
22 ) {
23 if (typeof routeFn !== 'function') {
24 throw new Error('Missing routing function')
25 }
26 }
27
28 on(route: string, ...fns: NonemptyReadonlyArray<Middleware<C>>) {
29 if (fns.length === 0) {
30 throw new TypeError('At least one handler must be provided')
31 }
32 this.handlers.set(route, Composer.compose(fns))
33 return this
34 }
35
36 otherwise(...fns: NonemptyReadonlyArray<Middleware<C>>) {
37 if (fns.length === 0) {
38 throw new TypeError('At least one otherwise handler must be provided')
39 }
40 this.otherwiseHandler = Composer.compose(fns)
41 return this
42 }
43
44 middleware() {
45 return Composer.lazy<C>((ctx) => {
46 const result = this.routeFn(ctx)
47 if (result == null) {
48 return this.otherwiseHandler
49 }
50 Object.assign(ctx, result.context)
51 Object.assign(ctx.state, result.state)
52 return this.handlers.get(result.route) ?? this.otherwiseHandler
53 })
54 }
55}
56
\No newline at end of file