@mionjs/platform-bun 0.8.7 → 0.8.8

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.
@@ -1,3 +1,4 @@
1
1
  export * from './src/types.ts';
2
2
  export * from './src/bunHttp.ts';
3
3
  export * from './src/constants.ts';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAOA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC"}
@@ -3,3 +3,4 @@ import { Server } from 'bun';
3
3
  export declare function resetBunHttpOpts(): void;
4
4
  export declare function setBunHttpOpts(options?: Partial<BunHttpOptions>): Readonly<BunHttpOptions>;
5
5
  export declare function startBunServer(options?: Partial<BunHttpOptions>): Promise<Server<any>>;
6
+ //# sourceMappingURL=bunHttp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bunHttp.d.ts","sourceRoot":"","sources":["../../../src/bunHttp.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAI/C,OAAO,EAAC,MAAM,EAAC,MAAM,KAAK,CAAC;AAO3B,wBAAgB,gBAAgB,SAI/B;AAED,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,4BAQ/D;AAED,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAsG5F"}
@@ -1,2 +1,3 @@
1
1
  import { BunHttpOptions } from './types.ts';
2
2
  export declare const DEFAULT_BUN_HTTP_OPTIONS: BunHttpOptions;
3
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/constants.ts"],"names":[],"mappings":"AAOA,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAE1C,eAAO,MAAM,wBAAwB,EAAE,cAStC,CAAC"}
@@ -7,3 +7,4 @@ export interface BunHttpOptions {
7
7
  }
8
8
  export {};
9
9
  export declare type __ΩBunHttpOptions = any[];
10
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAQA,KAAK,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,GACrE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AAG/D,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IAEb,OAAO,EAAE,eAAe,CAAC;IAEzB,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAK/C,WAAW,EAAE,MAAM,CAAC;CACvB"}
@@ -1,3 +1,4 @@
1
1
  export * from './src/types.ts';
2
2
  export * from './src/bunHttp.ts';
3
3
  export * from './src/constants.ts';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAOA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC"}
@@ -3,3 +3,4 @@ import { Server } from 'bun';
3
3
  export declare function resetBunHttpOpts(): void;
4
4
  export declare function setBunHttpOpts(options?: Partial<BunHttpOptions>): Readonly<BunHttpOptions>;
5
5
  export declare function startBunServer(options?: Partial<BunHttpOptions>): Promise<Server<any>>;
6
+ //# sourceMappingURL=bunHttp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bunHttp.d.ts","sourceRoot":"","sources":["../../../src/bunHttp.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAI/C,OAAO,EAAC,MAAM,EAAC,MAAM,KAAK,CAAC;AAO3B,wBAAgB,gBAAgB,SAI/B;AAED,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,4BAQ/D;AAED,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAsG5F"}
@@ -1,2 +1,3 @@
1
1
  import { BunHttpOptions } from './types.ts';
2
2
  export declare const DEFAULT_BUN_HTTP_OPTIONS: BunHttpOptions;
3
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/constants.ts"],"names":[],"mappings":"AAOA,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAE1C,eAAO,MAAM,wBAAwB,EAAE,cAStC,CAAC"}
@@ -7,3 +7,4 @@ export interface BunHttpOptions {
7
7
  }
8
8
  export {};
9
9
  export declare type __ΩBunHttpOptions = any[];
10
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAQA,KAAK,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,GACrE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AAG/D,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IAEb,OAAO,EAAE,eAAe,CAAC;IAEzB,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAK/C,WAAW,EAAE,MAAM,CAAC;CACvB"}
package/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ /* ########
2
+ * 2023 mion
3
+ * Author: Ma-jerez
4
+ * License: MIT
5
+ * The software is provided "as is", without warranty of any kind.
6
+ * ######## */
7
+
8
+ export * from './src/types.ts';
9
+ export * from './src/bunHttp.ts';
10
+ export * from './src/constants.ts';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mionjs/platform-bun",
3
- "version": "0.8.7",
3
+ "version": "0.8.8",
4
4
  "description": "mion server for bun runtime",
