@flight-framework/http 0.0.1 â 0.0.2
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 +19 -15
- package/dist/adapters/bun.d.ts +4 -4
- package/dist/adapters/bun.js.map +1 -1
- package/dist/adapters/deno.d.ts +4 -4
- package/dist/adapters/deno.js.map +1 -1
- package/dist/adapters/node.d.ts +4 -4
- package/dist/adapters/node.js.map +1 -1
- package/dist/index.d.ts +25 -9
- package/dist/index.js +152 -93
- package/dist/index.js.map +1 -1
- package/dist/{types-4GWmDi9X.d.ts â types-B3BnoXCG.d.ts} +7 -1
- package/package.json +56 -55
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
# @flight/http
|
|
1
|
+
# @flight-framework/http
|
|
2
2
|
|
|
3
3
|
Ultra-fast HTTP server for Flight Framework, built on Web Standards.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @flight/http
|
|
8
|
+
npm install @flight-framework/http
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
-
import { createServer } from '@flight/http';
|
|
15
|
-
import { serve } from '@flight/http/node';
|
|
14
|
+
import { createServer } from '@flight-framework/http';
|
|
15
|
+
import { serve } from '@flight-framework/http/node';
|
|
16
16
|
|
|
17
17
|
const app = createServer();
|
|
18
18
|
|
|
@@ -36,19 +36,19 @@ serve(app, { port: 3000 });
|
|
|
36
36
|
|
|
37
37
|
## Features
|
|
38
38
|
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
39
|
+
- **Ultra-fast** - Radix-tree based routing for maximum performance
|
|
40
|
+
- **Web Standards** - Uses native Request/Response APIs
|
|
41
|
+
- **Multi-runtime** - Works with Node.js, Bun, and Deno
|
|
42
|
+
- **Lightweight** - Minimal dependencies (~3kb core)
|
|
43
|
+
- **TypeScript** - Full type safety out of the box
|
|
44
44
|
|
|
45
45
|
## Runtime Adapters
|
|
46
46
|
|
|
47
47
|
### Node.js
|
|
48
48
|
|
|
49
49
|
```typescript
|
|
50
|
-
import { createServer } from '@flight/http';
|
|
51
|
-
import { serve } from '@flight/http/node';
|
|
50
|
+
import { createServer } from '@flight-framework/http';
|
|
51
|
+
import { serve } from '@flight-framework/http/node';
|
|
52
52
|
|
|
53
53
|
serve(app, { port: 3000 });
|
|
54
54
|
```
|
|
@@ -56,8 +56,8 @@ serve(app, { port: 3000 });
|
|
|
56
56
|
### Bun
|
|
57
57
|
|
|
58
58
|
```typescript
|
|
59
|
-
import { createServer } from '@flight/http';
|
|
60
|
-
import { serve } from '@flight/http/bun';
|
|
59
|
+
import { createServer } from '@flight-framework/http';
|
|
60
|
+
import { serve } from '@flight-framework/http/bun';
|
|
61
61
|
|
|
62
62
|
serve(app, { port: 3000 });
|
|
63
63
|
```
|
|
@@ -65,8 +65,8 @@ serve(app, { port: 3000 });
|
|
|
65
65
|
### Deno
|
|
66
66
|
|
|
67
67
|
```typescript
|
|
68
|
-
import { createServer } from '@flight/http';
|
|
69
|
-
import { serve } from '@flight/http/deno';
|
|
68
|
+
import { createServer } from '@flight-framework/http';
|
|
69
|
+
import { serve } from '@flight-framework/http/deno';
|
|
70
70
|
|
|
71
71
|
serve(app, { port: 3000 });
|
|
72
72
|
```
|
|
@@ -150,3 +150,7 @@ Set custom error handler.
|
|
|
150
150
|
### `app.fetch(request)`
|
|
151
151
|
|
|
152
152
|
Handle a Request and return a Response (Web Standard).
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT
|
package/dist/adapters/bun.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { E as Env, F as FlightHttpServer } from '../types-
|
|
1
|
+
import { E as Env, F as FlightHttpServer } from '../types-B3BnoXCG.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @flight/http - Bun Adapter
|
|
4
|
+
* @flight-framework/http - Bun Adapter
|
|
5
5
|
*
|
|
6
6
|
* Allows running Flight HTTP server on Bun runtime.
|
|
7
7
|
* Bun natively supports Web Standard Request/Response.
|
|
@@ -25,8 +25,8 @@ interface ServeOptions {
|
|
|
25
25
|
*
|
|
26
26
|
* @example
|
|
27
27
|
* ```typescript
|
|
28
|
-
* import { createServer } from '@flight/http';
|
|
29
|
-
* import { serve } from '@flight/http/bun';
|
|
28
|
+
* import { createServer } from '@flight-framework/http';
|
|
29
|
+
* import { serve } from '@flight-framework/http/bun';
|
|
30
30
|
*
|
|
31
31
|
* const app = createServer();
|
|
32
32
|
* app.get('/', (c) => c.json({ hello: 'world' }));
|
package/dist/adapters/bun.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/bun.ts"],"names":[],"mappings":";AAsDO,SAAS,KAAA,CACZ,GAAA,EACA,OAAA,GAAwB,EAAC,EAChB;AACT,EAAA,MAAM;AAAA,IACF,IAAA,GAAO,GAAA;AAAA,IACP,QAAA,GAAW,SAAA;AAAA,IACX;AAAA,GACJ,GAAI,OAAA;AAEJ,EAAA,MAAM,MAAA,GAAS,IAAI,KAAA,CAAM;AAAA,IACrB,IAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA,EAAO,CAAC,OAAA,KAAY,GAAA,CAAI,MAAM,OAAO;AAAA,GACxC,CAAA;AAED,EAAA,MAAM,OAAO,EAAE,IAAA,EAAM,OAAO,IAAA,EAAM,QAAA,EAAU,OAAO,QAAA,EAAS;AAE5D,EAAA,IAAI,QAAA,EAAU;AACV,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACjB,CAAA,MAAO;AACH,IAAA,OAAA,CAAQ,GAAA,CAAI;AAAA;AAAA;AAAA,oCAAA,EAGa,KAAK,IAAI,CAAA;AAAA,0BAAA,EACnB,IAAA,CAAK,QAAQ,CAAA,CAAA,EAAI,IAAA,CAAK,IAAI,CAAA;AAAA,CAChD,CAAA;AAAA,EACG;AAEA,EAAA,OAAO,MAAA;AACX","file":"bun.js","sourcesContent":["/**\r\n * @flight/http - Bun Adapter\r\n * \r\n * Allows running Flight HTTP server on Bun runtime.\r\n * Bun natively supports Web Standard Request/Response.\r\n */\r\n\r\nimport type { FlightHttpServer, Env } from '../types.js';\r\n\r\n// ============================================================================\r\n// Bun Server Types\r\n// ============================================================================\r\n\r\ninterface BunServeOptions {\r\n port?: number;\r\n hostname?: string;\r\n fetch: (request: Request) => Response | Promise<Response>;\r\n}\r\n\r\ninterface BunServer {\r\n stop: () => void;\r\n port: number;\r\n hostname: string;\r\n}\r\n\r\n// We don't import Bun types directly to avoid build issues\r\ndeclare const Bun: {\r\n serve: (options: BunServeOptions) => BunServer;\r\n};\r\n\r\n// ============================================================================\r\n// serve() Function\r\n// ============================================================================\r\n\r\nexport interface ServeOptions {\r\n port?: number;\r\n hostname?: string;\r\n onListen?: (info: { port: number; hostname: string }) => void;\r\n}\r\n\r\n/**\r\n * Start a Bun server with the Flight app\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight/http';\r\n * import { serve } from '@flight/http/bun';\r\n * \r\n * const app = createServer();\r\n * app.get('/', (c) => c.json({ hello: 'world' }));\r\n * \r\n * serve(app, { port: 3000 });\r\n * ```\r\n */\r\nexport function serve<E extends Env = Env>(\r\n app: FlightHttpServer<E>,\r\n options: ServeOptions = {}\r\n): BunServer {\r\n const {\r\n port = 3000,\r\n hostname = '0.0.0.0',\r\n onListen,\r\n } = options;\r\n\r\n const server = Bun.serve({\r\n port,\r\n hostname,\r\n fetch: (request) => app.fetch(request),\r\n });\r\n\r\n const info = { port: server.port, hostname: server.hostname };\r\n\r\n if (onListen) {\r\n onListen(info);\r\n } else {\r\n console.log(`\r\n âïļ Flight HTTP Server (Bun) running!\r\n \r\n â Local: http://localhost:${info.port}/\r\n â Network: http://${info.hostname}:${info.port}/\r\n`);\r\n }\r\n\r\n return server;\r\n}\r\n\r\n// Re-export useful types\r\nexport type { FlightHttpServer } from '../types.js';\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/bun.ts"],"names":[],"mappings":";AAsDO,SAAS,KAAA,CACZ,GAAA,EACA,OAAA,GAAwB,EAAC,EAChB;AACT,EAAA,MAAM;AAAA,IACF,IAAA,GAAO,GAAA;AAAA,IACP,QAAA,GAAW,SAAA;AAAA,IACX;AAAA,GACJ,GAAI,OAAA;AAEJ,EAAA,MAAM,MAAA,GAAS,IAAI,KAAA,CAAM;AAAA,IACrB,IAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA,EAAO,CAAC,OAAA,KAAY,GAAA,CAAI,MAAM,OAAO;AAAA,GACxC,CAAA;AAED,EAAA,MAAM,OAAO,EAAE,IAAA,EAAM,OAAO,IAAA,EAAM,QAAA,EAAU,OAAO,QAAA,EAAS;AAE5D,EAAA,IAAI,QAAA,EAAU;AACV,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACjB,CAAA,MAAO;AACH,IAAA,OAAA,CAAQ,GAAA,CAAI;AAAA;AAAA;AAAA,oCAAA,EAGa,KAAK,IAAI,CAAA;AAAA,0BAAA,EACnB,IAAA,CAAK,QAAQ,CAAA,CAAA,EAAI,IAAA,CAAK,IAAI,CAAA;AAAA,CAChD,CAAA;AAAA,EACG;AAEA,EAAA,OAAO,MAAA;AACX","file":"bun.js","sourcesContent":["/**\r\n * @flight-framework/http - Bun Adapter\r\n * \r\n * Allows running Flight HTTP server on Bun runtime.\r\n * Bun natively supports Web Standard Request/Response.\r\n */\r\n\r\nimport type { FlightHttpServer, Env } from '../types.js';\r\n\r\n// ============================================================================\r\n// Bun Server Types\r\n// ============================================================================\r\n\r\ninterface BunServeOptions {\r\n port?: number;\r\n hostname?: string;\r\n fetch: (request: Request) => Response | Promise<Response>;\r\n}\r\n\r\ninterface BunServer {\r\n stop: () => void;\r\n port: number;\r\n hostname: string;\r\n}\r\n\r\n// We don't import Bun types directly to avoid build issues\r\ndeclare const Bun: {\r\n serve: (options: BunServeOptions) => BunServer;\r\n};\r\n\r\n// ============================================================================\r\n// serve() Function\r\n// ============================================================================\r\n\r\nexport interface ServeOptions {\r\n port?: number;\r\n hostname?: string;\r\n onListen?: (info: { port: number; hostname: string }) => void;\r\n}\r\n\r\n/**\r\n * Start a Bun server with the Flight app\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight-framework/http';\r\n * import { serve } from '@flight-framework/http/bun';\r\n * \r\n * const app = createServer();\r\n * app.get('/', (c) => c.json({ hello: 'world' }));\r\n * \r\n * serve(app, { port: 3000 });\r\n * ```\r\n */\r\nexport function serve<E extends Env = Env>(\r\n app: FlightHttpServer<E>,\r\n options: ServeOptions = {}\r\n): BunServer {\r\n const {\r\n port = 3000,\r\n hostname = '0.0.0.0',\r\n onListen,\r\n } = options;\r\n\r\n const server = Bun.serve({\r\n port,\r\n hostname,\r\n fetch: (request) => app.fetch(request),\r\n });\r\n\r\n const info = { port: server.port, hostname: server.hostname };\r\n\r\n if (onListen) {\r\n onListen(info);\r\n } else {\r\n console.log(`\r\n âïļ Flight HTTP Server (Bun) running!\r\n \r\n â Local: http://localhost:${info.port}/\r\n â Network: http://${info.hostname}:${info.port}/\r\n`);\r\n }\r\n\r\n return server;\r\n}\r\n\r\n// Re-export useful types\r\nexport type { FlightHttpServer } from '../types.js';\r\n"]}
|
package/dist/adapters/deno.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { E as Env, F as FlightHttpServer } from '../types-
|
|
1
|
+
import { E as Env, F as FlightHttpServer } from '../types-B3BnoXCG.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @flight/http - Deno Adapter
|
|
4
|
+
* @flight-framework/http - Deno Adapter
|
|
5
5
|
*
|
|
6
6
|
* Allows running Flight HTTP server on Deno runtime.
|
|
7
7
|
* Deno natively supports Web Standard Request/Response.
|
|
@@ -20,8 +20,8 @@ interface ServeOptions {
|
|
|
20
20
|
*
|
|
21
21
|
* @example
|
|
22
22
|
* ```typescript
|
|
23
|
-
* import { createServer } from '@flight/http';
|
|
24
|
-
* import { serve } from '@flight/http/deno';
|
|
23
|
+
* import { createServer } from '@flight-framework/http';
|
|
24
|
+
* import { serve } from '@flight-framework/http/deno';
|
|
25
25
|
*
|
|
26
26
|
* const app = createServer();
|
|
27
27
|
* app.get('/', (c) => c.json({ hello: 'world' }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/deno.ts"],"names":[],"mappings":";AAmDO,SAAS,KAAA,CACZ,GAAA,EACA,OAAA,GAAwB,EAAC,EACQ;AACjC,EAAA,MAAM;AAAA,IACF,IAAA,GAAO,GAAA;AAAA,IACP,QAAA,GAAW,SAAA;AAAA,IACX;AAAA,GACJ,GAAI,OAAA;AAEJ,EAAA,MAAM,SAAS,IAAA,CAAK,KAAA;AAAA,IAChB,CAAC,OAAA,KAAY,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA;AAAA,IAC9B;AAAA,MACI,IAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA,EAAU,QAAA,GACJ,CAAC,MAAA,KAAW,SAAS,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,UAAU,MAAA,CAAO,QAAA,EAAU,CAAA,GACrE,CAAC,MAAA,KAAW;AACV,QAAA,OAAA,CAAQ,GAAA,CAAI;AAAA;AAAA;AAAA,oCAAA,EAGC,OAAO,IAAI,CAAA;AAAA,0BAAA,EACrB,MAAA,CAAO,QAAQ,CAAA,CAAA,EAAI,MAAA,CAAO,IAAI,CAAA;AAAA,CACpD,CAAA;AAAA,MACe;AAAA;AACR,GACJ;AAEA,EAAA,OAAO,MAAA;AACX","file":"deno.js","sourcesContent":["/**\r\n * @flight/http - Deno Adapter\r\n * \r\n * Allows running Flight HTTP server on Deno runtime.\r\n * Deno natively supports Web Standard Request/Response.\r\n */\r\n\r\nimport type { FlightHttpServer, Env } from '../types.js';\r\n\r\n// ============================================================================\r\n// Deno Server Types\r\n// ============================================================================\r\n\r\ninterface DenoServeOptions {\r\n port?: number;\r\n hostname?: string;\r\n onListen?: (params: { hostname: string; port: number }) => void;\r\n}\r\n\r\n// We don't import Deno types directly to avoid build issues\r\ndeclare const Deno: {\r\n serve: (\r\n handler: (request: Request) => Response | Promise<Response>,\r\n options?: DenoServeOptions\r\n ) => { shutdown: () => Promise<void> };\r\n};\r\n\r\n// ============================================================================\r\n// serve() Function\r\n// ============================================================================\r\n\r\nexport interface ServeOptions {\r\n port?: number;\r\n hostname?: string;\r\n onListen?: (info: { port: number; hostname: string }) => void;\r\n}\r\n\r\n/**\r\n * Start a Deno server with the Flight app\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight/http';\r\n * import { serve } from '@flight/http/deno';\r\n * \r\n * const app = createServer();\r\n * app.get('/', (c) => c.json({ hello: 'world' }));\r\n * \r\n * serve(app, { port: 3000 });\r\n * ```\r\n */\r\nexport function serve<E extends Env = Env>(\r\n app: FlightHttpServer<E>,\r\n options: ServeOptions = {}\r\n): { shutdown: () => Promise<void> } {\r\n const {\r\n port = 3000,\r\n hostname = '0.0.0.0',\r\n onListen,\r\n } = options;\r\n\r\n const server = Deno.serve(\r\n (request) => app.fetch(request),\r\n {\r\n port,\r\n hostname,\r\n onListen: onListen\r\n ? (params) => onListen({ port: params.port, hostname: params.hostname })\r\n : (params) => {\r\n console.log(`\r\n âïļ Flight HTTP Server (Deno) running!\r\n \r\n â Local: http://localhost:${params.port}/\r\n â Network: http://${params.hostname}:${params.port}/\r\n`);\r\n },\r\n }\r\n );\r\n\r\n return server;\r\n}\r\n\r\n// Re-export useful types\r\nexport type { FlightHttpServer } from '../types.js';\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/deno.ts"],"names":[],"mappings":";AAmDO,SAAS,KAAA,CACZ,GAAA,EACA,OAAA,GAAwB,EAAC,EACQ;AACjC,EAAA,MAAM;AAAA,IACF,IAAA,GAAO,GAAA;AAAA,IACP,QAAA,GAAW,SAAA;AAAA,IACX;AAAA,GACJ,GAAI,OAAA;AAEJ,EAAA,MAAM,SAAS,IAAA,CAAK,KAAA;AAAA,IAChB,CAAC,OAAA,KAAY,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA;AAAA,IAC9B;AAAA,MACI,IAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA,EAAU,QAAA,GACJ,CAAC,MAAA,KAAW,SAAS,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,UAAU,MAAA,CAAO,QAAA,EAAU,CAAA,GACrE,CAAC,MAAA,KAAW;AACV,QAAA,OAAA,CAAQ,GAAA,CAAI;AAAA;AAAA;AAAA,oCAAA,EAGC,OAAO,IAAI,CAAA;AAAA,0BAAA,EACrB,MAAA,CAAO,QAAQ,CAAA,CAAA,EAAI,MAAA,CAAO,IAAI,CAAA;AAAA,CACpD,CAAA;AAAA,MACe;AAAA;AACR,GACJ;AAEA,EAAA,OAAO,MAAA;AACX","file":"deno.js","sourcesContent":["/**\r\n * @flight-framework/http - Deno Adapter\r\n * \r\n * Allows running Flight HTTP server on Deno runtime.\r\n * Deno natively supports Web Standard Request/Response.\r\n */\r\n\r\nimport type { FlightHttpServer, Env } from '../types.js';\r\n\r\n// ============================================================================\r\n// Deno Server Types\r\n// ============================================================================\r\n\r\ninterface DenoServeOptions {\r\n port?: number;\r\n hostname?: string;\r\n onListen?: (params: { hostname: string; port: number }) => void;\r\n}\r\n\r\n// We don't import Deno types directly to avoid build issues\r\ndeclare const Deno: {\r\n serve: (\r\n handler: (request: Request) => Response | Promise<Response>,\r\n options?: DenoServeOptions\r\n ) => { shutdown: () => Promise<void> };\r\n};\r\n\r\n// ============================================================================\r\n// serve() Function\r\n// ============================================================================\r\n\r\nexport interface ServeOptions {\r\n port?: number;\r\n hostname?: string;\r\n onListen?: (info: { port: number; hostname: string }) => void;\r\n}\r\n\r\n/**\r\n * Start a Deno server with the Flight app\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight-framework/http';\r\n * import { serve } from '@flight-framework/http/deno';\r\n * \r\n * const app = createServer();\r\n * app.get('/', (c) => c.json({ hello: 'world' }));\r\n * \r\n * serve(app, { port: 3000 });\r\n * ```\r\n */\r\nexport function serve<E extends Env = Env>(\r\n app: FlightHttpServer<E>,\r\n options: ServeOptions = {}\r\n): { shutdown: () => Promise<void> } {\r\n const {\r\n port = 3000,\r\n hostname = '0.0.0.0',\r\n onListen,\r\n } = options;\r\n\r\n const server = Deno.serve(\r\n (request) => app.fetch(request),\r\n {\r\n port,\r\n hostname,\r\n onListen: onListen\r\n ? (params) => onListen({ port: params.port, hostname: params.hostname })\r\n : (params) => {\r\n console.log(`\r\n âïļ Flight HTTP Server (Deno) running!\r\n \r\n â Local: http://localhost:${params.port}/\r\n â Network: http://${params.hostname}:${params.port}/\r\n`);\r\n },\r\n }\r\n );\r\n\r\n return server;\r\n}\r\n\r\n// Re-export useful types\r\nexport type { FlightHttpServer } from '../types.js';\r\n"]}
|
package/dist/adapters/node.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createServer } from 'node:http';
|
|
2
|
-
import { E as Env, F as FlightHttpServer } from '../types-
|
|
2
|
+
import { E as Env, F as FlightHttpServer } from '../types-B3BnoXCG.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @flight/http - Node.js Adapter
|
|
5
|
+
* @flight-framework/http - Node.js Adapter
|
|
6
6
|
*
|
|
7
7
|
* Allows running Flight HTTP server on Node.js.
|
|
8
8
|
*/
|
|
@@ -20,8 +20,8 @@ interface ServeOptions {
|
|
|
20
20
|
*
|
|
21
21
|
* @example
|
|
22
22
|
* ```typescript
|
|
23
|
-
* import { createServer } from '@flight/http';
|
|
24
|
-
* import { serve } from '@flight/http/node';
|
|
23
|
+
* import { createServer } from '@flight-framework/http';
|
|
24
|
+
* import { serve } from '@flight-framework/http/node';
|
|
25
25
|
*
|
|
26
26
|
* const app = createServer();
|
|
27
27
|
* app.get('/', (c) => c.json({ hello: 'world' }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/node.ts"],"names":["createNodeServer"],"mappings":"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","file":"node.js","sourcesContent":["/**\r\n * @flight/http - Node.js Adapter\r\n * \r\n * Allows running Flight HTTP server on Node.js.\r\n */\r\n\r\nimport { createServer as createNodeServer, type IncomingMessage, type ServerResponse } from 'node:http';\r\nimport type { FlightHttpServer, Env } from '../types.js';\r\n\r\n// ============================================================================\r\n// Node.js Request Converter\r\n// ============================================================================\r\n\r\nasync function toWebRequest(req: IncomingMessage): Promise<Request> {\r\n const host = req.headers.host || 'localhost';\r\n const protocol = 'http'; // Simplified, use https detection in production\r\n const url = new URL(req.url || '/', `${protocol}://${host}`);\r\n\r\n // Collect body for non-GET/HEAD requests\r\n let body: BodyInit | null = null;\r\n\r\n if (req.method !== 'GET' && req.method !== 'HEAD') {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of req) {\r\n chunks.push(chunk as Buffer);\r\n }\r\n body = Buffer.concat(chunks);\r\n }\r\n\r\n // Convert headers\r\n const headers = new Headers();\r\n for (const [key, value] of Object.entries(req.headers)) {\r\n if (value) {\r\n if (Array.isArray(value)) {\r\n for (const v of value) {\r\n headers.append(key, v);\r\n }\r\n } else {\r\n headers.set(key, value);\r\n }\r\n }\r\n }\r\n\r\n return new Request(url.toString(), {\r\n method: req.method || 'GET',\r\n headers,\r\n body,\r\n });\r\n}\r\n\r\n// ============================================================================\r\n// Node.js Response Writer\r\n// ============================================================================\r\n\r\nasync function writeWebResponse(webResponse: Response, res: ServerResponse): Promise<void> {\r\n // Set status\r\n res.statusCode = webResponse.status;\r\n res.statusMessage = webResponse.statusText;\r\n\r\n // Set headers\r\n webResponse.headers.forEach((value, key) => {\r\n res.setHeader(key, value);\r\n });\r\n\r\n // Send body\r\n if (webResponse.body) {\r\n const reader = webResponse.body.getReader();\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n res.write(value);\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n }\r\n\r\n res.end();\r\n}\r\n\r\n// ============================================================================\r\n// serve() Function\r\n// ============================================================================\r\n\r\nexport interface ServeOptions {\r\n port?: number;\r\n hostname?: string;\r\n onListen?: (info: { port: number; hostname: string }) => void;\r\n}\r\n\r\n/**\r\n * Start a Node.js HTTP server with the Flight app\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight/http';\r\n * import { serve } from '@flight/http/node';\r\n * \r\n * const app = createServer();\r\n * app.get('/', (c) => c.json({ hello: 'world' }));\r\n * \r\n * serve(app, { port: 3000 });\r\n * ```\r\n */\r\nexport function serve<E extends Env = Env>(\r\n app: FlightHttpServer<E>,\r\n options: ServeOptions = {}\r\n): ReturnType<typeof createNodeServer> {\r\n const {\r\n port = 3000,\r\n hostname = '0.0.0.0',\r\n onListen,\r\n } = options;\r\n\r\n const server = createNodeServer(async (req, res) => {\r\n try {\r\n const webRequest = await toWebRequest(req);\r\n const webResponse = await app.fetch(webRequest);\r\n await writeWebResponse(webResponse, res);\r\n } catch (error) {\r\n console.error('[Flight HTTP Node] Error:', error);\r\n res.statusCode = 500;\r\n res.end('Internal Server Error');\r\n }\r\n });\r\n\r\n server.listen(port, hostname, () => {\r\n const info = { port, hostname };\r\n\r\n if (onListen) {\r\n onListen(info);\r\n } else {\r\n console.log(`\r\n âïļ Flight HTTP Server running!\r\n \r\n â Local: http://${hostname === '0.0.0.0' ? 'localhost' : hostname}:${port}/\r\n â Network: http://${hostname}:${port}/\r\n`);\r\n }\r\n });\r\n\r\n return server;\r\n}\r\n\r\n// Re-export useful types\r\nexport type { FlightHttpServer } from '../types.js';\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/node.ts"],"names":["createNodeServer"],"mappings":"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","file":"node.js","sourcesContent":["/**\r\n * @flight-framework/http - Node.js Adapter\r\n * \r\n * Allows running Flight HTTP server on Node.js.\r\n */\r\n\r\nimport { createServer as createNodeServer, type IncomingMessage, type ServerResponse } from 'node:http';\r\nimport type { FlightHttpServer, Env } from '../types.js';\r\n\r\n// ============================================================================\r\n// Node.js Request Converter\r\n// ============================================================================\r\n\r\nasync function toWebRequest(req: IncomingMessage): Promise<Request> {\r\n const host = req.headers.host || 'localhost';\r\n const protocol = 'http'; // Simplified, use https detection in production\r\n const url = new URL(req.url || '/', `${protocol}://${host}`);\r\n\r\n // Collect body for non-GET/HEAD requests\r\n let body: BodyInit | null = null;\r\n\r\n if (req.method !== 'GET' && req.method !== 'HEAD') {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of req) {\r\n chunks.push(chunk as Buffer);\r\n }\r\n body = Buffer.concat(chunks);\r\n }\r\n\r\n // Convert headers\r\n const headers = new Headers();\r\n for (const [key, value] of Object.entries(req.headers)) {\r\n if (value) {\r\n if (Array.isArray(value)) {\r\n for (const v of value) {\r\n headers.append(key, v);\r\n }\r\n } else {\r\n headers.set(key, value);\r\n }\r\n }\r\n }\r\n\r\n return new Request(url.toString(), {\r\n method: req.method || 'GET',\r\n headers,\r\n body,\r\n });\r\n}\r\n\r\n// ============================================================================\r\n// Node.js Response Writer\r\n// ============================================================================\r\n\r\nasync function writeWebResponse(webResponse: Response, res: ServerResponse): Promise<void> {\r\n // Set status\r\n res.statusCode = webResponse.status;\r\n res.statusMessage = webResponse.statusText;\r\n\r\n // Set headers\r\n webResponse.headers.forEach((value, key) => {\r\n res.setHeader(key, value);\r\n });\r\n\r\n // Send body\r\n if (webResponse.body) {\r\n const reader = webResponse.body.getReader();\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n res.write(value);\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n }\r\n\r\n res.end();\r\n}\r\n\r\n// ============================================================================\r\n// serve() Function\r\n// ============================================================================\r\n\r\nexport interface ServeOptions {\r\n port?: number;\r\n hostname?: string;\r\n onListen?: (info: { port: number; hostname: string }) => void;\r\n}\r\n\r\n/**\r\n * Start a Node.js HTTP server with the Flight app\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight-framework/http';\r\n * import { serve } from '@flight-framework/http/node';\r\n * \r\n * const app = createServer();\r\n * app.get('/', (c) => c.json({ hello: 'world' }));\r\n * \r\n * serve(app, { port: 3000 });\r\n * ```\r\n */\r\nexport function serve<E extends Env = Env>(\r\n app: FlightHttpServer<E>,\r\n options: ServeOptions = {}\r\n): ReturnType<typeof createNodeServer> {\r\n const {\r\n port = 3000,\r\n hostname = '0.0.0.0',\r\n onListen,\r\n } = options;\r\n\r\n const server = createNodeServer(async (req, res) => {\r\n try {\r\n const webRequest = await toWebRequest(req);\r\n const webResponse = await app.fetch(webRequest);\r\n await writeWebResponse(webResponse, res);\r\n } catch (error) {\r\n console.error('[Flight HTTP Node] Error:', error);\r\n res.statusCode = 500;\r\n res.end('Internal Server Error');\r\n }\r\n });\r\n\r\n server.listen(port, hostname, () => {\r\n const info = { port, hostname };\r\n\r\n if (onListen) {\r\n onListen(info);\r\n } else {\r\n console.log(`\r\n âïļ Flight HTTP Server running!\r\n \r\n â Local: http://${hostname === '0.0.0.0' ? 'localhost' : hostname}:${port}/\r\n â Network: http://${hostname}:${port}/\r\n`);\r\n }\r\n });\r\n\r\n return server;\r\n}\r\n\r\n// Re-export useful types\r\nexport type { FlightHttpServer } from '../types.js';\r\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { E as Env, S as ServerOptions, F as FlightHttpServer, H as HandlerOrMiddleware, M as Middleware, a as Handler, C as Context, b as FetchOptions, L as ListenOptions, c as HttpMethod, R as Route } from './types-
|
|
1
|
+
import { E as Env, S as ServerOptions, F as FlightHttpServer, H as HandlerOrMiddleware, M as Middleware, a as Handler, C as Context, b as FetchOptions, L as ListenOptions, c as HttpMethod, R as Route } from './types-B3BnoXCG.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @flight/http - Server
|
|
4
|
+
* @flight-framework/http - Server
|
|
5
5
|
*
|
|
6
6
|
* Main server class that implements the FlightHttpServer interface.
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
|
+
* PERFORMANCE OPTIMIZATIONS (2026):
|
|
9
|
+
* - Middleware chains pre-compiled at route registration (not per-request)
|
|
10
|
+
* - Minimal allocations in fetch() hot path
|
|
11
|
+
* - Uses optimized class-based Context
|
|
8
12
|
*/
|
|
9
13
|
|
|
10
14
|
declare class FlightHttp<E extends Env = Env> implements FlightHttpServer<E> {
|
|
@@ -13,6 +17,9 @@ declare class FlightHttp<E extends Env = Env> implements FlightHttpServer<E> {
|
|
|
13
17
|
private notFoundHandler;
|
|
14
18
|
private errorHandler;
|
|
15
19
|
private basePath;
|
|
20
|
+
private compiledNotFoundHandler?;
|
|
21
|
+
private middlewareVersion;
|
|
22
|
+
private lastCompiledVersion;
|
|
16
23
|
constructor(options?: ServerOptions);
|
|
17
24
|
get(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E>;
|
|
18
25
|
post(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E>;
|
|
@@ -30,16 +37,16 @@ declare class FlightHttp<E extends Env = Env> implements FlightHttpServer<E> {
|
|
|
30
37
|
listen(options?: ListenOptions | number): void;
|
|
31
38
|
private addRoute;
|
|
32
39
|
/**
|
|
33
|
-
*
|
|
40
|
+
* Get pre-compiled not found handler (with global middleware)
|
|
34
41
|
*/
|
|
35
|
-
private
|
|
42
|
+
private getCompiledNotFoundHandler;
|
|
36
43
|
}
|
|
37
44
|
/**
|
|
38
45
|
* Create a new Flight HTTP server
|
|
39
46
|
*
|
|
40
47
|
* @example
|
|
41
48
|
* ```typescript
|
|
42
|
-
* import { createServer } from '@flight/http';
|
|
49
|
+
* import { createServer } from '@flight-framework/http';
|
|
43
50
|
*
|
|
44
51
|
* const app = createServer();
|
|
45
52
|
*
|
|
@@ -51,16 +58,25 @@ declare class FlightHttp<E extends Env = Env> implements FlightHttpServer<E> {
|
|
|
51
58
|
declare function createServer<E extends Env = Env>(options?: ServerOptions): FlightHttpServer<E>;
|
|
52
59
|
|
|
53
60
|
/**
|
|
54
|
-
* @flight/http - Context
|
|
61
|
+
* @flight-framework/http - Context
|
|
55
62
|
*
|
|
56
63
|
* Request/Response context object passed to handlers.
|
|
57
|
-
*
|
|
64
|
+
*
|
|
65
|
+
* PERFORMANCE OPTIMIZATIONS (2026):
|
|
66
|
+
* - Class-based implementation (methods on prototype, not recreated per request)
|
|
67
|
+
* - Lazy URL parsing (parsed once, cached)
|
|
68
|
+
* - Lazy cookie parsing (parsed once, cached)
|
|
69
|
+
* - Minimal allocations in hot path
|
|
58
70
|
*/
|
|
59
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Create a new Context instance.
|
|
74
|
+
* Uses class-based implementation for optimal performance.
|
|
75
|
+
*/
|
|
60
76
|
declare function createContext<E extends Env = Env>(request: Request, params?: Record<string, string>, env?: E['Bindings']): Context<E>;
|
|
61
77
|
|
|
62
78
|
/**
|
|
63
|
-
* @flight/http - Router
|
|
79
|
+
* @flight-framework/http - Router
|
|
64
80
|
*
|
|
65
81
|
* Radix-tree based router for ultra-fast path matching.
|
|
66
82
|
* Uses radix3 under the hood.
|
package/dist/index.js
CHANGED
|
@@ -89,80 +89,151 @@ var Router = class {
|
|
|
89
89
|
};
|
|
90
90
|
|
|
91
91
|
// src/context.ts
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
92
|
+
var ContextImpl = class {
|
|
93
|
+
// Core properties
|
|
94
|
+
req;
|
|
95
|
+
env;
|
|
96
|
+
params;
|
|
97
|
+
variables;
|
|
98
|
+
// Cached values (lazy initialization)
|
|
99
|
+
_url;
|
|
100
|
+
_cookies;
|
|
101
|
+
_variables;
|
|
102
|
+
constructor(request, params, env) {
|
|
103
|
+
this.req = request;
|
|
104
|
+
this.params = params;
|
|
105
|
+
this.env = env;
|
|
106
|
+
this._variables = {};
|
|
107
|
+
this.variables = this._variables;
|
|
108
|
+
}
|
|
109
|
+
// ========================================================================
|
|
110
|
+
// Cached Getters (Lazy initialization)
|
|
111
|
+
// ========================================================================
|
|
112
|
+
/**
|
|
113
|
+
* Get parsed URL (cached after first access)
|
|
114
|
+
*/
|
|
115
|
+
get url() {
|
|
116
|
+
return this._url ??= new URL(this.req.url);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get pathname from cached URL
|
|
120
|
+
*/
|
|
121
|
+
get pathname() {
|
|
122
|
+
return this.url.pathname;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get query string from cached URL
|
|
126
|
+
*/
|
|
127
|
+
get query() {
|
|
128
|
+
return this.url.searchParams;
|
|
129
|
+
}
|
|
130
|
+
// ========================================================================
|
|
131
|
+
// Response Helpers (on prototype, not recreated)
|
|
132
|
+
// ========================================================================
|
|
133
|
+
json(data, status = 200) {
|
|
134
|
+
return new Response(JSON.stringify(data), {
|
|
135
|
+
status,
|
|
136
|
+
headers: { "Content-Type": "application/json; charset=utf-8" }
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
text(text, status = 200) {
|
|
140
|
+
return new Response(text, {
|
|
141
|
+
status,
|
|
142
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
html(html, status = 200) {
|
|
146
|
+
return new Response(html, {
|
|
147
|
+
status,
|
|
148
|
+
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
redirect(url, status = 302) {
|
|
152
|
+
return new Response(null, {
|
|
153
|
+
status,
|
|
154
|
+
headers: { Location: url }
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
// ========================================================================
|
|
158
|
+
// Variable Getter/Setter
|
|
159
|
+
// ========================================================================
|
|
160
|
+
get(key) {
|
|
161
|
+
return this._variables[key];
|
|
162
|
+
}
|
|
163
|
+
set(key, value) {
|
|
164
|
+
this._variables[key] = value;
|
|
165
|
+
}
|
|
166
|
+
// ========================================================================
|
|
167
|
+
// Request Helpers
|
|
168
|
+
// ========================================================================
|
|
169
|
+
header(name) {
|
|
170
|
+
return this.req.headers.get(name);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get cookie value (cookies parsed once, cached)
|
|
174
|
+
*/
|
|
175
|
+
cookie(name) {
|
|
176
|
+
if (!this._cookies) {
|
|
177
|
+
const cookieHeader = this.req.headers.get("cookie");
|
|
178
|
+
this._cookies = cookieHeader ? parseCookies(cookieHeader) : {};
|
|
140
179
|
}
|
|
141
|
-
|
|
142
|
-
}
|
|
180
|
+
return this._cookies[name];
|
|
181
|
+
}
|
|
182
|
+
};
|
|
143
183
|
function parseCookies(cookieHeader) {
|
|
144
184
|
const cookies = {};
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
185
|
+
const pairs = cookieHeader.split(";");
|
|
186
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
187
|
+
const pair = pairs[i].trim();
|
|
188
|
+
const eqIdx = pair.indexOf("=");
|
|
189
|
+
if (eqIdx > 0) {
|
|
190
|
+
const name = pair.slice(0, eqIdx);
|
|
191
|
+
const value = pair.slice(eqIdx + 1);
|
|
192
|
+
cookies[name] = value;
|
|
149
193
|
}
|
|
150
194
|
}
|
|
151
195
|
return cookies;
|
|
152
196
|
}
|
|
197
|
+
function createContext(request, params = {}, env = {}) {
|
|
198
|
+
return new ContextImpl(request, params, env);
|
|
199
|
+
}
|
|
153
200
|
|
|
154
201
|
// src/server.ts
|
|
202
|
+
function compileMiddlewareChain(middlewares, handler) {
|
|
203
|
+
if (middlewares.length === 0) {
|
|
204
|
+
return handler;
|
|
205
|
+
}
|
|
206
|
+
if (middlewares.length === 1) {
|
|
207
|
+
const mw = middlewares[0];
|
|
208
|
+
return (c) => mw(c, () => Promise.resolve(handler(c)));
|
|
209
|
+
}
|
|
210
|
+
return (c) => {
|
|
211
|
+
let index = 0;
|
|
212
|
+
const dispatch = () => {
|
|
213
|
+
if (index < middlewares.length) {
|
|
214
|
+
const middleware = middlewares[index++];
|
|
215
|
+
return Promise.resolve(middleware(c, dispatch));
|
|
216
|
+
}
|
|
217
|
+
return Promise.resolve(handler(c));
|
|
218
|
+
};
|
|
219
|
+
return dispatch();
|
|
220
|
+
};
|
|
221
|
+
}
|
|
155
222
|
var FlightHttp = class _FlightHttp {
|
|
156
223
|
router;
|
|
157
224
|
globalMiddleware = [];
|
|
158
225
|
notFoundHandler;
|
|
159
226
|
errorHandler;
|
|
160
227
|
basePath;
|
|
228
|
+
// Pre-compiled handlers cache (updated when middleware changes)
|
|
229
|
+
compiledNotFoundHandler;
|
|
230
|
+
middlewareVersion = 0;
|
|
231
|
+
lastCompiledVersion = -1;
|
|
161
232
|
constructor(options = {}) {
|
|
162
233
|
this.router = new Router();
|
|
163
234
|
this.basePath = options.basePath || "";
|
|
164
235
|
this.notFoundHandler = (c) => c.json(
|
|
165
|
-
{ error: "Not Found", path:
|
|
236
|
+
{ error: "Not Found", path: c.pathname },
|
|
166
237
|
404
|
|
167
238
|
);
|
|
168
239
|
this.errorHandler = (error, c) => c.json(
|
|
@@ -202,6 +273,7 @@ var FlightHttp = class _FlightHttp {
|
|
|
202
273
|
// ========================================================================
|
|
203
274
|
use(...handlers) {
|
|
204
275
|
this.globalMiddleware.push(...handlers);
|
|
276
|
+
this.middlewareVersion++;
|
|
205
277
|
return this;
|
|
206
278
|
}
|
|
207
279
|
// ========================================================================
|
|
@@ -222,6 +294,7 @@ var FlightHttp = class _FlightHttp {
|
|
|
222
294
|
// ========================================================================
|
|
223
295
|
notFound(handler) {
|
|
224
296
|
this.notFoundHandler = handler;
|
|
297
|
+
this.compiledNotFoundHandler = void 0;
|
|
225
298
|
return this;
|
|
226
299
|
}
|
|
227
300
|
onError(handler) {
|
|
@@ -229,12 +302,14 @@ var FlightHttp = class _FlightHttp {
|
|
|
229
302
|
return this;
|
|
230
303
|
}
|
|
231
304
|
// ========================================================================
|
|
232
|
-
// Core Fetch Handler
|
|
305
|
+
// Core Fetch Handler (Optimized Hot Path)
|
|
233
306
|
// ========================================================================
|
|
234
307
|
async fetch(request, options = {}) {
|
|
235
|
-
const url =
|
|
236
|
-
const
|
|
237
|
-
const
|
|
308
|
+
const url = request.url;
|
|
309
|
+
const pathStart = url.indexOf("/", url.indexOf("//") + 2);
|
|
310
|
+
const queryStart = url.indexOf("?", pathStart);
|
|
311
|
+
const path = queryStart === -1 ? url.slice(pathStart) : url.slice(pathStart, queryStart);
|
|
312
|
+
const method = request.method;
|
|
238
313
|
const match = this.router.match(method, path);
|
|
239
314
|
const context = createContext(
|
|
240
315
|
request,
|
|
@@ -242,22 +317,18 @@ var FlightHttp = class _FlightHttp {
|
|
|
242
317
|
options.env || {}
|
|
243
318
|
);
|
|
244
319
|
try {
|
|
245
|
-
const middlewares = [...this.globalMiddleware];
|
|
246
320
|
if (match) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (middlewares.length > 0) {
|
|
254
|
-
const composed = this.composeMiddleware(
|
|
255
|
-
middlewares,
|
|
256
|
-
this.notFoundHandler
|
|
321
|
+
if (this.globalMiddleware.length === 0) {
|
|
322
|
+
return await match.handler(context);
|
|
323
|
+
} else {
|
|
324
|
+
const composed = compileMiddlewareChain(
|
|
325
|
+
this.globalMiddleware,
|
|
326
|
+
match.handler
|
|
257
327
|
);
|
|
258
328
|
return await composed(context);
|
|
259
329
|
}
|
|
260
|
-
|
|
330
|
+
} else {
|
|
331
|
+
return await this.getCompiledNotFoundHandler()(context);
|
|
261
332
|
}
|
|
262
333
|
} catch (error) {
|
|
263
334
|
console.error("[Flight HTTP] Error:", error);
|
|
@@ -273,7 +344,7 @@ var FlightHttp = class _FlightHttp {
|
|
|
273
344
|
listen(options) {
|
|
274
345
|
const port = typeof options === "number" ? options : options?.port || 3e3;
|
|
275
346
|
console.log(`[Flight HTTP] Call adapter-specific listen() to start server on port ${port}`);
|
|
276
|
-
console.log('[Flight HTTP] Import from "@flight/http/node" or "@flight/http/bun"');
|
|
347
|
+
console.log('[Flight HTTP] Import from "@flight-framework/http/node" or "@flight-framework/http/bun"');
|
|
277
348
|
}
|
|
278
349
|
// ========================================================================
|
|
279
350
|
// Private Methods
|
|
@@ -282,31 +353,19 @@ var FlightHttp = class _FlightHttp {
|
|
|
282
353
|
const mainHandler = handlers[handlers.length - 1];
|
|
283
354
|
const routeMiddleware = handlers.slice(0, -1);
|
|
284
355
|
const fullPath = this.basePath + path;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
this.router.add(method, fullPath, composedHandler);
|
|
288
|
-
} else {
|
|
289
|
-
this.router.add(method, fullPath, mainHandler);
|
|
290
|
-
}
|
|
356
|
+
const compiledHandler = routeMiddleware.length > 0 ? compileMiddlewareChain(routeMiddleware, mainHandler) : mainHandler;
|
|
357
|
+
this.router.add(method, fullPath, compiledHandler);
|
|
291
358
|
return this;
|
|
292
359
|
}
|
|
293
360
|
/**
|
|
294
|
-
*
|
|
361
|
+
* Get pre-compiled not found handler (with global middleware)
|
|
295
362
|
*/
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (middleware) {
|
|
303
|
-
return await middleware(c, dispatch);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return await handler(c);
|
|
307
|
-
};
|
|
308
|
-
return await dispatch();
|
|
309
|
-
};
|
|
363
|
+
getCompiledNotFoundHandler() {
|
|
364
|
+
if (this.lastCompiledVersion !== this.middlewareVersion || !this.compiledNotFoundHandler) {
|
|
365
|
+
this.compiledNotFoundHandler = this.globalMiddleware.length > 0 ? compileMiddlewareChain(this.globalMiddleware, this.notFoundHandler) : this.notFoundHandler;
|
|
366
|
+
this.lastCompiledVersion = this.middlewareVersion;
|
|
367
|
+
}
|
|
368
|
+
return this.compiledNotFoundHandler;
|
|
310
369
|
}
|
|
311
370
|
};
|
|
312
371
|
function createServer(options = {}) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/router.ts","../src/context.ts","../src/server.ts"],"names":["createRadixRouter"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * @flight/http - Router\r\n * \r\n * Radix-tree based router for ultra-fast path matching.\r\n * Uses radix3 under the hood.\r\n */\r\n\r\nimport { createRouter as createRadixRouter, type RadixRouter } from 'radix3';\r\nimport type { Handler, HttpMethod, Route, Env } from './types.js';\r\n\r\n// ============================================================================\r\n// Router Types\r\n// ============================================================================\r\n\r\ninterface RouterNode<E extends Env = Env> {\r\n handlers: Map<HttpMethod | '*', Handler<E>>;\r\n}\r\n\r\ninterface MatchResult<E extends Env = Env> {\r\n handler: Handler<E>;\r\n params: Record<string, string>;\r\n}\r\n\r\n// ============================================================================\r\n// Router Class\r\n// ============================================================================\r\n\r\nexport class Router<E extends Env = Env> {\r\n private radix: RadixRouter<RouterNode<E>>;\r\n private routes: Route<E>[] = [];\r\n\r\n constructor() {\r\n this.radix = createRadixRouter<RouterNode<E>>();\r\n }\r\n\r\n /**\r\n * Add a route\r\n */\r\n add(method: HttpMethod | '*', path: string, handler: Handler<E>): void {\r\n // Normalize path\r\n const normalizedPath = this.normalizePath(path);\r\n\r\n // Get or create node\r\n let node = this.radix.lookup(normalizedPath);\r\n\r\n if (!node) {\r\n node = { handlers: new Map() };\r\n this.radix.insert(normalizedPath, node);\r\n }\r\n\r\n // Add handler for method\r\n node.handlers.set(method, handler);\r\n\r\n // Track route for debugging\r\n this.routes.push({\r\n method,\r\n path: normalizedPath,\r\n handler,\r\n middleware: [],\r\n });\r\n }\r\n\r\n /**\r\n * Match a request to a route\r\n */\r\n match(method: HttpMethod, path: string): MatchResult<E> | null {\r\n const normalizedPath = this.normalizePath(path);\r\n const result = this.radix.lookup(normalizedPath);\r\n\r\n if (!result) {\r\n return null;\r\n }\r\n\r\n // Try exact method first\r\n let handler = result.handlers.get(method);\r\n\r\n // Fall back to wildcard\r\n if (!handler) {\r\n handler = result.handlers.get('*');\r\n }\r\n\r\n if (!handler) {\r\n return null;\r\n }\r\n\r\n // radix3 returns params in the result via _params property\r\n // Also extract from the lookup result directly\r\n const params: Record<string, string> = (result as any).params || {};\r\n\r\n return { handler, params };\r\n }\r\n\r\n /**\r\n * Get all registered routes\r\n */\r\n getRoutes(): Route<E>[] {\r\n return [...this.routes];\r\n }\r\n\r\n /**\r\n * Normalize path\r\n */\r\n private normalizePath(path: string): string {\r\n // Ensure leading slash\r\n if (!path.startsWith('/')) {\r\n path = '/' + path;\r\n }\r\n\r\n // Remove trailing slash (except for root)\r\n if (path !== '/' && path.endsWith('/')) {\r\n path = path.slice(0, -1);\r\n }\r\n\r\n // Convert [param] to :param for radix3\r\n path = path.replace(/\\[([^\\]]+)\\]/g, ':$1');\r\n\r\n // Convert [...slug] to ** for catch-all\r\n path = path.replace(/\\[\\.\\.\\.([\\w]+)\\]/g, '**');\r\n\r\n return path;\r\n }\r\n\r\n /**\r\n * Extract params from matched path\r\n * @deprecated radix3 handles param extraction internally\r\n */\r\n private _extractParams(pattern: string, actualPath: string): Record<string, string> {\r\n const params: Record<string, string> = {};\r\n\r\n const patternParts = pattern.split('/');\r\n const actualParts = actualPath.split('/');\r\n\r\n for (let i = 0; i < patternParts.length; i++) {\r\n const patternPart = patternParts[i];\r\n if (!patternPart) continue;\r\n\r\n if (patternPart.startsWith(':')) {\r\n const paramName = patternPart.slice(1);\r\n params[paramName] = actualParts[i] || '';\r\n } else if (patternPart === '**') {\r\n // Catch-all: collect remaining parts\r\n const paramName = 'slug';\r\n params[paramName] = actualParts.slice(i).join('/');\r\n break;\r\n }\r\n }\r\n\r\n return params;\r\n }\r\n}\r\n","/**\r\n * @flight/http - Context\r\n * \r\n * Request/Response context object passed to handlers.\r\n * Similar to Hono's Context for familiarity.\r\n */\r\n\r\nimport type { Context, Env } from './types.js';\r\n\r\n// ============================================================================\r\n// Context Factory\r\n// ============================================================================\r\n\r\nexport function createContext<E extends Env = Env>(\r\n request: Request,\r\n params: Record<string, string> = {},\r\n env: E['Bindings'] = {} as E['Bindings']\r\n): Context<E> {\r\n const variables: Record<string, unknown> = {};\r\n\r\n return {\r\n req: request,\r\n env,\r\n params,\r\n variables: variables as E['Variables'],\r\n\r\n // Response helpers\r\n json<T>(data: T, status = 200): Response {\r\n return new Response(JSON.stringify(data), {\r\n status,\r\n headers: { 'Content-Type': 'application/json; charset=utf-8' },\r\n });\r\n },\r\n\r\n text(text: string, status = 200): Response {\r\n return new Response(text, {\r\n status,\r\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\r\n });\r\n },\r\n\r\n html(html: string, status = 200): Response {\r\n return new Response(html, {\r\n status,\r\n headers: { 'Content-Type': 'text/html; charset=utf-8' },\r\n });\r\n },\r\n\r\n redirect(url: string, status: 301 | 302 | 303 | 307 | 308 = 302): Response {\r\n return new Response(null, {\r\n status,\r\n headers: { Location: url },\r\n });\r\n },\r\n\r\n // Variable getter/setter\r\n get<K extends keyof E['Variables']>(key: K): E['Variables'][K] {\r\n return variables[key as string] as E['Variables'][K];\r\n },\r\n\r\n set<K extends keyof E['Variables']>(key: K, value: E['Variables'][K]): void {\r\n variables[key as string] = value;\r\n },\r\n\r\n // Request helpers\r\n header(name: string): string | null {\r\n return request.headers.get(name);\r\n },\r\n\r\n cookie(name: string): string | undefined {\r\n const cookieHeader = request.headers.get('cookie');\r\n if (!cookieHeader) return undefined;\r\n\r\n const cookies = parseCookies(cookieHeader);\r\n return cookies[name];\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Cookie Parser\r\n// ============================================================================\r\n\r\nfunction parseCookies(cookieHeader: string): Record<string, string> {\r\n const cookies: Record<string, string> = {};\r\n\r\n for (const cookie of cookieHeader.split(';')) {\r\n const [name, ...rest] = cookie.trim().split('=');\r\n if (name) {\r\n cookies[name] = rest.join('=');\r\n }\r\n }\r\n\r\n return cookies;\r\n}\r\n","/**\r\n * @flight/http - Server\r\n * \r\n * Main server class that implements the FlightHttpServer interface.\r\n * Inspired by Hono's design patterns.\r\n */\r\n\r\nimport { Router } from './router.js';\r\nimport { createContext } from './context.js';\r\nimport type {\r\n FlightHttpServer,\r\n Handler,\r\n Middleware,\r\n HandlerOrMiddleware,\r\n HttpMethod,\r\n Context,\r\n Env,\r\n ServerOptions,\r\n ListenOptions,\r\n FetchOptions,\r\n} from './types.js';\r\n\r\n// ============================================================================\r\n// Server Class\r\n// ============================================================================\r\n\r\nexport class FlightHttp<E extends Env = Env> implements FlightHttpServer<E> {\r\n private router: Router<E>;\r\n private globalMiddleware: Middleware<E>[] = [];\r\n private notFoundHandler: Handler<E>;\r\n private errorHandler: (error: Error, c: Context<E>) => Response | Promise<Response>;\r\n private basePath: string;\r\n\r\n constructor(options: ServerOptions = {}) {\r\n this.router = new Router<E>();\r\n this.basePath = options.basePath || '';\r\n\r\n // Default not found handler\r\n this.notFoundHandler = (c) => c.json(\r\n { error: 'Not Found', path: new URL(c.req.url).pathname },\r\n 404\r\n );\r\n\r\n // Default error handler\r\n this.errorHandler = (error, c) => c.json(\r\n { error: error.message || 'Internal Server Error' },\r\n 500\r\n );\r\n }\r\n\r\n // ========================================================================\r\n // Route Registration\r\n // ========================================================================\r\n\r\n get(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('GET', path, handlers);\r\n }\r\n\r\n post(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('POST', path, handlers);\r\n }\r\n\r\n put(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('PUT', path, handlers);\r\n }\r\n\r\n delete(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('DELETE', path, handlers);\r\n }\r\n\r\n patch(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('PATCH', path, handlers);\r\n }\r\n\r\n options(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('OPTIONS', path, handlers);\r\n }\r\n\r\n head(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('HEAD', path, handlers);\r\n }\r\n\r\n all(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('*', path, handlers);\r\n }\r\n\r\n // ========================================================================\r\n // Middleware\r\n // ========================================================================\r\n\r\n use(...handlers: Middleware<E>[]): FlightHttpServer<E> {\r\n this.globalMiddleware.push(...handlers);\r\n return this;\r\n }\r\n\r\n // ========================================================================\r\n // Sub-routing\r\n // ========================================================================\r\n\r\n route(path: string, router: FlightHttpServer<E>): FlightHttpServer<E> {\r\n // Get routes from sub-router\r\n if (router instanceof FlightHttp) {\r\n const routes = router.router.getRoutes();\r\n for (const route of routes) {\r\n const fullPath = this.basePath + path + route.path;\r\n this.router.add(route.method, fullPath, route.handler);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n // ========================================================================\r\n // Error Handling\r\n // ========================================================================\r\n\r\n notFound(handler: Handler<E>): FlightHttpServer<E> {\r\n this.notFoundHandler = handler;\r\n return this;\r\n }\r\n\r\n onError(handler: (error: Error, c: Context<E>) => Response | Promise<Response>): FlightHttpServer<E> {\r\n this.errorHandler = handler;\r\n return this;\r\n }\r\n\r\n // ========================================================================\r\n // Core Fetch Handler\r\n // ========================================================================\r\n\r\n async fetch(request: Request, options: FetchOptions = {}): Promise<Response> {\r\n const url = new URL(request.url);\r\n const path = url.pathname;\r\n const method = request.method.toUpperCase() as HttpMethod;\r\n\r\n // Match route\r\n const match = this.router.match(method, path);\r\n\r\n // Create context\r\n const context = createContext<E>(\r\n request,\r\n match?.params || {},\r\n (options.env || {}) as E['Bindings']\r\n );\r\n\r\n try {\r\n // Build middleware chain\r\n const middlewares = [...this.globalMiddleware];\r\n\r\n if (match) {\r\n // Compose middleware + handler\r\n const composed = this.composeMiddleware(\r\n middlewares,\r\n match.handler\r\n );\r\n return await composed(context);\r\n } else {\r\n // No route found\r\n if (middlewares.length > 0) {\r\n const composed = this.composeMiddleware(\r\n middlewares,\r\n this.notFoundHandler\r\n );\r\n return await composed(context);\r\n }\r\n return await this.notFoundHandler(context);\r\n }\r\n } catch (error) {\r\n console.error('[Flight HTTP] Error:', error);\r\n return await this.errorHandler(\r\n error instanceof Error ? error : new Error(String(error)),\r\n context\r\n );\r\n }\r\n }\r\n\r\n // ========================================================================\r\n // Listen (Node.js adapter will override this)\r\n // ========================================================================\r\n\r\n listen(options?: ListenOptions | number): void {\r\n const port = typeof options === 'number' ? options : options?.port || 3000;\r\n console.log(`[Flight HTTP] Call adapter-specific listen() to start server on port ${port}`);\r\n console.log('[Flight HTTP] Import from \"@flight/http/node\" or \"@flight/http/bun\"');\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods\r\n // ========================================================================\r\n\r\n private addRoute(\r\n method: HttpMethod | '*',\r\n path: string,\r\n handlers: HandlerOrMiddleware<E>[]\r\n ): FlightHttpServer<E> {\r\n // Last handler is the main handler\r\n const mainHandler = handlers[handlers.length - 1] as Handler<E>;\r\n const routeMiddleware = handlers.slice(0, -1) as Middleware<E>[];\r\n\r\n const fullPath = this.basePath + path;\r\n\r\n // If there's route-specific middleware, compose it\r\n if (routeMiddleware.length > 0) {\r\n const composedHandler = this.composeMiddleware(routeMiddleware, mainHandler);\r\n this.router.add(method, fullPath, composedHandler);\r\n } else {\r\n this.router.add(method, fullPath, mainHandler);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Compose middleware chain with final handler\r\n */\r\n private composeMiddleware(\r\n middlewares: Middleware<E>[],\r\n handler: Handler<E>\r\n ): Handler<E> {\r\n return async (c: Context<E>) => {\r\n let index = 0;\r\n\r\n const dispatch = async (): Promise<Response> => {\r\n if (index < middlewares.length) {\r\n const middleware = middlewares[index++];\r\n if (middleware) {\r\n return await middleware(c, dispatch);\r\n }\r\n }\r\n return await handler(c);\r\n };\r\n\r\n return await dispatch();\r\n };\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Factory Function\r\n// ============================================================================\r\n\r\n/**\r\n * Create a new Flight HTTP server\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight/http';\r\n * \r\n * const app = createServer();\r\n * \r\n * app.get('/', (c) => c.json({ message: 'Hello Flight!' }));\r\n * \r\n * export default app;\r\n * ```\r\n */\r\nexport function createServer<E extends Env = Env>(\r\n options: ServerOptions = {}\r\n): FlightHttpServer<E> {\r\n return new FlightHttp<E>(options);\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/router.ts","../src/context.ts","../src/server.ts"],"names":["createRadixRouter"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * @flight-framework/http - Router\r\n * \r\n * Radix-tree based router for ultra-fast path matching.\r\n * Uses radix3 under the hood.\r\n */\r\n\r\nimport { createRouter as createRadixRouter, type RadixRouter } from 'radix3';\r\nimport type { Handler, HttpMethod, Route, Env } from './types.js';\r\n\r\n// ============================================================================\r\n// Router Types\r\n// ============================================================================\r\n\r\ninterface RouterNode<E extends Env = Env> {\r\n handlers: Map<HttpMethod | '*', Handler<E>>;\r\n}\r\n\r\ninterface MatchResult<E extends Env = Env> {\r\n handler: Handler<E>;\r\n params: Record<string, string>;\r\n}\r\n\r\n// ============================================================================\r\n// Router Class\r\n// ============================================================================\r\n\r\nexport class Router<E extends Env = Env> {\r\n private radix: RadixRouter<RouterNode<E>>;\r\n private routes: Route<E>[] = [];\r\n\r\n constructor() {\r\n this.radix = createRadixRouter<RouterNode<E>>();\r\n }\r\n\r\n /**\r\n * Add a route\r\n */\r\n add(method: HttpMethod | '*', path: string, handler: Handler<E>): void {\r\n // Normalize path\r\n const normalizedPath = this.normalizePath(path);\r\n\r\n // Get or create node\r\n let node = this.radix.lookup(normalizedPath);\r\n\r\n if (!node) {\r\n node = { handlers: new Map() };\r\n this.radix.insert(normalizedPath, node);\r\n }\r\n\r\n // Add handler for method\r\n node.handlers.set(method, handler);\r\n\r\n // Track route for debugging\r\n this.routes.push({\r\n method,\r\n path: normalizedPath,\r\n handler,\r\n middleware: [],\r\n });\r\n }\r\n\r\n /**\r\n * Match a request to a route\r\n */\r\n match(method: HttpMethod, path: string): MatchResult<E> | null {\r\n const normalizedPath = this.normalizePath(path);\r\n const result = this.radix.lookup(normalizedPath);\r\n\r\n if (!result) {\r\n return null;\r\n }\r\n\r\n // Try exact method first\r\n let handler = result.handlers.get(method);\r\n\r\n // Fall back to wildcard\r\n if (!handler) {\r\n handler = result.handlers.get('*');\r\n }\r\n\r\n if (!handler) {\r\n return null;\r\n }\r\n\r\n // radix3 returns params in the result via _params property\r\n // Also extract from the lookup result directly\r\n const params: Record<string, string> = (result as any).params || {};\r\n\r\n return { handler, params };\r\n }\r\n\r\n /**\r\n * Get all registered routes\r\n */\r\n getRoutes(): Route<E>[] {\r\n return [...this.routes];\r\n }\r\n\r\n /**\r\n * Normalize path\r\n */\r\n private normalizePath(path: string): string {\r\n // Ensure leading slash\r\n if (!path.startsWith('/')) {\r\n path = '/' + path;\r\n }\r\n\r\n // Remove trailing slash (except for root)\r\n if (path !== '/' && path.endsWith('/')) {\r\n path = path.slice(0, -1);\r\n }\r\n\r\n // Convert [param] to :param for radix3\r\n path = path.replace(/\\[([^\\]]+)\\]/g, ':$1');\r\n\r\n // Convert [...slug] to ** for catch-all\r\n path = path.replace(/\\[\\.\\.\\.([\\w]+)\\]/g, '**');\r\n\r\n return path;\r\n }\r\n\r\n /**\r\n * Extract params from matched path\r\n * @deprecated radix3 handles param extraction internally\r\n */\r\n private _extractParams(pattern: string, actualPath: string): Record<string, string> {\r\n const params: Record<string, string> = {};\r\n\r\n const patternParts = pattern.split('/');\r\n const actualParts = actualPath.split('/');\r\n\r\n for (let i = 0; i < patternParts.length; i++) {\r\n const patternPart = patternParts[i];\r\n if (!patternPart) continue;\r\n\r\n if (patternPart.startsWith(':')) {\r\n const paramName = patternPart.slice(1);\r\n params[paramName] = actualParts[i] || '';\r\n } else if (patternPart === '**') {\r\n // Catch-all: collect remaining parts\r\n const paramName = 'slug';\r\n params[paramName] = actualParts.slice(i).join('/');\r\n break;\r\n }\r\n }\r\n\r\n return params;\r\n }\r\n}\r\n","/**\r\n * @flight-framework/http - Context\r\n * \r\n * Request/Response context object passed to handlers.\r\n * \r\n * PERFORMANCE OPTIMIZATIONS (2026):\r\n * - Class-based implementation (methods on prototype, not recreated per request)\r\n * - Lazy URL parsing (parsed once, cached)\r\n * - Lazy cookie parsing (parsed once, cached)\r\n * - Minimal allocations in hot path\r\n */\r\n\r\nimport type { Context, Env } from './types.js';\r\n\r\n// ============================================================================\r\n// Context Implementation (Class-based for performance)\r\n// ============================================================================\r\n\r\n/**\r\n * High-performance Context implementation.\r\n * Methods live on the prototype, not recreated per request.\r\n */\r\nclass ContextImpl<E extends Env = Env> implements Context<E> {\r\n // Core properties\r\n readonly req: Request;\r\n readonly env: E['Bindings'];\r\n readonly params: Record<string, string>;\r\n readonly variables: E['Variables'];\r\n\r\n // Cached values (lazy initialization)\r\n private _url?: URL;\r\n private _cookies?: Record<string, string>;\r\n private _variables: Record<string, unknown>;\r\n\r\n constructor(\r\n request: Request,\r\n params: Record<string, string>,\r\n env: E['Bindings']\r\n ) {\r\n this.req = request;\r\n this.params = params;\r\n this.env = env;\r\n this._variables = {};\r\n this.variables = this._variables as E['Variables'];\r\n }\r\n\r\n // ========================================================================\r\n // Cached Getters (Lazy initialization)\r\n // ========================================================================\r\n\r\n /**\r\n * Get parsed URL (cached after first access)\r\n */\r\n get url(): URL {\r\n return this._url ??= new URL(this.req.url);\r\n }\r\n\r\n /**\r\n * Get pathname from cached URL\r\n */\r\n get pathname(): string {\r\n return this.url.pathname;\r\n }\r\n\r\n /**\r\n * Get query string from cached URL\r\n */\r\n get query(): URLSearchParams {\r\n return this.url.searchParams;\r\n }\r\n\r\n // ========================================================================\r\n // Response Helpers (on prototype, not recreated)\r\n // ========================================================================\r\n\r\n json<T>(data: T, status = 200): Response {\r\n return new Response(JSON.stringify(data), {\r\n status,\r\n headers: { 'Content-Type': 'application/json; charset=utf-8' },\r\n });\r\n }\r\n\r\n text(text: string, status = 200): Response {\r\n return new Response(text, {\r\n status,\r\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\r\n });\r\n }\r\n\r\n html(html: string, status = 200): Response {\r\n return new Response(html, {\r\n status,\r\n headers: { 'Content-Type': 'text/html; charset=utf-8' },\r\n });\r\n }\r\n\r\n redirect(url: string, status: 301 | 302 | 303 | 307 | 308 = 302): Response {\r\n return new Response(null, {\r\n status,\r\n headers: { Location: url },\r\n });\r\n }\r\n\r\n // ========================================================================\r\n // Variable Getter/Setter\r\n // ========================================================================\r\n\r\n get<K extends keyof E['Variables']>(key: K): E['Variables'][K] {\r\n return this._variables[key as string] as E['Variables'][K];\r\n }\r\n\r\n set<K extends keyof E['Variables']>(key: K, value: E['Variables'][K]): void {\r\n this._variables[key as string] = value;\r\n }\r\n\r\n // ========================================================================\r\n // Request Helpers\r\n // ========================================================================\r\n\r\n header(name: string): string | null {\r\n return this.req.headers.get(name);\r\n }\r\n\r\n /**\r\n * Get cookie value (cookies parsed once, cached)\r\n */\r\n cookie(name: string): string | undefined {\r\n if (!this._cookies) {\r\n const cookieHeader = this.req.headers.get('cookie');\r\n this._cookies = cookieHeader ? parseCookies(cookieHeader) : {};\r\n }\r\n return this._cookies[name];\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Cookie Parser (optimized)\r\n// ============================================================================\r\n\r\nfunction parseCookies(cookieHeader: string): Record<string, string> {\r\n const cookies: Record<string, string> = {};\r\n const pairs = cookieHeader.split(';');\r\n\r\n for (let i = 0; i < pairs.length; i++) {\r\n const pair = pairs[i].trim();\r\n const eqIdx = pair.indexOf('=');\r\n if (eqIdx > 0) {\r\n const name = pair.slice(0, eqIdx);\r\n const value = pair.slice(eqIdx + 1);\r\n cookies[name] = value;\r\n }\r\n }\r\n\r\n return cookies;\r\n}\r\n\r\n// ============================================================================\r\n// Context Factory (returns class instance)\r\n// ============================================================================\r\n\r\n/**\r\n * Create a new Context instance.\r\n * Uses class-based implementation for optimal performance.\r\n */\r\nexport function createContext<E extends Env = Env>(\r\n request: Request,\r\n params: Record<string, string> = {},\r\n env: E['Bindings'] = {} as E['Bindings']\r\n): Context<E> {\r\n return new ContextImpl<E>(request, params, env);\r\n}\r\n\r\n// Export class for advanced usage/testing\r\nexport { ContextImpl };\r\n","/**\r\n * @flight-framework/http - Server\r\n * \r\n * Main server class that implements the FlightHttpServer interface.\r\n * \r\n * PERFORMANCE OPTIMIZATIONS (2026):\r\n * - Middleware chains pre-compiled at route registration (not per-request)\r\n * - Minimal allocations in fetch() hot path\r\n * - Uses optimized class-based Context\r\n */\r\n\r\nimport { Router } from './router.js';\r\nimport { createContext } from './context.js';\r\nimport type {\r\n FlightHttpServer,\r\n Handler,\r\n Middleware,\r\n HandlerOrMiddleware,\r\n HttpMethod,\r\n Context,\r\n Env,\r\n ServerOptions,\r\n ListenOptions,\r\n FetchOptions,\r\n} from './types.js';\r\n\r\n// ============================================================================\r\n// Pre-compiled Middleware Chain\r\n// ============================================================================\r\n\r\n/**\r\n * Pre-compile middleware chain into a single handler function.\r\n * This avoids closure creation on every request.\r\n */\r\nfunction compileMiddlewareChain<E extends Env>(\r\n middlewares: Middleware<E>[],\r\n handler: Handler<E>\r\n): Handler<E> {\r\n // No middleware - return handler directly (zero overhead)\r\n if (middlewares.length === 0) {\r\n return handler;\r\n }\r\n\r\n // Single middleware - inline optimization\r\n if (middlewares.length === 1) {\r\n const mw = middlewares[0];\r\n return (c: Context<E>) => mw(c, () => Promise.resolve(handler(c)));\r\n }\r\n\r\n // Multiple middlewares - build dispatch chain\r\n // Pre-build the chain at compile time, not runtime\r\n return (c: Context<E>) => {\r\n let index = 0;\r\n\r\n const dispatch = (): Promise<Response> => {\r\n if (index < middlewares.length) {\r\n const middleware = middlewares[index++];\r\n return Promise.resolve(middleware(c, dispatch));\r\n }\r\n return Promise.resolve(handler(c));\r\n };\r\n\r\n return dispatch();\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Server Class\r\n// ============================================================================\r\n\r\nexport class FlightHttp<E extends Env = Env> implements FlightHttpServer<E> {\r\n private router: Router<E>;\r\n private globalMiddleware: Middleware<E>[] = [];\r\n private notFoundHandler: Handler<E>;\r\n private errorHandler: (error: Error, c: Context<E>) => Response | Promise<Response>;\r\n private basePath: string;\r\n\r\n // Pre-compiled handlers cache (updated when middleware changes)\r\n private compiledNotFoundHandler?: Handler<E>;\r\n private middlewareVersion = 0;\r\n private lastCompiledVersion = -1;\r\n\r\n constructor(options: ServerOptions = {}) {\r\n this.router = new Router<E>();\r\n this.basePath = options.basePath || '';\r\n\r\n // Default not found handler\r\n this.notFoundHandler = (c) => c.json(\r\n { error: 'Not Found', path: c.pathname },\r\n 404\r\n );\r\n\r\n // Default error handler\r\n this.errorHandler = (error, c) => c.json(\r\n { error: error.message || 'Internal Server Error' },\r\n 500\r\n );\r\n }\r\n\r\n // ========================================================================\r\n // Route Registration\r\n // ========================================================================\r\n\r\n get(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('GET', path, handlers);\r\n }\r\n\r\n post(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('POST', path, handlers);\r\n }\r\n\r\n put(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('PUT', path, handlers);\r\n }\r\n\r\n delete(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('DELETE', path, handlers);\r\n }\r\n\r\n patch(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('PATCH', path, handlers);\r\n }\r\n\r\n options(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('OPTIONS', path, handlers);\r\n }\r\n\r\n head(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('HEAD', path, handlers);\r\n }\r\n\r\n all(path: string, ...handlers: HandlerOrMiddleware<E>[]): FlightHttpServer<E> {\r\n return this.addRoute('*', path, handlers);\r\n }\r\n\r\n // ========================================================================\r\n // Middleware\r\n // ========================================================================\r\n\r\n use(...handlers: Middleware<E>[]): FlightHttpServer<E> {\r\n this.globalMiddleware.push(...handlers);\r\n // Invalidate pre-compiled handlers\r\n this.middlewareVersion++;\r\n return this;\r\n }\r\n\r\n // ========================================================================\r\n // Sub-routing\r\n // ========================================================================\r\n\r\n route(path: string, router: FlightHttpServer<E>): FlightHttpServer<E> {\r\n if (router instanceof FlightHttp) {\r\n const routes = router.router.getRoutes();\r\n for (const route of routes) {\r\n const fullPath = this.basePath + path + route.path;\r\n this.router.add(route.method, fullPath, route.handler);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n // ========================================================================\r\n // Error Handling\r\n // ========================================================================\r\n\r\n notFound(handler: Handler<E>): FlightHttpServer<E> {\r\n this.notFoundHandler = handler;\r\n // Invalidate cached compiled handler\r\n this.compiledNotFoundHandler = undefined;\r\n return this;\r\n }\r\n\r\n onError(handler: (error: Error, c: Context<E>) => Response | Promise<Response>): FlightHttpServer<E> {\r\n this.errorHandler = handler;\r\n return this;\r\n }\r\n\r\n // ========================================================================\r\n // Core Fetch Handler (Optimized Hot Path)\r\n // ========================================================================\r\n\r\n async fetch(request: Request, options: FetchOptions = {}): Promise<Response> {\r\n // Fast path parsing - avoid new URL() here, let context handle it lazily\r\n const url = request.url;\r\n const pathStart = url.indexOf('/', url.indexOf('//') + 2);\r\n const queryStart = url.indexOf('?', pathStart);\r\n const path = queryStart === -1\r\n ? url.slice(pathStart)\r\n : url.slice(pathStart, queryStart);\r\n\r\n const method = request.method as HttpMethod;\r\n\r\n // Match route\r\n const match = this.router.match(method, path);\r\n\r\n // Create context (class-based, minimal allocations)\r\n const context = createContext<E>(\r\n request,\r\n match?.params || {},\r\n (options.env || {}) as E['Bindings']\r\n );\r\n\r\n try {\r\n if (match) {\r\n // Route found - execute with global middleware\r\n if (this.globalMiddleware.length === 0) {\r\n // No global middleware - direct handler call (fastest path)\r\n return await match.handler(context);\r\n } else {\r\n // Compile middleware chain\r\n const composed = compileMiddlewareChain(\r\n this.globalMiddleware,\r\n match.handler\r\n );\r\n return await composed(context);\r\n }\r\n } else {\r\n // No route found - execute not found handler\r\n return await this.getCompiledNotFoundHandler()(context);\r\n }\r\n } catch (error) {\r\n console.error('[Flight HTTP] Error:', error);\r\n return await this.errorHandler(\r\n error instanceof Error ? error : new Error(String(error)),\r\n context\r\n );\r\n }\r\n }\r\n\r\n // ========================================================================\r\n // Listen (Node.js adapter will override this)\r\n // ========================================================================\r\n\r\n listen(options?: ListenOptions | number): void {\r\n const port = typeof options === 'number' ? options : options?.port || 3000;\r\n console.log(`[Flight HTTP] Call adapter-specific listen() to start server on port ${port}`);\r\n console.log('[Flight HTTP] Import from \"@flight-framework/http/node\" or \"@flight-framework/http/bun\"');\r\n }\r\n\r\n // ========================================================================\r\n // Private Methods\r\n // ========================================================================\r\n\r\n private addRoute(\r\n method: HttpMethod | '*',\r\n path: string,\r\n handlers: HandlerOrMiddleware<E>[]\r\n ): FlightHttpServer<E> {\r\n // Last handler is the main handler\r\n const mainHandler = handlers[handlers.length - 1] as Handler<E>;\r\n const routeMiddleware = handlers.slice(0, -1) as Middleware<E>[];\r\n\r\n const fullPath = this.basePath + path;\r\n\r\n // Pre-compile route-specific middleware at registration time\r\n const compiledHandler = routeMiddleware.length > 0\r\n ? compileMiddlewareChain(routeMiddleware, mainHandler)\r\n : mainHandler;\r\n\r\n this.router.add(method, fullPath, compiledHandler);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Get pre-compiled not found handler (with global middleware)\r\n */\r\n private getCompiledNotFoundHandler(): Handler<E> {\r\n // Recompile if middleware changed\r\n if (this.lastCompiledVersion !== this.middlewareVersion || !this.compiledNotFoundHandler) {\r\n this.compiledNotFoundHandler = this.globalMiddleware.length > 0\r\n ? compileMiddlewareChain(this.globalMiddleware, this.notFoundHandler)\r\n : this.notFoundHandler;\r\n this.lastCompiledVersion = this.middlewareVersion;\r\n }\r\n return this.compiledNotFoundHandler;\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Factory Function\r\n// ============================================================================\r\n\r\n/**\r\n * Create a new Flight HTTP server\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createServer } from '@flight-framework/http';\r\n * \r\n * const app = createServer();\r\n * \r\n * app.get('/', (c) => c.json({ message: 'Hello Flight!' }));\r\n * \r\n * export default app;\r\n * ```\r\n */\r\nexport function createServer<E extends Env = Env>(\r\n options: ServerOptions = {}\r\n): FlightHttpServer<E> {\r\n return new FlightHttp<E>(options);\r\n}\r\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @flight/http - Types
|
|
2
|
+
* @flight-framework/http - Types
|
|
3
3
|
*
|
|
4
4
|
* Core type definitions for the HTTP server.
|
|
5
5
|
* Based on Web Standards API (Request, Response).
|
|
@@ -18,6 +18,12 @@ interface Context<E extends Env = Env> {
|
|
|
18
18
|
params: Record<string, string>;
|
|
19
19
|
/** Variables set by middleware */
|
|
20
20
|
variables: E['Variables'];
|
|
21
|
+
/** Cached parsed URL (lazy, parsed once) */
|
|
22
|
+
readonly url: URL;
|
|
23
|
+
/** Pathname from cached URL */
|
|
24
|
+
readonly pathname: string;
|
|
25
|
+
/** Query params from cached URL */
|
|
26
|
+
readonly query: URLSearchParams;
|
|
21
27
|
json: <T>(data: T, status?: number) => Response;
|
|
22
28
|
text: (text: string, status?: number) => Response;
|
|
23
29
|
html: (html: string, status?: number) => Response;
|
package/package.json
CHANGED
|
@@ -1,56 +1,57 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@flight-framework/http",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Ultra-fast HTTP server for Flight Framework - Built on Web Standards",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"flight",
|
|
7
|
+
"http",
|
|
8
|
+
"server",
|
|
9
|
+
"web-standards",
|
|
10
|
+
"edge"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "Flight Contributors",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./node": {
|
|
21
|
+
"types": "./dist/adapters/node.d.ts",
|
|
22
|
+
"import": "./dist/adapters/node.js"
|
|
23
|
+
},
|
|
24
|
+
"./bun": {
|
|
25
|
+
"types": "./dist/adapters/bun.d.ts",
|
|
26
|
+
"import": "./dist/adapters/bun.js"
|
|
27
|
+
},
|
|
28
|
+
"./deno": {
|
|
29
|
+
"types": "./dist/adapters/deno.d.ts",
|
|
30
|
+
"import": "./dist/adapters/deno.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"main": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"files": [
|
|
36
|
+
"dist"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsup",
|
|
40
|
+
"dev": "tsup --watch",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:watch": "vitest",
|
|
43
|
+
"lint": "eslint src/",
|
|
44
|
+
"clean": "rimraf dist",
|
|
45
|
+
"typecheck": "tsc --noEmit"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"radix3": "^1.1.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^22.0.0",
|
|
52
|
+
"rimraf": "^6.0.0",
|
|
53
|
+
"tsup": "^8.0.0",
|
|
54
|
+
"typescript": "^5.7.0",
|
|
55
|
+
"vitest": "^2.0.0"
|
|
56
|
+
}
|
|
56
57
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024-2026 Flight Contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|