@asenajs/asena 0.3.3 → 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.
- package/README.md +165 -140
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/adapter/AsenaAdapter.d.ts +19 -3
- package/dist/lib/adapter/AsenaAdapter.js.map +1 -1
- package/dist/lib/adapter/AsenaWebsocketAdapter.d.ts +2 -2
- package/dist/lib/adapter/AsenaWebsocketAdapter.js.map +1 -1
- package/dist/lib/adapter/types/RouteParams.d.ts +3 -0
- package/dist/lib/adapter/types/ServeOptions.d.ts +2 -2
- package/dist/lib/adapter/types/index.d.ts +4 -4
- package/dist/lib/adapter/types/index.js +4 -4
- package/dist/lib/adapter/types/index.js.map +1 -1
- package/dist/lib/ioc/CircularDependencyDetector.d.ts +49 -0
- package/dist/lib/ioc/CircularDependencyDetector.js +69 -0
- package/dist/lib/ioc/CircularDependencyDetector.js.map +1 -0
- package/dist/lib/ioc/Container.d.ts +9 -0
- package/dist/lib/ioc/Container.js +42 -11
- package/dist/lib/ioc/Container.js.map +1 -1
- package/dist/lib/ioc/CoreContainer.d.ts +78 -0
- package/dist/lib/ioc/CoreContainer.js +135 -0
- package/dist/lib/ioc/CoreContainer.js.map +1 -0
- package/dist/lib/ioc/IocEngine.d.ts +16 -6
- package/dist/lib/ioc/IocEngine.js +35 -7
- package/dist/lib/ioc/IocEngine.js.map +1 -1
- package/dist/lib/ioc/component/index.d.ts +1 -1
- package/dist/lib/ioc/component/index.js +1 -1
- package/dist/lib/ioc/component/index.js.map +1 -1
- package/dist/lib/ioc/constants/ComponentConstants.d.ts +27 -18
- package/dist/lib/ioc/constants/ComponentConstants.js +34 -20
- package/dist/lib/ioc/constants/ComponentConstants.js.map +1 -1
- package/dist/lib/ioc/decorators/CoreService.d.ts +8 -0
- package/dist/lib/ioc/decorators/CoreService.js +27 -0
- package/dist/lib/ioc/decorators/CoreService.js.map +1 -0
- package/dist/lib/ioc/decorators/index.d.ts +1 -0
- package/dist/lib/ioc/decorators/index.js +2 -0
- package/dist/lib/ioc/decorators/index.js.map +1 -0
- package/dist/lib/ioc/index.d.ts +5 -0
- package/dist/lib/ioc/index.js +5 -0
- package/dist/lib/ioc/index.js.map +1 -1
- package/dist/lib/ioc/types/CoreBootstrapPhase.d.ts +15 -0
- package/dist/lib/ioc/types/CoreBootstrapPhase.js +17 -0
- package/dist/lib/ioc/types/CoreBootstrapPhase.js.map +1 -0
- package/dist/lib/ioc/types/ICoreService.d.ts +9 -0
- package/dist/lib/ioc/types/ICoreService.js +2 -0
- package/dist/lib/ioc/types/ICoreService.js.map +1 -0
- package/dist/lib/ioc/types/ICoreServiceNamesType.d.ts +18 -0
- package/dist/lib/ioc/types/ICoreServiceNamesType.js +23 -0
- package/dist/lib/ioc/types/ICoreServiceNamesType.js.map +1 -0
- package/dist/lib/ioc/types/decorators/ControllerParams.d.ts +1 -1
- package/dist/lib/ioc/types/index.d.ts +3 -0
- package/dist/lib/ioc/types/index.js +3 -0
- package/dist/lib/ioc/types/index.js.map +1 -1
- package/dist/lib/server/AsenaServer.d.ts +85 -14
- package/dist/lib/server/AsenaServer.js +169 -61
- package/dist/lib/server/AsenaServer.js.map +1 -1
- package/dist/lib/server/AsenaServerFactory.d.ts +26 -0
- package/dist/lib/server/AsenaServerFactory.js +58 -0
- package/dist/lib/server/AsenaServerFactory.js.map +1 -0
- package/dist/lib/server/config/AsenaConfig.d.ts +91 -18
- package/dist/lib/server/decorators/Override.js +1 -1
- package/dist/lib/server/decorators/Override.js.map +1 -1
- package/dist/lib/server/decorators/components/Config.d.ts +1 -1
- package/dist/lib/server/decorators/components/Config.js +1 -1
- package/dist/lib/server/decorators/components/Config.js.map +1 -1
- package/dist/lib/server/decorators/components/Controller.d.ts +1 -1
- package/dist/lib/server/decorators/components/Controller.js +2 -2
- package/dist/lib/server/decorators/components/Controller.js.map +1 -1
- package/dist/lib/server/decorators/components/Middleware.js +2 -2
- package/dist/lib/server/decorators/components/Middleware.js.map +1 -1
- package/dist/lib/server/decorators/components/Schedule.d.ts +1 -1
- package/dist/lib/server/decorators/components/Schedule.js +2 -2
- package/dist/lib/server/decorators/components/Schedule.js.map +1 -1
- package/dist/lib/server/decorators/components/WebSocket.d.ts +1 -1
- package/dist/lib/server/decorators/components/WebSocket.js +2 -2
- package/dist/lib/server/decorators/components/WebSocket.js.map +1 -1
- package/dist/lib/server/decorators/index.d.ts +2 -0
- package/dist/lib/server/decorators/index.js +2 -0
- package/dist/lib/server/decorators/index.js.map +1 -1
- package/dist/lib/server/index.d.ts +2 -0
- package/dist/lib/server/index.js +2 -0
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/src/services/PrepareConfigService.d.ts +9 -5
- package/dist/lib/server/src/services/PrepareConfigService.js +32 -7
- package/dist/lib/server/src/services/PrepareConfigService.js.map +1 -1
- package/dist/lib/server/src/services/PrepareMiddlewareService.d.ts +8 -5
- package/dist/lib/server/src/services/PrepareMiddlewareService.js +28 -7
- package/dist/lib/server/src/services/PrepareMiddlewareService.js.map +1 -1
- package/dist/lib/server/src/services/PrepareStaticServeConfigService.d.ts +8 -5
- package/dist/lib/server/src/services/PrepareStaticServeConfigService.js +27 -6
- package/dist/lib/server/src/services/PrepareStaticServeConfigService.js.map +1 -1
- package/dist/lib/server/src/services/PrepareValidatorService.d.ts +8 -5
- package/dist/lib/server/src/services/PrepareValidatorService.js +27 -6
- package/dist/lib/server/src/services/PrepareValidatorService.js.map +1 -1
- package/dist/lib/server/src/services/PrepareWebsocketService.d.ts +8 -5
- package/dist/lib/server/src/services/PrepareWebsocketService.js +28 -9
- package/dist/lib/server/src/services/PrepareWebsocketService.js.map +1 -1
- package/dist/lib/server/web/decorators/http.base.d.ts +1 -1
- package/dist/lib/server/web/decorators/http.base.js.map +1 -1
- package/dist/lib/server/web/decorators/methods/Connect.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Delete.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Get.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Head.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Options.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Patch.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Post.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Put.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Trace.d.ts +1 -1
- package/dist/lib/server/web/websocket/AsenaSocket.js.map +1 -1
- package/dist/lib/server/web/websocket/AsenaWebSocketServer.d.ts +1 -1
- package/dist/lib/server/web/websocket/AsenaWebSocketServer.js.map +1 -1
- package/dist/lib/server/web/websocket/index.d.ts +1 -1
- package/dist/lib/server/web/websocket/index.js +1 -1
- package/dist/lib/server/web/websocket/index.js.map +1 -1
- package/dist/lib/utils/patternMatcher.d.ts +41 -0
- package/dist/lib/utils/patternMatcher.js +99 -0
- package/dist/lib/utils/patternMatcher.js.map +1 -0
- package/dist/lib/utils/typedMetadata.d.ts +3 -3
- package/dist/lib/utils/typedMetadata.js.map +1 -1
- package/package.json +12 -7
- package/dist/lib/server/src/PrepareService.d.ts +0 -8
- package/dist/lib/server/src/PrepareService.js +0 -9
- package/dist/lib/server/src/PrepareService.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,226 +1,251 @@
|
|
|
1
1
|
# Asena
|
|
2
2
|
|
|
3
|
-
|
|
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,
|
|
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
|
-
- **
|
|
13
|
-
- **Decorator-based
|
|
14
|
-
- **High Performance**:
|
|
15
|
-
- **WebSocket Support**:
|
|
16
|
-
- **Middleware
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
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
|
-
|
|
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
|
-
|
|
33
|
+
### Manual Setup
|
|
49
34
|
|
|
50
|
-
|
|
35
|
+
Install dependencies:
|
|
51
36
|
|
|
52
37
|
```bash
|
|
53
|
-
bun
|
|
38
|
+
bun add @asenajs/asena @asenajs/hono-adapter @asenajs/asena-logger
|
|
39
|
+
bun add -D @asenajs/asena-cli
|
|
54
40
|
```
|
|
55
41
|
|
|
56
|
-
|
|
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
|
-
"
|
|
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
|
-
|
|
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
|
|
64
|
+
Create your server (`src/index.ts`):
|
|
115
65
|
|
|
116
66
|
```typescript
|
|
117
|
-
|
|
118
|
-
import {
|
|
119
|
-
import {
|
|
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 [
|
|
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
|
|
79
|
+
await server.start();
|
|
126
80
|
```
|
|
127
81
|
|
|
128
|
-
|
|
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
|
|
90
|
+
export class HelloController {
|
|
138
91
|
@Get('/world')
|
|
139
|
-
|
|
92
|
+
async getHello(context: Context) {
|
|
140
93
|
return context.send('Hello World');
|
|
141
94
|
}
|
|
142
95
|
}
|
|
143
96
|
```
|
|
144
97
|
|
|
145
|
-
|
|
98
|
+
## Core Concepts
|
|
146
99
|
|
|
147
|
-
|
|
148
|
-
## only for fast developing purposes
|
|
149
|
-
asena dev start
|
|
150
|
-
```
|
|
100
|
+
### Controllers
|
|
151
101
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
|
|
121
|
+
### Services
|
|
122
|
+
|
|
123
|
+
Business logic with dependency injection:
|
|
160
124
|
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
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
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
189
|
+
### WebSocket
|
|
176
190
|
|
|
177
|
-
-
|
|
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
|
-
|
|
193
|
+
```typescript
|
|
194
|
+
@WebSocket('/chat')
|
|
195
|
+
export class ChatSocket extends AsenaWebSocketService {
|
|
196
|
+
onOpen(ws: Socket) {
|
|
197
|
+
ws.send('Welcome!');
|
|
198
|
+
}
|
|
184
199
|
|
|
185
|
-
|
|
200
|
+
onMessage(ws: Socket, message: string) {
|
|
201
|
+
ws.send(`Echo: ${message}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
186
205
|
|
|
187
|
-
|
|
188
|
-
- Low memory footprint
|
|
189
|
-
- Quick request processing
|
|
190
|
-
- Efficient WebSocket handling
|
|
206
|
+
## CLI Commands
|
|
191
207
|
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
219
|
+
Built on Bun runtime for exceptional performance:
|
|
196
220
|
|
|
197
|
-
| Framework
|
|
198
|
-
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
| NestJS (Bun)
|
|
203
|
-
| NestJS (
|
|
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
|
|
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
|
-
|
|
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
|
|
243
|
+
Contributions welcome! Submit a Pull Request on [GitHub](https://github.com/AsenaJs/Asena).
|
|
219
244
|
|
|
220
245
|
## License
|
|
221
246
|
|
|
222
|
-
|
|
247
|
+
MIT License - see [LICENSE](LICENSE) file.
|
|
223
248
|
|
|
224
249
|
## Support
|
|
225
250
|
|
|
226
|
-
|
|
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
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
|
|
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>,
|
|
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
|
|
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":"
|
|
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,
|
|
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
|
|
1
|
+
import type { ServeOptions } from 'bun';
|
|
2
2
|
import type { WSOptions } from '../../server/web/websocket';
|
|
3
|
-
export type AsenaServerOptions = ServeOptions
|
|
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
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
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
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
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,
|
|
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"}
|