@reckona/mreact-router 0.0.193 → 0.0.194

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/src/serve.ts CHANGED
@@ -18,6 +18,7 @@ import {
18
18
  } from "./built-runtime.js";
19
19
  import {
20
20
  allBuiltServerModuleFiles,
21
+ loadBuiltResponseHookArtifacts,
21
22
  loadBuiltServerModuleArtifacts,
22
23
  loadBuiltServerModuleArtifactsForRequest,
23
24
  } from "./built-server-module-artifacts.js";
@@ -30,13 +31,18 @@ import type { AppRouterImportPolicy } from "./import-policy.js";
30
31
  import {
31
32
  preloadBuiltRequestModules,
32
33
  renderAppRequest,
34
+ resolveAppRouterResponseHook,
33
35
  resolveAppRouterMiddleware,
34
36
  type AppRouterServerRenderArtifactLoader,
35
37
  type AppRouterRenderPreload,
36
38
  type AppRouterResponseHook,
37
39
  type RenderAppRequestRuntimeOptions,
38
40
  } from "./render.js";
39
- import type { RouterInstrumentation } from "./trace.js";
41
+ import {
42
+ invokeRouterInstrumentation,
43
+ traceContextFromRequest,
44
+ type RouterInstrumentation,
45
+ } from "./trace.js";
40
46
  import {
41
47
  bytesResponse,
42
48
  htmlResponse,
@@ -234,8 +240,10 @@ export async function createBuiltRequestRuntime(
234
240
  });
235
241
  },
236
242
  async render(request, renderOptions = {}) {
243
+ emitBuiltRequestStart(renderOptions.instrumentation, request);
237
244
  const response = await renderBuiltAppRequestWithRuntime({
238
245
  ...renderOptions,
246
+ instrumentation: withoutBuiltRequestInstrumentation(renderOptions.instrumentation),
239
247
  importPolicy:
240
248
  renderOptions.importPolicy === undefined
241
249
  ? defaultImportPolicy
@@ -245,10 +253,16 @@ export async function createBuiltRequestRuntime(
245
253
  runtime,
246
254
  });
247
255
 
248
- return applyBuiltAppResponseHook(response, {
249
- onResponse: renderOptions.onResponse,
250
- request,
251
- });
256
+ const finalResponse = await applyBuiltAppResponseHook(
257
+ response,
258
+ {
259
+ onResponse: renderOptions.onResponse,
260
+ request,
261
+ },
262
+ runtime,
263
+ );
264
+ emitBuiltRequestEnd(renderOptions.instrumentation, request, finalResponse.status);
265
+ return finalResponse;
252
266
  },
253
267
  };
254
268
  }
