-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
compose.ts
42 lines (35 loc) · 973 Bytes
/
compose.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import type { Context } from './context'
import type { Middleware, Next } from './types'
export function compose(middleware: Middleware[]) {
for (const fn of middleware) {
if (typeof fn !== 'function') {
throw new TypeError('Middleware must be composed of functions!')
}
}
return (context: Context, next?: Next) => {
// last called middleware #
let index = -1
return dispatch(0)
function dispatch(i: number): Promise<void> {
if (i <= index) {
return Promise.reject(new Error('next() called multiple times'))
}
index = i
let fn: Middleware = middleware[i]
if (i === middleware.length && next) {
fn = next
}
if (!fn) {
return Promise.resolve()
}
try {
const ctx = fn(context, async () => {
await dispatch(i + 1)
})
return Promise.resolve(ctx)
} catch (err) {
return Promise.reject(err)
}
}
}
}