@martel/calyx 0.1.0 → 1.0.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.
@@ -21,6 +21,11 @@ jobs:
21
21
  with:
22
22
  persist-credentials: false
23
23
 
24
+ - name: Setup Node
25
+ uses: actions/setup-node@v4
26
+ with:
27
+ node-version: 22
28
+
24
29
  - name: Setup Bun
25
30
  uses: oven-sh/setup-bun@v2
26
31
  with:
@@ -35,5 +40,4 @@ jobs:
35
40
  - name: Run semantic-release
36
41
  env:
37
42
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38
- NPM_TOKEN: 'OIDC' # Dummy token to bypass semantic-release check; npm CLI uses the OIDC id-token
39
- run: bunx semantic-release
43
+ run: npx semantic-release
package/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ # 1.0.0 (2026-07-01)
2
+
3
+
4
+ ### Features
5
+
6
+ * achieve full NestJS parity and compile request execution pipelines for performance ([ddc5b6b](https://github.com/bmartel/calyx/commit/ddc5b6bd24ff3c505b7a004c058f00535b1f2695))
package/README.md ADDED
@@ -0,0 +1,130 @@
1
+ # Calyx
2
+
3
+ Calyx is a high-performance, compile-ready, Bun-native TypeScript API framework modeled after the modular architecture and design patterns of **NestJS**.
4
+
5
+ It provides 100% conceptual and syntax compatibility, letting developers easily migrate NestJS applications to a native Bun runtime for **~2.5x higher throughput** and **3.5x lower latency**, with the option to compile the server directly into a single self-contained binary file.
6
+
7
+ ---
8
+
9
+ ## Key Features
10
+
11
+ * **⚡ Blazing Fast**: Engineered natively on `Bun.serve`, utilizing a fast radix routing engine and optimized request lifecycle executions.
12
+ * **ðŸ§Đ NestJS Decorators Compatibility**: Direct mappings of `@Module()`, `@Injectable()`, `@Controller()`, `@UseGuards()`, `@UseInterceptors()`, `@UsePipes()`, and `@UseFilters()`.
13
+ * **ðŸ“Ķ High Performance DI**: Fully featured Dependency Injection container with circular dependency protection, supporting custom (`useValue`/`useClass`/`useFactory`) and dynamic modules with **29x lower bootstrapping overhead**.
14
+ * **ðŸ›Ąïļ Complete Request Lifecycle**: Clean request pipelines with Guards, Interceptors, Pipe transforms (with metadata), and target exception Filters.
15
+ * **🚀 Binary Compilation**: Compiles down to a single standalone executable binary with zero external runtime dependencies using `bun build --compile`.
16
+
17
+ ---
18
+
19
+ ## Installation
20
+
21
+ Initialize your project and install Calyx with your package manager:
22
+
23
+ ```bash
24
+ bun add @martel/calyx reflect-metadata
25
+ ```
26
+
27
+ Ensure your `tsconfig.json` has legacy decorators enabled:
28
+
29
+ ```json
30
+ {
31
+ "compilerOptions": {
32
+ "experimentalDecorators": true,
33
+ "emitDecoratorMetadata": true
34
+ }
35
+ }
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Quick Start
41
+
42
+ ```typescript
43
+ import 'reflect-metadata';
44
+ import { Module, Injectable, Controller, Get, Query, UseGuards, CanActivate, ExecutionContext, VerdantFactory } from '@martel/calyx';
45
+
46
+ // 1. Define a Guard
47
+ @Injectable()
48
+ class AuthGuard implements CanActivate {
49
+ canActivate(context: ExecutionContext): boolean {
50
+ const req = context.switchToHttp().getRequest<Request>();
51
+ return req.headers.get('Authorization') === 'secret-token';
52
+ }
53
+ }
54
+
55
+ // 2. Define a Controller
56
+ @Controller('items')
57
+ class ItemsController {
58
+ @Get()
59
+ @UseGuards(AuthGuard)
60
+ getItems(@Query('limit') limit?: string) {
61
+ return { data: ['item1', 'item2'], limit: limit ? Number(limit) : 10 };
62
+ }
63
+ }
64
+
65
+ // 3. Define a Module
66
+ @Module({
67
+ controllers: [ItemsController],
68
+ })
69
+ class AppModule {}
70
+
71
+ // 4. Bootstrap Server
72
+ async function bootstrap() {
73
+ const app = await CalyxFactory.create(AppModule);
74
+ await app.listen(3000);
75
+ console.log('Calyx application is running on port 3000');
76
+ }
77
+ bootstrap();
78
+ ```
79
+
80
+ ---
81
+
82
+ ## Performance Comparison (Benchmarks)
83
+
84
+ Measured using process-isolated `autocannon` benchmarks (100 connections, 8s, no pipelining) comparing Calyx vs NestJS (Express adapter under Bun):
85
+
86
+ | Benchmark | Calyx (Bun Native) | NestJS (Express on Bun) | Speedup | Latency Improvement |
87
+ | :--- | :--- | :--- | :--- | :--- |
88
+ | **DI Bootstrapping** | **7.81 Ξs** | 227.56 Ξs | **~29x faster** | N/A |
89
+ | **Raw Route Throughput** | **59,408 req/sec** | 23,148 req/sec | **2.57x faster** | **3.5x lower** (1.10ms vs 3.88ms) |
90
+ | **Lifecycle Pipeline (Guards/Pipes)** | **25,152 req/sec** | 10,274 req/sec | **2.45x faster** | **2.8x lower** (3.25ms vs 9.28ms) |
91
+
92
+ ---
93
+
94
+ ## Comprehensive Documentation
95
+
96
+ For detailed guides, API reference, and examples, refer to the documentation in the repository:
97
+
98
+ * 📖 **[Dependency Injection & Module System](file:///e:/code/verdant/docs/dependency-injection.md)**: Custom providers, modular structures, and resolution visibility.
99
+ * 📖 **[Controllers & Routing](file:///e:/code/verdant/docs/controllers.md)**: HTTP request handlers, parameters, redirects, and manual response wrappers.
100
+ * 📖 **[Request Lifecycle Pipeline](file:///e:/code/verdant/docs/lifecycle.md)**: How Guards, Interceptors, Pipes, and Exception Filters interact.
101
+ * 📖 **[Migration & Standalone Binary Compilation Guide](file:///e:/code/verdant/docs/migration.md)**: A complete handbook on moving from NestJS to Calyx and compiling to a single executable.
102
+
103
+ ---
104
+
105
+ ## Commands
106
+
107
+ ### Run Unit Tests
108
+ ```bash
109
+ bun test
110
+ ```
111
+
112
+ ### Run Performance Benchmarks
113
+ ```bash
114
+ # DI container benchmark
115
+ bun benchmarks/di-benchmark.ts
116
+
117
+ # HTTP server benchmark (compares Calyx vs NestJS)
118
+ bun benchmarks/http-benchmark.ts
119
+ ```
120
+
121
+ ### Build Binary
122
+ ```bash
123
+ bun build --compile src/index.ts --outfile build/server
124
+ ```
125
+
126
+ ---
127
+
128
+ ## License
129
+
130
+ MIT
@@ -4,7 +4,7 @@ import { performance } from 'perf_hooks';
4
4
  import { Module as NestModule, Injectable as NestInjectable } from '@nestjs/common';
5
5
  import { NestFactory } from '@nestjs/core';
6
6
  // Import calyx
7
- import { Module as calyxModule, Injectable as calyxInjectable, calyxContainer } from '../src/index.ts';
7
+ import { Module as calyxModule, Injectable as calyxInjectable, CalyxContainer } from '../src/index.ts';
8
8
 
9
9
  // ----------------------------------------------------
10
10
  // Setup Dependency Tree classes
@@ -12,32 +12,32 @@ import { Module as calyxModule, Injectable as calyxInjectable, calyxContainer }
12
12
 
13
13
  // calyx classes
14
14
  @calyxInjectable()
15
- class calyxService5 {}
15
+ class CalyxService5 {}
16
16
 
17
17
  @calyxInjectable()
18
- class calyxService4 {
19
- constructor(public s5: calyxService5) {}
18
+ class CalyxService4 {
19
+ constructor(public s5: CalyxService5) {}
20
20
  }
21
21
 
22
22
  @calyxInjectable()
23
- class calyxService3 {
24
- constructor(public s4: calyxService4) {}
23
+ class CalyxService3 {
24
+ constructor(public s4: CalyxService4) {}
25
25
  }
26
26
 
27
27
  @calyxInjectable()
28
- class calyxService2 {
29
- constructor(public s3: calyxService3) {}
28
+ class CalyxService2 {
29
+ constructor(public s3: CalyxService3) {}
30
30
  }
31
31
 
32
32
  @calyxInjectable()
33
- class calyxService1 {
34
- constructor(public s2: calyxService2) {}
33
+ class CalyxService1 {
34
+ constructor(public s2: CalyxService2) {}
35
35
  }
36
36
 
37
37
  @calyxModule({
38
- providers: [calyxService1, calyxService2, calyxService3, calyxService4, calyxService5],
38
+ providers: [CalyxService1, CalyxService2, CalyxService3, CalyxService4, CalyxService5],
39
39
  })
40
- class calyxAppModule {}
40
+ class CalyxAppModule {}
41
41
 
42
42
  // NestJS classes
43
43
  @NestInjectable()
@@ -83,10 +83,10 @@ async function runBenchmark() {
83
83
  console.log(`Bootstrapping calyx container ${iterations} times...`);
84
84
  const calyxStart = performance.now();
85
85
  for (let i = 0; i < iterations; i++) {
86
- const container = new calyxContainer();
87
- container.bootstrap(calyxAppModule);
86
+ const container = new CalyxContainer();
87
+ container.bootstrap(CalyxAppModule);
88
88
  // Resolve one
89
- container.getGlobalOrAnyInstance(calyxService1);
89
+ container.getGlobalOrAnyInstance(CalyxService1);
90
90
  }
91
91
  const calyxEnd = performance.now();
92
92
  const calyxTime = calyxEnd - calyxStart;
@@ -12,7 +12,7 @@ import {
12
12
  CallHandler,
13
13
  PipeTransform,
14
14
  ExecutionContext,
15
- calyxFactory,
15
+ CalyxFactory,
16
16
  } from '../src/index.ts';
17
17
 
18
18
  class AuthGuard implements CanActivate {
@@ -50,7 +50,7 @@ class HelloController {
50
50
  class AppModule {}
51
51
 
52
52
  async function main() {
53
- const app = await calyxFactory.create(AppModule);
53
+ const app = await CalyxFactory.create(AppModule);
54
54
  await app.listen(4003);
55
55
  console.log('calyx lifecycle listening on 4003');
56
56
  }
@@ -1,5 +1,5 @@
1
1
  import 'reflect-metadata';
2
- import { Module, Controller, Get, calyxFactory } from '../src/index.ts';
2
+ import { Module, Controller, Get, CalyxFactory } from '../src/index.ts';
3
3
 
4
4
  @Controller('hello')
5
5
  class HelloController {
@@ -15,7 +15,7 @@ class HelloController {
15
15
  class AppModule {}
16
16
 
17
17
  async function main() {
18
- const app = await calyxFactory.create(AppModule);
18
+ const app = await CalyxFactory.create(AppModule);
19
19
  await app.listen(4001);
20
20
  console.log('calyx listening on 4001');
21
21
  }