owebjs 1.5.5-dev → 1.5.7-dev

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.
@@ -2,7 +2,7 @@ import {
2
2
  __name
3
3
  } from "../chunk-SHUYVCID.js";
4
4
  import path from "node:path";
5
- import { fileURLToPath } from "node:url";
5
+ import { pathToFileURL } from "node:url";
6
6
  import { buildRoutePath, buildRouteURL } from './utils.js';
7
7
  import { walk } from './walk.js';
8
8
  import { error, success, warn } from './logger.js';
@@ -13,27 +13,51 @@ import { WebSocketRoute } from '../structures/WebSocketRoute.js';
13
13
  import { FastifyWebSocketAdapter } from '../structures/FastifyWebSocketAdapter.js';
14
14
  import { formatSSE } from './utils.js';
15
15
  const websocketRoutes = {};
16
- const registeredWebSockets = /* @__PURE__ */ new Set();
17
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
18
- let matcherOverrides = {};
19
- let routeFunctions = {
16
+ const WS_REGISTRY_KEY = "ws:registered-routes";
17
+ const createMethodMap = /* @__PURE__ */ __name(() => ({
20
18
  get: {},
21
19
  post: {},
22
20
  put: {},
23
21
  delete: {},
24
22
  patch: {},
25
23
  options: {}
26
- };
27
- const temporaryRequests = {
28
- get: {},
29
- post: {},
30
- put: {},
31
- delete: {},
32
- patch: {},
33
- options: {}
34
- };
24
+ }), "createMethodMap");
25
+ let matcherOverrides = {};
26
+ let routeFunctions = createMethodMap();
27
+ let temporaryRequests = createMethodMap();
35
28
  let routesCache = [];
36
- const compiledRoutes = {};
29
+ let compiledRoutes = {};
30
+ function normalizeFsPath(filePath) {
31
+ return path.resolve(filePath).replaceAll("\\", "/").toLowerCase();
32
+ }
33
+ __name(normalizeFsPath, "normalizeFsPath");
34
+ async function importFreshModule(filePath, source) {
35
+ const resolvedHref = pathToFileURL(path.resolve(filePath)).href;
36
+ const cacheBuster = `?t=${Date.now()}-${Math.random().toString(36).slice(2)}`;
37
+ if (source?.length && !/['"]\.\.?\//.test(source)) {
38
+ const stampedSource = `${source}
39
+ //# sourceURL=${resolvedHref}${cacheBuster}`;
40
+ const dataUrl = `data:text/javascript;base64,${Buffer.from(stampedSource, "utf-8").toString("base64")}`;
41
+ try {
42
+ return await import(dataUrl);
43
+ } catch {
44
+ }
45
+ }
46
+ return import(resolvedHref + cacheBuster);
47
+ }
48
+ __name(importFreshModule, "importFreshModule");
49
+ function resetRuntimeCaches(oweb) {
50
+ matcherOverrides = {};
51
+ routeFunctions = createMethodMap();
52
+ temporaryRequests = createMethodMap();
53
+ routesCache = [];
54
+ compiledRoutes = {};
55
+ for (const key of Object.keys(websocketRoutes)) {
56
+ delete websocketRoutes[key];
57
+ }
58
+ oweb._internalKV.delete(WS_REGISTRY_KEY);
59
+ }
60
+ __name(resetRuntimeCaches, "resetRuntimeCaches");
37
61
  function removeExtension(filePath) {
38
62
  const lastDotIndex = filePath.lastIndexOf(".");
39
63
  if (lastDotIndex !== -1) {
@@ -91,8 +115,7 @@ const applyMatcherHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fall
91
115
  success(`Matcher ${filePath} compiled and reloaded in ${end}ms`, "HMR");
92
116
  } else {
93
117
  const start = Date.now();
94
- const newFilePath = filePath.replaceAll("\\", "/");
95
- const packageURL = new URL(path.resolve(newFilePath), `file://${__dirname}`).pathname.replaceAll("\\", "/");
118
+ const packageURL = pathToFileURL(path.resolve(filePath)).href;
96
119
  const cacheBuster = `?t=${Date.now()}`;
97
120
  def = (await import(packageURL + cacheBuster)).default;
98
121
  const end = Date.now() - start;
@@ -103,6 +126,7 @@ const applyMatcherHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fall
103
126
  }
104
127
  }, "applyMatcherHMR");