5
5
  "keywords": [
6
6
  "typescript",
@@ -30,7 +30,11 @@
30
30
  "lib": ".dist"
31
31
  },
32
32
  "files": [
33
- ".dist"
33
+ ".dist",
34
+ "index.ts",
35
+ "src",
36
+ "!src/**/*.spec.ts",
37
+ "!src/**/*.test.ts"
34
38
  ],
35
39
  "repository": {
36
40
  "type": "git",
@@ -56,8 +60,8 @@
56
60
  "url": "https://github.com/MionKit/mion/issues"
57
61
  },
58
62
  "dependencies": {
59
- "@mionjs/core": "0.8.7",
60
- "@mionjs/router": "0.8.7"
63
+ "@mionjs/core": "0.8.8",
64
+ "@mionjs/router": "0.8.8"
61
65
  },
62
66
  "devDependencies": {
63
67
  "@deepkit/core": "1.0.19",
@@ -67,5 +71,5 @@
67
71
  "peerDependencies": {
68
72
  "typescript": ">=6.0.0"
69
73
  },
70
- "gitHead": "03190d1125582fe2e37c9168f6e406a91b3c4cff"
74
+ "gitHead": "a92a438011336a078d394b75054422f3a56f8468"
71
75
  }
package/src/bunHttp.ts ADDED
@@ -0,0 +1,199 @@
1
+ /* ########
2
+ * 2023 mion
3
+ * Author: Ma-jerez
4
+ * License: MIT
5
+ * The software is provided "as is", without warranty of any kind.
6
+ * ######## */
7
+
8
+ import {
9
+ dispatchRoute,
10
+ getRouterFatalErrorResponse,
11
+ resetRouter,
12
+ decodeQueryBody,
13
+ setPlatformConfig,
14
+ MionResponse as MionResponse,
15
+ } from '@mionjs/router';
16
+ import {DEFAULT_BUN_HTTP_OPTIONS} from './constants.ts';
17
+ import type {BunHttpOptions} from './types.ts';
18
+ import {getENV, isMionCompileMode, SerializerModes} from '@mionjs/core';
19
+ import type {SerializerCode} from '@mionjs/core';
20
+ import {RpcError} from '@mionjs/core';
21
+ import {Server} from 'bun';
22
+
23
+ // ############# PRIVATE STATE #############
24
+
25
+ let httpOptions: Readonly<BunHttpOptions> = {...DEFAULT_BUN_HTTP_OPTIONS};
26
+ let defaultHeaders: [string, string][] = [['server', '@mionjs']];
27
+
28
+ export function resetBunHttpOpts() {
29
+ httpOptions = {...DEFAULT_BUN_HTTP_OPTIONS};
30
+ defaultHeaders = [['server', '@mionjs']];
31
+ resetRouter();
32
+ }
33
+
34
+ export function setBunHttpOpts(options?: Partial<BunHttpOptions>) {
35
+ httpOptions = {
36
+ ...httpOptions,
37
+ ...options,
38
+ };
39
+ // Pre-build default headers array once
40
+ defaultHeaders = [['server', '@mionjs'], ...Object.entries(httpOptions.defaultResponseHeaders)];
41
+ return httpOptions;
42
+ }
43
+
44
+ export async function startBunServer(options?: Partial<BunHttpOptions>): Promise<Server<any>> {
45
+ const isTest = getENV('NODE_ENV') === 'test';
46
+ const isCompiling = isMionCompileMode();
47
+
48
+ if (options) setBunHttpOpts(options);
49
+
50
+ if (isCompiling) {
51
+ console.log('Compiling routes metadata and skipping mion server initialization...', {
52
+ port: httpOptions.port,
53
+ httpOptions,
54
+ });
55
+ return undefined as any;
56
+ }
57
+
58
+ const port = httpOptions.port !== 80 ? `:${httpOptions.port}` : '';
59
+ const url = `http://localhost${port}`;
60
+ if (!isTest && !isCompiling) console.log(`mion bun server running on ${url}`);
61
+ const server = Bun.serve({
62
+ maxRequestBodySize: httpOptions.maxBodySize,
63
+ port: httpOptions.port,
64
+ ...httpOptions.options,
65
+
66
+ async fetch(req) {
67
+ const reqUrl = req.url;
68
+ const pathStart = reqUrl.indexOf('/', 8);
69
+ const queryStart = reqUrl.indexOf('?', pathStart);
70
+ const path = queryStart === -1 ? reqUrl.slice(pathStart) : reqUrl.slice(pathStart, queryStart);
71
+ const urlQuery = queryStart === -1 ? undefined : reqUrl.slice(queryStart + 1);
72
+ const contentType = req.headers.get('content-type') || '';
73
+ const isBinary = contentType.startsWith('application/octet-stream');
74
+ let rawBody: any = req.body
75
+ ? isBinary
76
+ ? await req.arrayBuffer()
77
+ : ((await req.json()) as Record<string, unknown>)
78
+ : undefined;
79
+ let reqBodyType: SerializerCode = isBinary ? SerializerModes.binary : SerializerModes.json;
80
+ const queryBody = decodeQueryBody(urlQuery, rawBody);
81
+ if (queryBody) {
82
+ rawBody = queryBody.rawBody;
83
+ reqBodyType = queryBody.bodyType;
84
+ }
85
+ const responseHeaders = new Headers(defaultHeaders);
86
+
87
+ try {
88
+ const platformResp = await dispatchRoute(
89
+ path,
90
+ rawBody,
91
+ req.headers,
92
+ responseHeaders,
93
+ req,
94
+ undefined,
95
+ reqBodyType,
96
+ urlQuery
97
+ );
98
+ return reply(platformResp, responseHeaders);
99
+ } catch (e) {
100
+ const error =
101
+ e instanceof RpcError
102
+ ? e
103
+ : new RpcError({
104
+ publicMessage: 'Unknown Error',
105
+ type: 'unknown-error',
106
+ originalError: e as Error,
107
+ });
108
+ return fatalFail(error, responseHeaders);
109
+ }
110
+ },
111
+ error(errReq) {
112
+ const responseHeaders = new Headers({
113
+ server: '@mionjs',
114
+ ...httpOptions.defaultResponseHeaders,
115
+ });
116
+ const error =
117
+ errReq instanceof RpcError
118
+ ? errReq
119
+ : new RpcError({
120
+ publicMessage: 'Connection Error',
121
+ type: 'response-connection-error',
122
+ originalError: errReq,
123
+ });
124
+ return fatalFail(error, responseHeaders);
125
+ },
126
+ });
127
+
128
+ const shutdownHandler = function () {
129
+ if (!isTest) console.log(`Shutting down mion server on ${url}`);
130
+ server.stop(true);
131
+ process.exit(0);
132
+ };
133
+
134
+ process.on('SIGINT', shutdownHandler);
135
+ process.on('SIGTERM', shutdownHandler);
136
+
137
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
138
+ const {options: _nativeOpts, ...serializableConfig} = httpOptions;
139
+ setPlatformConfig(serializableConfig);
140
+
141
+ // Hint to Bun's GC after initialization to clean up any temporary allocations
142
+ if (typeof Bun !== 'undefined' && Bun.gc) {
143
+ Bun.gc(false);
144
+ }
145
+ return server;
146
+ }
147
+
148
+ // only called whe there is an htt error or weird unhandled route errors
149
+ function fatalFail(err: RpcError<string>, responseHeaders: any): Response {
150
+ const routeResponse = getRouterFatalErrorResponse(err, responseHeaders);
151
+ return reply(routeResponse, responseHeaders);
152
+ }
153
+
154
+ function reply(
155
+ mionResp: MionResponse,
156
+ // TODO: fix issue with Native Bun Headers type messing with Node Headers type
157
+ // responseHeaders: Headers,
158
+ responseHeaders: any
159
+ ): Response {
160
+ const bodyType = mionResp.serializer;
161
+ switch (bodyType) {
162
+ case SerializerModes.stringifyJson: {
163
+ // Pass string directly to Response - Bun handles encoding internally
164
+ // and calculates content-length automatically. This avoids TextEncoder allocation.
165
+ // content-type already set by serializer
166
+ return new Response(mionResp.rawBody as string, {
167
+ status: mionResp.statusCode,
168
+ headers: responseHeaders,
169
+ });
170
+ }
171
+ case SerializerModes.json: {
172
+ // Platform adapter uses Response.json() which handles JSON.stringify internally
173
+ return Response.json(mionResp.body, {
174
+ status: mionResp.statusCode,
175
+ headers: responseHeaders,
176
+ });
177
+ }
178
+ case SerializerModes.binary: {
179
+ const serializer = mionResp.binSerializer!;
180
+ responseHeaders.set('content-length', String(serializer.getLength()));
181
+ // content-type already set by serializer
182
+ const response = new Response(serializer.getBufferView(), {
183
+ status: mionResp.statusCode,
184
+ headers: responseHeaders,
185
+ });
186
+ // Mark buffer as ended immediately - Bun copies the buffer to the response
187
+ serializer.markAsEnded();
188
+ return response;
189
+ }
190
+ default: {
191
+ const error = new RpcError({
192
+ publicMessage: 'unknown-mion-response-format',
193
+ type: 'unknown-error',
194
+ errorData: {bodyType},
195
+ });
196
+ return fatalFail(error, responseHeaders);
197
+ }
198
+ }
199
+ }
@@ -0,0 +1,19 @@
1
+ /* ########
2
+ * 2022 mion
3
+ * Author: Ma-jerez
4
+ * License: MIT
5
+ * The software is provided "as is", without warranty of any kind.
6
+ * ######## */
7
+
8
+ import {BunHttpOptions} from './types.ts';
9
+
10
+ export const DEFAULT_BUN_HTTP_OPTIONS: BunHttpOptions = {
11
+ port: 80,
12
+ options: {},
13
+ defaultResponseHeaders: {},
14
+ /**
15
+ * 256KB by default, same as lambda payload
16
+ * @link https://docs.aws.amazon.com/lambda/latest/operatorguide/payload.html
17
+ * */
18
+ maxBodySize: 256000, // 256KB
19
+ };
package/src/types.ts ADDED
@@ -0,0 +1,25 @@
1
+ /* ########
2
+ * 2022 mion
3
+ * Author: Ma-jerez
4
+ * License: MIT
5
+ * The software is provided "as is", without warranty of any kind.
6
+ * ######## */
7
+
8
+ /** Bun serve options without fetch/error handlers (those are provided by mion) */
9
+ type BunServeOptions = Omit<Bun.Serve.BaseServeOptions<unknown>, 'error'> &
10
+ Omit<Bun.Serve.HostnamePortServeOptions<unknown>, 'error'>;
11
+
12
+ // type-bun-http-options-start
13
+ export interface BunHttpOptions {
14
+ port: number;
15
+ /** Bun's native Server Options */
16
+ options: BunServeOptions;
17
+ /** Set of default response header to add to every response*/
18
+ defaultResponseHeaders: Record<string, string>;
19
+ /**
20
+ * 256KB by default, same as lambda payload
21
+ * @link https://docs.aws.amazon.com/lambda/latest/operatorguide/payload.html
22
+ * */
23
+ maxBodySize: number; // default 256KB
24
+ }
25
+ // type-bun-http-options-end