@remix-run/router 1.8.0 → 1.9.0-pre.1

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/dist/router.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { History, Location, Path, To } from "./history";
2
2
  import { Action as HistoryAction } from "./history";
3
- import type { DeferredData, AgnosticDataRouteMatch, AgnosticDataRouteObject, FormEncType, DetectErrorBoundaryFunction, RouteData, AgnosticRouteObject, Submission, AgnosticRouteMatch, HTMLFormMethod, MapRoutePropertiesFunction } from "./utils";
3
+ import type { AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticRouteObject, DeferredData, DetectErrorBoundaryFunction, FormEncType, HTMLFormMethod, MapRoutePropertiesFunction, RouteData, Submission, UIMatch } from "./utils";
4
4
  /**
5
5
  * A Router instance manages all navigation and data loading/mutations
6
6
  */
@@ -293,19 +293,12 @@ export interface StaticHandler {
293
293
  export interface RouterSubscriber {
294
294
  (state: RouterState): void;
295
295
  }
296
- interface UseMatchesMatch {
297
- id: string;
298
- pathname: string;
299
- params: AgnosticRouteMatch["params"];
300
- data: unknown;
301
- handle: unknown;
302
- }
303
296
  /**
304
297
  * Function signature for determining the key to be used in scroll restoration
305
298
  * for a given location
306
299
  */
307
300
  export interface GetScrollRestorationKeyFunction {
308
- (location: Location, matches: UseMatchesMatch[]): string | null;
301
+ (location: Location, matches: UIMatch[]): string | null;
309
302
  }
310
303
  /**
311
304
  * Function signature for determining the current scroll position
@@ -407,7 +400,6 @@ type FetcherStates<TData = any> = {
407
400
  formData: undefined;
408
401
  json: undefined;
409
402
  data: TData | undefined;
410
- " _hasFetcherDoneAnything "?: boolean;
411
403
  };
412
404
  Loading: {
413
405
  state: "loading";
@@ -418,7 +410,6 @@ type FetcherStates<TData = any> = {
418
410
  formData: Submission["formData"] | undefined;
419
411
  json: Submission["json"] | undefined;
420
412
  data: TData | undefined;
421
- " _hasFetcherDoneAnything "?: boolean;
422
413
  };
423
414
  Submitting: {
424
415
  state: "submitting";
@@ -429,7 +420,6 @@ type FetcherStates<TData = any> = {
429
420
  formData: Submission["formData"];
430
421
  json: Submission["json"];
431
422
  data: TData | undefined;
432
- " _hasFetcherDoneAnything "?: boolean;
433
423
  };
434
424
  };
435
425
  export type Fetcher<TData = any> = FetcherStates<TData>[keyof FetcherStates<TData>];
package/dist/router.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @remix-run/router v1.8.0
2
+ * @remix-run/router v1.9.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -534,6 +534,20 @@ function matchRoutes(routes, locationArg, basename) {
534
534
  }
535
535
  return matches;
536
536
  }
537
+ function convertRouteMatchToUiMatch(match, loaderData) {
538
+ let {
539
+ route,
540
+ pathname,
541
+ params
542
+ } = match;
543
+ return {
544
+ id: route.id,
545
+ pathname,
546
+ params,
547
+ data: loaderData[route.id],
548
+ handle: route.handle
549
+ };
550
+ }
537
551
  function flattenRoutes(routes, branches, parentsMeta, parentPath) {
538
552
  if (branches === void 0) {
539
553
  branches = [];
@@ -1190,7 +1204,7 @@ const redirectDocument = (url, init) => {
1190
1204
  * @private
1191
1205
  * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies
1192
1206
  */
1193
- class ErrorResponse {
1207
+ class ErrorResponseImpl {
1194
1208
  constructor(status, statusText, data, internal) {
1195
1209
  if (internal === void 0) {
1196
1210
  internal = false;
@@ -2050,8 +2064,7 @@ function createRouter(init) {
2050
2064
  fetchers: new Map(state.fetchers)
2051
2065
  });
2052
2066
  return startRedirectNavigation(state, actionResult, {
2053
- submission,
2054
- isFetchActionRedirect: true
2067
+ fetcherSubmission: submission
2055
2068
  });
2056
2069
  }
2057
2070
  }
@@ -2252,18 +2265,15 @@ function createRouter(init) {
2252
2265
  async function startRedirectNavigation(state, redirect, _temp) {
2253
2266
  let {
2254
2267
  submission,
2255
- replace,
2256
- isFetchActionRedirect
2268
+ fetcherSubmission,
2269
+ replace
2257
2270
  } = _temp === void 0 ? {} : _temp;
2258
2271
  if (redirect.revalidate) {
2259
2272
  isRevalidationRequired = true;
2260
2273
  }
2261
- let redirectLocation = createLocation(state.location, redirect.location, // TODO: This can be removed once we get rid of useTransition in Remix v2
2262
- _extends({
2274
+ let redirectLocation = createLocation(state.location, redirect.location, {
2263
2275
  _isRedirect: true
2264
- }, isFetchActionRedirect ? {
2265
- _isFetchActionRedirect: true
2266
- } : {}));
2276
+ });
2267
2277
  invariant(redirectLocation, "Expected a location on the redirect navigation");
2268
2278
  if (isBrowser) {
2269
2279
  let isDocumentReload = false;
@@ -2293,10 +2303,18 @@ function createRouter(init) {
2293
2303
  let redirectHistoryAction = replace === true ? Action.Replace : Action.Push;
2294
2304
  // Use the incoming submission if provided, fallback on the active one in
2295
2305
  // state.navigation
2296
- let activeSubmission = submission || getSubmissionFromNavigation(state.navigation);
2306
+ let {
2307
+ formMethod,
2308
+ formAction,
2309
+ formEncType
2310
+ } = state.navigation;
2311
+ if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) {
2312
+ submission = getSubmissionFromNavigation(state.navigation);
2313
+ }
2297
2314
  // If this was a 307/308 submission we want to preserve the HTTP method and
2298
2315
  // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the
2299
2316
  // redirected location
2317
+ let activeSubmission = submission || fetcherSubmission;
2300
2318
  if (redirectPreserveMethodStatusCodes.has(redirect.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) {
2301
2319
  await startNavigation(redirectHistoryAction, redirectLocation, {
2302
2320
  submission: _extends({}, activeSubmission, {
@@ -2305,20 +2323,14 @@ function createRouter(init) {
2305
2323
  // Preserve this flag across redirects
2306
2324
  preventScrollReset: pendingPreventScrollReset
2307
2325
  });
2308
- } else if (isFetchActionRedirect) {
2309
- // For a fetch action redirect, we kick off a new loading navigation
2310
- // without the fetcher submission, but we send it along for shouldRevalidate
2311
- await startNavigation(redirectHistoryAction, redirectLocation, {
2312
- overrideNavigation: getLoadingNavigation(redirectLocation),
2313
- fetcherSubmission: activeSubmission,
2314
- // Preserve this flag across redirects
2315
- preventScrollReset: pendingPreventScrollReset
2316
- });
2317
2326
  } else {
2318
- // If we have a submission, we will preserve it through the redirect navigation
2319
- let overrideNavigation = getLoadingNavigation(redirectLocation, activeSubmission);
2327
+ // If we have a navigation submission, we will preserve it through the
2328
+ // redirect navigation
2329
+ let overrideNavigation = getLoadingNavigation(redirectLocation, submission);
2320
2330
  await startNavigation(redirectHistoryAction, redirectLocation, {
2321
2331
  overrideNavigation,
2332
+ // Send fetcher submissions through for shouldRevalidate
2333
+ fetcherSubmission,
2322
2334
  // Preserve this flag across redirects
2323
2335
  preventScrollReset: pendingPreventScrollReset
2324
2336
  });
@@ -2526,7 +2538,7 @@ function createRouter(init) {
2526
2538
  }
2527
2539
  function getScrollKey(location, matches) {
2528
2540
  if (getScrollRestorationKey) {
2529
- let key = getScrollRestorationKey(location, matches.map(m => createUseMatchesMatch(m, state.loaderData)));
2541
+ let key = getScrollRestorationKey(location, matches.map(m => convertRouteMatchToUiMatch(m, state.loaderData)));
2530
2542
  return key || location.key;
2531
2543
  }
2532
2544
  return location.key;
@@ -2821,7 +2833,7 @@ function createStaticHandler(routes, opts) {
2821
2833
  });
2822
2834
  if (request.signal.aborted) {
2823
2835
  let method = isRouteRequest ? "queryRoute" : "query";
2824
- throw new Error(method + "() call aborted");
2836
+ throw new Error(method + "() call aborted: " + request.method + " " + request.url);
2825
2837
  }
2826
2838
  }
2827
2839
  if (isRedirectResult(result)) {
@@ -2936,7 +2948,7 @@ function createStaticHandler(routes, opts) {
2936
2948
  }))]);
2937
2949
  if (request.signal.aborted) {
2938
2950
  let method = isRouteRequest ? "queryRoute" : "query";
2939
- throw new Error(method + "() call aborted");
2951
+ throw new Error(method + "() call aborted: " + request.method + " " + request.url);
2940
2952
  }
2941
2953
  // Process and commit output from loaders
2942
2954
  let activeDeferreds = new Map();
@@ -3367,7 +3379,17 @@ async function callLoaderOrAction(type, request, match, matches, manifest, mapRo
3367
3379
  if (match.route.lazy) {
3368
3380
  if (handler) {
3369
3381
  // Run statically defined handler in parallel with lazy()
3370
- let values = await Promise.all([runHandler(handler), loadLazyRouteModule(match.route, mapRouteProperties, manifest)]);
3382
+ let handlerError;
3383
+ let values = await Promise.all([
3384
+ // If the handler throws, don't let it immediately bubble out,
3385
+ // since we need to let the lazy() execution finish so we know if this
3386
+ // route has a boundary that can handle the error
3387
+ runHandler(handler).catch(e => {
3388
+ handlerError = e;
3389
+ }), loadLazyRouteModule(match.route, mapRouteProperties, manifest)]);
3390
+ if (handlerError) {
3391
+ throw handlerError;
3392
+ }
3371
3393
  result = values[0];
3372
3394
  } else {
3373
3395
  // Load lazy route module, then run any returned handler
@@ -3471,7 +3493,7 @@ async function callLoaderOrAction(type, request, match, matches, manifest, mapRo
3471
3493
  if (resultType === ResultType.error) {
3472
3494
  return {
3473
3495
  type: resultType,
3474
- error: new ErrorResponse(status, result.statusText, data),
3496
+ error: new ErrorResponseImpl(status, result.statusText, data),
3475
3497
  headers: result.headers
3476
3498
  };
3477
3499
  }
@@ -3740,7 +3762,7 @@ function getInternalRouterError(status, _temp4) {
3740
3762
  errorMessage = "Invalid request method \"" + method.toUpperCase() + "\"";
3741
3763
  }
3742
3764
  }
3743
- return new ErrorResponse(status || 500, statusText, new Error(errorMessage), true);
3765
+ return new ErrorResponseImpl(status || 500, statusText, new Error(errorMessage), true);
3744
3766
  }
3745
3767
  // Find any returned redirect errors, starting from the lowest match
3746
3768
  function findRedirect(results) {
@@ -3867,22 +3889,6 @@ async function resolveDeferredData(result, signal, unwrap) {
3867
3889
  function hasNakedIndexQuery(search) {
3868
3890
  return new URLSearchParams(search).getAll("index").some(v => v === "");
3869
3891
  }
3870
- // Note: This should match the format exported by useMatches, so if you change
3871
- // this please also change that :) Eventually we'll DRY this up
3872
- function createUseMatchesMatch(match, loaderData) {
3873
- let {
3874
- route,
3875
- pathname,
3876
- params
3877
- } = match;
3878
- return {
3879
- id: route.id,
3880
- pathname,
3881
- params,
3882
- data: loaderData[route.id],
3883
- handle: route.handle
3884
- };
3885
- }
3886
3892
  function getTargetMatch(matches, location) {
3887
3893
  let search = typeof location === "string" ? parsePath(location).search : location.search;
3888
3894
  if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || "")) {
@@ -3985,8 +3991,7 @@ function getLoadingFetcher(submission, data) {
3985
3991
  formData: submission.formData,
3986
3992
  json: submission.json,
3987
3993
  text: submission.text,
3988
- data,
3989
- " _hasFetcherDoneAnything ": true
3994
+ data
3990
3995
  };
3991
3996
  return fetcher;
3992
3997
  } else {
@@ -3998,8 +4003,7 @@ function getLoadingFetcher(submission, data) {
3998
4003
  formData: undefined,
3999
4004
  json: undefined,
4000
4005
  text: undefined,
4001
- data,
4002
- " _hasFetcherDoneAnything ": true
4006
+ data
4003
4007
  };
4004
4008
  return fetcher;
4005
4009
  }
@@ -4013,8 +4017,7 @@ function getSubmittingFetcher(submission, existingFetcher) {
4013
4017
  formData: submission.formData,
4014
4018
  json: submission.json,
4015
4019
  text: submission.text,
4016
- data: existingFetcher ? existingFetcher.data : undefined,
4017
- " _hasFetcherDoneAnything ": true
4020
+ data: existingFetcher ? existingFetcher.data : undefined
4018
4021
  };
4019
4022
  return fetcher;
4020
4023
  }
@@ -4027,12 +4030,11 @@ function getDoneFetcher(data) {
4027
4030
  formData: undefined,
4028
4031
  json: undefined,
4029
4032
  text: undefined,
4030
- data,
4031
- " _hasFetcherDoneAnything ": true
4033
+ data
4032
4034
  };
4033
4035
  return fetcher;
4034
4036
  }
4035
4037
  //#endregion
4036
4038
 
4037
- export { AbortedDeferredError, Action, ErrorResponse, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, UNSAFE_DEFERRED_SYMBOL, DeferredData as UNSAFE_DeferredData, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getPathContributingMatches as UNSAFE_getPathContributingMatches, invariant as UNSAFE_invariant, warning as UNSAFE_warning, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, createStaticHandler, defer, generatePath, getStaticContextFromError, getToPathname, isDeferredData, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, redirectDocument, resolvePath, resolveTo, stripBasename };
4039
+ export { AbortedDeferredError, Action, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, UNSAFE_DEFERRED_SYMBOL, DeferredData as UNSAFE_DeferredData, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getPathContributingMatches as UNSAFE_getPathContributingMatches, invariant as UNSAFE_invariant, warning as UNSAFE_warning, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, createStaticHandler, defer, generatePath, getStaticContextFromError, getToPathname, isDeferredData, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, redirectDocument, resolvePath, resolveTo, stripBasename };
4038
4040
  //# sourceMappingURL=router.js.map