Skip to content

Commit bbf4d9d

Browse files
committed
feat(loader): access to the whole intercepted srvx instance
1 parent 76cf8e7 commit bbf4d9d

File tree

4 files changed

+36
-24
lines changed

4 files changed

+36
-24
lines changed

src/adapters/bun.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ class BunServer implements Server<BunFetchHandler> {
4040

4141
// Detect running in srvx loader
4242
const loader = (globalThis as any).__srvxLoader__ as
43-
| ((handler: ServerHandler) => void)
43+
| ((obj: { server: Server }) => void)
4444
| undefined;
4545
if (loader) {
4646
this.fetch = fetchHandler;
47-
loader(fetchHandler);
47+
loader({ server: this });
4848
return;
4949
}
5050

src/adapters/deno.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ class DenoServer implements Server<DenoFetchHandler> {
4545

4646
// Detect running in srvx loader
4747
const loader = (globalThis as any).__srvxLoader__ as
48-
| ((handler: ServerHandler) => void)
48+
| ((obj: { server: Server }) => void)
4949
| undefined;
5050
if (loader) {
5151
this.fetch = fetchHandler;
52-
loader(fetchHandler);
52+
loader({ server: this });
5353
return;
5454
}
5555

src/adapters/node.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,23 @@ class NodeServer implements Server {
6363

6464
const fetchHandler = (this.fetch = wrapFetch(this));
6565

66+
const handler = (nodeReq: NodeServerRequest, nodeRes: NodeServerResponse) => {
67+
const request = new NodeRequest({ req: nodeReq, res: nodeRes });
68+
request.waitUntil = this.#wait?.waitUntil;
69+
const res = fetchHandler(request);
70+
return res instanceof Promise
71+
? res.then((resolvedRes) => sendNodeResponse(nodeRes, resolvedRes))
72+
: sendNodeResponse(nodeRes, res);
73+
};
74+
75+
this.node = { handler, server: undefined };
76+
6677
// Detect running in srvx loader
6778
const loader = (globalThis as any).__srvxLoader__ as
68-
| ((handler: ServerHandler) => void)
79+
| ((obj: { server: Server }) => void)
6980
| undefined;
7081
if (loader) {
71-
loader(fetchHandler);
82+
loader({ server: this });
7283
return;
7384
}
7485

@@ -77,15 +88,6 @@ class NodeServer implements Server {
7788
this.#wait = createWaitUntil();
7889
this.waitUntil = this.#wait.waitUntil;
7990

80-
const handler = (nodeReq: NodeServerRequest, nodeRes: NodeServerResponse) => {
81-
const request = new NodeRequest({ req: nodeReq, res: nodeRes });
82-
request.waitUntil = this.#wait?.waitUntil;
83-
const res = fetchHandler(request);
84-
return res instanceof Promise
85-
? res.then((resolvedRes) => sendNodeResponse(nodeRes, resolvedRes))
86-
: sendNodeResponse(nodeRes, res);
87-
};
88-
8991
const tls = resolveTLSOptions(this.options);
9092
const { port, hostname: host } = resolvePortAndHost(this.options);
9193
this.serveOptions = {
@@ -115,7 +117,7 @@ class NodeServer implements Server {
115117
server = nodeHTTP.createServer(this.serveOptions as NodeHttp.ServerOptions, handler);
116118
}
117119

118-
this.node = { server, handler };
120+
this.node.server = server;
119121

120122
if (!options.manual) {
121123
this.serve();

src/loader.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ export type LoadedServerEntry = {
8282
* When `true`, no valid entry point could be located.
8383
*/
8484
notFound?: boolean;
85+
86+
/**
87+
* The original srvx server instance if the module used the loader API to export a server directly.
88+
*/
89+
srvxServer?: Server;
8590
};
8691

8792
export async function loadServerEntry(opts: LoadOptions): Promise<LoadedServerEntry> {
@@ -114,13 +119,13 @@ export async function loadServerEntry(opts: LoadOptions): Promise<LoadedServerEn
114119
// Import the user file
115120
let mod: any;
116121
let interceptedNodeHandler: NodeHttpHandler | undefined;
117-
let interceptedFetchHandler: ServerHandler | undefined;
122+
let interceptedServer: Server | undefined;
118123
try {
119124
if (opts.interceptHttpListen !== false) {
120125
const loaded = await interceptListen(() => import(url));
121126
mod = loaded.res;
122127
interceptedNodeHandler = loaded.listenHandler;
123-
interceptedFetchHandler = loaded.fetchHandler;
128+
interceptedServer = loaded.server;
124129
} else {
125130
mod = await import(url);
126131
}
@@ -145,7 +150,7 @@ export async function loadServerEntry(opts: LoadOptions): Promise<LoadedServerEn
145150
mod = (await opts?.onLoad?.(mod)) || mod;
146151

147152
let fetchHandler =
148-
mod?.fetch || mod?.default?.fetch || mod?.default?.default?.fetch || interceptedFetchHandler;
153+
mod?.fetch || mod?.default?.fetch || mod?.default?.default?.fetch || interceptedServer?.fetch;
149154
if (!fetchHandler && typeof mod?.default === "function" && mod.default.length < 2) {
150155
fetchHandler = mod.default;
151156
}
@@ -167,6 +172,7 @@ export async function loadServerEntry(opts: LoadOptions): Promise<LoadedServerEn
167172
nodeCompat,
168173
url,
169174
fetch: fetchHandler,
175+
srvxServer: interceptedServer,
170176
};
171177
}
172178

@@ -175,16 +181,20 @@ let _interceptQueue: Promise<unknown> = Promise.resolve();
175181

176182
async function interceptListen<T = unknown>(
177183
cb: () => T | Promise<T>,
178-
): Promise<{ res?: T; listenHandler?: NodeHttpHandler; fetchHandler?: ServerHandler }> {
184+
): Promise<{
185+
res?: T;
186+
listenHandler?: NodeHttpHandler;
187+
server?: Server;
188+
}> {
179189
// Chain onto the queue to ensure sequential execution
180190
const result = _interceptQueue.then(async () => {
181191
const originalListen = nodeHTTP.Server.prototype.listen;
182192
let res: T;
183193
let listenHandler: NodeHttpHandler | undefined;
184-
let fetchHandler: ServerHandler | undefined;
194+
let server: Server | undefined;
185195

186-
(globalThis as any).__srvxLoader__ = (handler: ServerHandler) => {
187-
fetchHandler = handler;
196+
(globalThis as any).__srvxLoader__ = (obj: { server?: Server }) => {
197+
server = obj.server;
188198
};
189199

190200
try {
@@ -226,7 +236,7 @@ async function interceptListen<T = unknown>(
226236
nodeHTTP.Server.prototype.listen = originalListen;
227237
delete (globalThis as any).__srvxLoader__;
228238
}
229-
return { res, listenHandler, fetchHandler };
239+
return { res, listenHandler, server };
230240
});
231241

232242
// Update queue to point to this operation (swallow errors for queue chaining)

0 commit comments

Comments
 (0)