@reckona/mreact-router 0.0.86 → 0.0.88

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/client.ts CHANGED
@@ -938,14 +938,7 @@ function isStyleModuleSpecifier(source: string): boolean {
938
938
  return styleModuleExtensions.has(extname(pathname));
939
939
  }
940
940
 
941
- const styleModuleExtensions = new Set([
942
- ".css",
943
- ".less",
944
- ".sass",
945
- ".scss",
946
- ".styl",
947
- ".stylus",
948
- ]);
941
+ const styleModuleExtensions = new Set([".css", ".less", ".sass", ".scss", ".styl", ".stylus"]);
949
942
 
950
943
  function renderedImportedExportNames(
951
944
  reference: ClientRouteStaticImportReference,
@@ -1272,13 +1265,10 @@ function hasViteTransformHook(plugin: Plugin): boolean {
1272
1265
  return viteTransformHookHandler(plugin) !== undefined;
1273
1266
  }
1274
1267
 
1275
- function viteTransformHookHandler(plugin: Plugin):
1276
- | ((
1277
- this: unknown,
1278
- code: string,
1279
- id: string,
1280
- options?: { ssr?: boolean | undefined },
1281
- ) => unknown)
1268
+ function viteTransformHookHandler(
1269
+ plugin: Plugin,
1270
+ ):
1271
+ | ((this: unknown, code: string, id: string, options?: { ssr?: boolean | undefined }) => unknown)
1282
1272
  | undefined {
1283
1273
  const transform = plugin.transform as unknown;
1284
1274
 
@@ -1580,8 +1570,7 @@ export async function buildClientRouteEntrySource(
1580
1570
  routeSourceAnalysis,
1581
1571
  options.filename,
1582
1572
  );
1583
- const routeHasEventBindings =
1584
- (compiled.metadata.eventHydrationManifest?.events.length ?? 0) > 0;
1573
+ const routeHasEventBindings = (compiled.metadata.eventHydrationManifest?.events.length ?? 0) > 0;
1585
1574
  const routeRequiresFullHydration =
1586
1575
  routeExplicitlyRequiresHydration ||
1587
1576
  routeUsesCells ||
@@ -1695,8 +1684,9 @@ __mreactGlobal.__mreactRouteCell = (nativeCell, initial) => {
1695
1684
  `
1696
1685
  : "";
1697
1686
  const routeCellHydrationIndent = routeUsesCells ? " " : " ";
1698
- const routeCleanupHydrationStart = routeUsesCleanupScope && !routeUsesCells
1699
- ? ` __mreactDisposeRoute(__mreactRouteId);
1687
+ const routeCleanupHydrationStart =
1688
+ routeUsesCleanupScope && !routeUsesCells
1689
+ ? ` __mreactDisposeRoute(__mreactRouteId);
1700
1690
  const __mreactRouteEffectDisposers = new Set();
1701
1691
  __mreactRouteDisposers.set(__mreactRouteId, () => {
1702
1692
  for (const __mreactDispose of Array.from(__mreactRouteEffectDisposers)) {
@@ -1705,7 +1695,7 @@ __mreactGlobal.__mreactRouteCell = (nativeCell, initial) => {
1705
1695
  __mreactRouteEffectDisposers.clear();
1706
1696
  });
1707
1697
  `
1708
- : "";
1698
+ : "";
1709
1699
  const routeCellDropFunction = routeUsesCells
1710
1700
  ? `
1711
1701
  function __mreactDropMismatchedRouteState(previousState, nextState) {
@@ -2249,6 +2239,7 @@ function __mreactApplyNavigationHtml(html, url) {
2249
2239
 
2250
2240
  __mreactMarkRouteHydrating();
2251
2241
  __mreactSyncHeadMetadata(template.content, html);
2242
+ __mreactUnmountCompatBoundaries(currentMarker);
2252
2243
  __mreactResumeNode(currentMarker, nextMarker);
2253
2244
  ${routeCleanupNavigationDispose} __mreactSyncRouteDataScripts(template.content, currentRouteId, nextRouteId);
2254
2245
 
@@ -2788,12 +2779,19 @@ function __mreactHydrateClientBoundaries(marker, references, components) {
2788
2779
  : JSON.parse(propsElement.textContent);
2789
2780
 
2790
2781
  if (compat) {
2791
- const container = document.createElement("span");
2782
+ const parentContainer = __mreactClientBoundaryParentContainer(placeholder, propsElement);
2783
+ const container = parentContainer ?? document.createElement("span");
2792
2784
  container.setAttribute("data-mreact-compat-boundary", name ?? "");
2793
- container.style.display = "contents";
2794
- placeholder.replaceWith(container);
2795
- __mreactCompatCreateRoot(container).render(__mreactCompatCreateElement(component, props));
2785
+ if (parentContainer === null) {
2786
+ container.style.display = "contents";
2787
+ placeholder.replaceWith(container);
2788
+ } else {
2789
+ placeholder.remove();
2790
+ }
2796
2791
  propsElement?.remove();
2792
+ const root = __mreactCompatCreateRoot(container);
2793
+ container.__mreactCompatRoot = root;
2794
+ root.render(__mreactCompatCreateElement(component, props));
2797
2795
  continue;
2798
2796
  }
2799
2797
 
@@ -2806,6 +2804,54 @@ function __mreactHydrateClientBoundaries(marker, references, components) {
2806
2804
  return true;
2807
2805
  }
2808
2806
 
2807
+ function __mreactClientBoundaryParentContainer(placeholder, propsElement) {
2808
+ const parent = placeholder.parentElement;
2809
+
2810
+ if (parent === null) {
2811
+ return null;
2812
+ }
2813
+
2814
+ for (const node of Array.from(parent.childNodes)) {
2815
+ if (node === placeholder || node === propsElement) {
2816
+ continue;
2817
+ }
2818
+
2819
+ if (node.nodeType === Node.TEXT_NODE && (node.textContent ?? "").trim() === "") {
2820
+ continue;
2821
+ }
2822
+
2823
+ return null;
2824
+ }
2825
+
2826
+ return parent;
2827
+ }
2828
+
2829
+ function __mreactUnmountCompatBoundaries(root) {
2830
+ const containers = [];
2831
+
2832
+ if (
2833
+ root.nodeType === Node.ELEMENT_NODE &&
2834
+ root.hasAttribute("data-mreact-compat-boundary")
2835
+ ) {
2836
+ containers.push(root);
2837
+ }
2838
+
2839
+ if (typeof root.querySelectorAll === "function") {
2840
+ containers.push(...root.querySelectorAll("[data-mreact-compat-boundary]"));
2841
+ }
2842
+
2843
+ for (const container of containers) {
2844
+ const compatRoot = container.__mreactCompatRoot;
2845
+
2846
+ if (compatRoot === undefined || typeof compatRoot.unmount !== "function") {
2847
+ continue;
2848
+ }
2849
+
2850
+ compatRoot.unmount();
2851
+ container.__mreactCompatRoot = undefined;
2852
+ }
2853
+ }
2854
+
2809
2855
  function __mreactHasNonSerializableClientBoundaries(marker) {
2810
2856
  return marker.querySelector(
2811
2857
  'template[data-mreact-client-boundary][data-mreact-client-boundary-nonserializable="true"]',
@@ -2912,6 +2958,7 @@ function __mreactResumeNode(current, next) {
2912
2958
  }
2913
2959
 
2914
2960
  if (__mreactShouldReplaceNode(current, next)) {
2961
+ __mreactUnmountCompatBoundaries(current);
2915
2962
  current.replaceWith(next);
2916
2963
  return;
2917
2964
  }
@@ -2924,6 +2971,7 @@ function __mreactResumeNode(current, next) {
2924
2971
  }
2925
2972
 
2926
2973
  if (current.nodeType !== Node.ELEMENT_NODE || next.nodeType !== Node.ELEMENT_NODE) {
2974
+ __mreactUnmountCompatBoundaries(current);
2927
2975
  current.replaceWith(next);
2928
2976
  return;
2929
2977
  }
@@ -3204,7 +3252,12 @@ function __mreactResumeChildren(current, next) {
3204
3252
  }
3205
3253
 
3206
3254
  while (current.childNodes.length > nextChildren.length) {
3207
- current.lastChild?.remove();
3255
+ const lastChild = current.lastChild;
3256
+ if (lastChild === null) {
3257
+ break;
3258
+ }
3259
+ __mreactUnmountCompatBoundaries(lastChild);
3260
+ lastChild.remove();
3208
3261
  }
3209
3262
  }
3210
3263
  `;
@@ -3235,6 +3288,15 @@ function workspaceRuntimePlugin(options: { routeFiles: readonly string[] }) {
3235
3288
  "@reckona/mreact-compat",
3236
3289
  ];
3237
3290
  const runtimePaths = new Map([
3291
+ ["react", reactCompatPath],
3292
+ ["react-dom", reactCompatPath],
3293
+ ["react-dom/client", reactCompatPath],
3294
+ ["react-dom/server", reactCompatPath],
3295
+ [
3296
+ "react/jsx-dev-runtime",
3297
+ packageFile("react-compat", "@reckona/mreact-compat", "jsx-dev-runtime"),
3298
+ ],
3299
+ ["react/jsx-runtime", packageFile("react-compat", "@reckona/mreact-compat", "jsx-runtime")],
3238
3300
  [
3239
3301
  "@reckona/mreact-reactive-core/internal",
3240
3302
  packageFile("reactive-core", "@reckona/mreact-reactive-core", "internal"),
@@ -3264,10 +3326,7 @@ function workspaceRuntimePlugin(options: { routeFiles: readonly string[] }) {
3264
3326
  "@reckona/mreact-compat/scheduler",
3265
3327
  packageFile("react-compat", "@reckona/mreact-compat", "scheduler"),
3266
3328
  ],
3267
- [
3268
- "@reckona/mreact-reactive-dom",
3269
- reactiveDomPath,
3270
- ],
3329
+ ["@reckona/mreact-reactive-dom", reactiveDomPath],
3271
3330
  ]);
3272
3331
 
3273
3332
  return {
@@ -3295,7 +3354,7 @@ function workspaceRuntimePlugin(options: { routeFiles: readonly string[] }) {
3295
3354
  buildApi.onResolve(
3296
3355
  {
3297
3356
  filter:
3298
- /^@reckona\/mreact-(?:compat|reactive-core|reactive-dom)(?:\/(?:event-priority|flight|internal|jsx-dev-runtime|jsx-runtime|scheduler))?$/,
3357
+ /^(?:react(?:\/jsx-(?:dev-)?runtime)?|react-dom(?:\/(?:client|server))?|@reckona\/mreact-(?:compat|reactive-core|reactive-dom)(?:\/(?:event-priority|flight|internal|jsx-dev-runtime|jsx-runtime|scheduler))?)$/,
3299
3358
  },
3300
3359
  (args) => {
3301
3360
  const path = runtimePaths.get(args.path);
@@ -3381,9 +3440,7 @@ function importerInRuntimePackage(
3381
3440
  const normalizedImporter = importer.split(/[\\/]+/).join("/");
3382
3441
  return (
3383
3442
  directories.some((directory) => importer.startsWith(`${directory}${sep}`)) ||
3384
- packageNames.some((packageName) =>
3385
- normalizedImporter.includes(`/node_modules/${packageName}/`),
3386
- )
3443
+ packageNames.some((packageName) => normalizedImporter.includes(`/node_modules/${packageName}/`))
3387
3444
  );
3388
3445
  }
3389
3446
 
@@ -3421,10 +3478,7 @@ function detectRouteCellStateHint(code: string): boolean {
3421
3478
  }
3422
3479
 
3423
3480
  function detectRouteReactiveEffectHint(code: string): boolean {
3424
- return (
3425
- /from\s+["']@reckona\/mreact-reactive-core["']/.test(code) &&
3426
- /\beffect\s*\(/.test(code)
3427
- );
3481
+ return /from\s+["']@reckona\/mreact-reactive-core["']/.test(code) && /\beffect\s*\(/.test(code);
3428
3482
  }
3429
3483
 
3430
3484
  async function inferClientReferenceManifestForBundle(options: {