@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.
- package/.dist/cjs/index.d.ts +1 -0
- package/.dist/cjs/index.d.ts.map +1 -0
- package/.dist/cjs/src/bunHttp.d.ts +1 -0
- package/.dist/cjs/src/bunHttp.d.ts.map +1 -0
- package/.dist/cjs/src/constants.d.ts +1 -0
- package/.dist/cjs/src/constants.d.ts.map +1 -0
- package/.dist/cjs/src/types.d.ts +1 -0
- package/.dist/cjs/src/types.d.ts.map +1 -0
- package/.dist/esm/index.d.ts +1 -0
- package/.dist/esm/index.d.ts.map +1 -0
- package/.dist/esm/src/bunHttp.d.ts +1 -0
- package/.dist/esm/src/bunHttp.d.ts.map +1 -0
- package/.dist/esm/src/constants.d.ts +1 -0
- package/.dist/esm/src/constants.d.ts.map +1 -0
- package/.dist/esm/src/types.d.ts +1 -0
- package/.dist/esm/src/types.d.ts.map +1 -0
- package/index.ts +10 -0
- package/package.json +9 -5
- package/src/bunHttp.ts +199 -0
- package/src/constants.ts +19 -0
- package/src/types.ts +25 -0
package/.dist/cjs/index.d.ts
CHANGED
|
@@ -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"}
|
|
@@ -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"}
|
package/.dist/cjs/src/types.d.ts
CHANGED
|
@@ -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/.dist/esm/index.d.ts
CHANGED
|
@@ -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"}
|
|
@@ -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"}
|
package/.dist/esm/src/types.d.ts
CHANGED
|
@@ -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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mionjs/platform-bun",
|
|
3
|
-
"version": "0.8.
|
|
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.
|
|
60
|
-
"@mionjs/router": "0.8.
|
|
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": "
|
|
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
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -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
|