sevok 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.
@@ -0,0 +1,32 @@
1
+ import { d as RuntimeAdapter, f as RuntimeCapabilities, p as Server } from "./core-BGp2ZR_k.mjs";
2
+
3
+ //#region src/deno.d.ts
4
+ /**
5
+ * Runtime adapter that backs `Server` with `Deno.serve()`.
6
+ */
7
+ declare class DenoRuntimeAdapter implements RuntimeAdapter {
8
+ #private;
9
+ readonly graceful = true;
10
+ get capabilities(): RuntimeCapabilities;
11
+ /**
12
+ * Translate generic server options into Deno's `serve` options.
13
+ */
14
+ setup(server: Server): void;
15
+ /**
16
+ * Start Deno's HTTP server and resolve only after the runtime reports the
17
+ * bound address via `onListen`.
18
+ */
19
+ serve(server: Server): Promise<{
20
+ url: string | undefined;
21
+ }>;
22
+ /**
23
+ * Derive the public URL from the last `onListen` callback.
24
+ */
25
+ get url(): string | undefined;
26
+ /**
27
+ * Gracefully shut down the Deno server, if one is active.
28
+ */
29
+ close(): Promise<void>;
30
+ }
31
+ //#endregion
32
+ export { DenoRuntimeAdapter };
package/dist/deno.mjs ADDED
@@ -0,0 +1,65 @@
1
+ import { n as resolveTLSOptions, r as runtimeCapabilities, t as printListening } from "./_node_like-BRaAGeNM.mjs";
2
+ import { a as fmtURL, s as resolvePortAndHost } from "./_shared-38k_JIsU.mjs";
3
+ //#region src/deno.ts
4
+ /**
5
+ * Runtime adapter that backs `Server` with `Deno.serve()`.
6
+ */
7
+ var DenoRuntimeAdapter = class {
8
+ #server;
9
+ #listeningPromise;
10
+ #listeningInfo;
11
+ #serveOptions;
12
+ graceful = true;
13
+ get capabilities() {
14
+ return runtimeCapabilities;
15
+ }
16
+ /**
17
+ * Translate generic server options into Deno's `serve` options.
18
+ */
19
+ setup(server) {
20
+ const { options } = server;
21
+ const tls = resolveTLSOptions(options);
22
+ this.#serveOptions = {
23
+ ...resolvePortAndHost(options),
24
+ reusePort: options.reusePort,
25
+ onError: options.error,
26
+ ...tls,
27
+ ...options.deno
28
+ };
29
+ }
30
+ /**
31
+ * Start Deno's HTTP server and resolve only after the runtime reports the
32
+ * bound address via `onListen`.
33
+ */
34
+ async serve(server) {
35
+ if (this.#server) return Promise.resolve(this.#listeningPromise).then(() => ({ url: this.url }));
36
+ const onListenPromise = Promise.withResolvers();
37
+ this.#listeningPromise = onListenPromise.promise;
38
+ this.#server = Deno.serve({
39
+ ...this.#serveOptions,
40
+ onListen: (info) => {
41
+ this.#listeningInfo = info;
42
+ if (this.#serveOptions?.onListen) this.#serveOptions.onListen(info);
43
+ printListening(server.options, this.url);
44
+ onListenPromise.resolve();
45
+ }
46
+ }, (request) => server.fetch(request));
47
+ return Promise.resolve(this.#listeningPromise).then(() => ({ url: this.url }));
48
+ }
49
+ /**
50
+ * Derive the public URL from the last `onListen` callback.
51
+ */
52
+ get url() {
53
+ return this.#listeningInfo ? fmtURL(this.#listeningInfo.hostname, this.#listeningInfo.port, !!this.#serveOptions.cert) : void 0;
54
+ }
55
+ /**
56
+ * Gracefully shut down the Deno server, if one is active.
57
+ */
58
+ async close() {
59
+ return Promise.resolve(this.#server?.shutdown()).then(() => {
60
+ this.#server = void 0;
61
+ });
62
+ }
63
+ };
64
+ //#endregion
65
+ export { DenoRuntimeAdapter };
@@ -0,0 +1,2 @@
1
+ import { A as WaitUntil, B as unstable_buildRouteTree, C as ServerPlugin, D as UnstableConvertRoutesToHandlerOptions, E as TLSOptions, F as loadServerAdapter, H as unstable_match, I as raceRequestAbort, L as runMiddleware, M as createContextKey, N as createWaitUntil, O as UnstableRouteMatch, P as isServerHandlerObject, R as serve, S as ServerOptions, T as ServerServeEvent, U as wrapFetch, V as unstable_convertRoutesToHandler, _ as ServerEventMapCustom, a as InvocationContext, b as ServerInit, c as InvocationContextValue, d as RuntimeAdapter, f as RuntimeCapabilities, g as ServerEventMap, h as ServerErrorEvent, i as HTTPMethod, j as WaitUntilFunction, k as UnstableRouteMatchResult, l as MaybePromise, m as ServerCloseEvent, n as DenoServerOptions, o as InvocationContextInit, p as Server, r as ErrorHandler, s as InvocationContextKey, t as BunServerOptions, u as NodeServerOptions, v as ServerHandler, w as ServerRoutes, x as ServerMiddleware, y as ServerHandlerObject, z as toServerHandlerObject } from "./core-BGp2ZR_k.mjs";
2
+ export { BunServerOptions, DenoServerOptions, ErrorHandler, HTTPMethod, InvocationContext, InvocationContextInit, InvocationContextKey, InvocationContextValue, MaybePromise, NodeServerOptions, RuntimeAdapter, RuntimeCapabilities, Server, ServerCloseEvent, ServerErrorEvent, ServerEventMap, ServerEventMapCustom, ServerHandler, ServerHandlerObject, ServerInit, ServerMiddleware, ServerOptions, ServerPlugin, ServerRoutes, ServerServeEvent, TLSOptions, UnstableConvertRoutesToHandlerOptions, UnstableRouteMatch, UnstableRouteMatchResult, WaitUntil, WaitUntilFunction, createContextKey, createWaitUntil, isServerHandlerObject, loadServerAdapter, raceRequestAbort, runMiddleware, serve, toServerHandlerObject, unstable_buildRouteTree, unstable_convertRoutesToHandler, unstable_match, wrapFetch };
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { _ as unstable_match, a as ServerServeEvent, c as createWaitUntil, d as raceRequestAbort, f as runMiddleware, g as unstable_convertRoutesToHandler, h as unstable_buildRouteTree, i as ServerErrorEvent, l as isServerHandlerObject, m as toServerHandlerObject, n as Server, p as serve, r as ServerCloseEvent, s as createContextKey, t as InvocationContext, u as loadServerAdapter, v as wrapFetch } from "./core-CmUugTW7.mjs";
2
+ export { InvocationContext, Server, ServerCloseEvent, ServerErrorEvent, ServerServeEvent, createContextKey, createWaitUntil, isServerHandlerObject, loadServerAdapter, raceRequestAbort, runMiddleware, serve, toServerHandlerObject, unstable_buildRouteTree, unstable_convertRoutesToHandler, unstable_match, wrapFetch };
package/dist/log.d.mts ADDED
@@ -0,0 +1,27 @@
1
+ import { x as ServerMiddleware } from "./core-BGp2ZR_k.mjs";
2
+
3
+ //#region src/log.d.ts
4
+ /**
5
+ * Logging middleware options.
6
+ *
7
+ * Reserved for future customization of log format and destination.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * declare module "sevok/log" {
12
+ * interface LogOptions {
13
+ * requestId?: boolean;
14
+ * }
15
+ * }
16
+ * ```
17
+ */
18
+ interface LogOptions {}
19
+ /**
20
+ * Create a request logger middleware.
21
+ *
22
+ * Each completed request prints timestamp, method, url, status code, and total
23
+ * response time using simple terminal colors.
24
+ */
25
+ declare const log: (_options?: LogOptions) => ServerMiddleware;
26
+ //#endregion
27
+ export { LogOptions, log };
package/dist/log.mjs ADDED
@@ -0,0 +1,26 @@
1
+ import { t as _color_default } from "./_color-B42q-MpL.mjs";
2
+ //#region src/log.ts
3
+ const statusColors = {
4
+ 1: _color_default.blue,
5
+ 2: _color_default.green,
6
+ 3: _color_default.yellow
7
+ };
8
+ /**
9
+ * Create a request logger middleware.
10
+ *
11
+ * Each completed request prints timestamp, method, url, status code, and total
12
+ * response time using simple terminal colors.
13
+ */
14
+ const log = (_options = {}) => {
15
+ return async (ctx, next) => {
16
+ const start = performance.now();
17
+ const req = ctx.request;
18
+ const res = await next(ctx);
19
+ const duration = performance.now() - start;
20
+ const statusColor = statusColors[Math.floor(res.status / 100)] || _color_default.red;
21
+ console.log(`${_color_default.gray(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}]`)} ${_color_default.bold(req.method)} ${_color_default.blue(req.url)} [${statusColor(res.status + "")}] ${_color_default.gray(`(${duration.toFixed(2)}ms)`)}`);
22
+ return res;
23
+ };
24
+ };
25
+ //#endregion
26
+ export { log };
@@ -0,0 +1,32 @@
1
+ import { d as RuntimeAdapter, f as RuntimeCapabilities, p as Server } from "./core-BGp2ZR_k.mjs";
2
+
3
+ //#region src/node.d.ts
4
+ /**
5
+ * Runtime adapter that backs `Server` with Node's HTTP, HTTPS, or HTTP/2
6
+ * servers depending on the effective TLS configuration.
7
+ */
8
+ declare class NodeRuntimeAdapter implements RuntimeAdapter {
9
+ #private;
10
+ readonly graceful = true;
11
+ get capabilities(): RuntimeCapabilities;
12
+ /**
13
+ * Create the underlying Node server instance but do not start listening yet.
14
+ */
15
+ setup(server: Server): void;
16
+ /**
17
+ * Start the Node server once and reuse the same ready promise afterwards.
18
+ */
19
+ serve(server: Server): Promise<{
20
+ url: string | undefined;
21
+ }>;
22
+ /**
23
+ * Return either a socket path or a formatted origin for TCP listeners.
24
+ */
25
+ get url(): string | undefined;
26
+ /**
27
+ * Stop accepting new work and optionally close active HTTP connections.
28
+ */
29
+ close(closeActiveConnections: boolean): Promise<void>;
30
+ }
31
+ //#endregion
32
+ export { NodeRuntimeAdapter };
package/dist/node.mjs ADDED
@@ -0,0 +1,139 @@
1
+ import { n as resolveTLSOptions, r as runtimeCapabilities, t as printListening } from "./_node_like-BRaAGeNM.mjs";
2
+ import { a as fmtURL, s as resolvePortAndHost } from "./_shared-38k_JIsU.mjs";
3
+ import nodeHTTP from "node:http";
4
+ import nodeHTTPS from "node:https";
5
+ import nodeHTTP2 from "node:http2";
6
+ //#region src/node.ts
7
+ /**
8
+ * Runtime adapter that backs `Server` with Node's HTTP, HTTPS, or HTTP/2
9
+ * servers depending on the effective TLS configuration.
10
+ */
11
+ var NodeRuntimeAdapter = class {
12
+ #server;
13
+ #serveOptions;
14
+ #isSecure;
15
+ #listeningPromise;
16
+ graceful = true;
17
+ get capabilities() {
18
+ return runtimeCapabilities;
19
+ }
20
+ /**
21
+ * Create the underlying Node server instance but do not start listening yet.
22
+ */
23
+ setup(server) {
24
+ const { options } = server;
25
+ const { hostname, port } = resolvePortAndHost(options);
26
+ const tls = resolveTLSOptions(options);
27
+ const isSecure = !!tls?.cert && options.protocol !== "http";
28
+ const isHttp2 = options.node?.http2 ?? isSecure;
29
+ this.#isSecure = isSecure;
30
+ this.#serveOptions = {
31
+ port,
32
+ host: hostname,
33
+ exclusive: !server.options.reusePort,
34
+ ...tls ? {
35
+ cert: tls.cert,
36
+ key: tls.key,
37
+ passphrase: tls.passphrase
38
+ } : {},
39
+ ...options.node
40
+ };
41
+ const handler = async (request, response) => {
42
+ await handleNodeRequest(server, request, response);
43
+ };
44
+ if (isHttp2) if (isSecure) this.#server = nodeHTTP2.createSecureServer({
45
+ allowHTTP1: true,
46
+ ...this.#serveOptions
47
+ }, handler);
48
+ else throw new Error("node.http2 option requires tls certificate!");
49
+ else if (isSecure) this.#server = nodeHTTPS.createServer(this.#serveOptions, handler);
50
+ else this.#server = nodeHTTP.createServer(this.#serveOptions, handler);
51
+ }
52
+ /**
53
+ * Start the Node server once and reuse the same ready promise afterwards.
54
+ */
55
+ async serve(server) {
56
+ if (this.#listeningPromise) return Promise.resolve(this.#listeningPromise).then(() => ({ url: this.url }));
57
+ this.#listeningPromise = new Promise((resolve) => {
58
+ this.#server.listen(this.#serveOptions, () => {
59
+ printListening(server.options, this.url);
60
+ resolve({ url: this.url });
61
+ });
62
+ });
63
+ return this.#listeningPromise;
64
+ }
65
+ /**
66
+ * Return either a socket path or a formatted origin for TCP listeners.
67
+ */
68
+ get url() {
69
+ const addr = this.#server?.address();
70
+ if (!addr) return;
71
+ return typeof addr === "string" ? addr : fmtURL(addr.address, addr.port, this.#isSecure);
72
+ }
73
+ /**
74
+ * Stop accepting new work and optionally close active HTTP connections.
75
+ */
76
+ close(closeActiveConnections) {
77
+ return new Promise((resolve, reject) => {
78
+ const server = this.#server;
79
+ if (server && closeActiveConnections && "closeAllConnections" in server) server.closeAllConnections();
80
+ if (!server || !server.listening) return resolve();
81
+ server.close((error) => error ? reject(error) : resolve());
82
+ });
83
+ }
84
+ };
85
+ /**
86
+ * Convert a Node request/response pair into fetch primitives and forward
87
+ * framework-level errors through the configured error handler.
88
+ */
89
+ async function handleNodeRequest(server, request, response) {
90
+ try {
91
+ const nextRequest = await toRequest(request);
92
+ await writeResponse(response, await server.fetch(nextRequest));
93
+ } catch (error) {
94
+ await writeResponse(response, server.options.error ? await server.options.error(error) : new Response("Internal Server Error", { status: 500 }));
95
+ }
96
+ }
97
+ /**
98
+ * Convert Node's `IncomingMessage` into a standard `Request`.
99
+ */
100
+ async function toRequest(request) {
101
+ const protocol = request.socket.encrypted ? "https" : "http";
102
+ const host = request.headers.host ?? "127.0.0.1";
103
+ const url = new URL(request.url ?? "/", `${protocol}://${host}`);
104
+ const headers = new Headers();
105
+ for (const [key, value] of Object.entries(request.headers)) {
106
+ if (Array.isArray(value)) {
107
+ for (const entry of value) headers.append(key, entry);
108
+ continue;
109
+ }
110
+ if (typeof value === "string") headers.set(key, value);
111
+ }
112
+ const init = {
113
+ method: request.method,
114
+ headers
115
+ };
116
+ if (request.method !== "GET" && request.method !== "HEAD") {
117
+ const { Readable } = await import("node:stream");
118
+ init.body = Readable.toWeb(request);
119
+ init.duplex = "half";
120
+ }
121
+ return new Request(url.toString(), init);
122
+ }
123
+ /**
124
+ * Write a fetch `Response` back to Node's `ServerResponse`.
125
+ */
126
+ async function writeResponse(response, nextResponse) {
127
+ response.statusCode = nextResponse.status;
128
+ response.statusMessage = nextResponse.statusText;
129
+ nextResponse.headers.forEach((value, key) => {
130
+ response.setHeader(key, value);
131
+ });
132
+ if (!nextResponse.body) {
133
+ response.end();
134
+ return;
135
+ }
136
+ response.end(Buffer.from(await nextResponse.arrayBuffer()));
137
+ }
138
+ //#endregion
139
+ export { NodeRuntimeAdapter };
@@ -0,0 +1,35 @@
1
+ import { l as MaybePromise, x as ServerMiddleware } from "./core-BGp2ZR_k.mjs";
2
+
3
+ //#region src/static.d.ts
4
+ /**
5
+ * Configuration for `serveStatic()`.
6
+ */
7
+ interface ServeStaticOptions {
8
+ /**
9
+ * The directory to serve static files from.
10
+ */
11
+ dir: string;
12
+ /**
13
+ * The HTTP methods to allow for serving static files.
14
+ */
15
+ methods?: string[];
16
+ /**
17
+ * A function to modify the HTML content before serving it.
18
+ */
19
+ renderHTML?: (ctx: {
20
+ request: Request;
21
+ html: string;
22
+ filename: string;
23
+ }) => MaybePromise<Response>;
24
+ }
25
+ /**
26
+ * Create middleware that serves files from a runtime-provided filesystem.
27
+ *
28
+ * Resolution follows common static-site conventions:
29
+ * - `/` maps to `index.html`
30
+ * - extensionless paths try `name.html` and `name/index.html`
31
+ * - explicit extensions are used as-is
32
+ */
33
+ declare function serveStatic(options: ServeStaticOptions): ServerMiddleware;
34
+ //#endregion
35
+ export { ServeStaticOptions, serveStatic };
@@ -0,0 +1,100 @@
1
+ //#region src/static.ts
2
+ const COMMON_MIME_TYPES = {
3
+ ".html": "text/html",
4
+ ".htm": "text/html",
5
+ ".css": "text/css",
6
+ ".js": "text/javascript",
7
+ ".mjs": "text/javascript",
8
+ ".json": "application/json",
9
+ ".txt": "text/plain",
10
+ ".xml": "application/xml",
11
+ ".gif": "image/gif",
12
+ ".ico": "image/vnd.microsoft.icon",
13
+ ".jpeg": "image/jpeg",
14
+ ".jpg": "image/jpeg",
15
+ ".png": "image/png",
16
+ ".svg": "image/svg+xml",
17
+ ".webp": "image/webp",
18
+ ".woff": "font/woff",
19
+ ".woff2": "font/woff2",
20
+ ".mp4": "video/mp4",
21
+ ".webm": "video/webm",
22
+ ".zip": "application/zip",
23
+ ".pdf": "application/pdf"
24
+ };
25
+ /**
26
+ * Create middleware that serves files from a runtime-provided filesystem.
27
+ *
28
+ * Resolution follows common static-site conventions:
29
+ * - `/` maps to `index.html`
30
+ * - extensionless paths try `name.html` and `name/index.html`
31
+ * - explicit extensions are used as-is
32
+ */
33
+ function serveStatic(options) {
34
+ const methods = new Set((options.methods || ["GET", "HEAD"]).map((m) => m.toUpperCase()));
35
+ return async (ctx, next) => {
36
+ const req = ctx.request;
37
+ if (!methods.has(req.method)) return next(ctx);
38
+ const path = (ctx.url ??= new URL(req.url)).pathname.slice(1).replace(/\/$/, "");
39
+ let paths;
40
+ if (path === "") paths = ["index.html"];
41
+ else if (extname(path) === "") paths = [`${path}.html`, `${path}/index.html`];
42
+ else paths = [path];
43
+ const fs = ctx.capabilities;
44
+ for (const path of paths) {
45
+ const filePath = await fs.resolve(options.dir, path);
46
+ if (!filePath) continue;
47
+ const file = await fs.open(filePath);
48
+ if (file?.isFile) {
49
+ const fileExt = extname(filePath);
50
+ const headers = new Headers({
51
+ "Content-Length": file.size.toString(),
52
+ "Content-Type": COMMON_MIME_TYPES[fileExt] || "application/octet-stream"
53
+ });
54
+ const stream = file.stream();
55
+ if (options.renderHTML && fileExt === ".html") {
56
+ const html = await read(stream);
57
+ return options.renderHTML({
58
+ html,
59
+ filename: filePath,
60
+ request: req
61
+ });
62
+ }
63
+ const acceptEncoding = req.headers.get("accept-encoding") || "";
64
+ if (acceptEncoding.includes("br")) {
65
+ headers.set("Content-Encoding", "br");
66
+ headers.delete("Content-Length");
67
+ headers.set("Vary", "Accept-Encoding");
68
+ const { readable, writable } = await fs.createBrotliCompress();
69
+ await stream.pipeTo(writable);
70
+ return new Response(readable, { headers });
71
+ } else if (acceptEncoding.includes("gzip")) {
72
+ headers.set("Content-Encoding", "gzip");
73
+ headers.delete("Content-Length");
74
+ headers.set("Vary", "Accept-Encoding");
75
+ const { readable, writable } = await fs.createGzip();
76
+ await stream.pipeTo(writable);
77
+ return new Response(readable, { headers });
78
+ } else return new Response(stream, { headers });
79
+ }
80
+ }
81
+ return next(ctx);
82
+ };
83
+ }
84
+ /**
85
+ * Extract a file extension without relying on Node's path helpers so the
86
+ * function also works in non-Node runtimes.
87
+ */
88
+ function extname(path) {
89
+ const lastSlash = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
90
+ const lastDot = path.lastIndexOf(".");
91
+ return lastDot > lastSlash ? path.slice(lastDot) : "";
92
+ }
93
+ /**
94
+ * Consume a `ReadableStream` into a UTF-8 string.
95
+ */
96
+ async function read(stream) {
97
+ return await new Response(stream).text();
98
+ }
99
+ //#endregion
100
+ export { serveStatic };
@@ -0,0 +1,56 @@
1
+ import { d as RuntimeAdapter, f as RuntimeCapabilities, j as WaitUntilFunction, p as Server } from "./core-BGp2ZR_k.mjs";
2
+
3
+ //#region src/stream.d.ts
4
+ /**
5
+ * Minimal request entry shape consumed by `handleRequestEntry()`.
6
+ *
7
+ * This intentionally matches service-worker-like runtimes that expose a request
8
+ * plus completion hooks rather than direct socket APIs.
9
+ */
10
+ interface RequestEntry {
11
+ readonly request: Request;
12
+ readonly waitUntil?: WaitUntilFunction;
13
+ completeWith(promise: Promise<Response>): void;
14
+ }
15
+ /**
16
+ * Options for consuming fetch events from an async stream.
17
+ */
18
+ type StreamServerOptions = {
19
+ /**
20
+ * Source of runtime-specific fetch events to dispatch through `Server`.
21
+ */
22
+ stream: AsyncIterableIterator<RequestEntry>;
23
+ /**
24
+ * The path to the stream worker file or address to be registered.
25
+ */
26
+ url?: string;
27
+ };
28
+ /**
29
+ * Complete a runtime request entry by routing it through `Server.fetch()`.
30
+ */
31
+ declare function handleRequestEntry(server: Server, entry: RequestEntry): void;
32
+ /**
33
+ * Adapter for environments that expose requests as an async iterator instead of
34
+ * a socket listener.
35
+ */
36
+ declare class StreamRuntimeAdapter implements RuntimeAdapter {
37
+ #private;
38
+ constructor(options: StreamServerOptions);
39
+ get capabilities(): RuntimeCapabilities;
40
+ /**
41
+ * No-op because the stream runtime does not need listener setup.
42
+ */
43
+ setup(): void;
44
+ /**
45
+ * Start consuming the event stream once and dispatch each event to `Server`.
46
+ */
47
+ serve(server: Server): Promise<{
48
+ url: string | undefined;
49
+ }>;
50
+ /**
51
+ * Stop dispatching future events from the stream.
52
+ */
53
+ close(): Promise<void>;
54
+ }
55
+ //#endregion
56
+ export { RequestEntry, StreamRuntimeAdapter, StreamServerOptions, handleRequestEntry };
@@ -0,0 +1,68 @@
1
+ //#region src/stream.ts
2
+ /**
3
+ * Complete a runtime request entry by routing it through `Server.fetch()`.
4
+ */
5
+ function handleRequestEntry(server, entry) {
6
+ const { request, waitUntil } = entry;
7
+ let context = server.createContext(request);
8
+ if (typeof waitUntil === "function") context = context.with({ waitUntil: (p) => waitUntil(p) });
9
+ entry.completeWith(Promise.resolve(server.handle(context)));
10
+ }
11
+ /**
12
+ * Adapter for environments that expose requests as an async iterator instead of
13
+ * a socket listener.
14
+ */
15
+ var StreamRuntimeAdapter = class {
16
+ #options;
17
+ #served = false;
18
+ #closed = false;
19
+ constructor(options) {
20
+ this.#options = options;
21
+ }
22
+ get capabilities() {
23
+ return streamCapabilities;
24
+ }
25
+ /**
26
+ * No-op because the stream runtime does not need listener setup.
27
+ */
28
+ setup() {}
29
+ /**
30
+ * Start consuming the event stream once and dispatch each event to `Server`.
31
+ */
32
+ async serve(server) {
33
+ if (this.#served) return { url: this.#options.url };
34
+ this.#served = true;
35
+ queueMicrotask(async () => {
36
+ for await (const event of this.#options.stream) {
37
+ if (this.#closed) return;
38
+ handleRequestEntry(server, event);
39
+ }
40
+ });
41
+ return { url: this.#options.url };
42
+ }
43
+ /**
44
+ * Stop dispatching future events from the stream.
45
+ */
46
+ async close() {
47
+ this.#closed = true;
48
+ this.#served = false;
49
+ }
50
+ };
51
+ /**
52
+ * Minimal capabilities available in stream-only environments.
53
+ */
54
+ const streamCapabilities = {
55
+ resolve: () => Promise.resolve(null),
56
+ open: () => Promise.resolve(null),
57
+ createGzip: () => createCompressionStream("gzip"),
58
+ createBrotliCompress() {
59
+ throw new Error("Does not provide Brotli compression.");
60
+ }
61
+ };
62
+ function createCompressionStream(format) {
63
+ const CompressionStreamCtor = globalThis.CompressionStream;
64
+ if (typeof CompressionStreamCtor !== "function") throw new Error("Does not provide CompressionStream.");
65
+ return new CompressionStreamCtor(format);
66
+ }
67
+ //#endregion
68
+ export { StreamRuntimeAdapter, handleRequestEntry };
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "sevok",
3
+ "version": "0.0.2",
4
+ "description": "Composable Server Primitives Across Runtimes",
5
+ "homepage": "https://sevok.pages.dev",
6
+ "license": "MIT",
7
+ "author": "Maofeng <hornjs@qq.com>",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/hornjs/sevok.git"
11
+ },
12
+ "files": [
13
+ "LICENSE",
14
+ "README.md",
15
+ "README.zh-CN.md",
16
+ "bin",
17
+ "dist"
18
+ ],
19
+ "type": "module",
20
+ "sideEffects": false,
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.mts",
24
+ "default": "./dist/index.mjs"
25
+ },
26
+ "./bun": {
27
+ "types": "./dist/bun.d.mts",
28
+ "default": "./dist/bun.mjs"
29
+ },
30
+ "./cli": {
31
+ "types": "./dist/cli.d.mts",
32
+ "default": "./dist/cli.mjs"
33
+ },
34
+ "./deno": {
35
+ "types": "./dist/deno.d.mts",
36
+ "default": "./dist/deno.mjs"
37
+ },
38
+ "./log": {
39
+ "types": "./dist/log.d.mts",
40
+ "default": "./dist/log.mjs"
41
+ },
42
+ "./node": {
43
+ "types": "./dist/node.d.mts",
44
+ "default": "./dist/node.mjs"
45
+ },
46
+ "./static": {
47
+ "types": "./dist/static.d.mts",
48
+ "default": "./dist/static.mjs"
49
+ },
50
+ "./stream": {
51
+ "types": "./dist/stream.d.mts",
52
+ "default": "./dist/stream.mjs"
53
+ },
54
+ "./package.json": "./package.json"
55
+ },
56
+ "dependencies": {
57
+ "@hornjs/evt": "^0.0.4",
58
+ "@types/bun": "^1.3.10",
59
+ "@types/deno": "^2.5.0"
60
+ },
61
+ "bin": {
62
+ "sevok": "./bin/sevok.mjs"
63
+ },
64
+ "types": "./dist/index.d.mts",
65
+ "publishConfig": {
66
+ "access": "public"
67
+ }
68
+ }