srvx 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_middleware.mjs +13 -0
- package/dist/_plugins.mjs +16 -0
- package/dist/_url.d.mts +13 -0
- package/dist/_url.mjs +151 -0
- package/dist/bun.d.mts +22 -0
- package/dist/bun.mjs +77 -0
- package/dist/cloudflare.d.mts +10 -0
- package/dist/cloudflare.mjs +53 -0
- package/dist/deno.d.mts +22 -0
- package/dist/deno.mjs +86 -0
- package/dist/generic.d.mts +9 -0
- package/dist/generic.mjs +36 -0
- package/dist/node.d.mts +55 -0
- package/dist/node.mjs +813 -0
- package/dist/{adapters/service-worker.d.mts → service-worker.d.mts} +4 -8
- package/dist/service-worker.mjs +80 -0
- package/dist/types.d.mts +210 -217
- package/package.json +29 -26
- package/dist/adapters/bun.d.mts +0 -24
- package/dist/adapters/bun.mjs +0 -80
- package/dist/adapters/cloudflare.d.mts +0 -12
- package/dist/adapters/cloudflare.mjs +0 -54
- package/dist/adapters/deno.d.mts +0 -25
- package/dist/adapters/deno.mjs +0 -83
- package/dist/adapters/generic.d.mts +0 -12
- package/dist/adapters/generic.mjs +0 -28
- package/dist/adapters/node.d.mts +0 -55
- package/dist/adapters/node.mjs +0 -1014
- package/dist/adapters/service-worker.mjs +0 -95
- package/dist/shared/srvx.BMykKwGg.mjs +0 -16
- package/dist/shared/srvx.CEIXM-sv.mjs +0 -18
- package/dist/shared/srvx.Ctaz0clH.mjs +0 -172
- package/dist/shared/srvx.DEE2RO4O.d.mts +0 -5
- package/dist/shared/srvx.zEohKxBQ.mjs +0 -20
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/_middleware.ts
|
|
2
|
+
function wrapFetch(server) {
|
|
3
|
+
const fetchHandler = server.options.fetch;
|
|
4
|
+
const middleware = server.options.middleware || [];
|
|
5
|
+
return middleware.length === 0 ? fetchHandler : (request) => callMiddleware(request, fetchHandler, middleware, 0);
|
|
6
|
+
}
|
|
7
|
+
function callMiddleware(request, fetchHandler, middleware, index) {
|
|
8
|
+
if (index === middleware.length) return fetchHandler(request);
|
|
9
|
+
return middleware[index](request, () => callMiddleware(request, fetchHandler, middleware, index + 1));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
export { wrapFetch };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/_plugins.ts
|
|
2
|
+
const errorPlugin = (server) => {
|
|
3
|
+
const errorHandler = server.options.error;
|
|
4
|
+
if (!errorHandler) return;
|
|
5
|
+
server.options.middleware.unshift((_req, next) => {
|
|
6
|
+
try {
|
|
7
|
+
const res = next();
|
|
8
|
+
return res instanceof Promise ? res.catch((error) => errorHandler(error)) : res;
|
|
9
|
+
} catch (error) {
|
|
10
|
+
return errorHandler(error);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { errorPlugin };
|
package/dist/_url.d.mts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/_url.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Wrapper for URL with fast path access to `.pathname` and `.search` props.
|
|
4
|
+
*
|
|
5
|
+
* **NOTE:** It is assumed that the input URL is already ecoded and formatted from an HTTP request and contains no hash.
|
|
6
|
+
*
|
|
7
|
+
* **NOTE:** Triggering the setters or getters on other props will deoptimize to full URL parsing.
|
|
8
|
+
*/
|
|
9
|
+
declare const FastURL: {
|
|
10
|
+
new (url: string): URL;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { FastURL as FastURL$1 };
|
package/dist/_url.mjs
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
//#region src/_utils.node.ts
|
|
2
|
+
function resolvePortAndHost(opts) {
|
|
3
|
+
const _port = opts.port ?? globalThis.process?.env.PORT ?? 3e3;
|
|
4
|
+
const port = typeof _port === "number" ? _port : Number.parseInt(_port, 10);
|
|
5
|
+
const hostname = opts.hostname ?? globalThis.process?.env.HOST;
|
|
6
|
+
return {
|
|
7
|
+
port,
|
|
8
|
+
hostname
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function fmtURL(host, port, secure) {
|
|
12
|
+
if (!host || !port) return void 0;
|
|
13
|
+
if (host.includes(":")) host = `[${host}]`;
|
|
14
|
+
return `http${secure ? "s" : ""}://${host}:${port}/`;
|
|
15
|
+
}
|
|
16
|
+
function printListening(opts, url) {
|
|
17
|
+
if (!url || (opts.silent ?? globalThis.process?.env?.TEST)) return;
|
|
18
|
+
const _url = new URL(url);
|
|
19
|
+
const allInterfaces = _url.hostname === "[::]" || _url.hostname === "0.0.0.0";
|
|
20
|
+
if (allInterfaces) {
|
|
21
|
+
_url.hostname = "localhost";
|
|
22
|
+
url = _url.href;
|
|
23
|
+
}
|
|
24
|
+
let listeningOn = `➜ Listening on:`;
|
|
25
|
+
let additionalInfo = allInterfaces ? " (all interfaces)" : "";
|
|
26
|
+
if (globalThis.process.stdout?.isTTY) {
|
|
27
|
+
listeningOn = `\u001B[32m${listeningOn}\u001B[0m`;
|
|
28
|
+
url = `\u001B[36m${url}\u001B[0m`;
|
|
29
|
+
additionalInfo = `\u001B[2m${additionalInfo}\u001B[0m`;
|
|
30
|
+
}
|
|
31
|
+
console.log(` ${listeningOn} ${url}${additionalInfo}`);
|
|
32
|
+
}
|
|
33
|
+
function resolveTLSOptions(opts) {
|
|
34
|
+
if (!opts.tls || opts.protocol === "http") return;
|
|
35
|
+
const cert = resolveCertOrKey(opts.tls.cert);
|
|
36
|
+
const key = resolveCertOrKey(opts.tls.key);
|
|
37
|
+
if (!cert && !key) {
|
|
38
|
+
if (opts.protocol === "https") throw new TypeError("TLS `cert` and `key` must be provided for `https` protocol.");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!cert || !key) throw new TypeError("TLS `cert` and `key` must be provided together.");
|
|
42
|
+
return {
|
|
43
|
+
cert,
|
|
44
|
+
key,
|
|
45
|
+
passphrase: opts.tls.passphrase
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function resolveCertOrKey(value) {
|
|
49
|
+
if (!value) return;
|
|
50
|
+
if (typeof value !== "string") throw new TypeError("TLS certificate and key must be strings in PEM format or file paths.");
|
|
51
|
+
if (value.startsWith("-----BEGIN ")) return value;
|
|
52
|
+
const { readFileSync } = process.getBuiltinModule("node:fs");
|
|
53
|
+
return readFileSync(value, "utf8");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/_url.ts
|
|
58
|
+
/**
|
|
59
|
+
* Wrapper for URL with fast path access to `.pathname` and `.search` props.
|
|
60
|
+
*
|
|
61
|
+
* **NOTE:** It is assumed that the input URL is already ecoded and formatted from an HTTP request and contains no hash.
|
|
62
|
+
*
|
|
63
|
+
* **NOTE:** Triggering the setters or getters on other props will deoptimize to full URL parsing.
|
|
64
|
+
*/
|
|
65
|
+
const FastURL = /* @__PURE__ */ (() => {
|
|
66
|
+
const FastURL$1 = class URL$1 {
|
|
67
|
+
#originalURL;
|
|
68
|
+
#parsedURL;
|
|
69
|
+
_pathname;
|
|
70
|
+
_urlqindex;
|
|
71
|
+
_query;
|
|
72
|
+
_search;
|
|
73
|
+
constructor(url) {
|
|
74
|
+
this.#originalURL = url;
|
|
75
|
+
}
|
|
76
|
+
get _url() {
|
|
77
|
+
if (!this.#parsedURL) this.#parsedURL = new globalThis.URL(this.#originalURL);
|
|
78
|
+
return this.#parsedURL;
|
|
79
|
+
}
|
|
80
|
+
toString() {
|
|
81
|
+
return this._url.toString();
|
|
82
|
+
}
|
|
83
|
+
toJSON() {
|
|
84
|
+
return this.toString();
|
|
85
|
+
}
|
|
86
|
+
get pathname() {
|
|
87
|
+
if (this.#parsedURL) return this.#parsedURL.pathname;
|
|
88
|
+
if (this._pathname === void 0) {
|
|
89
|
+
const url = this.#originalURL;
|
|
90
|
+
const protoIndex = url.indexOf("://");
|
|
91
|
+
if (protoIndex === -1) return this._url.pathname;
|
|
92
|
+
const pIndex = url.indexOf(
|
|
93
|
+
"/",
|
|
94
|
+
protoIndex + 4
|
|
95
|
+
/* :// */
|
|
96
|
+
);
|
|
97
|
+
if (pIndex === -1) return this._url.pathname;
|
|
98
|
+
const qIndex = this._urlqindex = url.indexOf("?", pIndex);
|
|
99
|
+
this._pathname = url.slice(pIndex, qIndex === -1 ? void 0 : qIndex);
|
|
100
|
+
}
|
|
101
|
+
return this._pathname;
|
|
102
|
+
}
|
|
103
|
+
set pathname(value) {
|
|
104
|
+
this._pathname = void 0;
|
|
105
|
+
this._url.pathname = value;
|
|
106
|
+
}
|
|
107
|
+
get searchParams() {
|
|
108
|
+
if (this.#parsedURL) return this.#parsedURL.searchParams;
|
|
109
|
+
if (!this._query) this._query = new URLSearchParams(this.search);
|
|
110
|
+
return this._query;
|
|
111
|
+
}
|
|
112
|
+
get search() {
|
|
113
|
+
if (this.#parsedURL) return this.#parsedURL.search;
|
|
114
|
+
if (this._search === void 0) {
|
|
115
|
+
const qIndex = this._urlqindex;
|
|
116
|
+
if (qIndex === -1 || qIndex === this.#originalURL.length - 1) this._search = "";
|
|
117
|
+
else this._search = qIndex === void 0 ? this._url.search : this.#originalURL.slice(qIndex);
|
|
118
|
+
}
|
|
119
|
+
return this._search;
|
|
120
|
+
}
|
|
121
|
+
set search(value) {
|
|
122
|
+
this._search = void 0;
|
|
123
|
+
this._query = void 0;
|
|
124
|
+
this._url.search = value;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const slowProps = [
|
|
128
|
+
"hash",
|
|
129
|
+
"host",
|
|
130
|
+
"hostname",
|
|
131
|
+
"href",
|
|
132
|
+
"origin",
|
|
133
|
+
"password",
|
|
134
|
+
"port",
|
|
135
|
+
"protocol",
|
|
136
|
+
"username"
|
|
137
|
+
];
|
|
138
|
+
for (const prop of slowProps) Object.defineProperty(FastURL$1.prototype, prop, {
|
|
139
|
+
get() {
|
|
140
|
+
return this._url[prop];
|
|
141
|
+
},
|
|
142
|
+
set(value) {
|
|
143
|
+
this._url[prop] = value;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
Object.setPrototypeOf(FastURL$1, globalThis.URL);
|
|
147
|
+
return FastURL$1;
|
|
148
|
+
})();
|
|
149
|
+
|
|
150
|
+
//#endregion
|
|
151
|
+
export { FastURL, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions };
|
package/dist/bun.d.mts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BunFetchHandler, Server, ServerOptions } from "./types.mjs";
|
|
2
|
+
import { FastURL$1 as FastURL } from "./_url.mjs";
|
|
3
|
+
import * as bun from "bun";
|
|
4
|
+
|
|
5
|
+
//#region src/adapters/bun.d.ts
|
|
6
|
+
declare const FastResponse: typeof globalThis.Response;
|
|
7
|
+
declare function serve(options: ServerOptions): BunServer;
|
|
8
|
+
declare class BunServer implements Server<BunFetchHandler> {
|
|
9
|
+
readonly runtime = "bun";
|
|
10
|
+
readonly options: Server["options"];
|
|
11
|
+
readonly bun: Server["bun"];
|
|
12
|
+
readonly serveOptions: bun.ServeOptions | bun.TLSServeOptions;
|
|
13
|
+
readonly fetch: BunFetchHandler;
|
|
14
|
+
constructor(options: ServerOptions);
|
|
15
|
+
serve(): Promise<this>;
|
|
16
|
+
get url(): string | undefined;
|
|
17
|
+
ready(): Promise<this>;
|
|
18
|
+
close(closeAll?: boolean): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { FastResponse, FastURL, serve };
|
package/dist/bun.mjs
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { FastURL, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "./_url.mjs";
|
|
2
|
+
import { wrapFetch } from "./_middleware.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/adapters/bun.ts
|
|
5
|
+
const FastResponse = Response;
|
|
6
|
+
function serve(options) {
|
|
7
|
+
return new BunServer(options);
|
|
8
|
+
}
|
|
9
|
+
var BunServer = class {
|
|
10
|
+
runtime = "bun";
|
|
11
|
+
options;
|
|
12
|
+
bun = {};
|
|
13
|
+
serveOptions;
|
|
14
|
+
fetch;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.options = {
|
|
17
|
+
...options,
|
|
18
|
+
middleware: [...options.middleware || []]
|
|
19
|
+
};
|
|
20
|
+
for (const plugin of options.plugins || []) plugin(this);
|
|
21
|
+
const fetchHandler = wrapFetch(this);
|
|
22
|
+
this.fetch = (request, server) => {
|
|
23
|
+
Object.defineProperties(request, {
|
|
24
|
+
runtime: {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
value: {
|
|
27
|
+
runtime: "bun",
|
|
28
|
+
bun: { server }
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
ip: {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get() {
|
|
34
|
+
return server?.requestIP(request)?.address;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return fetchHandler(request);
|
|
39
|
+
};
|
|
40
|
+
const tls = resolveTLSOptions(this.options);
|
|
41
|
+
this.serveOptions = {
|
|
42
|
+
...resolvePortAndHost(this.options),
|
|
43
|
+
reusePort: this.options.reusePort,
|
|
44
|
+
error: this.options.error,
|
|
45
|
+
...this.options.bun,
|
|
46
|
+
tls: {
|
|
47
|
+
cert: tls?.cert,
|
|
48
|
+
key: tls?.key,
|
|
49
|
+
passphrase: tls?.passphrase,
|
|
50
|
+
...this.options.bun?.tls
|
|
51
|
+
},
|
|
52
|
+
fetch: this.fetch
|
|
53
|
+
};
|
|
54
|
+
if (!options.manual) this.serve();
|
|
55
|
+
}
|
|
56
|
+
serve() {
|
|
57
|
+
if (!this.bun.server) this.bun.server = Bun.serve(this.serveOptions);
|
|
58
|
+
printListening(this.options, this.url);
|
|
59
|
+
return Promise.resolve(this);
|
|
60
|
+
}
|
|
61
|
+
get url() {
|
|
62
|
+
const server = this.bun?.server;
|
|
63
|
+
if (!server) return;
|
|
64
|
+
const address = server.address;
|
|
65
|
+
if (address) return fmtURL(address.address, address.port, server.protocol === "https");
|
|
66
|
+
return server.url.href;
|
|
67
|
+
}
|
|
68
|
+
ready() {
|
|
69
|
+
return Promise.resolve(this);
|
|
70
|
+
}
|
|
71
|
+
close(closeAll) {
|
|
72
|
+
return Promise.resolve(this.bun?.server?.stop(closeAll));
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
77
|
+
export { FastResponse, FastURL, serve };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Server, ServerOptions } from "./types.mjs";
|
|
2
|
+
import * as CF from "@cloudflare/workers-types";
|
|
3
|
+
|
|
4
|
+
//#region src/adapters/cloudflare.d.ts
|
|
5
|
+
declare const FastURL: typeof globalThis.URL;
|
|
6
|
+
declare const FastResponse: typeof globalThis.Response;
|
|
7
|
+
declare function serve(options: ServerOptions): Server<CF.ExportedHandlerFetchHandler>;
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { FastResponse, FastURL, serve };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { wrapFetch } from "./_middleware.mjs";
|
|
2
|
+
import { errorPlugin } from "./_plugins.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/adapters/cloudflare.ts
|
|
5
|
+
const FastURL = URL;
|
|
6
|
+
const FastResponse = Response;
|
|
7
|
+
function serve(options) {
|
|
8
|
+
return new CloudflareServer(options);
|
|
9
|
+
}
|
|
10
|
+
var CloudflareServer = class {
|
|
11
|
+
runtime = "cloudflare";
|
|
12
|
+
options;
|
|
13
|
+
serveOptions;
|
|
14
|
+
fetch;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.options = {
|
|
17
|
+
...options,
|
|
18
|
+
middleware: [...options.middleware || []]
|
|
19
|
+
};
|
|
20
|
+
for (const plugin of options.plugins || []) plugin(this);
|
|
21
|
+
errorPlugin(this);
|
|
22
|
+
const fetchHandler = wrapFetch(this);
|
|
23
|
+
this.fetch = (request, env, context) => {
|
|
24
|
+
Object.defineProperties(request, { runtime: {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
value: {
|
|
27
|
+
runtime: "cloudflare",
|
|
28
|
+
cloudflare: {
|
|
29
|
+
env,
|
|
30
|
+
context
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
} });
|
|
34
|
+
return fetchHandler(request);
|
|
35
|
+
};
|
|
36
|
+
this.serveOptions = { fetch: this.fetch };
|
|
37
|
+
if (!options.manual) this.serve();
|
|
38
|
+
}
|
|
39
|
+
serve() {
|
|
40
|
+
addEventListener("fetch", (event) => {
|
|
41
|
+
event.respondWith(this.fetch(event.request, {}, event));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
ready() {
|
|
45
|
+
return Promise.resolve().then(() => this);
|
|
46
|
+
}
|
|
47
|
+
close() {
|
|
48
|
+
return Promise.resolve();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
export { FastResponse, FastURL, serve };
|
package/dist/deno.d.mts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DenoFetchHandler, Server, ServerOptions } from "./types.mjs";
|
|
2
|
+
import { FastURL$1 as FastURL } from "./_url.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/adapters/deno.d.ts
|
|
5
|
+
declare const FastResponse: typeof globalThis.Response;
|
|
6
|
+
declare function serve(options: ServerOptions): DenoServer;
|
|
7
|
+
declare class DenoServer implements Server<DenoFetchHandler> {
|
|
8
|
+
#private;
|
|
9
|
+
readonly runtime = "deno";
|
|
10
|
+
readonly options: Server["options"];
|
|
11
|
+
readonly deno: Server["deno"];
|
|
12
|
+
readonly serveOptions: Deno.ServeTcpOptions | (Deno.ServeTcpOptions & Deno.TlsCertifiedKeyPem);
|
|
13
|
+
readonly fetch: DenoFetchHandler;
|
|
14
|
+
constructor(options: ServerOptions);
|
|
15
|
+
serve(): Promise<this>;
|
|
16
|
+
get url(): string | undefined;
|
|
17
|
+
ready(): Promise<Server>;
|
|
18
|
+
close(): Promise<void | undefined>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { FastResponse, FastURL, serve };
|
package/dist/deno.mjs
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { FastURL, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "./_url.mjs";
|
|
2
|
+
import { wrapFetch } from "./_middleware.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/adapters/deno.ts
|
|
5
|
+
const FastResponse = Response;
|
|
6
|
+
function serve(options) {
|
|
7
|
+
return new DenoServer(options);
|
|
8
|
+
}
|
|
9
|
+
var DenoServer = class {
|
|
10
|
+
runtime = "deno";
|
|
11
|
+
options;
|
|
12
|
+
deno = {};
|
|
13
|
+
serveOptions;
|
|
14
|
+
fetch;
|
|
15
|
+
#listeningPromise;
|
|
16
|
+
#listeningInfo;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.options = {
|
|
19
|
+
...options,
|
|
20
|
+
middleware: [...options.middleware || []]
|
|
21
|
+
};
|
|
22
|
+
for (const plugin of options.plugins || []) plugin(this);
|
|
23
|
+
const fetchHandler = wrapFetch(this);
|
|
24
|
+
this.fetch = (request, info) => {
|
|
25
|
+
Object.defineProperties(request, {
|
|
26
|
+
runtime: {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
value: {
|
|
29
|
+
runtime: "deno",
|
|
30
|
+
deno: {
|
|
31
|
+
info,
|
|
32
|
+
server: this.deno?.server
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
ip: {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get() {
|
|
39
|
+
return (info?.remoteAddr)?.hostname;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return fetchHandler(request);
|
|
44
|
+
};
|
|
45
|
+
const tls = resolveTLSOptions(this.options);
|
|
46
|
+
this.serveOptions = {
|
|
47
|
+
...resolvePortAndHost(this.options),
|
|
48
|
+
reusePort: this.options.reusePort,
|
|
49
|
+
onError: this.options.error,
|
|
50
|
+
...tls ? {
|
|
51
|
+
key: tls.key,
|
|
52
|
+
cert: tls.cert,
|
|
53
|
+
passphrase: tls.passphrase
|
|
54
|
+
} : {},
|
|
55
|
+
...this.options.deno
|
|
56
|
+
};
|
|
57
|
+
if (!options.manual) this.serve();
|
|
58
|
+
}
|
|
59
|
+
serve() {
|
|
60
|
+
if (this.deno?.server) return Promise.resolve(this.#listeningPromise).then(() => this);
|
|
61
|
+
const onListenPromise = Promise.withResolvers();
|
|
62
|
+
this.#listeningPromise = onListenPromise.promise;
|
|
63
|
+
this.deno.server = Deno.serve({
|
|
64
|
+
...this.serveOptions,
|
|
65
|
+
onListen: (info) => {
|
|
66
|
+
this.#listeningInfo = info;
|
|
67
|
+
if (this.options.deno?.onListen) this.options.deno.onListen(info);
|
|
68
|
+
printListening(this.options, this.url);
|
|
69
|
+
onListenPromise.resolve();
|
|
70
|
+
}
|
|
71
|
+
}, this.fetch);
|
|
72
|
+
return Promise.resolve(this.#listeningPromise).then(() => this);
|
|
73
|
+
}
|
|
74
|
+
get url() {
|
|
75
|
+
return this.#listeningInfo ? fmtURL(this.#listeningInfo.hostname, this.#listeningInfo.port, !!this.serveOptions.cert) : void 0;
|
|
76
|
+
}
|
|
77
|
+
ready() {
|
|
78
|
+
return Promise.resolve(this.#listeningPromise).then(() => this);
|
|
79
|
+
}
|
|
80
|
+
close() {
|
|
81
|
+
return Promise.resolve(this.deno?.server?.shutdown());
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
export { FastResponse, FastURL, serve };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Server, ServerOptions } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/adapters/generic.d.ts
|
|
4
|
+
declare const FastURL: typeof globalThis.URL;
|
|
5
|
+
declare const FastResponse: typeof globalThis.Response;
|
|
6
|
+
declare function serve(options: ServerOptions): Server;
|
|
7
|
+
|
|
8
|
+
//#endregion
|
|
9
|
+
export { FastResponse, FastURL, serve };
|
package/dist/generic.mjs
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { wrapFetch } from "./_middleware.mjs";
|
|
2
|
+
import { errorPlugin } from "./_plugins.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/adapters/generic.ts
|
|
5
|
+
const FastURL = URL;
|
|
6
|
+
const FastResponse = Response;
|
|
7
|
+
function serve(options) {
|
|
8
|
+
return new GenericServer(options);
|
|
9
|
+
}
|
|
10
|
+
var GenericServer = class {
|
|
11
|
+
runtime = "generic";
|
|
12
|
+
options;
|
|
13
|
+
fetch;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.options = {
|
|
16
|
+
...options,
|
|
17
|
+
middleware: [...options.middleware || []]
|
|
18
|
+
};
|
|
19
|
+
for (const plugin of options.plugins || []) plugin(this);
|
|
20
|
+
errorPlugin(this);
|
|
21
|
+
const fetchHandler = wrapFetch(this);
|
|
22
|
+
this.fetch = (request) => {
|
|
23
|
+
return Promise.resolve(fetchHandler(request));
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
serve() {}
|
|
27
|
+
ready() {
|
|
28
|
+
return Promise.resolve(this);
|
|
29
|
+
}
|
|
30
|
+
close() {
|
|
31
|
+
return Promise.resolve();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { FastResponse, FastURL, serve };
|
package/dist/node.d.mts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { FetchHandler, NodeHttpHandler, NodeServerRequest, NodeServerResponse, Server, ServerOptions, ServerRequest } from "./types.mjs";
|
|
2
|
+
import { FastURL$1 as FastURL } from "./_url.mjs";
|
|
3
|
+
import NodeHttp from "node:http";
|
|
4
|
+
import { Readable } from "node:stream";
|
|
5
|
+
|
|
6
|
+
//#region src/adapters/_node/request.d.ts
|
|
7
|
+
type NodeRequestContext = {
|
|
8
|
+
req: NodeServerRequest;
|
|
9
|
+
res?: NodeServerResponse;
|
|
10
|
+
};
|
|
11
|
+
declare const NodeRequest: {
|
|
12
|
+
new (nodeCtx: NodeRequestContext): ServerRequest;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/adapters/_node/headers.d.ts
|
|
17
|
+
declare const NodeRequestHeaders: {
|
|
18
|
+
new (nodeCtx: {
|
|
19
|
+
req: NodeServerRequest;
|
|
20
|
+
res?: NodeServerResponse;
|
|
21
|
+
}): globalThis.Headers;
|
|
22
|
+
};
|
|
23
|
+
declare const NodeResponseHeaders: {
|
|
24
|
+
new (nodeCtx: {
|
|
25
|
+
req?: NodeServerRequest;
|
|
26
|
+
res: NodeServerResponse;
|
|
27
|
+
}): globalThis.Headers;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/adapters/_node/response.d.ts
|
|
32
|
+
type NodeResponse = InstanceType<typeof NodeResponse>;
|
|
33
|
+
/**
|
|
34
|
+
* Fast Response for Node.js runtime
|
|
35
|
+
*
|
|
36
|
+
* It is faster because in most cases it doesn't create a full Response instance.
|
|
37
|
+
*/
|
|
38
|
+
declare const NodeResponse: {
|
|
39
|
+
new (body?: BodyInit | null, init?: ResponseInit): globalThis.Response & {
|
|
40
|
+
readonly nodeResponse: () => {
|
|
41
|
+
status: number;
|
|
42
|
+
statusText: string;
|
|
43
|
+
headers: NodeHttp.OutgoingHttpHeader[];
|
|
44
|
+
body: string | Buffer | Uint8Array | DataView | ReadableStream<Uint8Array> | Readable | undefined | null;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/adapters/node.d.ts
|
|
51
|
+
declare function serve(options: ServerOptions): Server;
|
|
52
|
+
declare function toNodeHandler(fetchHandler: FetchHandler): NodeHttpHandler;
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
export { NodeResponse as FastResponse, FastURL, NodeRequest, NodeRequestHeaders, NodeResponse, NodeResponseHeaders, serve, toNodeHandler };
|