|
1 | | -# Asena |
| 1 | +<p width="%100" align="center"> |
| 2 | + <img src="https://avatars.githubusercontent.com/u/179836938?s=200&v=4" width="150" align="center"/> |
| 3 | +</p> |
2 | 4 |
|
3 | | -A high-performance, NestJS-like IoC web framework built on Bun runtime with full dependency injection support. |
| 5 | +# Asena |
4 | 6 |
|
5 | | -## Documentation |
| 7 | +[](https://asena.sh) |
| 8 | +[](https://opensource.org/licenses/MIT) |
| 9 | +[](https://bun.sh) |
6 | 10 |
|
7 | | -For detailed documentation, visit [asena.sh](https://asena.sh). |
| 11 | +A high-performance IoC web framework for Bun runtime, bringing Spring Boot's automatic component discovery and field-based dependency injection to TypeScript. |
8 | 12 |
|
9 | | -Also check out [AsenaExample](https://github.com/LibirSoft/AsenaExample) for latest usage patterns. |
| 13 | +## Philosophy |
10 | 14 |
|
11 | | -## Key Features |
| 15 | +`Spring Boot` and `Quarkus` have established proven patterns for enterprise application development, but developers transitioning to TypeScript often find themselves reimplementing familiar concepts or adapting to unfamiliar architectures. `AsenaJS` addresses this gap by bringing automatic component discovery, field-based dependency injection to the `Bun` ecosystem. |
12 | 16 |
|
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 |
| 17 | +The framework eliminates boilerplate through automatic scanning of decorator-annotated classes, removing the need for explicit module declarations or manual wiring. Components marked with `@Controller`, `@Service`, or `@Repository` (via asena-drizzle package) are discovered and registered automatically, allowing developers to focus on business logic rather than configuration. This approach, combined with Bun's native performance characteristics, delivers both the familiar developer experience of Spring Boot and the speed expected from modern JavaScript runtimes. |
21 | 18 |
|
22 | | -## Quick Start |
| 19 | +`AsenaJS` is designed to make developers familiar with `Spring Boot` and `Quarkus` feel at home in the TypeScript ecosystem. As the framework evolves, we remain committed to this philosophy—bringing more proven patterns from the Java world while maintaining the performance advantages that `Bun` provides and flexiblity of Typescript. |
23 | 20 |
|
24 | | -### Using CLI (Recommended) |
25 | | - |
26 | | -```bash |
27 | | -bun add -D @asenajs/asena-cli |
28 | | -asena create my-project |
29 | | -cd my-project |
30 | | -asena dev start |
31 | | -``` |
| 21 | +## Documentation |
32 | 22 |
|
33 | | -### Manual Setup |
| 23 | +📚 **Full documentation:** [asena.sh](https://asena.sh) |
34 | 24 |
|
35 | | -Install dependencies: |
| 25 | +For complete guides, API reference, and advanced topics, visit our documentation site. |
36 | 26 |
|
37 | | -```bash |
38 | | -bun add @asenajs/asena @asenajs/hono-adapter @asenajs/asena-logger |
39 | | -bun add -D @asenajs/asena-cli |
40 | | -``` |
| 27 | +**Example Project:** [AsenaExample](https://github.com/LibirSoft/AsenaExample) - See latest usage patterns and best practices. |
41 | 28 |
|
42 | | -Configure TypeScript (`tsconfig.json`): |
43 | | - |
44 | | -```json |
45 | | -{ |
46 | | - "compilerOptions": { |
47 | | - "target": "ESNext", |
48 | | - "module": "ESNext", |
49 | | - "moduleResolution": "bundler", |
50 | | - "experimentalDecorators": true, |
51 | | - "emitDecoratorMetadata": true, |
52 | | - "strict": true, |
53 | | - "skipLibCheck": true |
54 | | - } |
55 | | -} |
56 | | -``` |
57 | | - |
58 | | -Initialize config: |
| 29 | +## Quick Start |
59 | 30 |
|
60 | 31 | ```bash |
61 | | -asena init |
62 | | -``` |
63 | | - |
64 | | -Create your server (`src/index.ts`): |
65 | | - |
66 | | -```typescript |
67 | | -import { AsenaServerFactory } from '@asenajs/asena'; |
68 | | -import { createHonoAdapter } from '@asenajs/hono-adapter'; |
69 | | -import { logger } from './logger'; |
70 | | - |
71 | | -const [adapter, asenaLogger] = createHonoAdapter(logger); |
72 | | - |
73 | | -const server = await AsenaServerFactory.create({ |
74 | | - adapter, |
75 | | - logger: asenaLogger, |
76 | | - port: 3000 |
77 | | -}); |
78 | | - |
79 | | -await server.start(); |
80 | | -``` |
81 | | - |
82 | | -Create a controller (`src/controllers/HelloController.ts`): |
83 | | - |
84 | | -```typescript |
85 | | -import { Controller } from '@asenajs/asena/server'; |
86 | | -import { Get } from '@asenajs/asena/web'; |
87 | | -import type { Context } from '@asenajs/hono-adapter'; |
88 | | - |
89 | | -@Controller('/hello') |
90 | | -export class HelloController { |
91 | | - @Get('/world') |
92 | | - async getHello(context: Context) { |
93 | | - return context.send('Hello World'); |
94 | | - } |
95 | | -} |
96 | | -``` |
97 | | - |
98 | | -## Core Concepts |
99 | | - |
100 | | -### Controllers |
101 | | - |
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 | | -} |
119 | | -``` |
120 | | - |
121 | | -### Services |
122 | | - |
123 | | -Business logic with dependency injection: |
124 | | - |
125 | | -```typescript |
126 | | -@Service() |
127 | | -export class UserService { |
128 | | - async findUser(id: string) { |
129 | | - // Your business logic |
130 | | - return { id, name: 'John' }; |
131 | | - } |
132 | | -} |
133 | | - |
134 | | -@Controller('/users') |
135 | | -export class UserController { |
136 | | - @Inject(UserService) |
137 | | - private userService: UserService; |
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 | | -} |
145 | | -``` |
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) { } |
187 | | -``` |
188 | | - |
189 | | -### WebSocket |
190 | | - |
191 | | -Built-in WebSocket support: |
192 | | - |
193 | | -```typescript |
194 | | -@WebSocket('/chat') |
195 | | -export class ChatSocket extends AsenaWebSocketService { |
196 | | - onOpen(ws: Socket) { |
197 | | - ws.send('Welcome!'); |
198 | | - } |
199 | | - |
200 | | - onMessage(ws: Socket, message: string) { |
201 | | - ws.send(`Echo: ${message}`); |
202 | | - } |
203 | | -} |
204 | | -``` |
205 | | - |
206 | | -## CLI Commands |
| 32 | +# Create new project |
| 33 | +bun add -g @asenajs/asena-cli |
| 34 | +asena create my-project --adapter=hono --logger --eslint --prettier |
| 35 | +cd my-project |
207 | 36 |
|
208 | | -```bash |
209 | | -asena create # Create new project |
210 | | -asena init # Initialize config |
211 | | -asena dev start # Development mode |
212 | | -asena build # Production build |
| 37 | +# Start development |
| 38 | +asena dev start |
213 | 39 | ``` |
214 | 40 |
|
215 | | -Full CLI documentation: [asena.sh/docs/cli](https://asena.sh/docs/cli/overview.html) |
| 41 | +Visit [asena.sh/docs/get-started](https://asena.sh/docs/get-started) for detailed setup instructions. |
216 | 42 |
|
217 | 43 | ## Performance |
218 | 44 |
|
219 | 45 | Built on Bun runtime for exceptional performance: |
220 | 46 |
|
221 | 47 | | Framework | Requests/sec | Latency (avg) | |
222 | 48 | |--------------------------|-----------------------|---------------| |
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 | |
| 49 | +| **Asena + Ergenecore** | **294,962.61** | **1.34ms** | |
| 50 | +| Hono | 266,476.83 | 1.49ms | |
| 51 | +| **Asena + Hono-adapter** | **233,182.35** | **1.70ms** | |
| 52 | +| NestJS (Bun) | 100,975.20 | 3.92ms | |
| 53 | +| NestJS (Node) | 88,083.22 | 5.33ms | |
228 | 54 |
|
229 | 55 | > Benchmark: 12 threads, 400 connections, 120s duration, Hello World endpoint |
230 | 56 |
|
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 | | -``` |
240 | | - |
241 | 57 | ## Contributing |
242 | 58 |
|
243 | | -Contributions welcome! Submit a Pull Request on [GitHub](https://github.com/AsenaJs/Asena). |
| 59 | +Contributions are welcome! Submit a Pull Request on [GitHub](https://github.com/AsenaJs/Asena). |
244 | 60 |
|
245 | 61 | ## License |
246 | 62 |
|
|
0 commit comments