@arikajs/dispatcher 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,7 +17,7 @@ const dispatcher = new Dispatcher(container);
17
17
  const response = await dispatcher.dispatch(matchedRoute, request, responseInstance);
18
18
  ```
19
19
 
20
- Arika Dispatcher is to ArikaJS what `illuminate/routing`’s dispatcher is to Laravel: it takes a route and makes things happen.
20
+ Arika Dispatcher is to ArikaJS the core execution engine for ArikaJS: it takes a route and makes things happen.
21
21
 
22
22
  ---
23
23
 
@@ -46,21 +46,28 @@ The goal of this package is to be the **reliable executor** of application logic
46
46
  - Automatic instantiation of controllers via Service Container
47
47
 
48
48
  - **Method Invocation**
49
- - Resolves method dependencies
49
+ - Resolves method dependencies (auto-DI if Container supports `.call()`)
50
50
  - Injects `Request` object automatically
51
51
  - Maps route parameters (e.g., `{id}`) to method arguments
52
52
 
53
53
  - **Middleware Pipeline**
54
54
  - Executes route-specific middleware
55
+ - **Executes Controller-specific middleware** (`static middleware = [...]` or `getMiddleware()`)
55
56
  - Onion-style execution flow (nested `next()` calls)
56
57
  - Asynchronous middleware support
57
58
  - Container-based middleware resolution
58
59
 
60
+ - **Exception Handling**
61
+ - Configurable global execution wrapper `setExceptionHandler((err, req, res) => ...)`
62
+ - Converts errors gracefully into responses
63
+
59
64
  - **Response Normalization**
60
65
  - Automatically converts return values to HTTP responses
61
66
  - Objects/Arrays → JSON response
62
67
  - Strings → Plain text response
63
68
  - `null`/`undefined` → 204 No Content
69
+ - View Objects (implementing `.render()`) → Rendered HTML
70
+ - NodeJS Streams (`Readable`) → Piped directly to Response
64
71
 
65
72
  ---
66
73
 
@@ -135,8 +142,36 @@ const dispatcher = new Dispatcher(app.container);
135
142
  const response = await dispatcher.dispatch(matched, request, response);
136
143
  ```
137
144
 
145
+ ### Global Exception Handler
146
+
147
+ You can intercept exceptions at the edge of execution and transform them into standard JSON responses, preventing hard crashes:
148
+
149
+ ```ts
150
+ dispatcher.setExceptionHandler((error, request, response) => {
151
+ if (error.name === 'AuthorizationException') {
152
+ return response.status(403).json({ error: error.message });
153
+ }
154
+
155
+ // Unhandled error fallback
156
+ return response.status(500).json({ error: 'Server Error' });
157
+ });
158
+ ```
159
+
138
160
  ---
139
161
 
162
+ ## Controller Middleware
163
+
164
+ Middleware don't just have to live on the route. The Dispatcher automatically scans your class-based controllers for middleware and merges them into the pipeline.
165
+
166
+ ```ts
167
+ class PostController {
168
+ // Static middleware applied to all routes mapping to this controller
169
+ static middleware = ['auth', 'verified'];
170
+
171
+ index() { /* ... */ }
172
+ }
173
+ ```
174
+
140
175
  ## Middleware Pipeline
141
176
 
142
177
  The `MiddlewarePipeline` executes middleware in an "onion" pattern, where each layer can perform logic before and after the next layer.
@@ -172,20 +207,30 @@ Conversion Rules:
172
207
  - **Strings/Buffers**: Sent as the body via `response.send()`
173
208
  - **null/undefined**: Sets status 204 (No Content)
174
209
  - **Response**: Returned as-is
210
+ - **Views**: Anything with an async `render()` function calls the function and sends the result
211
+ - **Streams**: Returned values extending `stream.Stream` pipe properly if the response driver supports `.stream()`
175
212
 
176
213
  ---
177
214
 