@@ -349,6 +363,7 @@ function builtRuntimePreloadRoutes(
349
363
  export async function renderBuiltAppRequest(
350
364
  options: RenderBuiltAppRequestOptions,
351
365
  ): Promise<Response> {
366
+ emitBuiltRequestStart(options.instrumentation, options.request);
352
367
  const runtime = await readBuiltRuntime({
353
368
  outDir: options.outDir,
354
369
  immutable: options.immutableRuntime,
@@ -356,11 +371,54 @@ export async function renderBuiltAppRequest(
356
371
  });
357
372
  const response = await renderBuiltAppRequestWithRuntime({
358
373
  ...options,
374
+ instrumentation: withoutBuiltRequestInstrumentation(options.instrumentation),
359
375
  importPolicy: mergeBuiltRuntimeImportPolicy(runtime, options.importPolicy),
360
376
  runtime,
361
377
  });
362
378
 
363
- return applyBuiltAppResponseHook(response, options);
379
+ const finalResponse = await applyBuiltAppResponseHook(response, options, runtime);
380
+ emitBuiltRequestEnd(options.instrumentation, options.request, finalResponse.status);
381
+ return finalResponse;
382
+ }
383
+
384
+ function withoutBuiltRequestInstrumentation(
385
+ instrumentation: RouterInstrumentation | undefined,
386
+ ): RouterInstrumentation | undefined {
387
+ if (instrumentation === undefined) {
388
+ return undefined;
389
+ }
390
+
391
+ const { onRequestEnd: _onRequestEnd, onRequestStart: _onRequestStart, ...remaining } =
392
+ instrumentation;
393
+ return remaining;
394
+ }
395
+
396
+ function emitBuiltRequestStart(
397
+ instrumentation: RouterInstrumentation | undefined,
398
+ request: Request,
399
+ ): void {
400
+ const trace = traceContextFromRequest(request);
401
+ invokeRouterInstrumentation(instrumentation?.onRequestStart, {
402
+ method: request.method,
403
+ path: new URL(request.url).pathname,
404
+ request,
405
+ ...(trace === undefined ? {} : { trace }),
406
+ });
407
+ }
408
+
409
+ function emitBuiltRequestEnd(
410
+ instrumentation: RouterInstrumentation | undefined,
411
+ request: Request,
412
+ status: number,
413
+ ): void {
414
+ const trace = traceContextFromRequest(request);
415
+ invokeRouterInstrumentation(instrumentation?.onRequestEnd, {
416
+ method: request.method,
417
+ path: new URL(request.url).pathname,
418
+ request,
419
+ status,
420
+ ...(trace === undefined ? {} : { trace }),
421
+ });
364
422
  }
365
423
 
366
424
  async function renderBuiltAppRequestWithRuntime(
@@ -534,8 +592,18 @@ function emitBuiltRenderTiming(
534
592
  async function applyBuiltAppResponseHook(
535
593
  response: Response,
536
594
  options: Pick<RenderBuiltAppRequestOptions, "onResponse" | "request">,
595
+ runtime: BuiltRuntime,
537
596
  ): Promise<Response> {
538
- const hooked = await options.onResponse?.(response, {
597
+ await loadBuiltResponseHookArtifacts(runtime);
598
+ const onResponse = await resolveAppRouterResponseHook({
599
+ appDir: runtime.appDir,
600
+ importPolicy: runtime.generatedImportPolicy,
601
+ onResponse: options.onResponse,
602
+ serverModules: runtime.serverModules,
603
+ serverModuleCacheVersion: runtime.serverModuleCacheVersion,
604
+ serverSourceFiles: runtime.serverSourceFiles,
605
+ });
606
+ const hooked = await onResponse?.(response, {
539
607
  request: options.request,
540
608
  });
541
609
 
@@ -814,6 +882,7 @@ function builtRenderAppRequestOptions(
814
882
  options.runtime.serverActionManifest,
815
883
  ),
816
884
  skipMiddleware: true,
885
+ onResponse: () => undefined,
817
886
  ...(options.preload === undefined ? {} : { preload: options.preload }),
818
887
  };
819
888
 
package/src/vite.ts CHANGED
@@ -277,6 +277,7 @@ export function createAppRouterVitePlugin(options: AppRouterVitePluginOptions):
277
277
  },
278
278
  configureServer(server) {
279
279
  server.middlewares.use(createDevCssProxyMiddleware());
280
+ server.middlewares.use(createClientRouteTransformMiddleware(project.routesDir, server));
280
281
 
281
282
  return () => {
282
283
  const middlewareOptions: AppRouterViteRuntimeMiddlewareOptions = {
@@ -451,6 +452,48 @@ export function prepareReactiveEffectRunDevtoolsEvent() { return undefined; }`;
451
452
  return plugin;
452
453
  }
453
454
 
455
+ function createClientRouteTransformMiddleware(
456
+ appDir: string,
457
+ server: ViteDevServer,
458
+ ): Connect.NextHandleFunction {
459
+ return (request, response, next) => {
460
+ void (async () => {
461
+ const url = new URL(request.url ?? "/", "http://localhost");
462
+
463
+ if (!url.pathname.startsWith(`${clientPrefix}routes/`)) {
464
+ next();
465
+ return;
466
+ }
467
+
468
+ const route = await clientRouteForRequestPath(appDir, url.pathname);
469
+
470
+ if (route === undefined) {
471
+ next();
472
+ return;
473
+ }
474
+
475
+ try {
476
+ const transformed = await server.transformRequest(`${url.pathname}${url.search}`);
477
+
478
+ if (transformed === null) {
479
+ next();
480
+ return;
481
+ }
482
+
483
+ await sendResponse(
484
+ response,
485
+ new Response(transformed.code, {
486
+ headers: { "content-type": "text/javascript; charset=utf-8" },
487
+ }),
488
+ );
489
+ } catch (error) {
490
+ sendViteErrorOverlay(server, error);
491
+ await sendResponse(response, clientAssetBuildErrorResponse(route.file, error));
492
+ }
493
+ })().catch(next);
494
+ };
495
+ }
496
+
454
497
  function isMreactClientSourceDependency(
455
498
  filename: string,
456
499
  normalizedSourceDirs: readonly string[],