@reckona/mreact-router 0.0.146 → 0.0.148

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/build.ts CHANGED
@@ -109,6 +109,7 @@ type ServerTransformOutput = ReturnType<typeof transform>;
109
109
  type ServerTransformCache = Map<string, Promise<ServerTransformOutput>>;
110
110
 
111
111
  export interface BuildAppOptions extends AppRouterProjectOptions {
112
+ onBuildProgress?: ((event: BuildAppProgressEvent) => void) | undefined;
112
113
  onBuildPhaseTiming?: ((timing: BuildAppPhaseTiming) => void) | undefined;
113
114
  outDir: string;
114
115
  targets?: readonly AppRouterBuildTarget[] | undefined;
@@ -178,6 +179,21 @@ export interface BuildAppPhaseTiming {
178
179
  phase: BuildAppPhase;
179
180
  }
180
181
 
182
+ export type BuildAppProgressEvent =
183
+ | {
184
+ kind: "phase-start";
185
+ phase: BuildAppPhase;
186
+ }
187
+ | {
188
+ kind: "phase-end";
189
+ ms: number;
190
+ phase: BuildAppPhase;
191
+ }
192
+ | {
193
+ count: number;
194
+ kind: "routes-discovered";
195
+ };
196
+
181
197
  export interface BuildAppResult {
182
198
  routes: AppRoute[];
183
199
  }
@@ -319,23 +335,26 @@ type StaticParams = Record<string, string | number | boolean | readonly string[]
319
335
 
320
336
  export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult> {
321
337
  const timingSink = options.onBuildPhaseTiming;
338
+ const progressSink = options.onBuildProgress;
339
+ const shouldTrackBuildPhases = timingSink !== undefined || progressSink !== undefined;
322
340
  const project = resolveAppRouterProjectOptions(options);
323
341
  const buildTargets = resolveBuildTargets(options.targets ?? project.buildTargets);
324
342
  const shouldBuildCloudflare = buildTargets.includes("cloudflare");
325
343
  const shouldBuildAwsLambda = buildTargets.includes("aws-lambda");
326
344
  const routes =
327
- timingSink === undefined
345
+ shouldTrackBuildPhases === false
328
346
  ? await scanAppRoutes({ appDir: project.routesDir })
329
- : await timeBuildPhase(timingSink, "scan", () =>
347
+ : await timeBuildPhase(timingSink, progressSink, "scan", () =>
330
348
  scanAppRoutes({ appDir: project.routesDir }),
331
349
  );
350
+ progressSink?.({ count: routes.length, kind: "routes-discovered" });
332
351
  await validateBuildMiddlewareControls(project.routesDir, routes);
333
352
  const viteDefine = options.viteConfig?.define;
334
353
  const vitePlugins = options.viteConfig?.plugins;
335
354
  const files =
336
- timingSink === undefined
355
+ shouldTrackBuildPhases === false
337
356
  ? await collectBuildFiles(project.projectRoot, project.allowedSourceDirs, project.routesDir)
338
- : await timeBuildPhase(timingSink, "collectFiles", () =>
357
+ : await timeBuildPhase(timingSink, progressSink, "collectFiles", () =>
339
358
  collectBuildFiles(project.projectRoot, project.allowedSourceDirs, project.routesDir),
340
359
  );
341
360
  const serverClientRouteInferenceCache = createClientRouteInferenceCache();
@@ -344,7 +363,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
344
363
  const clientDir = join(options.outDir, "client");
345
364
  const cloudflareDir = join(options.outDir, "cloudflare");
346
365
  const sourceAnalysis =
347
- timingSink === undefined
366
+ shouldTrackBuildPhases === false
348
367
  ? await analyzeBuildRouteSources({
349
368
  clientRouteInferenceCache: serverClientRouteInferenceCache,
350
369
  files,
@@ -353,7 +372,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
353
372
  routes,
354
373
  vitePlugins,
355
374
  })
356
- : await timeBuildPhase(timingSink, "analyzeSources", () =>
375
+ : await timeBuildPhase(timingSink, progressSink, "analyzeSources", () =>
357
376
  analyzeBuildRouteSources({
358
377
  clientRouteInferenceCache: serverClientRouteInferenceCache,
359
378
  files,
@@ -364,7 +383,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
364
383
  }),
365
384
  );
366
385
 
367
- if (timingSink === undefined) {
386
+ if (shouldTrackBuildPhases === false) {
368
387
  await validateProductionRoutes({
369
388
  clientRouteInferenceCache: serverClientRouteInferenceCache,
370
389
  files,
@@ -376,7 +395,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
376
395
  vitePlugins,
377
396
  });
378
397
  } else {
379
- await timeBuildPhase(timingSink, "validate", () =>
398
+ await timeBuildPhase(timingSink, progressSink, "validate", () =>
380
399
  validateProductionRoutes({
381
400
  clientRouteInferenceCache: serverClientRouteInferenceCache,
382
401
  files,
@@ -390,7 +409,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
390
409
  );
391
410
  }
392
411
 
393
- if (timingSink === undefined) {
412
+ if (shouldTrackBuildPhases === false) {
394
413
  await rm(options.outDir, { force: true, recursive: true });
395
414
  await Promise.all([
396
415
  mkdir(serverDir, { recursive: true }),
@@ -400,7 +419,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
400
419
  mkdir(join(clientDir, "assets", "routes"), { recursive: true }),
401
420
  ]);
402
421
  } else {
403
- await timeBuildPhase(timingSink, "prepareOutput", async () => {
422
+ await timeBuildPhase(timingSink, progressSink, "prepareOutput", async () => {
404
423
  await rm(options.outDir, { force: true, recursive: true });
405
424
  await Promise.all([
406
425
  mkdir(serverDir, { recursive: true }),
@@ -413,22 +432,22 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
413
432
  }
414
433
 
415
434
  const publicAssets =
416
- timingSink === undefined
435
+ shouldTrackBuildPhases === false
417
436
  ? await buildPublicAssetManifest(project, clientDir)
418
- : await timeBuildPhase(timingSink, "publicAssets", () =>
437
+ : await timeBuildPhase(timingSink, progressSink, "publicAssets", () =>
419
438
  buildPublicAssetManifest(project, clientDir),
420
439
  );
421
440
 
422
441
  const clientRouteInferenceCache = createClientRouteInferenceCache();
423
442
  const [serverActionManifest, serverModules, generatedImportPolicy] = await Promise.all([
424
- timingSink === undefined
443
+ shouldTrackBuildPhases === false
425
444
  ? collectBuildServerActionManifest({
426
445
  files,
427
446
  projectRoot: project.projectRoot,
428
447
  routes,
429
448
  routesDir: project.routesDir,
430
449
  })
431
- : timeBuildPhase(timingSink, "serverActionManifest", () =>
450
+ : timeBuildPhase(timingSink, progressSink, "serverActionManifest", () =>
432
451
  collectBuildServerActionManifest({
433
452
  files,
434
453
  projectRoot: project.projectRoot,
@@ -436,12 +455,12 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
436
455
  routesDir: project.routesDir,
437
456
  }),
438
457
  ),
439
- timingSink === undefined
440
- ? buildServerModuleArtifacts({
441
- bundleCache: new Map(),
442
- clientRouteInferenceCache: serverClientRouteInferenceCache,
443
- define: viteDefine,
444
- files,
458
+ shouldTrackBuildPhases === false
459
+ ? buildServerModuleArtifacts({
460
+ bundleCache: new Map(),
461
+ clientRouteInferenceCache: serverClientRouteInferenceCache,
462
+ define: viteDefine,
463
+ files,
445
464
  prebundleServerComponents: buildTargets.includes("node") || shouldBuildAwsLambda,
446
465
  project,
447
466
  projectRoot: project.projectRoot,
@@ -450,7 +469,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
450
469
  serverTransformCache,
451
470
  vitePlugins,
452
471
  })
453
- : timeBuildPhase(timingSink, "serverModules", () =>
472
+ : timeBuildPhase(timingSink, progressSink, "serverModules", () =>
454
473
  buildServerModuleArtifacts({
455
474
  bundleCache: new Map(),
456
475
  clientRouteInferenceCache: serverClientRouteInferenceCache,
@@ -465,14 +484,14 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
465
484
  vitePlugins,
466
485
  }),
467
486
  ),
468
- timingSink === undefined
487
+ shouldTrackBuildPhases === false
469
488
  ? buildGeneratedImportPolicy({
470
489
  files,
471
490
  projectRoot: project.projectRoot,
472
491
  routes,
473
492
  routesDir: project.routesDir,
474
493
  })
475
- : timeBuildPhase(timingSink, "importPolicy", () =>
494
+ : timeBuildPhase(timingSink, progressSink, "importPolicy", () =>
476
495
  buildGeneratedImportPolicy({
477
496
  files,
478
497
  projectRoot: project.projectRoot,
@@ -486,20 +505,20 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
486
505
  file: relative(project.projectRoot, route.file),
487
506
  }));
488
507
  const [serverModuleArtifacts, clientBundle] = await Promise.all([
489
- timingSink === undefined
508
+ shouldTrackBuildPhases === false
490
509
  ? writeServerModuleArtifactFiles(
491
510
  serverDir,
492
511
  serverModules,
493
512
  generatedImportPolicy.runtimePackages,
494
513
  )
495
- : timeBuildPhase(timingSink, "serverModuleArtifacts", () =>
514
+ : timeBuildPhase(timingSink, progressSink, "serverModuleArtifacts", () =>
496
515
  writeServerModuleArtifactFiles(
497
516
  serverDir,
498
517
  serverModules,
499
518
  generatedImportPolicy.runtimePackages,
500
519
  ),
501
520
  ),
502
- timingSink === undefined
521
+ shouldTrackBuildPhases === false
503
522
  ? writeClientRouteBundles({
504
523
  appDir: project.routesDir,
505
524
  assetBaseUrl: project.assetBaseUrl,
@@ -513,7 +532,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
513
532
  sourceMaps: project.clientSourceMaps,
514
533
  vitePlugins,
515
534
  })
516
- : timeBuildPhase(timingSink, "clientBundles", () =>
535
+ : timeBuildPhase(timingSink, progressSink, "clientBundles", () =>
517
536
  writeClientRouteBundles({
518
537
  appDir: project.routesDir,
519
538
  assetBaseUrl: project.assetBaseUrl,
@@ -533,9 +552,9 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
533
552
  const navigationRuntimeScript = clientRoutes.some(
534
553
  (route) => route.navigation === true && !route.client,
535
554
  )
536
- ? timingSink === undefined
555
+ ? shouldTrackBuildPhases === false
537
556
  ? await writeNavigationRuntimeBundle(clientDir, project.clientConsolePureFunctions)
538
- : await timeBuildPhase(timingSink, "navigationRuntime", () =>
557
+ : await timeBuildPhase(timingSink, progressSink, "navigationRuntime", () =>
539
558
  writeNavigationRuntimeBundle(clientDir, project.clientConsolePureFunctions),
540
559
  )
541
560
  : undefined;
@@ -555,7 +574,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
555
574
  ]),
556
575
  ).sort();
557
576
  const prerenderedRoutes =
558
- timingSink === undefined
577
+ shouldTrackBuildPhases === false
559
578
  ? await prerenderStaticRoutes({
560
579
  appDir: project.routesDir,
561
580
  assetBaseUrl: project.assetBaseUrl,
@@ -567,7 +586,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
567
586
  sourceAnalysis,
568
587
  vitePlugins,
569
588
  })
570
- : await timeBuildPhase(timingSink, "prerender", () =>
589
+ : await timeBuildPhase(timingSink, progressSink, "prerender", () =>
571
590
  prerenderStaticRoutes({
572
591
  appDir: project.routesDir,
573
592
  assetBaseUrl: project.assetBaseUrl,
@@ -583,7 +602,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
583
602
  let cloudflareRouteModules: CloudflareRouteModulesOutput | undefined;
584
603
  if (shouldBuildCloudflare) {
585
604
  cloudflareRouteModules =
586
- timingSink === undefined
605
+ shouldTrackBuildPhases === false
587
606
  ? await writeCloudflareRouteModules({
588
607
  cloudflareDir,
589
608
  define: viteDefine,
@@ -596,7 +615,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
596
615
  sourceAnalysis,
597
616
  vitePlugins,
598
617
  })
599
- : await timeBuildPhase(timingSink, "cloudflare", () =>
618
+ : await timeBuildPhase(timingSink, progressSink, "cloudflare", () =>
600
619
  writeCloudflareRouteModules({
601
620
  cloudflareDir,
602
621
  define: viteDefine,
@@ -667,13 +686,13 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
667
686
  ),
668
687
  ]);
669
688
  };
670
- if (timingSink === undefined) {
689
+ if (shouldTrackBuildPhases === false) {
671
690
  await writeManifestFiles();
672
691
  } else {
673
- await timeBuildPhase(timingSink, "writeManifests", writeManifestFiles);
692
+ await timeBuildPhase(timingSink, progressSink, "writeManifests", writeManifestFiles);
674
693
  }
675
694
 
676
- if (timingSink === undefined) {
695
+ if (shouldTrackBuildPhases === false) {
677
696
  await Promise.all([
678
697
  ...(shouldBuildAwsLambda ? [writeAwsLambdaHandlerArtifact(options.outDir)] : []),
679
698
  ...(shouldBuildCloudflare
@@ -688,7 +707,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
688
707
  : []),
689
708
  ]);
690
709
  } else {
691
- await timeBuildPhase(timingSink, "adapterArtifacts", async () => {
710
+ await timeBuildPhase(timingSink, progressSink, "adapterArtifacts", async () => {
692
711
  await Promise.all([
693
712
  ...(shouldBuildAwsLambda ? [writeAwsLambdaHandlerArtifact(options.outDir)] : []),
694
713
  ...(shouldBuildCloudflare
@@ -741,17 +760,25 @@ function typedRoutesDeclaration(routes: readonly AppRoute[]): string {
741
760
  }
742
761
 
743
762
  async function timeBuildPhase<T>(
744
- sink: (timing: BuildAppPhaseTiming) => void,
763
+ timingSink: ((timing: BuildAppPhaseTiming) => void) | undefined,
764
+ progressSink: ((event: BuildAppProgressEvent) => void) | undefined,
745
765
  phase: BuildAppPhase,
746
766
  run: () => Promise<T>,
747
767
  ): Promise<T> {
768
+ progressSink?.({ kind: "phase-start", phase });
748
769
  const startedAt = performance.now();
749
770
 
750
771
  try {
751
772
  return await run();
752
773
  } finally {
753
- sink({
754
- ms: roundBuildPhaseMs(performance.now() - startedAt),
774
+ const ms = roundBuildPhaseMs(performance.now() - startedAt);
775
+ timingSink?.({
776
+ ms,
777
+ phase,
778
+ });
779
+ progressSink?.({
780
+ kind: "phase-end",
781
+ ms,
755
782
  phase,
756
783
  });
757
784
  }
package/src/cli.ts CHANGED
@@ -1,10 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import { readFile } from "node:fs/promises";
3
4
  import { resolve } from "node:path";
4
- import { buildApp, packageAwsLambdaArtifact, packageCloudflarePagesArtifact } from "./build.js";
5
+ import {
6
+ buildApp,
7
+ packageAwsLambdaArtifact,
8
+ packageCloudflarePagesArtifact,
9
+ type BuildAppPhase,
10
+ type BuildAppProgressEvent,
11
+ } from "./build.js";
5
12
  import {
6
13
  buildTargetsFromCliTarget,
7
14
  createCliRequestLogger,
15
+ type CliBuildTarget,
8
16
  formatCliHelp,
9
17
  parseCliArguments,
10
18
  resolveCliAllowedHosts,
@@ -40,20 +48,42 @@ if (parsed !== undefined) {
40
48
  : undefined;
41
49
 
42
50
  if (command === "build") {
51
+ const startedAt = performance.now();
52
+ let activeBuildPhase: BuildAppPhase | undefined;
53
+ console.log(`mreact-router build v${await readRouterCliVersion()}`);
54
+ console.log(`Target: ${formatCliBuildTarget(parsed.target)}`);
55
+ console.log(`Root: ${process.cwd()}`);
56
+ console.log("Config: loading...");
43
57
  const loaded =
44
58
  routeArg === undefined
45
59
  ? await loadMreactRouterViteConfigDetails({ command: "build", cwd: process.cwd() })
46
60
  : { project: { appDir: resolve(routeArg) }, viteConfig: undefined };
47
- const result = await buildApp({
48
- ...loaded.project,
49
- ...(parsed.clientSourceMaps === undefined
50
- ? {}
51
- : { clientSourceMaps: parsed.clientSourceMaps }),
52
- outDir: resolve(".mreact"),
53
- targets: buildTargetsFromCliTarget(parsed.target),
54
- viteConfig: loaded.viteConfig,
55
- });
56
- console.log(`Built ${result.routes.length} routes.`);
61
+ try {
62
+ const result = await buildApp({
63
+ ...loaded.project,
64
+ ...(parsed.clientSourceMaps === undefined
65
+ ? {}
66
+ : { clientSourceMaps: parsed.clientSourceMaps }),
67
+ onBuildProgress(event) {
68
+ activeBuildPhase = updateBuildProgressLog(event, activeBuildPhase);
69
+ },
70
+ outDir: resolve(".mreact"),
71
+ targets: buildTargetsFromCliTarget(parsed.target),
72
+ viteConfig: loaded.viteConfig,
73
+ });
74
+ console.log(
75
+ `Built ${result.routes.length} routes in ${formatDurationSeconds(performance.now() - startedAt)}.`,
76
+ );
77
+ } catch (error) {
78
+ if (activeBuildPhase !== undefined) {
79
+ throw new Error(
80
+ `Build failed during ${formatBuildPhaseFailureLabel(activeBuildPhase)}: ${
81
+ error instanceof Error ? error.message : String(error)
82
+ }`,
83
+ );
84
+ }
85
+ throw error;
86
+ }
57
87
  } else if (command === "package") {
58
88
  if (routeArg === "aws-lambda") {
59
89
  const manifest = await packageAwsLambdaArtifact({
@@ -82,7 +112,11 @@ if (parsed !== undefined) {
82
112
  const loaded =
83
113
  routeArg === undefined
84
114
  ? await loadMreactRouterViteConfigDetails({ command: "serve", cwd: process.cwd() })
85
- : { project: { appDir: resolve(routeArg) }, serverPort: undefined, viteConfig: undefined };
115
+ : {
116
+ project: { appDir: resolve(routeArg) },
117
+ serverPort: undefined,
118
+ viteConfig: undefined,
119
+ };
86
120
  const server = await startDevServer({
87
121
  ...loaded.project,
88
122
  logger,
@@ -110,3 +144,101 @@ if (parsed !== undefined) {
110
144
  process.exitCode = 1;
111
145
  }
112
146
  }
147
+
148
+ async function readRouterCliVersion(): Promise<string> {
149
+ try {
150
+ const source = await readFile(new URL("../package.json", import.meta.url), "utf8");
151
+ const json = JSON.parse(source) as { version?: unknown };
152
+
153
+ return typeof json.version === "string" ? json.version : "unknown";
154
+ } catch {
155
+ return "unknown";
156
+ }
157
+ }
158
+
159
+ function formatCliBuildTarget(target: CliBuildTarget | undefined): string {
160
+ return target ?? "default";
161
+ }
162
+
163
+ function updateBuildProgressLog(
164
+ event: BuildAppProgressEvent,
165
+ activePhase: BuildAppPhase | undefined,
166
+ ): BuildAppPhase | undefined {
167
+ if (event.kind === "routes-discovered") {
168
+ console.log(`Routes: ${event.count} discovered`);
169
+ return activePhase;
170
+ }
171
+
172
+ if (event.kind !== "phase-start") {
173
+ return activePhase;
174
+ }
175
+
176
+ const message = buildPhaseProgressMessage(event.phase);
177
+ if (message !== undefined) {
178
+ console.log(message);
179
+ }
180
+
181
+ return event.phase;
182
+ }
183
+
184
+ function buildPhaseProgressMessage(phase: BuildAppPhase): string | undefined {
185
+ switch (phase) {
186
+ case "scan":
187
+ return "Routes: discovering...";
188
+ case "serverModules":
189
+ return "Server: building...";
190
+ case "clientBundles":
191
+ return "Client: building...";
192
+ case "writeManifests":
193
+ return "Artifacts: writing...";
194
+ default:
195
+ return undefined;
196
+ }
197
+ }
198
+
199
+ function formatBuildPhaseFailureLabel(phase: BuildAppPhase): string {
200
+ switch (phase) {
201
+ case "scan":
202
+ return "route discovery";
203
+ case "collectFiles":
204
+ return "source file collection";
205
+ case "analyzeSources":
206
+ return "source analysis";
207
+ case "validate":
208
+ return "production route validation";
209
+ case "prepareOutput":
210
+ return "output preparation";
211
+ case "publicAssets":
212
+ return "public asset collection";
213
+ case "serverActionManifest":
214
+ return "server action manifest generation";
215
+ case "serverModules":
216
+ return "server output build";
217
+ case "importPolicy":
218
+ return "import policy generation";
219
+ case "serverModuleArtifacts":
220
+ return "server artifact writing";
221
+ case "clientBundles":
222
+ return "client output build";
223
+ case "navigationRuntime":
224
+ return "navigation runtime build";
225
+ case "prerender":
226
+ return "static prerender";
227
+ case "cloudflare":
228
+ return "Cloudflare artifact generation";
229
+ case "writeManifests":
230
+ return "manifest writing";
231
+ case "adapterArtifacts":
232
+ return "adapter artifact writing";
233
+ }
234
+ }
235
+
236
+ function formatDurationSeconds(ms: number): string {
237
+ const seconds = ms / 1000;
238
+
239
+ if (seconds < 10) {
240
+ return `${Math.round(seconds * 10) / 10}s`;
241
+ }
242
+
243
+ return `${Math.round(seconds)}s`;
244
+ }
package/src/client.ts CHANGED
@@ -2515,7 +2515,34 @@ function __mreactEvaluateHydrationNode(factory) {
2515
2515
  }
2516
2516
  }
2517
2517
 
2518
- __mreactHydrateRoute();
2518
+ const __mreactRouteHydrationReported = Symbol.for("mreact.routeHydrationReported");
2519
+
2520
+ function __mreactReportRouteHydrationError(error) {
2521
+ if (error !== null && typeof error === "object") {
2522
+ if (error[__mreactRouteHydrationReported] === true) {
2523
+ return;
2524
+ }
2525
+ error[__mreactRouteHydrationReported] = true;
2526
+ }
2527
+
2528
+ if (typeof console !== "undefined" && typeof console.error === "function") {
2529
+ console.error(
2530
+ \`mreact: route hydration failed for route "\${__mreactRouteId}". Server HTML remains visible, but client interactivity for this route was not attached.\`,
2531
+ error,
2532
+ );
2533
+ }
2534
+ }
2535
+
2536
+ function __mreactRunRouteHydration(factory) {
2537
+ try {
2538
+ return factory();
2539
+ } catch (error) {
2540
+ __mreactReportRouteHydrationError(error);
2541
+ throw error;
2542
+ }
2543
+ }
2544
+
2545
+ __mreactRunRouteHydration(() => __mreactHydrateRoute());
2519
2546
  ${clientNavigation ? "__mreactInstallNavigation();" : ""}
2520
2547
 
2521
2548
  ${
@@ -2989,7 +3016,12 @@ ${routeCleanupNavigationDispose} __mreactSyncRouteDataScripts(template.content,
2989
3016
 
2990
3017
  const script = template.content.querySelector('script[type="module"][src]')?.getAttribute("src");
2991
3018
  if (script !== null && script !== undefined) {
2992
- void import(/* @vite-ignore */ script).then((module) => module.${routeHydrationContract.routeHydrateExport}?.());
3019
+ void import(/* @vite-ignore */ script)
3020
+ .then((module) => __mreactRunRouteHydration(() => module.${routeHydrationContract.routeHydrateExport}?.()))
3021
+ .catch((error) => {
3022
+ __mreactReportRouteHydrationError(error);
3023
+ throw error;
3024
+ });
2993
3025
  } else {
2994
3026
  __mreactMarkRouteHydrated();
2995
3027
  }
package/src/index.ts CHANGED
@@ -75,6 +75,7 @@ export type {
75
75
  BuildAppPhase,
76
76
  BuildAppPhaseTiming,
77
77
  BuildAppOptions,
78
+ BuildAppProgressEvent,
78
79
  BuildAppResult,
79
80
  BuiltImportPolicyArtifact,
80
81
  CloudflarePagesArtifactManifest,
package/src/vite.ts CHANGED
@@ -287,7 +287,8 @@ export function cell(initial) {
287
287
  if (id === virtualReactiveDevtoolsId) {
288
288
  return `export function emitReactiveDevtoolsEvent() {}
289
289
  export function hasReactiveDevtoolsEmitter() { return false; }
290
- export function currentDevtoolsEmitter() { return undefined; }`;
290
+ export function currentDevtoolsEmitter() { return undefined; }
291
+ export function currentReactiveDevtools() { return undefined; }`;
291
292
  }
292
293
 
293
294
  if (id.startsWith(virtualClientPrefix)) {