@asenajs/asena 0.1.19 → 0.2.1
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 +75 -143
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/adapter/AsenaAdapter.d.ts +1 -2
- package/dist/lib/adapter/AsenaAdapter.js.map +1 -1
- package/dist/lib/adapter/AsenaWebsocketAdapter.d.ts +1 -2
- package/dist/lib/adapter/AsenaWebsocketAdapter.js.map +1 -1
- package/dist/lib/{server/web → adapter}/types/ApiParams.d.ts +3 -3
- package/dist/lib/adapter/types/ApiParams.js.map +1 -0
- package/dist/lib/{server/web → adapter}/types/BaseMiddleware.d.ts +2 -2
- package/dist/lib/adapter/types/BaseMiddleware.js.map +1 -0
- package/dist/lib/adapter/types/RouteParams.d.ts +2 -2
- package/dist/lib/adapter/types/WebSocketRegistry.d.ts +1 -1
- package/dist/lib/adapter/types/index.d.ts +3 -0
- package/dist/lib/adapter/types/index.js +3 -0
- package/dist/lib/adapter/types/index.js.map +1 -1
- package/dist/lib/ioc/Container.d.ts +1 -0
- package/dist/lib/ioc/Container.js +74 -38
- package/dist/lib/ioc/Container.js.map +1 -1
- package/dist/lib/ioc/IocEngine.js +20 -8
- package/dist/lib/ioc/IocEngine.js.map +1 -1
- package/dist/lib/ioc/component/Scope.js.map +1 -0
- package/dist/lib/ioc/component/componentUtils.js +5 -4
- package/dist/lib/ioc/component/componentUtils.js.map +1 -1
- package/dist/lib/ioc/component/decorators/Inject.js +5 -4
- package/dist/lib/ioc/component/decorators/Inject.js.map +1 -1
- package/dist/lib/ioc/component/decorators/PostConstruct.js +2 -2
- package/dist/lib/ioc/component/decorators/PostConstruct.js.map +1 -1
- package/dist/lib/ioc/component/decorators/Strategy.js +5 -5
- package/dist/lib/ioc/component/decorators/Strategy.js.map +1 -1
- package/dist/lib/ioc/component/index.d.ts +1 -0
- package/dist/lib/ioc/component/index.js +1 -0
- package/dist/lib/ioc/component/index.js.map +1 -1
- package/dist/lib/ioc/types/decorators/ComponentParams.d.ts +1 -1
- package/dist/lib/ioc/types/index.d.ts +0 -1
- package/dist/lib/ioc/types/index.js +0 -1
- package/dist/lib/ioc/types/index.js.map +1 -1
- package/dist/lib/logger/DefaultLogger.js +1 -1
- package/dist/lib/logger/DefaultLogger.js.map +1 -1
- package/dist/lib/server/AsenaServer.js +4 -4
- package/dist/lib/server/AsenaServer.js.map +1 -1
- package/dist/lib/server/config/index.d.ts +1 -0
- package/dist/lib/server/config/index.js +2 -0
- package/dist/lib/server/config/index.js.map +1 -0
- package/dist/lib/server/decorators/Override.js +2 -2
- package/dist/lib/server/decorators/Override.js.map +1 -1
- package/dist/lib/server/decorators/components/Middleware.js +1 -1
- package/dist/lib/server/decorators/components/Middleware.js.map +1 -1
- package/dist/lib/server/index.d.ts +0 -1
- package/dist/lib/server/index.js +0 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/types/index.d.ts +2 -2
- package/dist/lib/server/types/index.js +2 -2
- package/dist/lib/server/types/index.js.map +1 -1
- package/dist/lib/server/web/decorators/http.base.d.ts +2 -2
- package/dist/lib/server/web/decorators/http.base.js +3 -3
- 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/Connect.js +1 -1
- package/dist/lib/server/web/decorators/methods/Connect.js.map +1 -1
- package/dist/lib/server/web/decorators/methods/Delete.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Delete.js +1 -1
- package/dist/lib/server/web/decorators/methods/Delete.js.map +1 -1
- package/dist/lib/server/web/decorators/methods/Get.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Get.js +1 -1
- package/dist/lib/server/web/decorators/methods/Get.js.map +1 -1
- package/dist/lib/server/web/decorators/methods/Head.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Head.js +1 -1
- package/dist/lib/server/web/decorators/methods/Head.js.map +1 -1
- package/dist/lib/server/web/decorators/methods/Options.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Options.js +1 -1
- package/dist/lib/server/web/decorators/methods/Options.js.map +1 -1
- package/dist/lib/server/web/decorators/methods/Patch.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Patch.js +1 -1
- package/dist/lib/server/web/decorators/methods/Patch.js.map +1 -1
- package/dist/lib/server/web/decorators/methods/Post.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Post.js +1 -1
- package/dist/lib/server/web/decorators/methods/Post.js.map +1 -1
- package/dist/lib/server/web/decorators/methods/Put.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Put.js +1 -1
- package/dist/lib/server/web/decorators/methods/Put.js.map +1 -1
- package/dist/lib/server/web/decorators/methods/Trace.d.ts +1 -1
- package/dist/lib/server/web/decorators/methods/Trace.js +1 -1
- package/dist/lib/server/web/decorators/methods/Trace.js.map +1 -1
- package/dist/lib/server/web/helper/middlewareHelper.d.ts +2 -2
- package/dist/lib/server/web/helper/middlewareHelper.js +3 -3
- package/dist/lib/server/web/helper/middlewareHelper.js.map +1 -1
- package/dist/lib/server/web/types/HttpMethod.js.map +1 -0
- package/dist/lib/server/web/types/HttpStatus.js.map +1 -0
- package/dist/lib/server/web/types/index.d.ts +2 -2
- package/dist/lib/server/web/types/index.js +2 -2
- package/dist/lib/server/web/types/index.js.map +1 -1
- package/dist/lib/server/web/websocket/AsenaSocket.d.ts +1 -0
- package/dist/lib/server/web/websocket/AsenaSocket.js +3 -0
- package/dist/lib/server/web/websocket/AsenaSocket.js.map +1 -1
- package/dist/lib/server/web/websocket/AsenaWebSocketServer.js +1 -1
- package/dist/lib/server/web/websocket/AsenaWebSocketServer.js.map +1 -1
- package/dist/lib/server/web/websocket/index.d.ts +1 -0
- package/dist/lib/server/web/websocket/index.js +1 -0
- package/dist/lib/server/web/websocket/index.js.map +1 -1
- package/dist/lib/utils/typedMetadata.d.ts +1 -0
- package/dist/lib/utils/typedMetadata.js +4 -1
- package/dist/lib/utils/typedMetadata.js.map +1 -1
- package/package.json +16 -15
- package/dist/lib/adapter/hono/HonoAdapter.d.ts +0 -28
- package/dist/lib/adapter/hono/HonoAdapter.js +0 -114
- package/dist/lib/adapter/hono/HonoAdapter.js.map +0 -1
- package/dist/lib/adapter/hono/HonoContextWrapper.d.ts +0 -32
- package/dist/lib/adapter/hono/HonoContextWrapper.js +0 -97
- package/dist/lib/adapter/hono/HonoContextWrapper.js.map +0 -1
- package/dist/lib/adapter/hono/HonoWebsocketAdapter.d.ts +0 -19
- package/dist/lib/adapter/hono/HonoWebsocketAdapter.js +0 -87
- package/dist/lib/adapter/hono/HonoWebsocketAdapter.js.map +0 -1
- package/dist/lib/adapter/hono/defaults/ConfigService.d.ts +0 -4
- package/dist/lib/adapter/hono/defaults/ConfigService.js +0 -3
- package/dist/lib/adapter/hono/defaults/ConfigService.js.map +0 -1
- package/dist/lib/adapter/hono/defaults/Context.d.ts +0 -3
- package/dist/lib/adapter/hono/defaults/Context.js +0 -2
- package/dist/lib/adapter/hono/defaults/Context.js.map +0 -1
- package/dist/lib/adapter/hono/defaults/MiddlewareService.d.ts +0 -5
- package/dist/lib/adapter/hono/defaults/MiddlewareService.js +0 -4
- package/dist/lib/adapter/hono/defaults/MiddlewareService.js.map +0 -1
- package/dist/lib/adapter/hono/defaults/ValidationService.d.ts +0 -10
- package/dist/lib/adapter/hono/defaults/ValidationService.js +0 -3
- package/dist/lib/adapter/hono/defaults/ValidationService.js.map +0 -1
- package/dist/lib/adapter/hono/defaults/index.d.ts +0 -4
- package/dist/lib/adapter/hono/defaults/index.js +0 -5
- package/dist/lib/adapter/hono/defaults/index.js.map +0 -1
- package/dist/lib/adapter/hono/index.d.ts +0 -6
- package/dist/lib/adapter/hono/index.js +0 -7
- package/dist/lib/adapter/hono/index.js.map +0 -1
- package/dist/lib/adapter/hono/types/HonoHandler.d.ts +0 -5
- package/dist/lib/adapter/hono/types/HonoHandler.js +0 -2
- package/dist/lib/adapter/hono/types/HonoHandler.js.map +0 -1
- package/dist/lib/adapter/hono/types/index.d.ts +0 -2
- package/dist/lib/adapter/hono/types/index.js +0 -3
- package/dist/lib/adapter/hono/types/index.js.map +0 -1
- package/dist/lib/adapter/hono/utils/createHonoAdapter.d.ts +0 -3
- package/dist/lib/adapter/hono/utils/createHonoAdapter.js +0 -6
- package/dist/lib/adapter/hono/utils/createHonoAdapter.js.map +0 -1
- package/dist/lib/adapter/hono/utils/middlewareParser.d.ts +0 -4
- package/dist/lib/adapter/hono/utils/middlewareParser.js +0 -15
- package/dist/lib/adapter/hono/utils/middlewareParser.js.map +0 -1
- package/dist/lib/ioc/types/Scope.js.map +0 -1
- package/dist/lib/server/web/http/HttpMethod.js.map +0 -1
- package/dist/lib/server/web/http/HttpStatus.js.map +0 -1
- package/dist/lib/server/web/http/index.d.ts +0 -2
- package/dist/lib/server/web/http/index.js +0 -3
- package/dist/lib/server/web/http/index.js.map +0 -1
- package/dist/lib/server/web/types/ApiParams.js.map +0 -1
- package/dist/lib/server/web/types/BaseMiddleware.js.map +0 -1
- /package/dist/lib/{server/web → adapter}/types/ApiParams.js +0 -0
- /package/dist/lib/{server/web → adapter}/types/BaseMiddleware.js +0 -0
- /package/dist/lib/ioc/{types → component}/Scope.d.ts +0 -0
- /package/dist/lib/ioc/{types → component}/Scope.js +0 -0
- /package/dist/lib/server/web/{http → types}/HttpMethod.d.ts +0 -0
- /package/dist/lib/server/web/{http → types}/HttpMethod.js +0 -0
- /package/dist/lib/server/web/{http → types}/HttpStatus.d.ts +0 -0
- /package/dist/lib/server/web/{http → types}/HttpStatus.js +0 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Asena
|
|
2
2
|
|
|
3
3
|
Asena is a NestJS-like IoC web framework built on top of Hono and Bun. It combines the power of dependency injection
|
|
4
|
-
with the performance of Bun runtime and the flexibility of
|
|
4
|
+
with the performance of Bun runtime and the flexibility of Adapter design system.
|
|
5
5
|
|
|
6
6
|
## Documentation
|
|
7
7
|
|
|
@@ -15,16 +15,48 @@ For detailed documentation, please visit [not ready yet](https://asena.sh). Docu
|
|
|
15
15
|
- **WebSocket Support**: Built-in WebSocket handling capabilities
|
|
16
16
|
- **Middleware System**: Flexible middleware architecture
|
|
17
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
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bun add @asenajs/asena
|
|
26
|
+
```
|
|
18
27
|
|
|
19
28
|
## Quick Start
|
|
20
29
|
|
|
30
|
+
The easiest way to create a new Asena project is using the CLI:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Create a new project
|
|
34
|
+
bun add -D @asenajs/asena-cli
|
|
35
|
+
asena create
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This will create a new project with the following structure:
|
|
39
|
+
```
|
|
40
|
+
├── src/
|
|
41
|
+
│ ├── controllers/
|
|
42
|
+
│ │ └── AsenaController.ts
|
|
43
|
+
│ └── index.ts
|
|
44
|
+
├── package.json
|
|
45
|
+
├── tsconfig.json
|
|
46
|
+
├── .eslintrc.js
|
|
47
|
+
├── .eslintignore
|
|
48
|
+
└── .prettierrc.js
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Alternatively, you can create a project manually:
|
|
52
|
+
|
|
21
53
|
First, create a new project using Bun:
|
|
22
54
|
|
|
23
55
|
```bash
|
|
24
56
|
bun init
|
|
25
57
|
```
|
|
26
58
|
|
|
27
|
-
For decorators working properly, you need to add some settings to your tsconfig. Here is
|
|
59
|
+
For decorators working properly, you need to add some settings to your tsconfig. Here is a recommended file:
|
|
28
60
|
|
|
29
61
|
```json
|
|
30
62
|
{
|
|
@@ -46,7 +78,7 @@ For decorators working properly, you need to add some settings to your tsconfig.
|
|
|
46
78
|
"noEmit": true,
|
|
47
79
|
|
|
48
80
|
// Best practices
|
|
49
|
-
"strict":
|
|
81
|
+
"strict": true,
|
|
50
82
|
"skipLibCheck": true,
|
|
51
83
|
"noFallthroughCasesInSwitch": true,
|
|
52
84
|
|
|
@@ -61,8 +93,7 @@ For decorators working properly, you need to add some settings to your tsconfig.
|
|
|
61
93
|
Then, install the required packages:
|
|
62
94
|
|
|
63
95
|
```bash
|
|
64
|
-
|
|
65
|
-
bun add @asenajs/asena hono winston
|
|
96
|
+
bun add @asenajs/asena @asenajs/hono-adapter
|
|
66
97
|
```
|
|
67
98
|
|
|
68
99
|
Add @asenajs/asena-cli to your package. This package provides a CLI for creating and managing Asena projects.
|
|
@@ -74,8 +105,6 @@ bun add -D @asenajs/asena-cli
|
|
|
74
105
|
Then, create a new asena-config.ts file using the CLI:
|
|
75
106
|
|
|
76
107
|
```bash
|
|
77
|
-
|
|
78
|
-
## Creates a asena-config.ts file with default values (requires manual updates). Source folder is 'src'.
|
|
79
108
|
asena init
|
|
80
109
|
```
|
|
81
110
|
|
|
@@ -86,33 +115,37 @@ Create index.ts file under your src folder:
|
|
|
86
115
|
|
|
87
116
|
```typescript
|
|
88
117
|
// src/index.ts
|
|
89
|
-
|
|
90
|
-
|
|
118
|
+
import { AsenaServer } from '@asenajs/asena';
|
|
119
|
+
import { DefaultLogger } from "@asenajs/asena/logger";
|
|
120
|
+
import { createHonoAdapter } from '@asenajs/hono-adapter';
|
|
121
|
+
|
|
122
|
+
const [adapter, logger] = createHonoAdapter(new DefaultLogger());
|
|
123
|
+
await new AsenaServer(adapter)
|
|
124
|
+
.logger(logger)
|
|
125
|
+
.port(3000)
|
|
126
|
+
.start(true);
|
|
91
127
|
```
|
|
92
128
|
|
|
93
129
|
To run asena you need at least one controller. Create a new controller:
|
|
94
130
|
|
|
95
131
|
```typescript
|
|
96
132
|
// src/controllers/TestController.ts
|
|
97
|
-
import type { Context } from '@asenajs/
|
|
133
|
+
import type { Context } from '@asenajs/hono-adapter';
|
|
98
134
|
import { Controller } from '@asenajs/asena/server';
|
|
99
135
|
import { Get } from '@asenajs/asena/web';
|
|
100
136
|
|
|
101
137
|
@Controller('/hello')
|
|
102
138
|
export class TestController {
|
|
103
|
-
|
|
104
139
|
@Get('/world')
|
|
105
140
|
public async getHello(context: Context) {
|
|
106
141
|
return context.send('Hello World');
|
|
107
142
|
}
|
|
108
|
-
|
|
109
143
|
}
|
|
110
144
|
```
|
|
111
145
|
|
|
112
146
|
Finally, run the project:
|
|
113
147
|
|
|
114
148
|
```bash
|
|
115
|
-
|
|
116
149
|
## only for fast developing purposes
|
|
117
150
|
asena dev start
|
|
118
151
|
```
|
|
@@ -120,159 +153,46 @@ asena dev start
|
|
|
120
153
|
```bash
|
|
121
154
|
## or you can simply build then run your bundled project
|
|
122
155
|
asena build
|
|
123
|
-
## then go to dist folder and run the project this way it will consume less memory
|
|
156
|
+
## then go to dist folder and run the project this way it will consume less memory and it will be faster.
|
|
124
157
|
bun index.asena.js
|
|
125
158
|
```
|
|
126
159
|
|
|
127
|
-
##
|
|
160
|
+
## CLI Commands
|
|
128
161
|
|
|
129
|
-
|
|
162
|
+
For more information about CLI commands and usage, please visit:
|
|
163
|
+
[Asena CLI Documentation](https://github.com/AsenaJs/Asena-cli/blob/master/README.md)
|
|
130
164
|
|
|
131
|
-
### Middleware
|
|
132
165
|
|
|
133
|
-
|
|
166
|
+
## Project Structure
|
|
134
167
|
|
|
135
|
-
```typescript
|
|
136
|
-
// src/middleware/TestMiddleware.ts
|
|
137
|
-
import type { AsenaNextHandler } from '@asenajs/asena/adapter';
|
|
138
|
-
import type { Context, MiddlewareService } from '@asenajs/asena/adapter/hono';
|
|
139
|
-
import { Middleware } from '@asenajs/asena/server';
|
|
140
|
-
|
|
141
|
-
@Middleware()
|
|
142
|
-
export class TestMiddleware implements MiddlewareService {
|
|
143
|
-
public handle(context: Context, next: AsenaNextHandler) {
|
|
144
|
-
context.setValue('testValue', 'test');
|
|
145
|
-
|
|
146
|
-
next();
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
168
|
```
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
@Service()
|
|
159
|
-
export class HelloService {
|
|
160
|
-
private _foo = 'bar';
|
|
161
|
-
|
|
162
|
-
public get foo(): string {
|
|
163
|
-
return this._foo;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
public set foo(value: string) {
|
|
167
|
-
this._foo = value;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
169
|
+
lib/
|
|
170
|
+
├── adapter/ # HTTP adapter implementations
|
|
171
|
+
├── server/ # Core server functionality
|
|
172
|
+
├── ioc/ # Dependency injection container
|
|
173
|
+
├── utils/ # Utility functions
|
|
174
|
+
├── test/ # Test utilities
|
|
175
|
+
└── logger/ # Logging system
|
|
170
176
|
```
|
|
171
177
|
|
|
172
|
-
### Controller
|
|
173
|
-
|
|
174
|
-
Controller with a GET route that uses the middleware and service.
|
|
175
|
-
|
|
176
|
-
```typescript
|
|
177
|
-
// src/controller/TestController.ts
|
|
178
|
-
import { type Context, Controller, Get, Inject } from '@asenajs/asena';
|
|
179
|
-
import { HelloService } from '../service/HelloService.ts';
|
|
180
|
-
import { TestMiddleware } from '../middleware/TestMiddleware.ts';
|
|
181
|
-
|
|
182
|
-
@Controller('/v1')
|
|
183
|
-
export class TestController {
|
|
184
|
-
@Inject(HelloService)
|
|
185
|
-
private helloService: HelloService;
|
|
186
|
-
|
|
187
|
-
@Get('foo')
|
|
188
|
-
public async getFoo(context: Context) {
|
|
189
|
-
return context.send(this.helloService.foo);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
@Get({ path: 'world', middlewares: [TestMiddleware] })
|
|
193
|
-
public async getHello(context: Context) {
|
|
194
|
-
const testValue: string = context.getValue('testValue');
|
|
195
|
-
|
|
196
|
-
return context.send(testValue);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
### Index
|
|
202
|
-
|
|
203
|
-
The main file that starts the server.
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
// src/index.ts
|
|
207
|
-
import { AsenaServer, createHonoAdapter } from '@asenajs/asena';
|
|
208
|
-
import { DefaultLogger } from '@asenajs/asena/logger';
|
|
209
|
-
|
|
210
|
-
const [adapter, serverLogger] = createHonoAdapter(new DefaultLogger());
|
|
211
|
-
await new AsenaServer(adapter, serverLogger).port(3000).start(true);
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
then run
|
|
215
|
-
|
|
216
|
-
```bash
|
|
217
|
-
asena dev start
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
You should see the following output:
|
|
221
|
-
|
|
222
|
-
```text
|
|
223
|
-
|
|
224
|
-
Build completed successfully.
|
|
225
|
-
2024-11-19 17:58:35 [info]:
|
|
226
|
-
___ _____ ______ _ __ ___
|
|
227
|
-
/ | / ___/ / ____// | / // |
|
|
228
|
-
/ /| | \__ \ / __/ / |/ // /| |
|
|
229
|
-
/ ___ | ___/ // /___ / /| // ___ |
|
|
230
|
-
/_/ |_|/____//_____//_/ |_//_/ |_|
|
|
231
|
-
|
|
232
|
-
2024-11-19 17:58:35 [info]: IoC initialized
|
|
233
|
-
2024-11-19 17:58:35 [info]: No server services found
|
|
234
|
-
2024-11-19 17:58:35 [info]: Controller: V1 found
|
|
235
|
-
2024-11-19 17:58:35 [info]: Successfully registered GET route for PATH: /v1/foo
|
|
236
|
-
2024-11-19 17:58:35 [info]: Successfully registered GET route for PATH: /v1/world
|
|
237
|
-
2024-11-19 17:58:35 [info]: No websockets found
|
|
238
|
-
2024-11-19 17:58:35 [info]: Server started on port 3000
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
and you see the result on your browser [http://localhost:3000/v1/foo](http://localhost:3000/v1/foo) with "bar" message.
|
|
242
|
-
|
|
243
|
-
`Note`: For more example, you can check this project [Example](https://github.com/LibirSoft/AsenaExample).
|
|
244
|
-
|
|
245
178
|
## Core Concepts
|
|
246
179
|
|
|
247
180
|
- **Controllers**: Handle incoming requests using decorators
|
|
248
181
|
- **Services**: Business logic containers that can be injected
|
|
249
|
-
- **ServerSrvices**: Server-wide services that can be injected (e.g. Database)
|
|
250
182
|
- **Middleware**: Request/Response interceptors
|
|
251
|
-
- **
|
|
252
|
-
- **
|
|
253
|
-
- **Validators**: Request validation system
|
|
254
|
-
|
|
255
|
-
## Architecture
|
|
256
|
-
|
|
257
|
-
Asena follows a modular architecture with:
|
|
258
|
-
|
|
259
|
-
- IoC Container for dependency management
|
|
260
|
-
- Adapter pattern for framework integration
|
|
261
|
-
- Decorator-based routing system
|
|
262
|
-
- Middleware pipeline
|
|
263
|
-
- WebSocket integration
|
|
264
|
-
- Context management
|
|
183
|
+
- **WebSocket**: Built-in WebSocket support
|
|
184
|
+
- **HTTP Status**: Standard HTTP status codes and utilities
|
|
265
185
|
|
|
266
186
|
## Performance
|
|
267
187
|
|
|
268
|
-
Built on Bun runtime
|
|
188
|
+
Built on Bun runtime, Asena provides:
|
|
269
189
|
|
|
270
190
|
- Fast startup time
|
|
271
191
|
- Low memory footprint
|
|
272
192
|
- Quick request processing
|
|
273
193
|
- Efficient WebSocket handling
|
|
274
194
|
|
|
275
|
-
|
|
195
|
+
Here is the benchmark result of Asena with Hono adapter (Basic hello world example) in every test we used bun to run
|
|
276
196
|
the project:
|
|
277
197
|
|
|
278
198
|
### Performance Comparison (Fastest to Slowest)
|
|
@@ -280,7 +200,7 @@ the project:
|
|
|
280
200
|
| Framework | Requests/sec | Latency (avg) | Transfer/sec |
|
|
281
201
|
| ------------------------------------ | ------------ | ------------- | ------------ |
|
|
282
202
|
| Hono | 147,031.08 | 2.69ms | 18.09MB |
|
|
283
|
-
| Asena
|
|
203
|
+
| Asena + Hono-adapter | 137,148.80 | 2.89ms | 16.74MB |
|
|
284
204
|
| NestJS (Bun + Fastify) | 81,652.05 | 6.01ms | 13.78MB |
|
|
285
205
|
| NestJS (Bun) | 64,435.83 | 6.14ms | 11.80MB |
|
|
286
206
|
| NestJS (Bun + kiyasov/platform-hono) | 45,082.27 | 8.79ms | 5.55MB |
|
|
@@ -295,3 +215,15 @@ the project:
|
|
|
295
215
|
> - Running on same hardware
|
|
296
216
|
|
|
297
217
|
_Note: Lower latency and higher requests/sec indicate better performance_
|
|
218
|
+
|
|
219
|
+
## Contributing
|
|
220
|
+
|
|
221
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
222
|
+
|
|
223
|
+
## License
|
|
224
|
+
|
|
225
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
226
|
+
|
|
227
|
+
## Support
|
|
228
|
+
|
|
229
|
+
If you encounter any issues or have questions, please open an issue on the [GitHub repository](https://github.com/AsenaJs/Asena/issues).
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { AsenaServer
|
|
1
|
+
export { AsenaServer } from './lib/server';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { AsenaServer
|
|
1
|
+
export { AsenaServer } from './lib/server';
|
|
2
2
|
//# 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,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { AsenaServeOptions, ErrorHandler, RouteParams } from './types';
|
|
2
|
-
import type { BaseMiddleware } from '../server/web/types';
|
|
1
|
+
import type { AsenaServeOptions, BaseMiddleware, ErrorHandler, RouteParams } from './types';
|
|
3
2
|
import type { Server } from 'bun';
|
|
4
3
|
import type { AsenaWebsocketAdapter } from './AsenaWebsocketAdapter';
|
|
5
4
|
import type { ServerLogger } from '../logger';
|
|
@@ -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":"AAMA;;;;;;;;;GASG;AACH,MAAM,OAAgB,YAAY;IAEhC;;OAEG;IACa,IAAI,CAAS;IAE7B;;OAEG;IACI,GAAG,CAAI;IAEd;;OAEG;IACI,gBAAgB,CAAM;IAE7B;;OAEG;IACO,IAAI,CAAS;IAEvB;;OAEG;IACO,MAAM,GAAiB,OAAO,CAAC;IAEzC;;;;OAIG;IACH,YAAsB,gBAAqB,EAAE,MAAqB;QAChE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YAErB,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;gBAClC,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;CA6CF"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { AsenaWebSocketService, WSOptions } from '../server/web/websocket';
|
|
2
2
|
import type { WebSocketHandler } from 'bun';
|
|
3
|
-
import type { WebsocketAdapterParams, WebSocketRegistry } from './types';
|
|
3
|
+
import type { BaseMiddleware, WebsocketAdapterParams, WebSocketRegistry } from './types';
|
|
4
4
|
import type { ServerLogger } from '../logger';
|
|
5
|
-
import type { BaseMiddleware } from '../server/web/types';
|
|
6
5
|
import type { AsenaContext } from './AsenaContext';
|
|
7
6
|
/**
|
|
8
7
|
* Abstract class that provides a base implementation for WebSocket adapters.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AsenaWebsocketAdapter.js","sourceRoot":"","sources":["../../../lib/adapter/AsenaWebsocketAdapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AsenaWebsocketAdapter.js","sourceRoot":"","sources":["../../../lib/adapter/AsenaWebsocketAdapter.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AACH,MAAM,OAAgB,qBAAqB;IAEzB,IAAI,CAAS;IAE7B;;;;;;;;OAQG;IACO,WAAW,CAAuB;IAE5C;;;OAGG;IACK,IAAI,CAAI;IAEhB;;;OAGG;IACK,UAAU,CAAmB;IAErC;;;OAGG;IACK,OAAO,GAAiB,OAAO,CAAC;IAExC;;;OAGG;IACH,YAAsB,MAAkC;QACtD,IAAI,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,MAAM,EAAE,MAAM,CAAC;IAChC,CAAC;IAwBD,kDAAkD;IAElD;;OAEG;IACH,IAAW,GAAG;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,IAAW,GAAG,CAAC,KAAQ;QACrB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,IAAc,UAAU;QACtB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,IAAc,UAAU,CAAC,KAA2B;QAClD,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,6 +1,6 @@
|
|
|
1
|
-
import type { HttpMethod } from '
|
|
2
|
-
import type { AsenaContext } from '
|
|
3
|
-
import type { MiddlewareClass, ValidatorClass } from "
|
|
1
|
+
import type { HttpMethod } from '../../server/web/types';
|
|
2
|
+
import type { AsenaContext } from '../index';
|
|
3
|
+
import type { MiddlewareClass, ValidatorClass } from "../../server/web/middleware";
|
|
4
4
|
/**
|
|
5
5
|
* Interface representing a route configuration.
|
|
6
6
|
*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiParams.js","sourceRoot":"","sources":["../../../../lib/adapter/types/ApiParams.ts"],"names":[],"mappings":""}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Class } from '../../types';
|
|
1
|
+
import type { Class } from '../../server/types';
|
|
2
2
|
import type { ApiParams } from './ApiParams';
|
|
3
|
-
import type { AsenaContext, AsenaMiddlewareHandler } from '
|
|
3
|
+
import type { AsenaContext, AsenaMiddlewareHandler } from '../index';
|
|
4
4
|
/**
|
|
5
5
|
* Interface representing a base middleware.
|
|
6
6
|
*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseMiddleware.js","sourceRoot":"","sources":["../../../../lib/adapter/types/BaseMiddleware.ts"],"names":[],"mappings":"AAiEA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { HttpMethod } from '../../server/web/
|
|
2
|
-
import type { BaseMiddleware, BaseValidator } from '../../server/web/types';
|
|
1
|
+
import type { HttpMethod } from '../../server/web/types';
|
|
3
2
|
import type { AsenaHandler } from './AsenaHandler';
|
|
4
3
|
import type { AsenaContext } from '../AsenaContext';
|
|
4
|
+
import type { BaseMiddleware, BaseValidator } from "./BaseMiddleware";
|
|
5
5
|
export interface RouteParams<C extends AsenaContext<any, any>, VS> {
|
|
6
6
|
method: HttpMethod;
|
|
7
7
|
path: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AsenaWebSocketService } from '../../server/web/websocket';
|
|
2
|
-
import type { BaseMiddleware } from '../../server/web/types';
|
|
3
2
|
import type { AsenaContext } from '../AsenaContext';
|
|
3
|
+
import type { BaseMiddleware } from "./BaseMiddleware";
|
|
4
4
|
export interface WebsocketServiceRegistry<C extends AsenaContext<any, any>> {
|
|
5
5
|
socket: AsenaWebSocketService<any>;
|
|
6
6
|
middlewares: BaseMiddleware<C>[];
|
|
@@ -6,4 +6,7 @@ export * from './SendOptions';
|
|
|
6
6
|
export * from './WebsocketAdapterParams';
|
|
7
7
|
export * from './WebSocketRegistry';
|
|
8
8
|
export * from './ServeOptions';
|
|
9
|
+
export * from "./BaseMiddleware";
|
|
10
|
+
export * from "./ApiParams";
|
|
11
|
+
export * from "./AsenaHandler";
|
|
9
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,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
|
|
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,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentConstants } from './constants';
|
|
2
|
-
import { getTypedMetadata } from '../utils/typedMetadata';
|
|
2
|
+
import { getOwnTypedMetadata, getTypedMetadata } from '../utils/typedMetadata';
|
|
3
3
|
export class Container {
|
|
4
4
|
_services = {};
|
|
5
5
|
constructor(services) {
|
|
@@ -85,54 +85,90 @@ export class Container {
|
|
|
85
85
|
return newInstance;
|
|
86
86
|
}
|
|
87
87
|
async executePostConstructs(newInstance, Class) {
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
const prototypeChain = this.getPrototypeChain(Class);
|
|
89
|
+
for (const classInChain of prototypeChain.reverse()) {
|
|
90
|
+
const postConstructs = getOwnTypedMetadata(ComponentConstants.PostConstructKey, classInChain);
|
|
91
|
+
if (!postConstructs) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
for (const postConstruct of postConstructs) {
|
|
95
|
+
try {
|
|
96
|
+
await newInstance[postConstruct]();
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.log("Error in post construct, exiting process");
|
|
100
|
+
console.error(error);
|
|
101
|
+
// then exit the process
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
94
105
|
}
|
|
95
106
|
}
|
|
96
107
|
async injectStrategies(newInstance, Class) {
|
|
97
|
-
const
|
|
98
|
-
for (const
|
|
99
|
-
|
|
108
|
+
const prototypeChain = this.getPrototypeChain(Class);
|
|
109
|
+
for (const classInChain of prototypeChain.reverse()) {
|
|
110
|
+
const strategyList = getOwnTypedMetadata(ComponentConstants.StrategyKey, classInChain);
|
|
111
|
+
if (!strategyList)
|
|
100
112
|
continue;
|
|
113
|
+
for (const [propertyKey, interfaceName] of Object.entries(strategyList)) {
|
|
114
|
+
if (!interfaceName) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (typeof interfaceName !== 'string') {
|
|
118
|
+
throw new Error('interfaceName must be a string');
|
|
119
|
+
}
|
|
120
|
+
if (Object.getOwnPropertyDescriptor(newInstance, propertyKey))
|
|
121
|
+
continue;
|
|
122
|
+
const strategy = await this.resolveStrategy(interfaceName);
|
|
123
|
+
const expression = getOwnTypedMetadata(ComponentConstants.ExpressionKey, classInChain);
|
|
124
|
+
Object.defineProperty(newInstance, propertyKey, {
|
|
125
|
+
get() {
|
|
126
|
+
return expression && expression[propertyKey] ? strategy.map((s) => expression[propertyKey](s)) : strategy;
|
|
127
|
+
},
|
|
128
|
+
enumerable: true,
|
|
129
|
+
configurable: true,
|
|
130
|
+
});
|
|
101
131
|
}
|
|
102
|
-
if (typeof interfaceName !== 'string') {
|
|
103
|
-
throw new Error('interfaceName must be a string');
|
|
104
|
-
}
|
|
105
|
-
const strategy = await this.resolveStrategy(interfaceName);
|
|
106
|
-
const expression = getTypedMetadata(ComponentConstants.ExpressionKey, Class);
|
|
107
|
-
Object.defineProperty(newInstance, propertyKey, {
|
|
108
|
-
get() {
|
|
109
|
-
return expression && expression[propertyKey] ? strategy.map((s) => expression[propertyKey](s)) : strategy;
|
|
110
|
-
},
|
|
111
|
-
enumerable: true,
|
|
112
|
-
configurable: true,
|
|
113
|
-
});
|
|
114
132
|
}
|
|
115
133
|
}
|
|
116
134
|
async injectDependencies(newInstance, Class) {
|
|
117
|
-
const
|
|
118
|
-
for (const
|
|
119
|
-
const
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
135
|
+
const prototypeChain = this.getPrototypeChain(Class);
|
|
136
|
+
for (const classInChain of prototypeChain.reverse()) {
|
|
137
|
+
const deps = getOwnTypedMetadata(ComponentConstants.DependencyKey, classInChain);
|
|
138
|
+
if (!deps)
|
|
139
|
+
continue;
|
|
140
|
+
for (const [k, name] of Object.entries(deps)) {
|
|
141
|
+
if (Object.getOwnPropertyDescriptor(newInstance, k))
|
|
142
|
+
continue;
|
|
143
|
+
const instance = await this.resolve(name);
|
|
144
|
+
if (instance === null) {
|
|
145
|
+
throw new Error('Instance cant be null ' + name);
|
|
146
|
+
}
|
|
147
|
+
if (Array.isArray(instance) && instance.length < 1) {
|
|
148
|
+
throw new Error('instance error cannot be null');
|
|
149
|
+
}
|
|
150
|
+
const expression = getOwnTypedMetadata(ComponentConstants.ExpressionKey, classInChain);
|
|
151
|
+
Object.defineProperty(newInstance, k, {
|
|
152
|
+
get: () => {
|
|
153
|
+
return expression && expression[k] ? expression[k](instance) : instance;
|
|
154
|
+
},
|
|
155
|
+
enumerable: true,
|
|
156
|
+
configurable: true,
|
|
157
|
+
});
|
|
125
158
|
}
|
|
126
|
-
const expression = getTypedMetadata(ComponentConstants.ExpressionKey, Class);
|
|
127
|
-
Object.defineProperty(newInstance, k, {
|
|
128
|
-
get: () => {
|
|
129
|
-
return expression && expression[k] ? expression[k](instance) : instance;
|
|
130
|
-
},
|
|
131
|
-
enumerable: true,
|
|
132
|
-
configurable: true,
|
|
133
|
-
});
|
|
134
159
|
}
|
|
135
160
|
}
|
|
161
|
+
getPrototypeChain(Class) {
|
|
162
|
+
const chain = [];
|
|
163
|
+
let currentClass = Class;
|
|
164
|
+
while (currentClass &&
|
|
165
|
+
currentClass !== Object.prototype &&
|
|
166
|
+
!currentClass.toString().includes('[native code]')) {
|
|
167
|
+
chain.push(currentClass);
|
|
168
|
+
currentClass = Object.getPrototypeOf(currentClass);
|
|
169
|
+
}
|
|
170
|
+
return chain;
|
|
171
|
+
}
|
|
136
172
|
get services() {
|
|
137
173
|
return this._services;
|
|
138
174
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Container.js","sourceRoot":"","sources":["../../../lib/ioc/Container.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"Container.js","sourceRoot":"","sources":["../../../lib/ioc/Container.ts"],"names":[],"mappings":"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"}
|