UNPKG

3.84 kBJavaScriptView Raw
1// deno-lint-ignore-file no-explicit-any
2export { pipe as combine } from 'ts-functional-pipe';
3import { ResolvablePromise } from '@worker-tools/resolvable-promise';
4import { AppendOnlyList } from "./utils/append-only-list.js";
5export class EffectsList extends AppendOnlyList {
6}
7/**
8 * @deprecated Function might change name
9 */
10export function executeEffects(effects, response) {
11 var _a;
12 // TODO: to reduce or reduceRight, that is the question...
13 // reduceRight matches the behavior of my initial, non-compose friendly middleware model
14 // which was just increasingly deep levels of wrapped function calls.
15 // In that model, the effects (post-processes) of the last applied middleware were executed first.
16 // Regular reduce matches the order in which middlewares are applied,
17 // which probably is close what users expect to happen, anyway...
18 return (_a = [...effects].reduceRight(async (response, effect) => { var _a; return (_a = effect(await response)) !== null && _a !== void 0 ? _a : response; }, response)) !== null && _a !== void 0 ? _a : response;
19}
20/**
21 * A helper function to create user-defined middleware.
22 *
23 * Its main purpose is to allow developers to create correctly typed middleware without dealing with generics.
24 * This is achieved via the `_defaultExt` parameter, which is used to infer the types of the *extension* added to the *context*.
25 * As the `_` prefix implies, it is not actually used.
26 * The purpose of the default extension object is solely to tell the type checker which additional keys to expect on the context object after this middleware is applied.
27 * The job of adding (default) values to the context belongs to the middleware function.
28 *
29 * Here are some example usages. All are valid in JavaScript and TypeScript:
30 *
31 * ```ts
32 * const fn = createMiddleware({}, _ => _)
33 * const gn = createMiddleware({}, async ax => ({ ...await ax }))
34 * const hn = createMiddleware({ foo: '' }, async ax => ({ ...await ax, foo: 'star' }))
35 * const jn = createMiddleware({ bar: '' }, async ax => {
36 * const x = await ax;
37 * x.effects.push(resp => {
38 * resp.headers.set('x-middleware', 'jn')
39 * })
40 * return { ...x, bar: 'star' }
41 * })
42 * const myMW = combine(fn, hn, jn, gn)
43 * //=> Context & { foo: string } & { bar: string }
44 * ```
45 *
46 * @param _defaultExt The default extension to the current context. Can also be a function that returns the extension object, to avoid unnecessary memory allocation.
47 * @param middlewareFn A middleware functions: Adds the keys listed in `defaultExt` to the context
48 * @returns The provided `middlewareFn` with type annotations inferred based on `defaultExt`
49 */
50export function createMiddleware(_defaultExt, middlewareFn) {
51 return middlewareFn;
52}
53/**
54 * Takes a handler function of the form `(x: Request, ctx: Context) => Awaitable<Response>` and applies middleware to it.
55 * @deprecated Name might change, errorHandler not implemented
56 */
57export function withMiddleware(middleware, handler, _errorHandler) {
58 return async (request, ...args) => {
59 const handle = new ResolvablePromise();
60 const handled = Promise.resolve(handle);
61 const effects = new EffectsList();
62 const ctx = { request, effects, handled, args: [request, ...args], waitUntil: () => { } };
63 try {
64 const userCtx = await middleware(ctx);
65 const userRes = await handler(request, userCtx);
66 const response = await executeEffects(effects, userRes);
67 handle.resolve(response);
68 return response;
69 }
70 catch (err) {
71 throw err;
72 // TODO
73 // if (fallback && err instanceof Response) {
74 // fallback(request, Object.assign(ctx, { response: err }))
75 // }
76 }
77 };
78}
79//# sourceMappingURL=context.js.map
\No newline at end of file