@asenajs/asena 0.3.2 → 0.4.0

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.
Files changed (126) hide show
  1. package/README.md +165 -140
  2. package/dist/index.d.ts +2 -1
  3. package/dist/index.js +2 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/adapter/AsenaAdapter.d.ts +19 -3
  6. package/dist/lib/adapter/AsenaAdapter.js.map +1 -1
  7. package/dist/lib/adapter/AsenaWebsocketAdapter.d.ts +2 -2
  8. package/dist/lib/adapter/AsenaWebsocketAdapter.js.map +1 -1
  9. package/dist/lib/adapter/types/RouteParams.d.ts +3 -0
  10. package/dist/lib/adapter/types/ServeOptions.d.ts +2 -2
  11. package/dist/lib/adapter/types/index.d.ts +4 -4
  12. package/dist/lib/adapter/types/index.js +4 -4
  13. package/dist/lib/adapter/types/index.js.map +1 -1
  14. package/dist/lib/ioc/CircularDependencyDetector.d.ts +49 -0
  15. package/dist/lib/ioc/CircularDependencyDetector.js +69 -0
  16. package/dist/lib/ioc/CircularDependencyDetector.js.map +1 -0
  17. package/dist/lib/ioc/Container.d.ts +9 -0
  18. package/dist/lib/ioc/Container.js +42 -11
  19. package/dist/lib/ioc/Container.js.map +1 -1
  20. package/dist/lib/ioc/CoreContainer.d.ts +78 -0
  21. package/dist/lib/ioc/CoreContainer.js +135 -0
  22. package/dist/lib/ioc/CoreContainer.js.map +1 -0
  23. package/dist/lib/ioc/IocEngine.d.ts +16 -6
  24. package/dist/lib/ioc/IocEngine.js +35 -7
  25. package/dist/lib/ioc/IocEngine.js.map +1 -1
  26. package/dist/lib/ioc/component/index.d.ts +1 -1
  27. package/dist/lib/ioc/component/index.js +1 -1
  28. package/dist/lib/ioc/component/index.js.map +1 -1
  29. package/dist/lib/ioc/constants/ComponentConstants.d.ts +27 -18
  30. package/dist/lib/ioc/constants/ComponentConstants.js +34 -20
  31. package/dist/lib/ioc/constants/ComponentConstants.js.map +1 -1
  32. package/dist/lib/ioc/decorators/CoreService.d.ts +8 -0
  33. package/dist/lib/ioc/decorators/CoreService.js +27 -0
  34. package/dist/lib/ioc/decorators/CoreService.js.map +1 -0
  35. package/dist/lib/ioc/decorators/index.d.ts +1 -0
  36. package/dist/lib/ioc/decorators/index.js +2 -0
  37. package/dist/lib/ioc/decorators/index.js.map +1 -0
  38. package/dist/lib/ioc/index.d.ts +5 -0
  39. package/dist/lib/ioc/index.js +5 -0
  40. package/dist/lib/ioc/index.js.map +1 -1
  41. package/dist/lib/ioc/types/CoreBootstrapPhase.d.ts +15 -0
  42. package/dist/lib/ioc/types/CoreBootstrapPhase.js +17 -0
  43. package/dist/lib/ioc/types/CoreBootstrapPhase.js.map +1 -0
  44. package/dist/lib/ioc/types/ICoreService.d.ts +9 -0
  45. package/dist/lib/ioc/types/ICoreService.js +2 -0
  46. package/dist/lib/ioc/types/ICoreService.js.map +1 -0
  47. package/dist/lib/ioc/types/ICoreServiceNamesType.d.ts +18 -0
  48. package/dist/lib/ioc/types/ICoreServiceNamesType.js +23 -0
  49. package/dist/lib/ioc/types/ICoreServiceNamesType.js.map +1 -0
  50. package/dist/lib/ioc/types/decorators/ControllerParams.d.ts +1 -1
  51. package/dist/lib/ioc/types/index.d.ts +3 -0
  52. package/dist/lib/ioc/types/index.js +3 -0
  53. package/dist/lib/ioc/types/index.js.map +1 -1
  54. package/dist/lib/server/AsenaServer.d.ts +85 -14
  55. package/dist/lib/server/AsenaServer.js +169 -61
  56. package/dist/lib/server/AsenaServer.js.map +1 -1
  57. package/dist/lib/server/AsenaServerFactory.d.ts +26 -0
  58. package/dist/lib/server/AsenaServerFactory.js +58 -0
  59. package/dist/lib/server/AsenaServerFactory.js.map +1 -0
  60. package/dist/lib/server/config/AsenaConfig.d.ts +91 -18
  61. package/dist/lib/server/decorators/Override.js +1 -1
  62. package/dist/lib/server/decorators/Override.js.map +1 -1
  63. package/dist/lib/server/decorators/components/Config.d.ts +1 -1
  64. package/dist/lib/server/decorators/components/Config.js +1 -1
  65. package/dist/lib/server/decorators/components/Config.js.map +1 -1
  66. package/dist/lib/server/decorators/components/Controller.d.ts +1 -1
  67. package/dist/lib/server/decorators/components/Controller.js +2 -2
  68. package/dist/lib/server/decorators/components/Controller.js.map +1 -1
  69. package/dist/lib/server/decorators/components/Middleware.js +2 -2
  70. package/dist/lib/server/decorators/components/Middleware.js.map +1 -1
  71. package/dist/lib/server/decorators/components/Schedule.d.ts +1 -1
  72. package/dist/lib/server/decorators/components/Schedule.js +2 -2
  73. package/dist/lib/server/decorators/components/Schedule.js.map +1 -1
  74. package/dist/lib/server/decorators/components/WebSocket.d.ts +1 -1
  75. package/dist/lib/server/decorators/components/WebSocket.js +2 -2
  76. package/dist/lib/server/decorators/components/WebSocket.js.map +1 -1
  77. package/dist/lib/server/decorators/index.d.ts +2 -0
  78. package/dist/lib/server/decorators/index.js +2 -0
  79. package/dist/lib/server/decorators/index.js.map +1 -1
  80. package/dist/lib/server/index.d.ts +2 -0
  81. package/dist/lib/server/index.js +2 -0
  82. package/dist/lib/server/index.js.map +1 -1
  83. package/dist/lib/server/src/services/PrepareConfigService.d.ts +9 -5
  84. package/dist/lib/server/src/services/PrepareConfigService.js +32 -7
  85. package/dist/lib/server/src/services/PrepareConfigService.js.map +1 -1
  86. package/dist/lib/server/src/services/PrepareMiddlewareService.d.ts +8 -5
  87. package/dist/lib/server/src/services/PrepareMiddlewareService.js +28 -7
  88. package/dist/lib/server/src/services/PrepareMiddlewareService.js.map +1 -1
  89. package/dist/lib/server/src/services/PrepareStaticServeConfigService.d.ts +8 -5
  90. package/dist/lib/server/src/services/PrepareStaticServeConfigService.js +27 -6
  91. package/dist/lib/server/src/services/PrepareStaticServeConfigService.js.map +1 -1
  92. package/dist/lib/server/src/services/PrepareValidatorService.d.ts +8 -5
  93. package/dist/lib/server/src/services/PrepareValidatorService.js +27 -6
  94. package/dist/lib/server/src/services/PrepareValidatorService.js.map +1 -1
  95. package/dist/lib/server/src/services/PrepareWebsocketService.d.ts +8 -5
  96. package/dist/lib/server/src/services/PrepareWebsocketService.js +28 -9
  97. package/dist/lib/server/src/services/PrepareWebsocketService.js.map +1 -1
  98. package/dist/lib/server/web/decorators/http.base.d.ts +1 -1
  99. package/dist/lib/server/web/decorators/http.base.js.map +1 -1
  100. package/dist/lib/server/web/decorators/methods/Connect.d.ts +1 -1
  101. package/dist/lib/server/web/decorators/methods/Delete.d.ts +1 -1
  102. package/dist/lib/server/web/decorators/methods/Get.d.ts +1 -1
  103. package/dist/lib/server/web/decorators/methods/Head.d.ts +1 -1
  104. package/dist/lib/server/web/decorators/methods/Options.d.ts +1 -1
  105. package/dist/lib/server/web/decorators/methods/Patch.d.ts +1 -1
  106. package/dist/lib/server/web/decorators/methods/Post.d.ts +1 -1
  107. package/dist/lib/server/web/decorators/methods/Put.d.ts +1 -1
  108. package/dist/lib/server/web/decorators/methods/Trace.d.ts +1 -1
  109. package/dist/lib/server/web/websocket/AsenaSocket.js +12 -8
  110. package/dist/lib/server/web/websocket/AsenaSocket.js.map +1 -1
  111. package/dist/lib/server/web/websocket/AsenaWebSocketServer.d.ts +1 -1
  112. package/dist/lib/server/web/websocket/AsenaWebSocketServer.js.map +1 -1
  113. package/dist/lib/server/web/websocket/AsenaWebSocketService.js +1 -1
  114. package/dist/lib/server/web/websocket/AsenaWebSocketService.js.map +1 -1
  115. package/dist/lib/server/web/websocket/index.d.ts +1 -1
  116. package/dist/lib/server/web/websocket/index.js +1 -1
  117. package/dist/lib/server/web/websocket/index.js.map +1 -1
  118. package/dist/lib/utils/patternMatcher.d.ts +41 -0
  119. package/dist/lib/utils/patternMatcher.js +99 -0
  120. package/dist/lib/utils/patternMatcher.js.map +1 -0
  121. package/dist/lib/utils/typedMetadata.d.ts +3 -3
  122. package/dist/lib/utils/typedMetadata.js.map +1 -1
  123. package/package.json +12 -7
  124. package/dist/lib/server/src/PrepareService.d.ts +0 -8
  125. package/dist/lib/server/src/PrepareService.js +0 -9
  126. package/dist/lib/server/src/PrepareService.js.map +0 -1
