srvx 0.9.2 → 0.9.3

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.
@@ -0,0 +1,61 @@
1
+ import { Colors } from "./_utils.cli-B2YzwlOv.mjs";
2
+
3
+ //#region src/_middleware.ts
4
+ function wrapFetch(server) {
5
+ const fetchHandler = server.options.fetch;
6
+ const middleware = server.options.middleware || [];
7
+ return middleware.length === 0 ? fetchHandler : (request) => callMiddleware(request, fetchHandler, middleware, 0);
8
+ }
9
+ function callMiddleware(request, fetchHandler, middleware, index) {
10
+ if (index === middleware.length) return fetchHandler(request);
11
+ return middleware[index](request, () => callMiddleware(request, fetchHandler, middleware, index + 1));
12
+ }
13
+
14
+ //#endregion
15
+ //#region src/_plugins.ts
16
+ const errorPlugin = (server) => {
17
+ const errorHandler = server.options.error;
18
+ if (!errorHandler) return;
19
+ server.options.middleware.unshift((_req, next) => {
20
+ try {
21
+ const res = next();
22
+ return res instanceof Promise ? res.catch((error) => errorHandler(error)) : res;
23
+ } catch (error) {
24
+ return errorHandler(error);
25
+ }
26
+ });
27
+ };
28
+ const gracefulShutdownPlugin = (server) => {
29
+ const config = server.options?.gracefulShutdown;
30
+ if (!globalThis.process?.on || config === false || config === void 0 && (process.env.CI || process.env.TEST)) return;
31
+ const gracefulShutdown = config === true || !config?.gracefulTimeout ? Number.parseInt(process.env.SERVER_SHUTDOWN_TIMEOUT || "") || 3 : config.gracefulTimeout;
32
+ const forceShutdown = config === true || !config?.forceTimeout ? Number.parseInt(process.env.SERVER_FORCE_SHUTDOWN_TIMEOUT || "") || 5 : config.forceTimeout;
33
+ let isShuttingDown = false;
34
+ const shutdown = async () => {
35
+ if (isShuttingDown) return;
36
+ isShuttingDown = true;
37
+ console.log(Colors.gray(`\nShutting down server... (timeout in ${gracefulShutdown}+${forceShutdown}s)`));
38
+ let timeout;
39
+ await Promise.race([server.close().finally(() => {
40
+ clearTimeout(timeout);
41
+ console.log(Colors.green("Server closed all connections."));
42
+ }), new Promise((resolve) => {
43
+ timeout = setTimeout(() => {
44
+ console.warn(Colors.yellow(`Forcing closing connections to exit... (timeout in ${forceShutdown}s)`));
45
+ timeout = setTimeout(() => {
46
+ console.error(Colors.red("Could not close connections in time, force exiting."));
47
+ resolve();
48
+ }, 1e3);
49
+ return server.close(true).finally(() => {
50
+ clearTimeout(timeout);
51
+ resolve();
52
+ });
53
+ }, 1e3);
54
+ })]);
55
+ globalThis.process.exit(0);
56
+ };
57
+ for (const sig of ["SIGINT", "SIGTERM"]) globalThis.process.on(sig, shutdown);
58
+ };
59
+
60
+ //#endregion
61
+ export { errorPlugin, gracefulShutdownPlugin, wrapFetch };
@@ -0,0 +1,4 @@
1
+ import "./_inherit-B9eAGP_O.mjs";
2
+ import { callNodeHandler } from "./call-BUTAdRs1.mjs";
3
+
4
+ export { callNodeHandler };
@@ -93,6 +93,17 @@ interface ServerOptions {
93
93
  */
94
94
  silent?: boolean;
95
95
  /**
96
+ * Graceful shutdown on SIGINT and SIGTERM signals.
97
+ *
98
+ * Supported for Node.js, Deno and Bun runtimes.
99
+ *
100
+ * @default true (disabled in test and ci environments)
101
+ */
102
+ gracefulShutdown?: boolean | {
103
+ gracefulTimeout?: number;
104
+ forceTimeout?: number;
105
+ };
106
+ /**
96
107
  * TLS server options.
97
108
  */
98
109
  tls?: {
@@ -1,5 +1,5 @@
1
- import { BunFetchHandler, Server, ServerOptions } from "../_chunks/types-4jUOEbJe.mjs";
2
- import { FastURL$2 as FastURL } from "../_chunks/_url-D-jAQyRZ.mjs";
1
+ import { BunFetchHandler, Server, ServerOptions } from "../_chunks/types-sQhe-gMy.mjs";
2
+ import { FastURL$2 as FastURL } from "../_chunks/_url-Dd8UPFqt.mjs";
3
3
  import * as bun from "bun";
4
4
 
5
5
  //#region src/adapters/bun.d.ts
@@ -1,7 +1,8 @@
1
+ import "../_chunks/_utils.cli-B2YzwlOv.mjs";
1
2
  import "../_chunks/_inherit-B9eAGP_O.mjs";
2
3
  import { FastURL$1 as FastURL } from "../_chunks/_url-DF-_pEPn.mjs";
3
4
  import { createWaitUntil, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "../_chunks/_utils-dqVgpDNy.mjs";
4
- import { wrapFetch } from "../_chunks/_middleware-Z-W2xNSK.mjs";
5
+ import { gracefulShutdownPlugin, wrapFetch } from "../_chunks/_plugins-DBERsPAu.mjs";
5
6
 
6
7
  //#region src/adapters/bun.ts
7
8
  const FastResponse = Response;
@@ -21,6 +22,7 @@ var BunServer = class {
21
22
  middleware: [...options.middleware || []]
22
23
  };
23
24
  for (const plugin of options.plugins || []) plugin(this);
25
+ gracefulShutdownPlugin(this);
24
26
  const fetchHandler = wrapFetch(this);
25
27
  this.#wait = createWaitUntil();
26
28
  this.fetch = (request, server) => {
@@ -1,4 +1,4 @@
1
- import { Server, ServerOptions } from "../_chunks/types-4jUOEbJe.mjs";
1
+ import { Server, ServerOptions } from "../_chunks/types-sQhe-gMy.mjs";
2
2
  import * as CF from "@cloudflare/workers-types";
3
3
 
4
4
  //#region src/adapters/cloudflare.d.ts
@@ -1,5 +1,5 @@
1
- import { wrapFetch } from "../_chunks/_middleware-Z-W2xNSK.mjs";
2
- import { errorPlugin } from "../_chunks/_plugins-DOhVIkXu.mjs";
1
+ import "../_chunks/_utils.cli-B2YzwlOv.mjs";
2
+ import { errorPlugin, wrapFetch } from "../_chunks/_plugins-DBERsPAu.mjs";
3
3
 
4
4
  //#region src/adapters/cloudflare.ts
5
5
  const FastURL = URL;
@@ -1,5 +1,5 @@
1
- import { DenoFetchHandler, Server, ServerOptions } from "../_chunks/types-4jUOEbJe.mjs";
2
- import { FastURL$2 as FastURL } from "../_chunks/_url-D-jAQyRZ.mjs";
1
+ import { DenoFetchHandler, Server, ServerOptions } from "../_chunks/types-sQhe-gMy.mjs";
2
+ import { FastURL$2 as FastURL } from "../_chunks/_url-Dd8UPFqt.mjs";
3
3
 
4
4
  //#region src/adapters/deno.d.ts
5
5
  declare const FastResponse: typeof globalThis.Response;
@@ -1,7 +1,8 @@
1
+ import "../_chunks/_utils.cli-B2YzwlOv.mjs";
1
2
  import "../_chunks/_inherit-B9eAGP_O.mjs";
2
3
  import { FastURL$1 as FastURL } from "../_chunks/_url-DF-_pEPn.mjs";
3
4
  import { createWaitUntil, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "../_chunks/_utils-dqVgpDNy.mjs";
4
- import { wrapFetch } from "../_chunks/_middleware-Z-W2xNSK.mjs";
5
+ import { gracefulShutdownPlugin, wrapFetch } from "../_chunks/_plugins-DBERsPAu.mjs";
5
6
 
6
7
  //#region src/adapters/deno.ts
7
8
  const FastResponse = Response;
@@ -23,6 +24,7 @@ var DenoServer = class {
23
24
  middleware: [...options.middleware || []]
24
25
  };
25
26
  for (const plugin of options.plugins || []) plugin(this);
27
+ gracefulShutdownPlugin(this);
26
28
  const fetchHandler = wrapFetch(this);
27
29
  this.#wait = createWaitUntil();
28
30
  this.fetch = (request, info) => {
@@ -1,4 +1,4 @@
1
- import { Server, ServerOptions } from "../_chunks/types-4jUOEbJe.mjs";
1
+ import { Server, ServerOptions } from "../_chunks/types-sQhe-gMy.mjs";
2
2
 
3
3
  //#region src/adapters/generic.d.ts
4
4
  declare const FastURL: typeof globalThis.URL;
@@ -1,6 +1,6 @@
1
+ import "../_chunks/_utils.cli-B2YzwlOv.mjs";
1
2
  import { createWaitUntil } from "../_chunks/_utils-dqVgpDNy.mjs";
2
- import { wrapFetch } from "../_chunks/_middleware-Z-W2xNSK.mjs";
3
- import { errorPlugin } from "../_chunks/_plugins-DOhVIkXu.mjs";
3
+ import { errorPlugin, wrapFetch } from "../_chunks/_plugins-DBERsPAu.mjs";
4
4
 
5
5
  //#region src/adapters/generic.ts
6
6
  const FastURL = URL;
@@ -1,5 +1,5 @@
1
- import { FetchHandler, NodeHttpHandler, NodeServerRequest, NodeServerResponse, Server, ServerOptions, ServerRequest } from "../_chunks/types-4jUOEbJe.mjs";
2
- import { FastURL$2 as FastURL } from "../_chunks/_url-D-jAQyRZ.mjs";
1
+ import { FetchHandler, NodeHttpHandler, NodeServerRequest, NodeServerResponse, Server, ServerOptions, ServerRequest } from "../_chunks/types-sQhe-gMy.mjs";
2
+ import { FastURL$2 as FastURL } from "../_chunks/_url-Dd8UPFqt.mjs";
3
3
  import { Readable } from "node:stream";
4
4
 
5
5
  //#region src/adapters/_node/request.d.ts
@@ -1,9 +1,9 @@
1
+ import "../_chunks/_utils.cli-B2YzwlOv.mjs";
1
2
  import { lazyInherit } from "../_chunks/_inherit-B9eAGP_O.mjs";
2
3
  import { FastURL$1 as FastURL } from "../_chunks/_url-DF-_pEPn.mjs";
3
4
  import { createWaitUntil, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "../_chunks/_utils-dqVgpDNy.mjs";
4
- import { wrapFetch } from "../_chunks/_middleware-Z-W2xNSK.mjs";
5
- import { errorPlugin } from "../_chunks/_plugins-DOhVIkXu.mjs";
6
- import { NodeResponse, callNodeHandler } from "../_chunks/call-gjL9LWHI.mjs";
5
+ import { errorPlugin, gracefulShutdownPlugin, wrapFetch } from "../_chunks/_plugins-DBERsPAu.mjs";
6
+ import { NodeResponse, callNodeHandler } from "../_chunks/call-BUTAdRs1.mjs";
7
7
  import nodeHTTP, { IncomingMessage, ServerResponse } from "node:http";
8
8
  import { Duplex, Readable } from "node:stream";
9
9
  import nodeHTTPS from "node:https";
@@ -568,6 +568,7 @@ var NodeServer = class {
568
568
  };
569
569
  for (const plugin of options.plugins || []) plugin(this);
570
570
  errorPlugin(this);
571
+ gracefulShutdownPlugin(this);
571
572
  const fetchHandler = this.fetch = wrapFetch(this);
572
573
  this.#wait = createWaitUntil();
573
574
  const handler = (nodeReq, nodeRes) => {
@@ -1,4 +1,4 @@
1
- import { Server, ServerOptions, ServerRequest } from "../_chunks/types-4jUOEbJe.mjs";
1
+ import { Server, ServerOptions, ServerRequest } from "../_chunks/types-sQhe-gMy.mjs";
2
2
 
3
3
  //#region src/adapters/service-worker.d.ts
4
4
  declare const FastURL: typeof globalThis.URL;
@@ -1,5 +1,5 @@
1
- import { wrapFetch } from "../_chunks/_middleware-Z-W2xNSK.mjs";
2
- import { errorPlugin } from "../_chunks/_plugins-DOhVIkXu.mjs";
1
+ import "../_chunks/_utils.cli-B2YzwlOv.mjs";
2
+ import { errorPlugin, wrapFetch } from "../_chunks/_plugins-DBERsPAu.mjs";
3
3
 
4
4
  //#region src/adapters/service-worker.ts
5
5
  const FastURL = URL;
package/dist/cli.mjs CHANGED
@@ -103,18 +103,6 @@ async function serve() {
103
103
  await server.ready();
104
104
  await globalThis.__srvx_listen_cb__?.();
105
105
  printInfo(entry);
106
- let cleanupCalled = false;
107
- const cleanup = (exitCode) => {
108
- if (cleanupCalled) return;
109
- cleanupCalled = true;
110
- console.log(Colors.gray("\rGracefully stopping server..."));
111
- server.close(true).catch(console.error).then(() => {
112
- console.log(Colors.gray("Server stopped."));
113
- process.exit(exitCode || 0);
114
- });
115
- };
116
- process.on("SIGINT", () => cleanup(130));
117
- process.on("SIGTERM", () => cleanup(143));
118
106
  } catch (error) {
119
107
  console.error(error);
120
108
  process.exit(1);
@@ -148,7 +136,7 @@ async function loadEntry(opts) {
148
136
  const nodeHandler = listenHandler || (typeof mod.default === "function" ? mod.default : void 0);
149
137
  if (nodeHandler) {
150
138
  _legacyNode = true;
151
- const { callNodeHandler } = await import("./_chunks/call-Bz_KtGHu.mjs");
139
+ const { callNodeHandler } = await import("./_chunks/call-DdhHMGpi.mjs");
152
140
  fetchHandler = (webReq) => callNodeHandler(nodeHandler, webReq);
153
141
  }
154
142
  }
@@ -229,7 +217,7 @@ async function interceptListen(cb) {
229
217
  };
230
218
  }
231
219
  async function version() {
232
- const version$1 = "0.9.1";
220
+ const version$1 = "0.9.3";
233
221
  return `srvx ${version$1}\n${runtime()}`;
234
222
  }
235
223
  function runtime() {
package/dist/log.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { ServerMiddleware } from "./_chunks/types-4jUOEbJe.mjs";
1
+ import { ServerMiddleware } from "./_chunks/types-sQhe-gMy.mjs";
2
2
 
3
3
  //#region src/log.d.ts
4
4
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
package/dist/static.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { ServerMiddleware } from "./_chunks/types-4jUOEbJe.mjs";
1
+ import { ServerMiddleware } from "./_chunks/types-sQhe-gMy.mjs";
2
2
 
3
3
  //#region src/static.d.ts
4
4
  interface ServeStaticOptions {
package/dist/types.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { BunFetchHandler, CloudflareFetchHandler, DenoFetchHandler, ErrorHandler, FastResponse, FastURL, FetchHandler, NodeHTTPMiddleware, NodeHttpHandler, NodeServerRequest, NodeServerResponse, Server, ServerHandler, ServerMiddleware, ServerOptions, ServerPlugin, ServerRequest, ServerRequestContext, ServerRuntimeContext, serve } from "./_chunks/types-4jUOEbJe.mjs";
1
+ import { BunFetchHandler, CloudflareFetchHandler, DenoFetchHandler, ErrorHandler, FastResponse, FastURL, FetchHandler, NodeHTTPMiddleware, NodeHttpHandler, NodeServerRequest, NodeServerResponse, Server, ServerHandler, ServerMiddleware, ServerOptions, ServerPlugin, ServerRequest, ServerRequestContext, ServerRuntimeContext, serve } from "./_chunks/types-sQhe-gMy.mjs";
2
2
  export { BunFetchHandler, CloudflareFetchHandler, DenoFetchHandler, ErrorHandler, FastResponse, FastURL, FetchHandler, NodeHTTPMiddleware, NodeHttpHandler, NodeServerRequest, NodeServerResponse, Server, ServerHandler, ServerMiddleware, ServerOptions, ServerPlugin, ServerRequest, ServerRequestContext, ServerRuntimeContext, serve };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "srvx",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "description": "Universal Server API based on web platform standards. Works seamlessly with Deno, Bun and Node.js.",
5
5
  "homepage": "https://srvx.h3.dev",
6
6
  "repository": "h3js/srvx",
@@ -1,13 +0,0 @@
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 };
@@ -1,16 +0,0 @@
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 };
@@ -1,4 +0,0 @@
1
- import "./_inherit-B9eAGP_O.mjs";
2
- import { callNodeHandler } from "./call-gjL9LWHI.mjs";
3
-
4
- export { callNodeHandler };