@reckona/mreact-router 0.0.182 → 0.0.184

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/render.ts CHANGED
@@ -195,6 +195,7 @@ export interface RenderAppRequestOptions {
195
195
  instrumentation?: RouterInstrumentation | undefined;
196
196
  logger?: AppRouterLogger | undefined;
197
197
  navigationScripts?: ReadonlyMap<string, string> | undefined;
198
+ onRenderError?: ((error: unknown) => void) | undefined;
198
199
  onResponse?: AppRouterResponseHook | undefined;
199
200
  queryClient?: QueryClient | undefined;
200
201
  request: Request;
@@ -794,6 +795,7 @@ export type AppRouterMiddlewareResult =
794
795
  export async function resolveAppRouterMiddleware(options: {
795
796
  appDir: string;
796
797
  define?: UserConfig["define"] | undefined;
798
+ devServerModuleCacheVersion?: string | undefined;
797
799
  importPolicy?: AppRouterImportPolicy | undefined;
798
800
  instrumentation?: RouterInstrumentation | undefined;
799
801
  middlewareControl?: RouteMiddlewareControl | undefined;
@@ -862,6 +864,7 @@ async function renderAppRequestInternal(
862
864
  ? ({ request: options.request, type: "continue" } satisfies AppRouterMiddlewareResult)
863
865
  : await resolveAppRouterMiddleware({
864
866
  appDir: options.appDir,
867
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
865
868
  importPolicy: options.importPolicy,
866
869
  instrumentation: options.instrumentation,
867
870
  middlewareControl,
@@ -1097,6 +1100,7 @@ async function renderAppRequestInternal(
1097
1100
  filename: matched.route.file,
1098
1101
  importPolicy: options.importPolicy,
1099
1102
  instrumentation: options.instrumentation,
1103
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
1100
1104
  request: options.request,
1101
1105
  routeId: routeIdForPath(matched.route.path),
1102
1106
  routePath: matched.route.path,
@@ -1271,7 +1275,7 @@ async function renderAppRequestInternal(
1271
1275
  assetBaseUrl: options.assetBaseUrl,
1272
1276
  currentStyleSheets: clientStyleSheets,
1273
1277
  currentScript: clientRoute ? clientScript : undefined,
1274
- currentNavigationScript: clientRoute ? undefined : navigationScript,
1278
+ currentNavigationScript: navigationScript,
1275
1279
  routeScripts: options.clientScripts,
1276
1280
  })}${html}`,
1277
1281
  preparedActions.htmlReplacements,
@@ -1558,7 +1562,7 @@ async function renderAppRequestInternal(
1558
1562
  assetBaseUrl: options.assetBaseUrl,
1559
1563
  currentStyleSheets: clientStyleSheets,
1560
1564
  currentScript: clientRoute ? clientScript : undefined,
1561
- currentNavigationScript: clientRoute ? undefined : navigationScript,
1565
+ currentNavigationScript: navigationScript,
1562
1566
  routeScripts: options.clientScripts,
1563
1567
  })}${html}`,
1564
1568
  preparedActions.htmlReplacements,
@@ -1629,6 +1633,7 @@ async function renderAppRequestInternal(
1629
1633
  filename: "error.mreact.tsx",
1630
1634
  pageFile: matched.route.file,
1631
1635
  });
1636
+ options.onRenderError?.(error);
1632
1637
 
1633
1638
  const response = await renderSpecialRoute({
1634
1639
  appDir: options.appDir,
@@ -1767,11 +1772,15 @@ function navigationRuntimeScriptTag(
1767
1772
  script: string | undefined,
1768
1773
  assetBaseUrl: string | undefined,
1769
1774
  ): string {
1770
- return script === undefined
1771
- ? ""
1772
- : `<script type="module" src="${escapeHtmlAttribute(
1773
- assetPath(script, assetBaseUrl ?? "/_mreact/client/"),
1774
- )}"></script>`;
1775
+ if (script === undefined) {
1776
+ return "";
1777
+ }
1778
+
1779
+ const json = JSON.stringify({
1780
+ script: assetPath(script, assetBaseUrl ?? "/_mreact/client/"),
1781
+ }).replaceAll("<", "\\u003c");
1782
+
1783
+ return `<script type="application/json" id="mreact-navigation-runtime">${json}</script>`;
1775
1784
  }
1776
1785
 
1777
1786
  function routePrefetchManifestScript(
@@ -2370,6 +2379,7 @@ function devExternalSourceDirs(
2370
2379
  async function runMiddleware(options: {
2371
2380
  appDir: string;
2372
2381
  define?: UserConfig["define"] | undefined;
2382
+ devServerModuleCacheVersion?: string | undefined;
2373
2383
  importPolicy?: AppRouterImportPolicy | undefined;
2374
2384
  instrumentation?: RouterInstrumentation | undefined;
2375
2385
  middlewareControl?: RouteMiddlewareControl | undefined;
@@ -2440,6 +2450,7 @@ async function runMiddleware(options: {
2440
2450
  serverModules: options.serverModules,
2441
2451
  serverModuleCacheVersion: options.serverModuleCacheVersion,
2442
2452
  serverSourceFiles: options.serverSourceFiles,
2453
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
2443
2454
  vitePlugins: options.vitePlugins,
2444
2455
  });
2445
2456
  } finally {
@@ -2538,6 +2549,7 @@ async function loadMiddlewareModule(options: {
2538
2549
  appDir: string;
2539
2550
  code?: string | undefined;
2540
2551
  define?: UserConfig["define"] | undefined;
2552
+ devServerModuleCacheVersion?: string | undefined;
2541
2553
  file: string;
2542
2554
  importPolicy?: AppRouterImportPolicy | undefined;
2543
2555
  serverModules?: ReadonlyMap<string, BuiltServerModuleArtifact> | undefined;
@@ -2552,10 +2564,12 @@ async function loadMiddlewareModule(options: {
2552
2564
  options.serverModuleCacheVersion,
2553
2565
  options.serverSourceFiles,
2554
2566
  ));
2567
+ const moduleCacheVersion =
2568
+ options.serverModuleCacheVersion ?? options.devServerModuleCacheVersion;
2555
2569
  const cacheKey =
2556
- options.serverModuleCacheVersion === undefined
2570
+ moduleCacheVersion === undefined
2557
2571
  ? undefined
2558
- : `middleware\0${options.appDir}\0${options.file}\0${options.serverModuleCacheVersion}\0${memoizedHashText(code)}\0${importPolicyCacheKey(options.importPolicy)}\0${viteDefineCacheKey(options.define)}\0${vitePluginsCacheKey(options.vitePlugins)}`;
2572
+ : `middleware\0${options.serverModuleCacheVersion === undefined ? "dev" : "build"}\0${options.appDir}\0${options.file}\0${moduleCacheVersion}\0${memoizedHashText(code)}\0${importPolicyCacheKey(options.importPolicy)}\0${viteDefineCacheKey(options.define)}\0${vitePluginsCacheKey(options.vitePlugins)}`;
2559
2573
 
2560
2574
  if (cacheKey !== undefined) {
2561
2575
  const cached = readRouterRuntimeCacheEntry(
@@ -2576,6 +2590,7 @@ async function loadMiddlewareModule(options: {
2576
2590
  file: options.file,
2577
2591
  importPolicy: options.importPolicy,
2578
2592
  prebuiltArtifact: prebuiltRequestModuleArtifact(options.serverModules, options.file, code),
2593
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
2579
2594
  serverModuleCacheVersion: options.serverModuleCacheVersion,
2580
2595
  vitePlugins: options.vitePlugins,
2581
2596
  }).catch((error) => {
@@ -2637,6 +2652,7 @@ async function loadBundledMiddlewareModule(options: {
2637
2652
  appDir: string;
2638
2653
  code: string;
2639
2654
  define?: UserConfig["define"] | undefined;
2655
+ devServerModuleCacheVersion?: string | undefined;
2640
2656
  file: string;
2641
2657
  importPolicy?: AppRouterImportPolicy | undefined;
2642
2658
  prebuiltArtifact?: BuiltServerModuleOutputLike | undefined;
@@ -2663,10 +2679,10 @@ async function loadBundledMiddlewareModule(options: {
2663
2679
  }));
2664
2680
 
2665
2681
  return importAppRouterSourceModule<MiddlewareModule>({
2666
- ...(options.serverModuleCacheVersion === undefined
2682
+ ...((options.serverModuleCacheVersion ?? options.devServerModuleCacheVersion) === undefined
2667
2683
  ? {}
2668
2684
  : {
2669
- cacheKey: `middleware:${options.file}:${options.serverModuleCacheVersion}:${memoizedHashText(compiled)}:${viteDefineCacheKey(options.define)}:${vitePluginsCacheKey(options.vitePlugins)}`,
2685
+ cacheKey: `middleware:${options.serverModuleCacheVersion === undefined ? "dev" : "build"}:${options.file}:${options.serverModuleCacheVersion ?? options.devServerModuleCacheVersion}:${memoizedHashText(compiled)}:${viteDefineCacheKey(options.define)}:${vitePluginsCacheKey(options.vitePlugins)}`,
2670
2686
  }),
2671
2687
  code: compiled,
2672
2688
  define: options.define,
@@ -4447,6 +4463,7 @@ async function loadRouteData(options: {
4447
4463
  code: string;
4448
4464
  context: RouteDataContext;
4449
4465
  define?: UserConfig["define"] | undefined;
4466
+ devServerModuleCacheVersion?: string | undefined;
4450
4467
  filename: string;
4451
4468
  importPolicy?: AppRouterImportPolicy | undefined;
4452
4469
  serverModules?: ReadonlyMap<string, BuiltServerModuleArtifact> | undefined;
@@ -4474,6 +4491,7 @@ async function loadRouteDataWithInstrumentation(options: {
4474
4491
  code: string;
4475
4492
  context: RouteDataContext;
4476
4493
  define?: UserConfig["define"] | undefined;
4494
+ devServerModuleCacheVersion?: string | undefined;
4477
4495
  filename: string;
4478
4496
  importPolicy?: AppRouterImportPolicy | undefined;
4479
4497
  instrumentation?: RouterInstrumentation | undefined;
@@ -4514,16 +4532,19 @@ async function loadRouteLoaderModule(options: {
4514
4532
  appDir: string;
4515
4533
  code: string;
4516
4534
  define?: UserConfig["define"] | undefined;
4535
+ devServerModuleCacheVersion?: string | undefined;
4517
4536
  filename: string;
4518
4537
  importPolicy?: AppRouterImportPolicy | undefined;
4519
4538
  serverModules?: ReadonlyMap<string, BuiltServerModuleArtifact> | undefined;
4520
4539
  serverModuleCacheVersion?: string | undefined;
4521
4540
  vitePlugins?: readonly PluginOption[] | undefined;
4522
4541
  }): Promise<RouteLoaderModule> {
4542
+ const moduleCacheVersion =
4543
+ options.serverModuleCacheVersion ?? options.devServerModuleCacheVersion;
4523
4544
  const cacheKey =
4524
- options.serverModuleCacheVersion === undefined
4545
+ moduleCacheVersion === undefined
4525
4546
  ? undefined
4526
- : `${options.appDir}\0${options.filename}\0${options.serverModuleCacheVersion}\0${memoizedHashText(options.code)}\0${importPolicyCacheKey(options.importPolicy)}\0${viteDefineCacheKey(options.define)}\0${vitePluginsCacheKey(options.vitePlugins)}`;
4547
+ : `${options.serverModuleCacheVersion === undefined ? "dev" : "build"}\0${options.appDir}\0${options.filename}\0${moduleCacheVersion}\0${memoizedHashText(options.code)}\0${importPolicyCacheKey(options.importPolicy)}\0${viteDefineCacheKey(options.define)}\0${vitePluginsCacheKey(options.vitePlugins)}`;
4527
4548
 
4528
4549
  if (cacheKey !== undefined) {
4529
4550
  const cached = readRouterRuntimeCacheEntry(
@@ -4602,6 +4623,7 @@ async function loadBundledRouteLoaderModule(options: {
4602
4623
  appDir: string;
4603
4624
  code: string;
4604
4625
  define?: UserConfig["define"] | undefined;
4626
+ devServerModuleCacheVersion?: string | undefined;
4605
4627
  filename: string;
4606
4628
  importPolicy?: AppRouterImportPolicy | undefined;
4607
4629
  prebuiltArtifact?: BuiltServerModuleOutputLike | undefined;
@@ -4632,10 +4654,10 @@ async function loadBundledRouteLoaderModule(options: {
4632
4654
  }));
4633
4655
 
4634
4656
  return await importAppRouterSourceModule<RouteLoaderModule>({
4635
- ...(options.serverModuleCacheVersion === undefined
4657
+ ...((options.serverModuleCacheVersion ?? options.devServerModuleCacheVersion) === undefined
4636
4658
  ? {}
4637
4659
  : {
4638
- cacheKey: `loader:${options.filename}:${options.serverModuleCacheVersion}:${memoizedHashText(code)}:${viteDefineCacheKey(options.define)}`,
4660
+ cacheKey: `loader:${options.serverModuleCacheVersion === undefined ? "dev" : "build"}:${options.filename}:${options.serverModuleCacheVersion ?? options.devServerModuleCacheVersion}:${memoizedHashText(code)}:${viteDefineCacheKey(options.define)}:${vitePluginsCacheKey(options.vitePlugins)}`,
4639
4661
  }),
4640
4662
  code,
4641
4663
  define: options.define,
package/src/vite.ts CHANGED
@@ -178,6 +178,10 @@ export function createAppRouterVitePlugin(options: AppRouterVitePluginOptions):
178
178
  "@reckona/mreact-compat/scheduler",
179
179
  packageFile("react-compat", "@reckona/mreact-compat", "scheduler"),
180
180
  ],
181
+ [
182
+ "@reckona/mreact-compat/server",
183
+ packageFile("react-compat", "@reckona/mreact-compat", "server"),
184
+ ],
181
185
  ["@reckona/mreact-router/link", packageFile("router", "@reckona/mreact-router", "link")],
182
186
  [
183
187
  "@reckona/mreact-router/navigation-state",
@@ -265,7 +269,11 @@ export function createAppRouterVitePlugin(options: AppRouterVitePluginOptions):
265
269
 
266
270
  devServerModuleCacheVersion += 1;
267
271
  const timestamp = Date.now();
268
- const updates = Array.from(context.server.moduleGraph.idToModuleMap.values())
272
+ const hotModules =
273
+ context.modules.length > 0
274
+ ? context.modules
275
+ : Array.from(context.server.moduleGraph.idToModuleMap.values());
276
+ const updates = hotModules
269
277
  .filter((moduleNode) => isMreactClientDevModuleId(moduleNode.id))
270
278
  .map((moduleNode) => {
271
279
  context.server.moduleGraph.invalidateModule(moduleNode);
@@ -584,6 +592,9 @@ async function handleAppRouterViteRequest(
584
592
  clientStylesByFile,
585
593
  clientRouteInferenceCache: options.clientRouteInferenceCache,
586
594
  navigationScripts,
595
+ onRenderError(error) {
596
+ sendViteErrorOverlay(options.viteDevServer, error);
597
+ },
587
598
  request,
588
599
  logger: options.logger,
589
600
  routeCache: options.routeCache,
@@ -595,10 +606,37 @@ async function handleAppRouterViteRequest(
595
606
  }),
596
607
  );
597
608
  } catch (error) {
609
+ sendViteErrorOverlay(options.viteDevServer, error);
598
610
  next(error);
599
611
  }
600
612
  }
601
613
 
614
+ function sendViteErrorOverlay(server: ViteDevServer | undefined, error: unknown): void {
615
+ if (server === undefined) {
616
+ return;
617
+ }
618
+
619
+ if (error instanceof Error) {
620
+ server.ssrFixStacktrace(error);
621
+ }
622
+ server.ws.send({
623
+ type: "error",
624
+ err: viteErrorPayload(error),
625
+ });
626
+ }
627
+
628
+ function viteErrorPayload(error: unknown): { message: string; stack: string } {
629
+ if (error instanceof Error) {
630
+ return {
631
+ message: error.message,
632
+ stack: error.stack ?? error.message,
633
+ };
634
+ }
635
+
636
+ const message = String(error);
637
+ return { message, stack: message };
638
+ }
639
+
602
640
  /**
603
641
  * Renders a development client asset generated by the app-router Vite integration.
604
642
  */