package/README.md CHANGED
@@ -1,226 +1,251 @@
1
1
  # Asena
2
2
 
3
- Asena is a NestJS-like IoC web framework built on top of Bun. It combines the power of dependency injection
4
- with the performance of Bun runtime and the flexibility of Adapter design system.
3
+ A high-performance, NestJS-like IoC web framework built on Bun runtime with full dependency injection support.
5
4
 
6
5
  ## Documentation
7
6
 
8
- For detailed documentation, please visit [not ready yet](https://asena.sh). Documentation is still in progress, but updates are being made regularly. You can check this project [AsenaExample](https://github.com/LibirSoft/AsenaExample). I am always updating it to latest usages.
7
+ For detailed documentation, visit [asena.sh](https://asena.sh).
8
+
9
+ Also check out [AsenaExample](https://github.com/LibirSoft/AsenaExample) for latest usage patterns.
9
10
 
10
11
  ## Key Features
11
12
 
12
- - **Dependency Injection**: Built-in IoC container for managing dependencies
13
- - **Decorator-based Development**: Similar to NestJS, using TypeScript decorators for routing and DI
14
- - **High Performance**: Leverages Bun runtime for optimal performance
15
- - **WebSocket Support**: Built-in WebSocket handling capabilities
16
- - **Middleware System**: Flexible middleware architecture
17
- - **HTTP Adapters**: Extensible adapter system with Hono as default
18
- - **Zero Dependencies**: Only uses reflect-metadata for dependency injection
19
- - **TypeScript Support**: Full TypeScript support with strict mode
20
- - **Modular Architecture**: Easy to extend and customize
13
+ - **Full IoC Container**: Field-based dependency injection for all components
14
+ - **Decorator-based**: TypeScript decorators for routing and DI (similar to NestJS)
15
+ - **High Performance**: Built on Bun runtime for optimal speed
16
+ - **WebSocket Support**: Native WebSocket handling
17
+ - **Flexible Middleware**: Multi-level middleware system (global, controller, route)
18
+ - **Adapter System**: Pluggable HTTP adapters (Hono default)
19
+ - **Type-Safe**: Full TypeScript support with strict mode
20
+ - **Zero Config**: Minimal setup required
21
21
 
22
22
  ## Quick Start
23
23
 
24
- The easiest way to create a new Asena project is using the CLI:
24
+ ### Using CLI (Recommended)
25
25
 
26
26
  ```bash
27
- # Create a new project
28
27
  bun add -D @asenajs/asena-cli
29
- asena create
30
- ```
31
-
32
- This will create a new project with the following structure:
33
-
34
- ```
35
- ├── src/
36
- │ ├── controllers/
37
- │ │ └── AsenaController.ts
38
- │ └── index.ts
39
- ├── package.json
40
- ├── tsconfig.json
41
- ├── .eslintrc.js
42
- ├── .eslintignore
43
- └── .prettierrc.js
28
+ asena create my-project
29
+ cd my-project
30
+ asena dev start
44
31
  ```
45
- ## Alternative start
46
-
47
32
 
48
- Alternatively, you can create a project manually:
33
+ ### Manual Setup
49
34
 
50
- First, create a new project using Bun:
35
+ Install dependencies:
51
36
 
52
37
  ```bash
53
- bun init
38
+ bun add @asenajs/asena @asenajs/hono-adapter @asenajs/asena-logger
39
+ bun add -D @asenajs/asena-cli
54
40
  ```
55
41
 
56
- For decorators working properly, you need to add some settings to your tsconfig. Here is a recommended file:
42
+ Configure TypeScript (`tsconfig.json`):
57
43
 
58
44
  ```json
59
45
  {
60
46
  "compilerOptions": {
61
- // Enable latest features
62
- "lib": ["ESNext", "DOM"],
63
47
  "target": "ESNext",
64
48
  "module": "ESNext",
65
- "moduleDetection": "force",
66
- "jsx": "react-jsx",
67
- "allowJs": true,
49
+ "moduleResolution": "bundler",
68
50
  "experimentalDecorators": true,
69
51
  "emitDecoratorMetadata": true,
70
-
71
- // Bundler mode
72
- "moduleResolution": "bundler",
73
- "allowImportingTsExtensions": true,
74
- "verbatimModuleSyntax": true,
75
- "noEmit": true,
76
-
77
- // Best practices
78
52
  "strict": true,
79
- "skipLibCheck": true,
80
- "noFallthroughCasesInSwitch": true,
81
-
82
- // Some stricter flags
83
- "noUnusedLocals": true,
84
- "noUnusedParameters": true,
85
- "noPropertyAccessFromIndexSignature": true
53
+ "skipLibCheck": true
86
54
  }
87
55
  }
88
56
  ```
89
- After that you need to make sure to edit your tsConfig.json it should look like this
90
- Then, install these packages:
91
- * `@asenajs/asena`: Base package
92
- * `@asenajs/hono-adapter`: For web-server. Asena currently only support hono adapter.
93
- * `@asenajs/asena-logger`: For better logs
94
- * **OPTIONAL** `@asenajs/asena-drizzle`: For better drizzle integration (completely **optional**) you can check package from here [asena-drizzle](https://github.com/AsenaJs/asena-drizzle)
95
- ```bash
96
- bun install @asenajs/asena @asenajs/hono-adapter @asenajs/asena-logger
97
- ```
98
57
 
99
- * `@asenajs/asena-cli`: This package provides a CLI for creating and managing Asena projects.
100
-
101
- ```bash
102
- bun install -D @asenajs/asena-cli
103
- ```
104
- After installation, you need to create asena-config.ts file you can create it with asena-cli
58
+ Initialize config:
105
59
 
106
60
  ```bash
107
61
  asena init
108
62
  ```
109
- this will create you asena-config file.
110
-
111
- `Note`: Built options directly copy of bun options, you can check bun documentation for more
112
- options. [Bun Documentation](https://bun.sh/docs/bundler#reference)
113
63
 
114
- Create index.ts file under your src folder:
64
+ Create your server (`src/index.ts`):
115
65
 
116
66
  ```typescript
117
- // src/index.ts
118
- import {AsenaServer} from '@asenajs/asena';
119
- import {createHonoAdapter} from '@asenajs/hono-adapter';
120
- import {logger} from './logger/logger';
67
+ import { AsenaServerFactory } from '@asenajs/asena';
68
+ import { createHonoAdapter } from '@asenajs/hono-adapter';
69
+ import { logger } from './logger';
121
70
 
122
- const [honoAdapter,asenaLogger] = createHonoAdapter(logger);
71
+ const [adapter, asenaLogger] = createHonoAdapter(logger);
123
72
 
73
+ const server = await AsenaServerFactory.create({
74
+ adapter,
75
+ logger: asenaLogger,
76
+ port: 3000
77
+ });
124
78
 
125
- await new AsenaServer(honoAdapter, asenaLogger).port(3000).start();
79
+ await server.start();
126
80
  ```
127
81
 
128
- To run asena you need at least one controller. Create a new controller:
82
+ Create a controller (`src/controllers/HelloController.ts`):
129
83
 
130
84
  ```typescript
131
- // src/controllers/TestController.ts
132
- import type { Context } from '@asenajs/hono-adapter';
133
85
  import { Controller } from '@asenajs/asena/server';
134
86
  import { Get } from '@asenajs/asena/web';
87
+ import type { Context } from '@asenajs/hono-adapter';
135
88
 
136
89
  @Controller('/hello')
137
- export class TestController {
90
+ export class HelloController {
138
91
  @Get('/world')
139
- public async getHello(context: Context) {
92
+ async getHello(context: Context) {
140
93
  return context.send('Hello World');
141
94
  }
142
95
  }
143
96
  ```
144
97
 
145
- Finally, run the project:
98
+ ## Core Concepts
146
99
 
147
- ```bash
148
- ## only for fast developing purposes
149
- asena dev start
150
- ```
100
+ ### Controllers
151
101
 
152
- ```bash
153
- ## or you can simply build then run your bundled project
154
- asena build
155
- ## then go to dist folder and run the project this way it will consume less memory and it will be faster.
156
- bun index.asena.js
102
+ Handle HTTP requests with decorators:
103
+
104
+ ```typescript
105
+ @Controller('/users')
106
+ export class UserController {
107
+ @Get('/:id')
108
+ async getUser(context: Context) {
109
+ const id = context.req.param('id');
110
+ return context.json({ id, name: 'John' });
111
+ }
112
+
113
+ @Post('/')
114
+ async createUser(context: Context) {
115
+ const body = await context.req.json();
116
+ return context.json({ success: true });
117
+ }
118
+ }
157
119
  ```
158
120
 
159
- ## CLI Commands
121
+ ### Services
122
+
123
+ Business logic with dependency injection:
160
124
 
161
- For more information about CLI commands and usage, please visit:
162
- [Asena CLI Documentation](https://asena.sh/docs/cli/overview.html)
125
+ ```typescript
126
+ @Service()
127
+ export class UserService {
128
+ async findUser(id: string) {
129
+ // Your business logic
130
+ return { id, name: 'John' };
131
+ }
132
+ }
163
133
 
164
- ## Project Structure
134
+ @Controller('/users')
135
+ export class UserController {
136
+ @Inject(UserService)
137
+ private userService: UserService;
165
138
 
139
+ @Get('/:id')
140
+ async getUser(context: Context) {
141
+ const user = await this.userService.findUser(context.req.param('id'));
142
+ return context.json(user);
143
+ }
144
+ }
166
145
  ```
167
- lib/
168
- ├── adapter/ # HTTP adapter implementations
169
- ├── server/ # Core server functionality
170
- ├── ioc/ # Dependency injection container
171
- ├── utils/ # Utility functions
172
- ├── test/ # Test utilities
146
+
147
+ ### Middleware
148
+
149
+ Multi-level middleware support:
150
+
151
+ ```typescript
152
+ @Middleware()
153
+ export class AuthMiddleware extends MiddlewareService {
154
+ async handle(context: Context, next: Function) {
155
+ // Check authentication
156
+ await next();
157
+ }
158
+ }
159
+
160
+ // Global middleware via Config
161
+ @Config()
162
+ export class AppConfig {
163
+ globalMiddlewares() {
164
+ return [
165
+ LoggerMiddleware, // Apply to all routes
166
+
167
+ // Pattern-based
168
+ {
169
+ middleware: AuthMiddleware,
170
+ routes: { include: ['/api/*', '/admin/*'] }
171
+ },
172
+ {
173
+ middleware: RateLimitMiddleware,
174
+ routes: { exclude: ['/health', '/metrics'] }
175
+ }
176
+ ];
177
+ }
178
+ }
179
+
180
+ // Controller-level
181
+ @Controller({ path: '/admin', middlewares: [AuthMiddleware] })
182
+ export class AdminController { }
183
+
184
+ // Route-level
185
+ @Get({ path: '/users', middlewares: [AuthMiddleware] })
186
+ async getUsers(context: Context) { }
173
187
  ```
174
188
 
175
- ## Core Concepts
189
+ ### WebSocket
176
190
 
177
- - **Controllers**: Handle incoming requests using decorators
178
- - **Services**: Business logic containers that can be injected
179
- - **Middleware**: Request/Response interceptors
180
- - **WebSocket**: Built-in WebSocket support
181
- - **HTTP Status**: Standard HTTP status codes and utilities
191
+ Built-in WebSocket support:
182
192
 
183
- ## Performance
193
+ ```typescript
194
+ @WebSocket('/chat')
195
+ export class ChatSocket extends AsenaWebSocketService {
196
+ onOpen(ws: Socket) {
197
+ ws.send('Welcome!');
198
+ }
184
199
 
185
- Built on Bun runtime, Asena provides:
200
+ onMessage(ws: Socket, message: string) {
201
+ ws.send(`Echo: ${message}`);
202
+ }
203
+ }
204
+ ```
186
205
 
187
- - Fast startup time
188
- - Low memory footprint
189
- - Quick request processing
190
- - Efficient WebSocket handling
206
+ ## CLI Commands
191
207
 
192
- Here is the benchmark result of Asena with Hono adapter (Basic hello world example) in every test we used bun to run
193
- the project:
208
+ ```bash
209
+ asena create # Create new project
210
+ asena init # Initialize config
211
+ asena dev start # Development mode
212
+ asena build # Production build
213
+ ```
214
+
215
+ Full CLI documentation: [asena.sh/docs/cli](https://asena.sh/docs/cli/overview.html)
216
+
217
+ ## Performance
194
218
 
195
- ### Performance Comparison (Fastest to Slowest)
219
+ Built on Bun runtime for exceptional performance:
196
220
 
197
- | Framework | Requests/sec | Latency (avg) | Transfer/sec |
198
- | ------------------------------------ | ------------ | ------------- | ------------ |
199
- | Hono | 147,031.08 | 2.69ms | 18.09MB |
200
- | Asena + Hono-adapter | 137,148.80 | 2.89ms | 16.74MB |
201
- | NestJS (Bun + Fastify) | 81,652.05 | 6.01ms | 13.78MB |
202
- | NestJS (Bun) | 64,435.83 | 6.14ms | 11.80MB |
203
- | NestJS (Bun + kiyasov/platform-hono) | 45,082.27 | 8.79ms | 5.55MB |
204
- | NestJS (Node) | 17,649.89 | 24.43ms | 4.02MB |
221
+ | Framework | Requests/sec | Latency (avg) |
222
+ |--------------------------|-----------------------|---------------|
223
+ | **Asena + Ergenecore** | **294962.61** | **1.34ms** |
224
+ | Hono | 266476.83 | 1.49ms |
225
+ | **Asena + Hono-adapter** | **233182.35** | **1.70ms** |
226
+ | NestJS (Bun) | 100975.20 | 3.92ms |
227
+ | NestJS (Node) | 88083.22 | 5.33ms |
205
228
 
206
- > Benchmark conditions:
207
- >
208
- > - 12 threads
209
- > - 400 connections
210
- > - 120 seconds duration
211
- > - Simple "Hello World" endpoint
212
- > - Running on same hardware
229
+ > Benchmark: 12 threads, 400 connections, 120s duration, Hello World endpoint
213
230
 
214
- _Note: Lower latency and higher requests/sec indicate better performance_
231
+ ## Architecture
232
+
233
+ ```
234
+ lib/
235
+ ├── ioc/ # IoC container & dependency injection
236
+ ├── server/ # Core server & routing
237
+ ├── adapter/ # HTTP adapter abstraction
238
+ └── utils/ # Utilities & helpers
239
+ ```
215
240
 
216
241
  ## Contributing
217
242
 
218
- Contributions are welcome! Please feel free to submit a Pull Request.
243
+ Contributions welcome! Submit a Pull Request on [GitHub](https://github.com/AsenaJs/Asena).
219
244
 
220
245
  ## License
221
246
 
222
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
247
+ MIT License - see [LICENSE](LICENSE) file.
223
248
 
224
249
  ## Support
225
250
 
226
- If you encounter any issues or have questions, please open an issue on the [GitHub repository](https://github.com/AsenaJs/Asena/issues).
251
+ Issues or questions? Open an issue on [GitHub](https://github.com/AsenaJs/Asena/issues).
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- export { AsenaServer } from './lib/server';
1
+ export { AsenaServerFactory, AsenaServer } from './lib/server';
2
+ export { ICoreServiceNames, ComponentConstants } from './lib/ioc';
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
- export { AsenaServer } from './lib/server';
1
+ export { AsenaServerFactory, AsenaServer } from './lib/server';
2
+ export { ICoreServiceNames, ComponentConstants } from './lib/ioc';
2
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC"}
@@ -3,6 +3,7 @@ import type { Server } from 'bun';
3
3
  import type { AsenaWebsocketAdapter } from './AsenaWebsocketAdapter';
4
4
  import type { ServerLogger } from '../logger';
5
5
  import type { AsenaContext } from './AsenaContext';
6
+ import type { GlobalMiddlewareRouteConfig } from '../server/config';
6
7
  /**
7
8
  * Abstract class representing an adapter for the Asena framework.
8
9
  * This adapter serves as a base interface between the framework and different server implementations.
@@ -40,10 +41,25 @@ export declare abstract class AsenaAdapter<C extends AsenaContext<any, any>, VS>
40
41
  abstract setPort(port: number): void;
41
42
  /**
42
43
  * Registers middleware to the application
44
+ *
43
45
  * @param middleware - Middleware implementation
44
- * @param path - Optional path to apply the middleware to
46
+ * @param config - Optional route configuration for pattern matching
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * // Old API (still supported)
51
+ * adapter.use(middleware);
52
+ *
53
+ * // New API with pattern matching
54
+ * adapter.use(middleware, {
55
+ * routes: {
56
+ * include: ['/api/*'],
57
+ * exclude: ['/api/health']
58
+ * }
59
+ * });
60
+ * ```
45
61
  */
46
- abstract use(middleware: BaseMiddleware<C>, path?: string): Promise<void> | void;
62
+ abstract use(middleware: BaseMiddleware<C>, config?: GlobalMiddlewareRouteConfig): Promise<void> | void;
47
63
  /**
48
64
  * Registers a new route with the application
49
65
  * @param params - Route configuration parameters
@@ -63,7 +79,7 @@ export declare abstract class AsenaAdapter<C extends AsenaContext<any, any>, VS>
63
79
  * Initializes and starts the server
64
80
  * @returns Server instance
65
81
  */
66
- abstract start(): Promise<Server> | Server;
82
+ abstract start(): Promise<Server<any>> | Server<any>;
67
83
  /**
68
84
  * Sets up global error handling
69
85
  * @param errorHandler - Error handler implementation
@@ -1 +1 @@
1
- {"version":3,"file":"AsenaAdapter.js","sourceRoot":"","sources":["../../../lib/adapter/AsenaAdapter.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,MAAM,OAAgB,YAAY;IAEhC;;OAEG;IACa,IAAI,CAAS;IAE7B;;OAEG;IACO,IAAI,CAAS;IAEvB;;OAEG;IACO,MAAM,GAAiB,OAAO,CAAC;IAEzC;;OAEG;IACO,gBAAgB,CAAwB;IAElD;;;;OAIG;IACH,YAAsB,MAAoB,EAAE,gBAAwC;QAClF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QAC3C,CAAC;IACH,CAAC;CAwDF"}
1
+ {"version":3,"file":"AsenaAdapter.js","sourceRoot":"","sources":["../../../lib/adapter/AsenaAdapter.ts"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH,MAAM,OAAgB,YAAY;IAEhC;;OAEG;IACa,IAAI,CAAS;IAE7B;;OAEG;IACO,IAAI,CAAS;IAEvB;;OAEG;IACO,MAAM,GAAiB,OAAO,CAAC;IAEzC;;OAEG;IACO,gBAAgB,CAAwB;IAElD;;;;OAIG;IACH,YAAsB,MAAoB,EAAE,gBAAwC;QAClF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QAC3C,CAAC;IACH,CAAC;CAuEF"}
@@ -61,11 +61,11 @@ export declare abstract class AsenaWebsocketAdapter {
61
61
  /**
62
62
  * Gets the WebSocket handler
63
63
  */
64
- get websocket(): WebSocketHandler;
64
+ get websocket(): WebSocketHandler<any>;
65
65
  /**
66
66
  * Sets the WebSocket handler
67
67
  */
68
- set websocket(value: WebSocketHandler);
68
+ set websocket(value: WebSocketHandler<any>);
69
69
  /**
70
70
  * Gets the logger instance
71
71
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AsenaWebsocketAdapter.js","sourceRoot":"","sources":["../../../lib/adapter/AsenaWebsocketAdapter.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,MAAM,OAAgB,qBAAqB;IAEzB,IAAI,CAAS;IAE7B;;;;;;;;OAQG;IACO,WAAW,CAAoB;IAEzC;;;OAGG;IACK,UAAU,CAAmB;IAErC;;;OAGG;IACK,OAAO,GAAiB,OAAO,CAAC;IAExC;;;OAGG;IACH,YAAsB,MAAoB;QACxC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAoBD;;OAEG;IACH,IAAc,UAAU;QACtB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,IAAc,UAAU,CAAC,KAAwB;QAC/C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,IAAW,SAAS,CAAC,KAAuB;QAC1C,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,IAAW,MAAM,CAAC,KAAmB;QACnC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;CAEF"}
1
+ {"version":3,"file":"AsenaWebsocketAdapter.js","sourceRoot":"","sources":["../../../lib/adapter/AsenaWebsocketAdapter.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,MAAM,OAAgB,qBAAqB;IAEzB,IAAI,CAAS;IAE7B;;;;;;;;OAQG;IACO,WAAW,CAAoB;IAEzC;;;OAGG;IACK,UAAU,CAAwB;IAE1C;;;OAGG;IACK,OAAO,GAAiB,OAAO,CAAC;IAExC;;;OAGG;IACH,YAAsB,MAAoB;QACxC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAoBD;;OAEG;IACH,IAAc,UAAU;QACtB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,IAAc,UAAU,CAAC,KAAwB;QAC/C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,IAAW,SAAS,CAAC,KAA4B;QAC/C,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,IAAW,MAAM,CAAC,KAAmB;QACnC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;CAEF"}
@@ -11,9 +11,12 @@ export interface RouteParams<C extends AsenaContext<any, any>, VS, E = any> {
11
11
  handler: AsenaHandler<C>;
12
12
  staticServe: BaseStaticServeParams<C, E>;
13
13
  validator: BaseValidator<VS>;
14
+ controllerName?: string;
15
+ controllerBasePath?: string;
14
16
  }
15
17
  export interface WebsocketRouteParams<C extends AsenaContext<any, any>> {
16
18
  path: string;
17
19
  middlewares: BaseMiddleware<C>[];
18
20
  websocketService: AsenaWebSocketService<any>;
21
+ controllerName?: string;
19
22
  }
@@ -1,6 +1,6 @@
1
- import type { ServeOptions, TLSServeOptions, UnixServeOptions, UnixTLSServeOptions } from 'bun';
1
+ import type { ServeOptions } from 'bun';
2
2
  import type { WSOptions } from '../../server/web/websocket';
3
- export type AsenaServerOptions = ServeOptions | TLSServeOptions | UnixServeOptions | UnixTLSServeOptions;
3
+ export type AsenaServerOptions = ServeOptions;
4
4
  export interface AsenaServeOptions {
5
5
  serveOptions?: AsenaServerOptions;
6
6
  wsOptions?: WSOptions;
@@ -5,7 +5,7 @@ export * from './RouteParams';
5
5
  export * from './SendOptions';
6
6
  export * from './WebSocketRegistry';
7
7
  export * from './ServeOptions';
8
- export * from "./BaseMiddleware";
9
- export * from "./ApiParams";
10
- export * from "./AsenaHandler";
11
- export * from "./BaseStaticServeParams";
8
+ export * from './BaseMiddleware';
9
+ export * from './ApiParams';
10
+ export * from './AsenaHandler';
11
+ export * from './BaseStaticServeParams';
@@ -5,8 +5,8 @@ export * from './RouteParams';
5
5
  export * from './SendOptions';
6
6
  export * from './WebSocketRegistry';
7
7
  export * from './ServeOptions';
8
- export * from "./BaseMiddleware";
9
- export * from "./ApiParams";
10
- export * from "./AsenaHandler";
11
- export * from "./BaseStaticServeParams";
8
+ export * from './BaseMiddleware';
9
+ export * from './ApiParams';
10
+ export * from './AsenaHandler';
11
+ export * from './BaseStaticServeParams';
12
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/adapter/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,yBAAyB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/adapter/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @description Custom error class for circular dependency detection
3
+ * Provides detailed information about the circular dependency chain
4
+ */
5
+ export declare class CircularDependencyError extends Error {
6
+ constructor(message: string);
7
+ }
8
+ /**
9
+ * @description Detector for circular dependencies in the IoC container
10
+ * Tracks the resolution stack and detects cycles during dependency injection
11
+ */
12
+ export declare class CircularDependencyDetector {
13
+ private resolutionStack;
14
+ /**
15
+ * @description Check if service creates circular dependency
16
+ * @param {string} serviceName - The service being resolved
17
+ * @throws {CircularDependencyError} If circular dependency is detected
18
+ * @returns {void}
19
+ */
20
+ checkCircular(serviceName: string): void;
21
+ /**
22
+ * @description Push service to resolution stack
23
+ * @param {string} serviceName - The service being resolved
24
+ * @returns {void}
25
+ */
26
+ push(serviceName: string): void;
27
+ /**
28
+ * @description Pop service from resolution stack
29
+ * @param {string} serviceName - The service that was resolved
30
+ * @returns {void}
31
+ */
32
+ pop(serviceName: string): void;
33
+ /**
34
+ * @description Clear the resolution stack
35
+ * Useful for testing or manual stack reset
36
+ * @returns {void}
37
+ */
38
+ clear(): void;
39
+ /**
40
+ * @description Get current resolution stack as array
41
+ * @returns {string[]} Array of service names in resolution order
42
+ */
43
+ getStack(): string[];
44
+ /**
45
+ * @description Check if stack is empty
46
+ * @returns {boolean}
47
+ */
48
+ isEmpty(): boolean;
49
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @description Custom error class for circular dependency detection
3
+ * Provides detailed information about the circular dependency chain
4
+ */
5
+ export class CircularDependencyError extends Error {
6
+ constructor(message) {
7
+ super(message);
8
+ this.name = 'CircularDependencyError';
9
+ }
10
+ }
11
+ /**
12
+ * @description Detector for circular dependencies in the IoC container
13
+ * Tracks the resolution stack and detects cycles during dependency injection
14
+ */
15
+ export class CircularDependencyDetector {
16
+ resolutionStack = new Set();
17
+ /**
18
+ * @description Check if service creates circular dependency
19
+ * @param {string} serviceName - The service being resolved
20
+ * @throws {CircularDependencyError} If circular dependency is detected
21
+ * @returns {void}
22
+ */
23
+ checkCircular(serviceName) {
24
+ if (this.resolutionStack.has(serviceName)) {
25
+ const stack = Array.from(this.resolutionStack);
26
+ const chain = [...stack, serviceName].join(' -> ');
27
+ throw new CircularDependencyError(`Circular dependency detected: ${chain}`);
28
+ }
29
+ }
30
+ /**
31
+ * @description Push service to resolution stack
32
+ * @param {string} serviceName - The service being resolved
33
+ * @returns {void}
34
+ */
35
+ push(serviceName) {
36
+ this.resolutionStack.add(serviceName);
37
+ }
38
+ /**
39
+ * @description Pop service from resolution stack
40
+ * @param {string} serviceName - The service that was resolved
41
+ * @returns {void}
42
+ */
43
+ pop(serviceName) {
44
+ this.resolutionStack.delete(serviceName);
45
+ }
46
+ /**
47
+ * @description Clear the resolution stack
48
+ * Useful for testing or manual stack reset
49
+ * @returns {void}
50
+ */
51
+ clear() {
52
+ this.resolutionStack.clear();
53
+ }
54
+ /**
55
+ * @description Get current resolution stack as array
56
+ * @returns {string[]} Array of service names in resolution order
57
+ */
58
+ getStack() {
59
+ return Array.from(this.resolutionStack);
60
+ }
61
+ /**
62
+ * @description Check if stack is empty
63
+ * @returns {boolean}
64
+ */
65
+ isEmpty() {
66
+ return this.resolutionStack.size === 0;
67
+ }
68
+ }
69
+ //# sourceMappingURL=CircularDependencyDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CircularDependencyDetector.js","sourceRoot":"","sources":["../../../lib/ioc/CircularDependencyDetector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAEhD,YAAmB,OAAe;QAChC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CAEF;AAED;;;GAGG;AACH,MAAM,OAAO,0BAA0B;IAE7B,eAAe,GAAgB,IAAI,GAAG,EAAE,CAAC;IAEjD;;;;;OAKG;IACI,aAAa,CAAC,WAAmB;QACtC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC/C,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAEnD,MAAM,IAAI,uBAAuB,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,IAAI,CAAC,WAAmB;QAC7B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACI,GAAG,CAAC,WAAmB;QAC5B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC;IAED;;;;OAIG;IACI,KAAK;QACV,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACI,QAAQ;QACb,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACI,OAAO;QACZ,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,KAAK,CAAC,CAAC;IACzC,CAAC;CAEF"}