1+ // Abstract.
2+ import { MiddlewareCore } from './middleware-core.abstract' ;
3+ // Type.
4+ import { MiddlewareFunction } from '../type' ;
5+ /**
6+ * @description The base abstraction for arguments middleware.
7+ * @export
8+ * @class MiddlewareBase
9+ * @template [T=any]
10+ */
11+ export abstract class MiddlewareBase <
12+ T = any ,
13+ O = T [ ] ,
14+ U extends Function = MiddlewareFunction < T >
15+ > extends MiddlewareCore < T , O , U > {
16+ /**
17+ * @description
18+ * @type {number }
19+ */
20+ #index = 0 ;
21+
22+ /**
23+ * @description
24+ * @type {U[] }
25+ */
26+ #middleware: U [ ] ;
27+
28+ /**
29+ * @description
30+ * @type {() => void }
31+ */
32+ #onComplete: ( args : O ) => void = ( ) => { } ;
33+
34+ /**
35+ * Creates an instance of `MiddlewareBase`.
36+ * @constructor
37+ * @param {...U[] } middleware
38+ */
39+ constructor ( ...middleware : U [ ] ) {
40+ super ( ) ;
41+ this . #middleware = middleware ;
42+ }
43+
44+ /**
45+ * @description
46+ * @public
47+ * @param {...T[] } args
48+ * @returns {this }
49+ */
50+ public execute ( ...args : T [ ] ) {
51+ this . #index = 0 ;
52+ this . #next( ...args ) ;
53+ return this ;
54+ }
55+
56+ /**
57+ * @description
58+ * @public
59+ * @async
60+ * @param {...T[] } args
61+ * @returns {unknown }
62+ */
63+ public override async executeAsync ( ...args : T [ ] ) : Promise < O > {
64+ this . #index = 0 ;
65+ return new Promise < O > ( async resolve => (
66+ await this . #nextAsync( ...args ) ,
67+ this . onComplete ( ( ) => resolve ( args as O ) )
68+ ) ) ;
69+ }
70+
71+ /**
72+ * @description
73+ * @public
74+ * @param {(args: T[]) => void } onComplete
75+ */
76+ public onComplete ( onComplete : ( args : O ) => void ) : void {
77+ this . #onComplete = onComplete ;
78+ }
79+
80+ /**
81+ * @description
82+ * @public
83+ * @param {U } middleware
84+ * @returns {this }
85+ */
86+ public use ( middleware : U ) : this {
87+ return this . #middleware. push ( middleware ) , this ;
88+ }
89+
90+ /**
91+ * @description
92+ * @param {...T[] } args
93+ */
94+ #next( ...args : T [ ] ) : void {
95+ this . #index < this . #middleware. length
96+ ? this . #middleware[ this . #index++ ] ( args , ( ) => this . #next( ...args ) )
97+ : this . #onComplete( args as O ) ;
98+ }
99+
100+ /**
101+ * @description
102+ * @async
103+ * @param {...T[] } args
104+ * @returns {* }
105+ */
106+ async #nextAsync( ...args : T [ ] ) : Promise < void > {
107+ this . #index < this . #middleware. length
108+ ? await this . #middleware[ this . #index++ ] ( args , ( ) => this . #nextAsync( ...args ) )
109+ : this . #onComplete( args as O ) ;
110+ }
111+ }
0 commit comments