178
- ## Project Structure (recommended)
179
-
180
- Inside the `arika-dispatcher` repository:
181
-
182
- - `src/`
183
- - `Dispatcher.ts` – Main coordinator
184
- - `ControllerResolver.ts` – DI-aware handler resolution
185
- - `MethodInvoker.ts` – Dynamic method execution
186
- - `ResponseResolver.ts` – Logic for normalizing return values
187
- - `MiddlewarePipeline.ts` – The execution stack for middleware
188
- - `index.ts` – Public exports
215
+ ## 🏗 Architecture
216
+
217
+ ```text
218
+ dispatcher/
219
+ ├── src/
220
+ │ ├── Contracts
221
+ │ │ ├── Container.ts
222
+ │ │ ├── Http.ts
223
+ │ │ └── Router.ts
224
+ │ ├── ControllerResolver.ts
225
+ │ ├── Dispatcher.ts
226
+ │ ├── index.ts
227
+ │ ├── MethodInvoker.ts
228
+ │ └── ResponseResolver.ts
229
+ ├── tests/
230
+ ├── package.json
231
+ ├── tsconfig.json
232
+ └── README.md
233
+ ```
189
234
 
190
235
  ---
191
236
 
@@ -3,8 +3,8 @@ export interface Request {
3
3
  }
4
4
  export interface Response {
5
5
  status(code: number): this;
6
- send(data: any): this;
7
- json(data: any): this;
6
+ send(data: any, status?: number): this;
7
+ json(data: any, status?: number): this;
8
8
  [key: string]: any;
9
9
  }
10
10
  //# sourceMappingURL=Http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../../src/Contracts/Http.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,OAAO;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB"}
1
+ {"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../../src/Contracts/Http.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,OAAO;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB"}
@@ -5,5 +5,6 @@ export interface MatchedRoute {
5
5
  [key: string]: any;
6
6
  };
7
7
  params: Record<string, string>;
8
+ hasParams: boolean;
8
9
  }
9
10
  //# sourceMappingURL=Router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Router.d.ts","sourceRoot":"","sources":["../../src/Contracts/Router.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE;QACH,OAAO,EAAE,GAAG,CAAC;QACb,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACtB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC"}