105
128
  const applyRouteHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fallbackDir, path2, content) => {
129
+ const normalizedChangedPath = normalizeFsPath(path2);
106
130
  if (path2.endsWith("hooks.js") || path2.endsWith("hooks.ts")) {
107
131
  warn(`Hot Module Replacement is not supported for hooks. Restart the server for changes to take effect.`, "HMR");
108
132
  return;
@@ -118,14 +142,30 @@ const applyRouteHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fallba
118
142
  const files = await walk(workingDir, [], fallbackDir);
119
143
  const routes = await generateRoutes(files, path2);
120
144
  routesCache = routes;
121
- const f = routes.find((x) => x.fileInfo.filePath == path2);
122
- if (f?.fn?.prototype instanceof WebSocketRoute) {
145
+ const f = routes.find((x) => normalizeFsPath(x.fileInfo.filePath) === normalizedChangedPath);
146
+ if (!f) {
147
+ warn(`HMR could not resolve route metadata for file ${path2}`, "HMR");
148
+ return;
149
+ }
150
+ if (!path2.endsWith(".ts") && content.length) {
151
+ const fresh = await importFreshModule(path2, content);
152
+ if (fresh?.default) {
153
+ f.fn = fresh.default;
154
+ }
155
+ }
156
+ if (f.fn?.prototype instanceof WebSocketRoute) {
123
157
  assignSpecificRoute(oweb, f);
124
158
  const end2 = Date.now() - start;
125
159
  success(`WebSocket Route ${f.url} created in ${end2}ms`, "HMR");
126
160
  return;
127
161
  }
128
- temporaryRequests[f.method.toLowerCase()][f.url] = inner(oweb, f);
162
+ const method = f.method.toLowerCase();
163
+ const nextHandler = inner(oweb, f);
164
+ if (routeFunctions[method][f.url]) {
165
+ routeFunctions[method][f.url] = nextHandler;
166
+ } else {
167
+ temporaryRequests[method][f.url] = nextHandler;
168
+ }
129
169
  const end = Date.now() - start;
130
170
  success(`Route ${f.method.toUpperCase()}:${f.url} created in ${end}ms`, "HMR");
131
171
  } else if (op === "modify-file") {
@@ -133,17 +173,31 @@ const applyRouteHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fallba
133
173
  const files = await walk(workingDir, [], fallbackDir);
134
174
  const routes = await generateRoutes(files, path2);
135
175
  routesCache = routes;
136
- const f = routes.find((x) => x.fileInfo.filePath == path2);
137
- if (f?.fn?.prototype instanceof WebSocketRoute) {
176
+ const f = routes.find((x) => normalizeFsPath(x.fileInfo.filePath) === normalizedChangedPath);
177
+ if (!f) {
178
+ warn(`HMR could not resolve route metadata for file ${path2}`, "HMR");
179
+ return;
180
+ }
181
+ if (!path2.endsWith(".ts") && content.length) {
182
+ const fresh = await importFreshModule(path2, content);
183
+ if (fresh?.default) {
184
+ f.fn = fresh.default;
185
+ }
186
+ }
187
+ if (f.fn?.prototype instanceof WebSocketRoute) {
138
188
  websocketRoutes[f.url] = new f.fn();
139
189
  const end2 = Date.now() - start;
140
190
  success(`WebSocket Route ${f.url} reloaded in ${end2}ms`, "HMR");
141
191
  return;
142
192
  }
143
- if (f.url in temporaryRequests[f.method.toLowerCase()]) {
144
- temporaryRequests[f.method.toLowerCase()][f.url] = inner(oweb, f);
193
+ const method = f.method.toLowerCase();
194
+ const nextHandler = inner(oweb, f);
195
+ if (routeFunctions[method][f.url]) {
196
+ routeFunctions[method][f.url] = nextHandler;
197
+ } else if (f.url in temporaryRequests[method]) {
198
+ temporaryRequests[method][f.url] = nextHandler;
145
199
  } else {
146
- routeFunctions[f.method.toLowerCase()][f.url] = inner(oweb, f);
200
+ routeFunctions[method][f.url] = nextHandler;
147
201
  }
148
202
  const end = Date.now() - start;
149
203
  success(`Route ${f.method.toUpperCase()}:${f.url} reloaded in ${end}ms`, "HMR");
@@ -176,8 +230,7 @@ const generateRoutes = /* @__PURE__ */ __name(async (files, onlyGenerateFn) => {
176
230
  const routes = [];
177
231
  for (const file of files) {
178
232
  const parsedFile = path.parse(file.rel);
179
- const filePath = file.filePath.replaceAll("\\", "/");
180
- const packageURL = new URL(path.resolve(filePath), `file://${__dirname}`).pathname.replaceAll("\\", "/");
233
+ const packageURL = pathToFileURL(path.resolve(file.filePath)).href;
181
234
  const routePath = buildRoutePath(parsedFile);
182
235
  const route = buildRouteURL(routePath);
183
236
  if (compiledRoutes[file.filePath]) {
@@ -191,7 +244,7 @@ const generateRoutes = /* @__PURE__ */ __name(async (files, onlyGenerateFn) => {
191
244
  continue;
192
245
  }
193
246
  let routeFuncs;
194
- if (!(onlyGenerateFn && file.filePath !== onlyGenerateFn)) {
247
+ if (!(onlyGenerateFn && normalizeFsPath(file.filePath) !== normalizeFsPath(onlyGenerateFn))) {
195
248
  const cacheBuster = `?t=${Date.now()}`;
196
249
  const def = await import(packageURL + cacheBuster);
197
250
  routeFuncs = def.default;
@@ -212,141 +265,186 @@ function inner(oweb, route) {
212
265
  }
213
266
  const routeFunc = new route.fn();
214
267
  const matchers = route.matchers;
268
+ const hooks = route.fileInfo.hooks;
269
+ const hasHooks = hooks.length > 0;
270
+ const hasMatchers = matchers.length > 0;
215
271
  const isParametric = route.url.includes(":") || route.url.includes("*");
216
- return function(req, res) {
217
- if (oweb._internalKV.get("hmr") && isParametric) {
218
- const currentPath = req.raw.url.split("?")[0];
219
- const method = req.method.toLowerCase();
220
- const specificHandler = temporaryRequests[method]?.[currentPath];
221
- if (specificHandler && specificHandler !== temporaryRequests[route.method][route.url]) {
222
- return specificHandler(req, res);
272
+ const handleIsAsync = routeFunc.handle.constructor.name === "AsyncFunction";
273
+ const hasRouteErrorHandler = typeof routeFunc?.handleError === "function";
274
+ const hmrEnabled = !!oweb._internalKV.get("hmr");
275
+ const checkMatchers = /* @__PURE__ */ __name((req) => {
276
+ if (!hasMatchers) return true;
277
+ for (const matcher of matchers) {
278
+ const param = req.params[matcher.paramName];
279
+ const fun = matcherOverrides[matcher.matcherName];
280
+ if (fun) {
281
+ return fun(param);
223
282
  }
224
283
  }
225
- const checkMatchers = /* @__PURE__ */ __name(() => {
226
- for (const matcher of matchers) {
227
- const param = req.params[matcher.paramName];
228
- const fun = matcherOverrides[matcher.matcherName];
229
- if (fun) {
230
- return fun(param);
231
- }
284
+ return true;
285
+ }, "checkMatchers");
286
+ const handleError = /* @__PURE__ */ __name((req, res, err) => {
287
+ const normalizedError = err instanceof Error ? err : new Error(String(err));
288
+ if (hasRouteErrorHandler) {
289
+ routeFunc.handleError(req, res, normalizedError);
290
+ } else {
291
+ oweb._options.OWEB_INTERNAL_ERROR_HANDLER(req, res, normalizedError);
292
+ }
293
+ }, "handleError");
294
+ const streamResult = /* @__PURE__ */ __name(async (req, res, result, isAsyncIterable) => {
295
+ const iterator = isAsyncIterable ? result[Symbol.asyncIterator]() : result[Symbol.iterator]();
296
+ let firstChunk;
297
+ try {
298
+ firstChunk = await iterator.next();
299
+ } catch (err) {
300
+ handleError(req, res, err);
301
+ return;
302
+ }
303
+ if (res.sent) return;
304
+ if (firstChunk.done) {
305
+ if (firstChunk.value !== void 0) res.send(firstChunk.value);
306
+ return;
307
+ }
308
+ const rawObj = res.raw;
309
+ const uwsRes = rawObj.res && typeof rawObj.res.cork === "function" ? rawObj.res : null;
310
+ const corkedOp = /* @__PURE__ */ __name((op) => {
311
+ if (uwsRes) uwsRes.cork(op);
312
+ else op();
313
+ }, "corkedOp");
314
+ corkedOp(() => {
315
+ const headers = {
316
+ ...res.getHeaders(),
317
+ "Content-Type": "text/event-stream",
318
+ "Cache-Control": "no-cache",
319
+ Connection: "keep-alive"
320
+ };
321
+ res.raw.writeHead(200, headers);
322
+ if (res.raw.flushHeaders) res.raw.flushHeaders();
323
+ });
324
+ let aborted = false;
325
+ const onAborted = /* @__PURE__ */ __name(() => {
326
+ aborted = true;
327
+ }, "onAborted");
328
+ if (res.raw.on) {
329
+ res.raw.on("close", onAborted);
330
+ res.raw.on("aborted", onAborted);
331
+ } else if (rawObj["onAborted"]) {
332
+ rawObj["onAborted"](onAborted);
333
+ }
334
+ try {
335
+ corkedOp(() => {
336
+ res.raw.write(formatSSE(firstChunk.value));
337
+ });
338
+ while (true) {
339
+ if (aborted || res.raw.destroyed) break;
340
+ const chunk = await iterator.next();
341
+ if (chunk.done) break;
342
+ corkedOp(() => {
343
+ res.raw.write(formatSSE(chunk.value));
344
+ });
232
345
  }
233
- return true;
234
- }, "checkMatchers");
235
- const handle = /* @__PURE__ */ __name(async () => {
236
- let result;
237
- try {
238
- if (routeFunc.handle.constructor.name === "AsyncFunction") {
239
- result = await routeFunc.handle(req, res);
240
- } else {
241
- result = routeFunc.handle(req, res);
242
- if (result instanceof Promise) {
243
- result = await result;
244
- }
245
- }
246
- } catch (error2) {
247
- if (routeFunc?.handleError) {
248
- routeFunc.handleError(req, res, error2);
249
- } else {
250
- oweb._options.OWEB_INTERNAL_ERROR_HANDLER(req, res, error2);
251
- }
252
- return;
346
+ } catch (err) {
347
+ error("Error while streaming response for " + route.method.toUpperCase() + ":" + route.url + " - " + err.message, "SSE");
348
+ } finally {
349
+ if (res.raw.off) {
350
+ res.raw.off("close", onAborted);
351
+ res.raw.off("aborted", onAborted);
253
352
  }
254
- if (res.sent) return;
255
- const isIterable = result && typeof result[Symbol.iterator] === "function";
256
- const isAsyncIterable = result && typeof result[Symbol.asyncIterator] === "function";
257
- if (isIterable || isAsyncIterable) {
258
- const iterator = isAsyncIterable ? result[Symbol.asyncIterator]() : result[Symbol.iterator]();
259
- let firstChunk;
260
- try {
261
- firstChunk = await iterator.next();
262
- } catch (err) {
263
- if (routeFunc?.handleError) routeFunc.handleError(req, res, err);
264
- else oweb._options.OWEB_INTERNAL_ERROR_HANDLER(req, res, err);
265
- return;
266
- }
267
- if (res.sent) return;
268
- if (firstChunk.done) {
269
- if (firstChunk.value !== void 0) res.send(firstChunk.value);
270
- return;
271
- }
272
- const rawObj = res.raw;
273
- const uwsRes = rawObj.res && typeof rawObj.res.cork === "function" ? rawObj.res : null;
274
- const corkedOp = /* @__PURE__ */ __name((op) => {
275
- if (uwsRes) uwsRes.cork(op);
276
- else op();
277
- }, "corkedOp");
353
+ if (!aborted && !res.raw.destroyed) {
278
354
  corkedOp(() => {
279
- const headers = {
280
- ...res.getHeaders(),
281
- "Content-Type": "text/event-stream",
282
- "Cache-Control": "no-cache",
283
- Connection: "keep-alive"
284
- };
285
- res.raw.writeHead(200, headers);
286
- if (res.raw.flushHeaders) res.raw.flushHeaders();
355
+ res.raw.end();
287
356
  });
288
- let aborted = false;
289
- const onAborted = /* @__PURE__ */ __name(() => {
290
- aborted = true;
291
- }, "onAborted");
292
- if (res.raw.on) {
293
- res.raw.on("close", onAborted);
294
- res.raw.on("aborted", onAborted);
295
- } else if (rawObj["onAborted"]) {
296
- rawObj["onAborted"](onAborted);
297
- }
298
- try {
299
- corkedOp(() => {
300
- res.raw.write(formatSSE(firstChunk.value));
301
- });
302
- while (true) {
303
- if (aborted || res.raw.destroyed) break;
304
- const chunk = await iterator.next();
305
- if (chunk.done) break;
306
- corkedOp(() => {
307
- res.raw.write(formatSSE(chunk.value));
308
- });
309
- }
310
- } catch (err) {
311
- error(`Error while streaming response for ${route.method.toUpperCase()}:${route.url} - ${err.message}`, "SSE");
312
- } finally {
313
- if (res.raw.off) {
314
- res.raw.off("close", onAborted);
315
- res.raw.off("aborted", onAborted);
316
- }
317
- if (!aborted && !res.raw.destroyed) {
318
- corkedOp(() => {
319
- res.raw.end();
320
- });
321
- }
322
- }
357
+ }
358
+ }
359
+ }, "streamResult");
360
+ const finalizeResult = /* @__PURE__ */ __name((req, res, result) => {
361
+ if (res.sent) return;
362
+ const isIterable = result && typeof result[Symbol.iterator] === "function";
363
+ const isAsyncIterable = result && typeof result[Symbol.asyncIterator] === "function";
364
+ if (isIterable || isAsyncIterable) {
365
+ streamResult(req, res, result, isAsyncIterable);
366
+ return;
367
+ }
368
+ if (!res.sent && result !== void 0) {
369
+ res.send(result);
370
+ }
371
+ }, "finalizeResult");
372
+ const executeRoute = handleIsAsync ? async (req, res) => {
373
+ try {
374
+ const result = await routeFunc.handle(req, res);
375
+ finalizeResult(req, res, result);
376
+ } catch (error2) {
377
+ handleError(req, res, error2);
378
+ }
379
+ } : (req, res) => {
380
+ let result;
381
+ try {
382
+ result = routeFunc.handle(req, res);
383
+ } catch (error2) {
384
+ handleError(req, res, error2);
385
+ return;
386
+ }
387
+ if (result instanceof Promise) {
388
+ result.then((resolved) => {
389
+ finalizeResult(req, res, resolved);
390
+ }).catch((error2) => {
391
+ handleError(req, res, error2);
392
+ });
393
+ return;
394
+ }
395
+ finalizeResult(req, res, result);
396
+ };
397
+ const isSimpleRoute = !hmrEnabled && !hasHooks && !hasMatchers && !isParametric;
398
+ if (isSimpleRoute) {
399
+ return function(req, res) {
400
+ executeRoute(req, res);
401
+ };
402
+ }
403
+ const runHooks = /* @__PURE__ */ __name((req, res) => {
404
+ let hookIndex = 0;
405
+ const runNextHook = /* @__PURE__ */ __name((hookErr) => {
406
+ if (hookErr) {
407
+ handleError(req, res, hookErr);
323
408
  return;
324
409
  }
325
- if (!res.sent && result !== void 0) {
326
- res.send(result);
410
+ if (res.sent) return;
411
+ if (hookIndex >= hooks.length) {
412
+ executeRoute(req, res);
413
+ return;
327
414
  }
328
- }, "handle");
329
- if (route.fileInfo.hooks.length) {
330
- for (let index = 0; index < route.fileInfo.hooks.length; index++) {
331
- const hookFun = route.fileInfo.hooks[index];
332
- const hookInstance = typeof hookFun === "function" ? new hookFun() : hookFun;
333
- hookInstance.handle(req, res, () => {
334
- if (index + 1 == route.fileInfo.hooks.length) {
335
- if (!checkMatchers()) {
336
- send404(req, res);
337
- } else {
338
- handle();
339
- }
340
- }
341
- });
415
+ const hookFun = hooks[hookIndex++];
416
+ const hookInstance = typeof hookFun === "function" ? new hookFun() : hookFun;
417
+ let doneCalled = false;
418
+ const done = /* @__PURE__ */ __name((doneErr) => {
419
+ if (doneCalled) return;
420
+ doneCalled = true;
421
+ runNextHook(doneErr);
422
+ }, "done");
423
+ try {
424
+ hookInstance.handle(req, res, done);
425
+ } catch (err) {
426
+ done(err);
342
427
  }
343
- } else {
344
- if (!checkMatchers()) {
345
- send404(req, res);
346
- } else {
347
- handle();
428
+ }, "runNextHook");
429
+ runNextHook();
430
+ }, "runHooks");
431
+ return function(req, res) {
432
+ if (hmrEnabled && isParametric) {
433
+ const currentPath = req.raw.url.split("?")[0];
434
+ const method = req.method.toLowerCase();
435
+ const specificHandler = temporaryRequests[method]?.[currentPath];
436
+ if (specificHandler) {
437
+ return specificHandler(req, res);
348
438
  }
349
439
  }
440
+ if (!checkMatchers(req)) {
441
+ return send404(req, res);
442
+ }
443
+ if (!hasHooks) {
444
+ executeRoute(req, res);
445
+ return;
446
+ }
447
+ runHooks(req, res);
350
448
  };
351
449
  }
352
450
  __name(inner, "inner");
@@ -358,11 +456,21 @@ function send404(req, res) {
358
456
  });
359
457
  }
360
458
  __name(send404, "send404");
459
+ function getRegisteredWebSocketsForApp(oweb) {
460
+ let wsRegistry = oweb._internalKV.get(WS_REGISTRY_KEY);
461
+ if (!wsRegistry) {
462
+ wsRegistry = /* @__PURE__ */ new Set();
463
+ oweb._internalKV.set(WS_REGISTRY_KEY, wsRegistry);
464
+ }
465
+ return wsRegistry;
466
+ }
467
+ __name(getRegisteredWebSocketsForApp, "getRegisteredWebSocketsForApp");
361
468
  function assignSpecificRoute(oweb, route) {
362
469
  if (!route?.fn) return;
363
470
  if (route?.fn?.prototype instanceof WebSocketRoute) {
364
471
  const wsInstance = new route.fn();
365
472
  websocketRoutes[route.url] = wsInstance;
473
+ const registeredWebSockets = getRegisteredWebSocketsForApp(oweb);
366
474
  if (!registeredWebSockets.has(route.url)) {
367
475
  registeredWebSockets.add(route.url);
368
476
  if (oweb._options.uWebSocketsEnabled && oweb.uServer) {
@@ -461,27 +569,34 @@ function assignSpecificRoute(oweb, route) {
461
569
  return;
462
570
  }
463
571
  const routeFunc = new route.fn();
464
- routeFunctions[route.method][route.url] = inner(oweb, route);
465
- oweb[route.method](route.url, routeFunc._options || {}, function(req, res) {
466
- if (routeFunctions[route.method][route.url]) {
467
- return routeFunctions[route.method][route.url](req, res);
468
- } else {
469
- const vals = temporaryRequests[route.method];
470
- const keys = Object.keys(vals);
471
- if (!vals || !keys.length) {
472
- return send404(req, res);
473
- }
474
- const f = keys.find((tempName) => {
475
- const matcher = match(tempName);
476
- return matcher(req.url);
477
- });
478
- if (f && vals[f]) {
479
- return vals[f](req, res);
572
+ const routeHandler = inner(oweb, route);
573
+ if (!routeHandler) return;
574
+ const hmrEnabled = !!oweb._internalKV.get("hmr");
575
+ if (hmrEnabled) {
576
+ routeFunctions[route.method][route.url] = routeHandler;
577
+ oweb[route.method](route.url, routeFunc._options || {}, function(req, res) {
578
+ if (routeFunctions[route.method][route.url]) {
579
+ return routeFunctions[route.method][route.url](req, res);
480
580
  } else {
481
- return send404(req, res);
581
+ const vals = temporaryRequests[route.method];
582
+ const keys = Object.keys(vals);
583
+ if (!vals || !keys.length) {
584
+ return send404(req, res);
585
+ }
586
+ const f = keys.find((tempName) => {
587
+ const matcher = match(tempName);
588
+ return matcher(req.url);
589
+ });
590
+ if (f && vals[f]) {
591
+ return vals[f](req, res);
592
+ } else {
593
+ return send404(req, res);
594
+ }
482
595
  }
483
- }
484
- });
596
+ });
597
+ return;
598
+ }
599
+ oweb[route.method](route.url, routeFunc._options || {}, routeHandler);
485
600
  }
486
601
  __name(assignSpecificRoute, "assignSpecificRoute");
487
602
  async function loadMatchers(directoryPath) {
@@ -490,17 +605,18 @@ async function loadMatchers(directoryPath) {
490
605
  ".ts"
491
606
  ].includes(path.extname(f)));
492
607
  for (const file of files) {
493
- const filePath = path.join(directoryPath, file).replaceAll("\\", "/");
608
+ const filePath = path.join(directoryPath, file);
494
609
  const fileName = path.basename(filePath);
495
- const packageURL = new URL(path.resolve(filePath), `file://${__dirname}`).pathname.replaceAll("\\", "/");
610
+ const packageURL = pathToFileURL(path.resolve(filePath)).href;
496
611
  const def = await import(packageURL);
497
612
  matcherOverrides[removeExtension(fileName)] = def.default;
498
613
  }
499
614
  }
500
615
  __name(loadMatchers, "loadMatchers");
501
616
  const assignRoutes = /* @__PURE__ */ __name(async (oweb, directory, matchersDirectory) => {
617
+ resetRuntimeCaches(oweb);
502
618
  if (matchersDirectory) {
503
- loadMatchers(matchersDirectory);
619
+ await loadMatchers(matchersDirectory);
504
620
  }
505
621
  const files = await walk(directory);
506
622
  const routes = await generateRoutes(files);
@@ -522,14 +638,16 @@ const assignRoutes = /* @__PURE__ */ __name(async (oweb, directory, matchersDire
522
638
  }
523
639
  }
524
640
  __name(fallbackHandle, "fallbackHandle");
525
- for (const element of [
526
- "get",
527
- "post",
528
- "put",
529
- "patch",
530
- "delete"
531
- ]) {
532
- oweb[element]("*", fallbackHandle);
641
+ if (oweb._internalKV.get("hmr")) {
642
+ for (const element of [
643
+ "get",
644
+ "post",
645
+ "put",
646
+ "patch",
647
+ "delete"
648
+ ]) {
649
+ oweb[element]("*", fallbackHandle);
650
+ }
533
651
  }
534
652
  for (const route of routes) {
535
653
  assignSpecificRoute(oweb, route);
@@ -2,11 +2,10 @@ import {
2
2
  __name
3
3
  } from "../chunk-SHUYVCID.js";
4
4
  import { readdirSync, statSync } from "node:fs";
5
- import { fileURLToPath, pathToFileURL } from "node:url";
5
+ import { pathToFileURL } from "node:url";
6
6
  import path from "node:path";
7
7
  import { mergePaths } from './utils.js';
8
8
  import { warn } from './logger.js';
9
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
9
  const isParentOrGrandparent = /* @__PURE__ */ __name((parentFolderPath, childFolderPath) => {
11
10
  if (childFolderPath.startsWith(parentFolderPath)) {
12
11
  const relativePath = path.relative(parentFolderPath, childFolderPath);
@@ -15,8 +14,7 @@ const isParentOrGrandparent = /* @__PURE__ */ __name((parentFolderPath, childFol
15
14
  }
16
15
  return false;
17
16
  }, "isParentOrGrandparent");
18
- const hookPaths = /* @__PURE__ */ new Set();
19
- const walk = /* @__PURE__ */ __name(async (directory, tree = [], fallbackDir) => {
17
+ const walk = /* @__PURE__ */ __name(async (directory, tree = [], fallbackDir, hookPaths = /* @__PURE__ */ new Set()) => {
20
18
  const results = [];
21
19
  const readDirPriority = readdirSync(directory);
22
20
  readDirPriority.sort((a, b) => {
@@ -40,7 +38,7 @@ const walk = /* @__PURE__ */ __name(async (directory, tree = [], fallbackDir) =>
40
38
  results.push(...await walk(filePath, [
41
39
  ...tree,
42
40
  fileName
43
- ], fallbackDir));
41
+ ], fallbackDir, hookPaths));
44
42
  } else {
45
43
  if (![
46
44
  ".js",
@@ -76,7 +74,8 @@ const walk = /* @__PURE__ */ __name(async (directory, tree = [], fallbackDir) =>
76
74
  rootWalkDir = path.dirname(rootWalkDir);
77
75
  }
78
76
  const relHook = path.relative(rootWalkDir, hookPath);
79
- const targetDir = path.join(process.cwd(), fallbackDir, relHook);
77
+ const fallbackRoot = path.isAbsolute(fallbackDir) ? fallbackDir : path.join(process.cwd(), fallbackDir);
78
+ const targetDir = path.join(fallbackRoot, relHook);
80
79
  targetFile = path.join(targetDir, "_hooks.js");
81
80
  } else {
82
81
  targetFile = path.join(hookPath, "_hooks.js");