|
1 | | -import { addPatch } from './addPatch'; |
2 | | -import { calledFunctions, functions } from './data'; |
3 | | -import type { BaseFunction, PatchData, PatchFunction, PatchedFunction } from './definition'; |
| 1 | +import type { BaseFunction, PatchFunction, PatchedFunction } from './definition'; |
| 2 | +import { withMiddleware } from './midleware'; |
4 | 3 |
|
5 | 4 | export const makeFunction = <T extends BaseFunction>(fn: T): PatchedFunction<T> => { |
6 | | - const patches = new Set<PatchData<T>>(); |
7 | | - |
8 | | - patches.add({ |
9 | | - patchFunction: (_next, ...args) => fn(...args), |
10 | | - }); |
11 | | - |
12 | | - const result = ((...args: Parameters<T>): ReturnType<T> => { |
13 | | - let newFn: T = fn; |
14 | | - |
15 | | - for (const patch of patches) { |
16 | | - if (patch.condition && !patch.condition()) { |
17 | | - continue; |
| 5 | + const wrapped = withMiddleware(fn); |
| 6 | + const patch = (fn: PatchFunction<T>, condition?: () => boolean) => { |
| 7 | + return wrapped.use((ctx, next) => { |
| 8 | + if (!condition || condition()) { |
| 9 | + return fn(next as unknown as T, ...ctx); |
18 | 10 | } |
19 | | - |
20 | | - const nextFn = newFn; |
21 | | - newFn = ((...args: Parameters<T>) => patch.patchFunction(nextFn, ...args)) as T; |
22 | | - } |
23 | | - |
24 | | - calledFunctions.add(result); |
25 | | - return newFn(...args); |
26 | | - }) as PatchedFunction<T>; |
27 | | - |
28 | | - functions.set(result, patches as Set<PatchData<BaseFunction>>); |
29 | | - |
30 | | - result.patch = (patch: PatchFunction<T>, condition?: () => boolean) => addPatch(result, patch, condition); |
31 | | - |
32 | | - result.originalSignature = (() => { |
| 11 | + return next(...ctx); |
| 12 | + }); |
| 13 | + }; |
| 14 | + const originalSignature = (() => { |
33 | 15 | throw new Error('OriginalSignature of patched functions is not meant to be executed directly.'); |
34 | 16 | }) as unknown as T; |
35 | | - result.patchSignature = (() => { |
| 17 | + const patchSignature = (() => { |
36 | 18 | throw new Error('PatchSignature of patched functions is not meant to be executed directly.'); |
37 | 19 | }) as unknown as PatchFunction<T>; |
38 | 20 |
|
39 | | - return result; |
| 21 | + return Object.assign(wrapped, { |
| 22 | + patch, |
| 23 | + originalSignature, |
| 24 | + patchSignature, |
| 25 | + }) as PatchedFunction<T>; |
40 | 26 | }; |
0 commit comments