1
+ {"version":3,"file":"Router.d.ts","sourceRoot":"","sources":["../../src/Contracts/Router.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE;QACH,OAAO,EAAE,GAAG,CAAC;QACb,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACtB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,SAAS,EAAE,OAAO,CAAC;CACtB"}
@@ -8,11 +8,18 @@ export declare class Dispatcher {
8
8
  private middlewareGroups;
9
9
  private routeMiddleware;
10
10
  private parameterBinders;
11
+ private exceptionHandler?;
12
+ executionPlans: Map<any, any>;
11
13
  constructor(container?: any | undefined);
14
+ precompile(routes: any[]): void;
12
15
  /**
13
16
  * Set the container for resolving controllers.
14
17
  */
15
18
  setContainer(container: any): this;
19
+ /**
20
+ * Set a global exception handler to catch and format errors from route execution.
21
+ */
22
+ setExceptionHandler(handler: (error: any, request: Request, response: Response) => any): this;
16
23
  /**
17
24
  * Set the middleware groups mapping.
18
25
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Dispatcher.d.ts","sourceRoot":"","sources":["../src/Dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMlD,qBAAa,UAAU;IAQP,OAAO,CAAC,SAAS,CAAC;IAP9B,OAAO,CAAC,kBAAkB,CAAC,CAAqB;IAChD,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,gBAAgB,CAAwD;gBAE5D,SAAS,CAAC,EAAE,GAAG,YAAA;IAQnC;;OAEG;IACI,YAAY,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI;IAMzC;;OAEG;IACI,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI;IAK/D;;OAEG;IACI,kBAAkB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAKhE;;OAEG;IACI,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI;IAS7C;;OAEG;IACU,QAAQ,CACjB,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,GACnB,OAAO,CAAC,QAAQ,CAAC;IAyCpB;;OAEG;YACW,iBAAiB;CAYlC"}
1
+ {"version":3,"file":"Dispatcher.d.ts","sourceRoot":"","sources":["../src/Dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMlD,qBAAa,UAAU;IAUP,OAAO,CAAC,SAAS,CAAC;IAT9B,OAAO,CAAC,kBAAkB,CAAC,CAAqB;IAChD,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,gBAAgB,CAAwD;IAChF,OAAO,CAAC,gBAAgB,CAAC,CAA4D;IAC9E,cAAc,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAa;gBAE7B,SAAS,CAAC,EAAE,GAAG,YAAA;IAQ5B,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE;IAmD/B;;OAEG;IACI,YAAY,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI;IAOzC;;OAEG;IACI,mBAAmB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,GAAG,GAAG,IAAI;IAKpG;;OAEG;IACI,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI;IAK/D;;OAEG;IACI,kBAAkB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAKhE;;OAEG;IACI,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI;IAS7C;;OAEG;IACU,QAAQ,CACjB,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,GACnB,OAAO,CAAC,QAAQ,CAAC;IAyEpB;;OAEG;YACW,iBAAiB;CAYlC"}
@@ -11,18 +11,78 @@ class Dispatcher {
11
11
  this.middlewareGroups = {};
12
12
  this.routeMiddleware = {};
13
13
  this.parameterBinders = new Map();
14
- this.invoker = new MethodInvoker_1.MethodInvoker();
14
+ this.executionPlans = new Map();
15
+ this.invoker = new MethodInvoker_1.MethodInvoker(container);
15
16
  this.responseResolver = new ResponseResolver_1.ResponseResolver();
16
17
  if (container) {
17
18
  this.controllerResolver = new ControllerResolver_1.ControllerResolver(container);
18
19
  }
19
20
  }
21
+ precompile(routes) {
22
+ for (let i = 0; i < routes.length; i++) {
23
+ const route = routes[i];
24
+ const handler = route.handler;
25
+ let resolvedHandler;
26
+ let controllerMiddleware = [];
27
+ if (Array.isArray(handler)) {
28
+ if (this.controllerResolver) {
29
+ try {
30
+ const resolved = this.controllerResolver.resolve(handler);
31
+ resolvedHandler = resolved;
32
+ if (typeof resolved.controller.getMiddleware === 'function') {
33
+ controllerMiddleware = resolved.controller.getMiddleware() || [];
34
+ }
35
+ else if (resolved.controller.constructor && resolved.controller.constructor.middleware) {
36
+ controllerMiddleware = resolved.controller.constructor.middleware;
37
+ }
38
+ }
39
+ catch (e) {
40
+ // Skip if cannot resolve at boot (e.g. missing container)
41
+ continue;
42
+ }
43
+ }
44
+ else {
45
+ continue;
46
+ }
47
+ }
48
+ else {
49
+ resolvedHandler = handler;
50
+ }
51
+ const hasMiddleware = (route.middleware && route.middleware.length > 0) || (controllerMiddleware && controllerMiddleware.length > 0);
52
+ this.executionPlans.set(route, {
53
+ route,
54
+ hasMiddleware,
55
+ controllerMiddleware,
56
+ resolvedHandler,
57
+ handler: (req, res, params) => this.invoker.invoke(resolvedHandler, req, res, params),
58
+ middleware: hasMiddleware ? [...(route.middleware || []), ...(controllerMiddleware || [])] : []
59
+ });
60
+ // Pre-serialize simple responses if possible (only if handler takes no arguments)
61
+ if (!hasMiddleware && typeof resolvedHandler === 'function' && resolvedHandler.length === 0) {
62
+ try {
63
+ const result = resolvedHandler();
64
+ if (result && typeof result === 'object' && !(result instanceof Promise)) {
65
+ this.responseResolver.bufferCache.set(route, Buffer.from(JSON.stringify(result)));
66
+ }
67
+ }
68
+ catch (e) { }
69
+ }
70
+ }
71
+ }
20
72
  /**
21
73
  * Set the container for resolving controllers.
22
74
  */
23
75
  setContainer(container) {
24
76
  this.container = container;
25
77
  this.controllerResolver = new ControllerResolver_1.ControllerResolver(container);
78
+ this.invoker.setContainer(container);
79
+ return this;
80
+ }
81
+ /**
82
+ * Set a global exception handler to catch and format errors from route execution.
83
+ */
84
+ setExceptionHandler(handler) {
85
+ this.exceptionHandler = handler;
26
86
  return this;
27
87
  }
28
88
  /**
@@ -57,37 +117,72 @@ class Dispatcher {
57
117
  async dispatch(matchedRoute, request, response) {
58
118
  const { route, params } = matchedRoute;
59
119
  const handler = route.handler;
60
- // 0. Resolve Route Parameters (Model Binding)
61
- const resolvedParams = await this.resolveParameters(params);
120
+ // Set parameters on the request object
121
+ if (typeof request.setParams === 'function') {
122
+ request.setParams(params);
123
+ }
124
+ // 0. Resolve Route Parameters (Model Binding) - only if we have binders
125
+ const resolvedParams = this.parameterBinders.size > 0 ? await this.resolveParameters(params) : params;
62
126
  // 1. Resolve Handler
63
127
  let resolvedHandler;
64
- if (Array.isArray(handler)) {
65
- if (!this.controllerResolver) {
66
- throw new Error('Container required for controller resolution.');
67
- }
68
- resolvedHandler = this.controllerResolver.resolve(handler);
69
- }
70
- else if (typeof handler === 'function') {
71
- resolvedHandler = handler;
128
+ let controllerMiddleware = [];
129
+ const plan = this.executionPlans.get(route);
130
+ if (plan) {
131
+ resolvedHandler = plan.resolvedHandler;
132
+ controllerMiddleware = plan.controllerMiddleware;
72
133
  }
73
134
  else {
74
- throw new Error('Invalid route handler.');
135
+ if (Array.isArray(handler)) {
136
+ if (!this.controllerResolver) {
137
+ throw new Error('Container required for controller resolution.');
138
+ }
139
+ const resolved = this.controllerResolver.resolve(handler);
140
+ resolvedHandler = resolved;
141
+ // Extract controller-level middleware
142
+ if (typeof resolved.controller.getMiddleware === 'function') {
143
+ controllerMiddleware = resolved.controller.getMiddleware() || [];
144
+ }
145
+ else if (resolved.controller.constructor && resolved.controller.constructor.middleware) {
146
+ controllerMiddleware = resolved.controller.constructor.middleware;
147
+ }
148
+ }
149
+ else if (typeof handler === 'function') {
150
+ resolvedHandler = handler;
151
+ }
152
+ else {
153
+ throw new Error('Invalid route handler.');
154
+ }
75
155
  }
76
156
  // 2. Prepare Middleware Pipeline
77
157
  const pipeline = new middleware_1.Pipeline(this.container);
158
+ if (plan && plan.hasMiddleware) {
159
+ pipeline.pipe(plan.middleware);
160
+ }
161
+ else if (!plan) {
162
+ // Fallback for non-plan routes
163
+ if (route.middleware)
164
+ pipeline.pipe(route.middleware);
165
+ if (controllerMiddleware)
166
+ pipeline.pipe(controllerMiddleware);
167
+ }
78
168
  pipeline.setMiddlewareGroups(this.middlewareGroups);
79
169
  pipeline.setAliases(this.routeMiddleware);
80
- // Add route-level middleware
81
- if (route.middleware && route.middleware.length > 0) {
82
- pipeline.pipe(route.middleware);
83
- }
84
170
  // 3. Execute Pipeline
85
- return await pipeline.handle(request, async (req) => {
86
- // 4. Invoke Handler
87
- const result = await this.invoker.invoke(resolvedHandler, req, resolvedParams);
88
- // 5. Normalize Response
89
- return this.responseResolver.resolve(result, response);
90
- }, response);
171
+ try {
172
+ return await pipeline.handle(request, async (req) => {
173
+ // 4. Invoke Handler
174
+ const result = await this.invoker.invoke(resolvedHandler, req, response, resolvedParams);
175
+ // 5. Normalize Response
176
+ return await this.responseResolver.resolve(result, response);
177
+ }, response);
178
+ }
179
+ catch (error) {
180
+ if (this.exceptionHandler) {
181
+ const handledResult = await this.exceptionHandler(error, request, response);
182
+ return await this.responseResolver.resolve(handledResult, response);
183
+ }
184
+ throw error;
185
+ }
91
186
  }
92
187
  /**
93
188
  * Resolve route parameters using registered binders.
@@ -1 +1 @@
1
- {"version":3,"file":"Dispatcher.js","sourceRoot":"","sources":["../src/Dispatcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Dispatcher.js","sourceRoot":"","sources":["../src/Dispatcher.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,14 @@
1
- import { Request } from './Contracts/Http';
1
+ import { Request, Response } from './Contracts/Http';
2
2
  export declare class MethodInvoker {
3
+ private container?;
4
+ constructor(container?: any | undefined);
5
+ setContainer(container: any): this;
3
6
  /**
4
7
  * Invoke the handler (closure or controller method) with injected parameters.
5
8
  */
6
9
  invoke(handler: Function | {
7
10
  controller: any;
8
11
  method: string;
9
- }, request: Request, params: Record<string, any>): Promise<any>;
12
+ }, request: Request, response: Response, params: Record<string, any>): Promise<any>;
10
13
  }
