@remix-run/router 0.0.0-experimental-9c60e757e → 0.0.0-experimental-3ce8d73c7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # `@remix-run/router`
2
2
 
3
+ ## 1.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add support for Lazy Route Discovery (a.k.a. Fog of War) ([#11626](https://github.com/remix-run/react-router/pull/11626))
8
+
9
+ - RFC: <https://github.com/remix-run/react-router/discussions/11113>
10
+ - `unstable_patchRoutesOnMiss` docs: <https://reactrouter.com/en/main/routers/create-browser-router>
11
+
3
12
  ## 1.16.1
4
13
 
5
14
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @remix-run/router v0.0.0-experimental-9c60e757e
2
+ * @remix-run/router v0.0.0-experimental-3ce8d73c7
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1216,7 +1216,7 @@ function getResolveToMatches(matches, v7_relativeSplatPath) {
1216
1216
  // match so we include splat values for "." links. See:
1217
1217
  // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329
1218
1218
  if (v7_relativeSplatPath) {
1219
- return pathMatches.map((match, idx) => idx === matches.length - 1 ? match.pathname : match.pathnameBase);
1219
+ return pathMatches.map((match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase);
1220
1220
  }
1221
1221
  return pathMatches.map(match => match.pathnameBase);
1222
1222
  }
@@ -2058,6 +2058,8 @@ function createRouter(init) {
2058
2058
  // Always respect the user flag. Otherwise don't reset on mutation
2059
2059
  // submission navigations unless they redirect
2060
2060
  let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true;
2061
+
2062
+ // Commit any in-flight routes at the end of the HMR revalidation "navigation"
2061
2063
  if (inFlightDataRoutes) {
2062
2064
  dataRoutes = inFlightDataRoutes;
2063
2065
  inFlightDataRoutes = undefined;
@@ -3524,21 +3526,32 @@ function createRouter(init) {
3524
3526
  let partialMatches = matches;
3525
3527
  let route = partialMatches.length > 0 ? partialMatches[partialMatches.length - 1].route : null;
3526
3528
  while (true) {
3529
+ let isNonHMR = inFlightDataRoutes == null;
3530
+ let routesToUse = inFlightDataRoutes || dataRoutes;
3527
3531
  try {
3528
- await loadLazyRouteChildren(route, patchRoutesOnMissImpl, pathname, partialMatches, dataRoutes || inFlightDataRoutes, manifest, mapRouteProperties, pendingPatchRoutes, signal);
3529
- if (signal.aborted) {
3530
- return {
3531
- type: "aborted"
3532
- };
3533
- }
3532
+ await loadLazyRouteChildren(patchRoutesOnMissImpl, pathname, partialMatches, routesToUse, manifest, mapRouteProperties, pendingPatchRoutes, signal);
3534
3533
  } catch (e) {
3535
3534
  return {
3536
3535
  type: "error",
3537
3536
  error: e,
3538
3537
  partialMatches
3539
3538
  };
3539
+ } finally {
3540
+ // If we are not in the middle of an HMR revalidation and we changed the
3541
+ // routes, provide a new identity so when we `updateState` at the end of
3542
+ // this navigation/fetch `router.routes` will be a new identity and
3543
+ // trigger a re-run of memoized `router.routes` dependencies.
3544
+ // HMR will already update the identity and reflow when it lands
3545
+ // `inFlightDataRoutes` in `completeNavigation`
3546
+ if (isNonHMR) {
3547
+ dataRoutes = [...dataRoutes];
3548
+ }
3549
+ }
3550
+ if (signal.aborted) {
3551
+ return {
3552
+ type: "aborted"
3553
+ };
3540
3554
  }
3541
- let routesToUse = inFlightDataRoutes || dataRoutes;
3542
3555
  let newMatches = matchRoutes(routesToUse, pathname, basename);
3543
3556
  let matchedSplat = false;
3544
3557
  if (newMatches) {
@@ -3567,21 +3580,14 @@ function createRouter(init) {
3567
3580
  }
3568
3581
  let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
3569
3582
 
3570
- // Loop detection if we find the same partials after a run through patchRoutesOnMiss
3583
+ // If we are no longer partially matching anything, this was either a
3584
+ // legit splat match above, or it's a 404. Also avoid loops if the
3585
+ // second pass results in the same partial matches
3571
3586
  if (!newPartialMatches || partialMatches.map(m => m.route.id).join("-") === newPartialMatches.map(m => m.route.id).join("-")) {
3572
- // We are no longer partially matching anything new so this was either a
3573
- // legit splat match above, or it's a 404
3574
- if (matchedSplat) {
3575
- return {
3576
- type: "success",
3577
- matches: newMatches
3578
- };
3579
- } else {
3580
- return {
3581
- type: "success",
3582
- matches: null
3583
- };
3584
- }
3587
+ return {
3588
+ type: "success",
3589
+ matches: matchedSplat ? newMatches : null
3590
+ };
3585
3591
  }
3586
3592
  partialMatches = newPartialMatches;
3587
3593
  route = partialMatches[partialMatches.length - 1].route;
@@ -3598,6 +3604,35 @@ function createRouter(init) {
3598
3604
  manifest = {};
3599
3605
  inFlightDataRoutes = convertRoutesToDataRoutes(newRoutes, mapRouteProperties, undefined, manifest);
3600
3606
  }
3607
+
3608
+ // single-patch implementation:
3609
+ // router.patchRoutes(parentId, children);
3610
+ //
3611
+ // batch-patch implementation:
3612
+ // router.patchRoutes((patch) => {
3613
+ // patch(parentId1, children1);
3614
+ // patch(parentId2, children2);
3615
+ // patch(parentId3, children3);
3616
+ // });
3617
+ function patchRoutes(routeIdOrCb, children) {
3618
+ let isNonHMR = inFlightDataRoutes == null;
3619
+ let routesToUse = inFlightDataRoutes || dataRoutes;
3620
+ if (typeof routeIdOrCb === "function") {
3621
+ routeIdOrCb((r, c) => patchRoutesImpl(r, c, routesToUse, manifest, mapRouteProperties));
3622
+ } else if (typeof routeIdOrCb === "string" && children != null) {
3623
+ patchRoutesImpl(routeIdOrCb, children, routesToUse, manifest, mapRouteProperties);
3624
+ }
3625
+
3626
+ // If we are not in the middle of an HMR revalidation and we changed the
3627
+ // routes, provide a new identity and trigger a reflow via `updateState`
3628
+ // to re-run memoized `router.routes` dependencies.
3629
+ // HMR will already update the identity and reflow when it lands
3630
+ // `inFlightDataRoutes` in `completeNavigation`
3631
+ if (isNonHMR) {
3632
+ dataRoutes = [...dataRoutes];
3633
+ updateState({});
3634
+ }
3635
+ }
3601
3636
  router = {
3602
3637
  get basename() {
3603
3638
  return basename;
@@ -3629,9 +3664,7 @@ function createRouter(init) {
3629
3664
  dispose,
3630
3665
  getBlocker,
3631
3666
  deleteBlocker,
3632
- patchRoutes(routeId, children) {
3633
- return patchRoutes(routeId, children, dataRoutes || inFlightDataRoutes, manifest, mapRouteProperties);
3634
- },
3667
+ patchRoutes,
3635
3668
  _internalFetchControllers: fetchControllers,
3636
3669
  _internalActiveDeferreds: activeDeferreds,
3637
3670
  // TODO: Remove setRoutes, it's temporary to avoid dealing with
@@ -4449,38 +4482,33 @@ function shouldRevalidateLoader(loaderMatch, arg) {
4449
4482
  }
4450
4483
 
4451
4484
  /**
4452
- * Idempotent utility to execute route.children() method to lazily load route
4485
+ * Idempotent utility to execute patchRoutesOnMiss() to lazily load route
4453
4486
  * definitions and update the routes/routeManifest
4454
4487
  */
4455
- async function loadLazyRouteChildren(route, patchRoutesOnMissImpl, path, matches, routes, manifest, mapRouteProperties, pendingRouteChildren, signal) {
4488
+ async function loadLazyRouteChildren(patchRoutesOnMissImpl, path, matches, routes, manifest, mapRouteProperties, pendingRouteChildren, signal) {
4456
4489
  let key = [path, ...matches.map(m => m.route.id)].join("-");
4457
- let pending = pendingRouteChildren.get(key);
4458
- let children = null;
4459
- if (!pending) {
4460
- let maybePromise = patchRoutesOnMissImpl(path, matches, (r, c) => patchRoutes(r, c, routes, manifest, mapRouteProperties));
4461
- if (isPromise(maybePromise)) {
4462
- pending = maybePromise;
4463
- pendingRouteChildren.set(key, pending);
4464
- } else {
4465
- children = maybePromise;
4466
- }
4467
- }
4468
4490
  try {
4469
- if (pending) {
4470
- children = await pending;
4491
+ let pending = pendingRouteChildren.get(key);
4492
+ if (!pending) {
4493
+ pending = patchRoutesOnMissImpl({
4494
+ path,
4495
+ matches,
4496
+ patch: (routeId, children) => {
4497
+ if (!signal.aborted) {
4498
+ patchRoutesImpl(routeId, children, routes, manifest, mapRouteProperties);
4499
+ }
4500
+ }
4501
+ });
4502
+ pendingRouteChildren.set(key, pending);
4471
4503
  }
4472
- if (children && !signal.aborted) {
4473
- if (route) {
4474
- patchRoutes(route.id, children, routes, manifest, mapRouteProperties);
4475
- } else {
4476
- warning(false, "You cannot return routes from `patchRoutesOnMiss` when there were no " + "partial matches, since React Router doesn't know where to patch the " + "routes. Please use `patch(routeId, children)` instead.");
4477
- }
4504
+ if (pending && isPromise(pending)) {
4505
+ await pending;
4478
4506
  }
4479
4507
  } finally {
4480
4508
  pendingRouteChildren.delete(key);
4481
4509
  }
4482
4510
  }
4483
- function patchRoutes(routeId, children, routes, manifest, mapRouteProperties) {
4511
+ function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties) {
4484
4512
  if (routeId) {
4485
4513
  var _route$children;
4486
4514
  let route = manifest[routeId];
@@ -4492,8 +4520,8 @@ function patchRoutes(routeId, children, routes, manifest, mapRouteProperties) {
4492
4520
  route.children = dataChildren;
4493
4521
  }
4494
4522
  } else {
4495
- let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, ["patch", String(routes.length || "0")], manifest);
4496
- routes.push(...dataChildren);
4523
+ let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, ["patch", String(routesToUse.length || "0")], manifest);
4524
+ routesToUse.push(...dataChildren);
4497
4525
  }
4498
4526
  }
4499
4527