11
14
  //# sourceMappingURL=MethodInvoker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MethodInvoker.d.ts","sourceRoot":"","sources":["../src/MethodInvoker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,qBAAa,aAAa;IACtB;;OAEG;IACU,MAAM,CACf,OAAO,EAAE,QAAQ,GAAG;QAAE,UAAU,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EACvD,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,OAAO,CAAC,GAAG,CAAC;CAQlB"}
1
+ {"version":3,"file":"MethodInvoker.d.ts","sourceRoot":"","sources":["../src/MethodInvoker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAErD,qBAAa,aAAa;IACV,OAAO,CAAC,SAAS,CAAC;gBAAV,SAAS,CAAC,EAAE,GAAG,YAAA;IAE5B,YAAY,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI;IAKzC;;OAEG;IACU,MAAM,CACf,OAAO,EAAE,QAAQ,GAAG;QAAE,UAAU,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EACvD,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,OAAO,CAAC,GAAG,CAAC;CAmBlB"}
@@ -2,15 +2,31 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MethodInvoker = void 0;
4
4
  class MethodInvoker {
5
+ constructor(container) {
6
+ this.container = container;
7
+ }
8
+ setContainer(container) {
9
+ this.container = container;
10
+ return this;
11
+ }
5
12
  /**
6
13
  * Invoke the handler (closure or controller method) with injected parameters.
7
14
  */
8
- async invoke(handler, request, params) {
15
+ async invoke(handler, request, response, params) {
9
16
  if (typeof handler === 'function') {
10
- return await handler(request, ...Object.values(params));
17
+ // If container has a call method (e.g., Arika Foundation container), delegate to it
18
+ // This enables advanced method DI using reflect-metadata
19
+ if (this.container && typeof this.container.call === 'function') {
20
+ return await this.container.call(handler, { request, response, ...params });
21
+ }
22
+ return await handler(request, response, ...Object.values(params));
11
23
  }
12
24
  const { controller, method } = handler;
13
- return await controller[method](request, ...Object.values(params));
25
+ // Container-based advanced method DI
26
+ if (this.container && typeof this.container.call === 'function') {
27
+ return await this.container.call([controller, method], { request, response, ...params });
28
+ }
29
+ return await controller[method](request, response, ...Object.values(params));
14
30
  }
15
31
  }
16
32
  exports.MethodInvoker = MethodInvoker;
@@ -1 +1 @@
1
- {"version":3,"file":"MethodInvoker.js","sourceRoot":"","sources":["../src/MethodInvoker.ts"],"names":[],"mappings":";;;AAEA,MAAa,aAAa;IACtB;;OAEG;IACI,KAAK,CAAC,MAAM,CACf,OAAuD,EACvD,OAAgB,EAChB,MAA2B;QAE3B,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAChC,OAAO,MAAM,OAAO,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QACvC,OAAO,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACvE,CAAC;CACJ;AAhBD,sCAgBC"}
1
+ {"version":3,"file":"MethodInvoker.js","sourceRoot":"","sources":["../src/MethodInvoker.ts"],"names":[],"mappings":";;;AAEA,MAAa,aAAa;IACtB,YAAoB,SAAe;QAAf,cAAS,GAAT,SAAS,CAAM;IAAI,CAAC;IAEjC,YAAY,CAAC,SAAc;QAC9B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,MAAM,CACf,OAAuD,EACvD,OAAgB,EAChB,QAAkB,EAClB,MAA2B;QAE3B,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAChC,oFAAoF;YACpF,yDAAyD;YACzD,IAAI,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC9D,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;YAChF,CAAC;YACD,OAAO,MAAM,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAEvC,qCAAqC;QACrC,IAAI,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC9D,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC7F,CAAC;QAED,OAAO,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACjF,CAAC;CACJ;AAnCD,sCAmCC"}
@@ -1,8 +1,9 @@
1
1
  import { Response } from './Contracts/Http';
2
2
  export declare class ResponseResolver {
3
+ bufferCache: Map<any, Buffer>;
3
4
  /**
4
5
  * Resolve and normalize the handler return value into a Response object.
5
6
  */
6
- resolve(value: any, response: Response): Response;
7
+ resolve(value: any, response: Response, route?: any): Response | Promise<Response>;
7
8
  }
8
9
  //# sourceMappingURL=ResponseResolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ResponseResolver.d.ts","sourceRoot":"","sources":["../src/ResponseResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,qBAAa,gBAAgB;IACzB;;OAEG;IACI,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ;CAuB3D"}
1
+ {"version":3,"file":"ResponseResolver.d.ts","sourceRoot":"","sources":["../src/ResponseResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,qBAAa,gBAAgB;IAClB,WAAW,EAAE,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAa;IAEjD;;OAEG;IACI,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;CA4C5F"}
@@ -1,13 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ResponseResolver = void 0;
4
+ const stream_1 = require("stream");
4
5
  class ResponseResolver {
6
+ constructor() {
7
+ this.bufferCache = new Map();
8
+ }
5
9
  /**
6
10
  * Resolve and normalize the handler return value into a Response object.
7
11
  */
8
- resolve(value, response) {
12
+ resolve(value, response, route) {
13
+ if (route && this.bufferCache.has(route)) {
14
+ return response.send(this.bufferCache.get(route));
15
+ }
16
+ // Handle null or undefined (empty response)
17
+ if (value === null || value === undefined) {
18
+ return response.status(204).send('');
19
+ }
20
+ // Output of a View or object with a render() method
21
+ if (value && typeof value.render === 'function') {
22
+ const rendered = value.render();
23
+ if (rendered instanceof Promise) {
24
+ return rendered.then(r => response.send(r));
25
+ }
26
+ return response.send(rendered);
27
+ }
28
+ // If it's a native stream, map to the response's stream handler if supported
29
+ if (value instanceof stream_1.Stream) {
30
+ if (typeof response.stream === 'function') {
31
+ return response.stream(value);
32
+ }
33
+ // fallback, assuming some other mechanism handles it
34
+ return value;
35
+ }
9
36
  // If it's already a Response object (basic duck typing check for framework response)
10
- if (value && typeof value.send === 'function' && typeof value.status === 'function') {
37
+ if (typeof value.send === 'function' && typeof value.status === 'function') {
11
38
  return value;
12
39
  }
13
40
  if (typeof value === 'object' && value !== null) {
@@ -17,10 +44,6 @@ class ResponseResolver {
17
44
  if (typeof value === 'string' || Buffer.isBuffer(value)) {
18
45
  return response.send(value);
19
46
  }
20
- // Handle null or undefined (empty response)
21
- if (value === null || value === undefined) {
22
- return response.status(204).send('');
23
- }
24
47
  // Default to string conversion
25
48
  return response.send(String(value));
26
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ResponseResolver.js","sourceRoot":"","sources":["../src/ResponseResolver.ts"],"names":[],"mappings":";;;AAEA,MAAa,gBAAgB;IACzB;;OAEG;IACI,OAAO,CAAC,KAAU,EAAE,QAAkB;QACzC,qFAAqF;QACrF,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAClF,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC9C,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,6CAA6C;QAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACtD,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,4CAA4C;QAC5C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,+BAA+B;QAC/B,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC;CACJ;AA3BD,4CA2BC"}
1
+ {"version":3,"file":"ResponseResolver.js","sourceRoot":"","sources":["../src/ResponseResolver.ts"],"names":[],"mappings":";;;AACA,mCAAgC;AAEhC,MAAa,gBAAgB;IAA7B;QACW,gBAAW,GAAqB,IAAI,GAAG,EAAE,CAAC;IAiDrD,CAAC;IA/CG;;OAEG;IACI,OAAO,CAAC,KAAU,EAAE,QAAkB,EAAE,KAAW;QACtD,IAAI,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,CAAC;QACvD,CAAC;QACD,4CAA4C;QAC5C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,oDAAoD;QACpD,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,QAAQ,YAAY,OAAO,EAAE,CAAC;gBAC9B,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAChD,CAAC;YACD,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;QAED,6EAA6E;QAC7E,IAAI,KAAK,YAAY,eAAM,EAAE,CAAC;YAC1B,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBACxC,OAAO,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;YACD,qDAAqD;YACrD,OAAO,KAAY,CAAC;QACxB,CAAC;QAED,qFAAqF;QACrF,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACzE,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC9C,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,6CAA6C;QAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACtD,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,+BAA+B;QAC/B,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC;CACJ;AAlDD,4CAkDC"}
package/package.json CHANGED
@@ -1,45 +1,47 @@
1
1
  {
2
- "name": "@arikajs/dispatcher",
3
- "version": "0.0.3",
4
- "description": "Request dispatching and handler execution layer of the ArikaJS framework.",
5
- "license": "MIT",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "scripts": {
9
- "build": "tsc -p tsconfig.json",
10
- "clean": "rm -rf dist",
11
- "prepare": "echo skip",
12
- "test": "npx tsx tests/Dispatcher.test.ts",
13
- "test:watch": "npx tsx --watch tests/Dispatcher.test.ts"
14
- },
15
- "files": [
16
- "dist"
17
- ],
18
- "keywords": [
19
- "arika",
20
- "arika-js",
21
- "framework",
22
- "dispatcher",
23
- "controller",
24
- "middleware"
25
- ],
26
- "engines": {
27
- "node": ">=20.0.0"
28
- },
29
- "repository": {
30
- "type": "git",
31
- "url": "git+https://github.com/arikajs/dispatcher.git"
32
- },
33
- "bugs": {
34
- "url": "https://github.com/arikajs/dispatcher/issues"
35
- },
36
- "homepage": "https://github.com/arikajs/dispatcher#readme",
37
- "dependencies": {
38
- "@arikajs/middleware": "file:../middleware"
39
- },
40
- "devDependencies": {
41
- "@types/node": "^20.11.24",
42
- "typescript": "^5.3.3"
43
- },
44
- "author": "Prakash Tank"
2
+ "name": "@arikajs/dispatcher",
3
+ "version": "0.0.5",
4
+ "description": "Request dispatching and handler execution layer of the ArikaJS framework.",
5
+ "license": "MIT",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc -p tsconfig.json",
10
+ "clean": "rm -rf dist",
11
+ "prepare": "echo skip",
12
+ "test": "npx tsx tests/Dispatcher.test.ts",
13
+ "test:watch": "npx tsx --watch tests/Dispatcher.test.ts",
14
+ "dev": "tsc -p tsconfig.json --watch"
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "keywords": [
20
+ "arika",
21
+ "arika-js",
22
+ "framework",
23
+ "dispatcher",
24
+ "controller",
25
+ "middleware"
26
+ ],
27
+ "engines": {
28
+ "node": ">=20.0.0"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/ArikaJs/arikajs.git",
33
+ "directory": "packages/dispatcher"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/ArikaJs/arikajs/issues"
37
+ },
38
+ "homepage": "https://github.com/ArikaJs/arikajs/tree/main/packages/dispatcher#readme",
39
+ "dependencies": {
40
+ "@arikajs/middleware": "*"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^20.11.24",
44
+ "typescript": "^5.3.3"
45
+ },
46
+ "author": "Prakash Tank"
45
47
  }