@remix-run/router 1.9.0-pre.0 → 1.9.0-pre.2

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/utils.d.ts CHANGED
@@ -111,20 +111,20 @@ export type Submission = {
111
111
  * Arguments passed to route loader/action functions. Same for now but we keep
112
112
  * this as a private implementation detail in case they diverge in the future.
113
113
  */
114
- interface DataFunctionArgs {
114
+ interface DataFunctionArgs<Context> {
115
115
  request: Request;
116
116
  params: Params;
117
- context?: any;
117
+ context?: Context;
118
118
  }
119
119
  /**
120
120
  * Arguments passed to loader functions
121
121
  */
122
- export interface LoaderFunctionArgs extends DataFunctionArgs {
122
+ export interface LoaderFunctionArgs<Context = any> extends DataFunctionArgs<Context> {
123
123
  }
124
124
  /**
125
125
  * Arguments passed to action functions
126
126
  */
127
- export interface ActionFunctionArgs extends DataFunctionArgs {
127
+ export interface ActionFunctionArgs<Context = any> extends DataFunctionArgs<Context> {
128
128
  }
129
129
  /**
130
130
  * Loaders and actions can return anything except `undefined` (`null` is a
@@ -135,14 +135,14 @@ type DataFunctionValue = Response | NonNullable<unknown> | null;
135
135
  /**
136
136
  * Route loader function signature
137
137
  */
138
- export interface LoaderFunction {
139
- (args: LoaderFunctionArgs): Promise<DataFunctionValue> | DataFunctionValue;
138
+ export interface LoaderFunction<Context = any> {
139
+ (args: LoaderFunctionArgs<Context>): Promise<DataFunctionValue> | DataFunctionValue;
140
140
  }
141
141
  /**
142
142
  * Route action function signature
143
143
  */
144
- export interface ActionFunction {
145
- (args: ActionFunctionArgs): Promise<DataFunctionValue> | DataFunctionValue;
144
+ export interface ActionFunction<Context = any> {
145
+ (args: ActionFunctionArgs<Context>): Promise<DataFunctionValue> | DataFunctionValue;
146
146
  }
147
147
  /**
148
148
  * Arguments passed to shouldRevalidate function
@@ -301,6 +301,14 @@ export declare function convertRoutesToDataRoutes(routes: AgnosticRouteObject[],
301
301
  * @see https://reactrouter.com/utils/match-routes
302
302
  */
303
303
  export declare function matchRoutes<RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject>(routes: RouteObjectType[], locationArg: Partial<Location> | string, basename?: string): AgnosticRouteMatch<string, RouteObjectType>[] | null;
304
+ export interface UIMatch<Data = unknown, Handle = unknown> {
305
+ id: string;
306
+ pathname: string;
307
+ params: AgnosticRouteMatch["params"];
308
+ data: Data;
309
+ handle: Handle;
310
+ }
311
+ export declare function convertRouteMatchToUiMatch(match: AgnosticDataRouteMatch, loaderData: RouteData): UIMatch;
304
312
  /**
305
313
  * Returns a path with params interpolated.
306
314
  *
package/history.ts CHANGED
@@ -49,15 +49,18 @@ export interface Path {
49
49
  hash: string;
50
50
  }
51
51
 
52
+ // TODO: (v7) Change the Location generic default from `any` to `unknown` and
53
+ // remove Remix `useLocation` wrapper.
54
+
52
55
  /**
53
56
  * An entry in a history stack. A location contains information about the
54
57
  * URL path, as well as possibly some arbitrary state and a key.
55
58
  */
56
- export interface Location extends Path {
59
+ export interface Location<State = any> extends Path {
57
60
  /**
58
61
  * A value of arbitrary data associated with this location.
59
62
  */
60
- state: any;
63
+ state: State;
61
64
 
62
65
  /**
63
66
  * A unique string associated with this location. May be used to safely store
@@ -97,8 +100,8 @@ export interface Listener {
97
100
 
98
101
  /**
99
102
  * Describes a location that is the destination of some navigation, either via
100
- * `history.push` or `history.replace`. May be either a URL or the pieces of a
101
- * URL path.
103
+ * `history.push` or `history.replace`. This may be either a URL or the pieces
104
+ * of a URL path.
102
105
  */
103
106
  export type To = string | Partial<Path>;
104
107
 
@@ -500,7 +503,7 @@ export function warning(cond: any, message: string) {
500
503
  try {
501
504
  // Welcome to debugging history!
502
505
  //
503
- // This error is thrown as a convenience so you can more easily
506
+ // This error is thrown as a convenience, so you can more easily
504
507
  // find the source for a warning that appears in the console by
505
508
  // enabling "pause on exceptions" in your JavaScript debugger.
506
509
  throw new Error(message);
package/index.ts CHANGED
@@ -25,6 +25,7 @@ export type {
25
25
  ShouldRevalidateFunction,
26
26
  ShouldRevalidateFunctionArgs,
27
27
  TrackedPromise,
28
+ UIMatch,
28
29
  V7_FormMethod,
29
30
  } from "./utils";
30
31
 
@@ -84,6 +85,7 @@ export {
84
85
  DeferredData as UNSAFE_DeferredData,
85
86
  ErrorResponseImpl as UNSAFE_ErrorResponseImpl,
86
87
  convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes,
88
+ convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch,
87
89
  getPathContributingMatches as UNSAFE_getPathContributingMatches,
88
90
  } from "./utils";
89
91
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remix-run/router",
3
- "version": "1.9.0-pre.0",
3
+ "version": "1.9.0-pre.2",
4
4
  "description": "Nested/Data-driven/Framework-agnostic Routing",
5
5
  "keywords": [
6
6
  "remix",
package/router.ts CHANGED
@@ -11,7 +11,6 @@ import type {
11
11
  ActionFunction,
12
12
  AgnosticDataRouteMatch,
13
13
  AgnosticDataRouteObject,
14
- AgnosticRouteMatch,
15
14
  AgnosticRouteObject,
16
15
  DataResult,
17
16
  DeferredData,
@@ -31,12 +30,14 @@ import type {
31
30
  ShouldRevalidateFunctionArgs,
32
31
  Submission,
33
32
  SuccessResult,
33
+ UIMatch,
34
34
  V7_FormMethod,
35
35
  V7_MutationFormMethod,
36
36
  } from "./utils";
37
37
  import {
38
38
  ErrorResponseImpl,
39
39
  ResultType,
40
+ convertRouteMatchToUiMatch,
40
41
  convertRoutesToDataRoutes,
41
42
  getPathContributingMatches,
42
43
  immutableRouteKeys,
@@ -394,20 +395,12 @@ export interface RouterSubscriber {
394
395
  (state: RouterState): void;
395
396
  }
396
397
 
397
- interface UseMatchesMatch {
398
- id: string;
399
- pathname: string;
400
- params: AgnosticRouteMatch["params"];
401
- data: unknown;
402
- handle: unknown;
403
- }
404
-
405
398
  /**
406
399
  * Function signature for determining the key to be used in scroll restoration
407
400
  * for a given location
408
401
  */
409
402
  export interface GetScrollRestorationKeyFunction {
410
- (location: Location, matches: UseMatchesMatch[]): string | null;
403
+ (location: Location, matches: UIMatch[]): string | null;
411
404
  }
412
405
 
413
406
  /**
@@ -2461,7 +2454,7 @@ export function createRouter(init: RouterInit): Router {
2461
2454
  if (getScrollRestorationKey) {
2462
2455
  let key = getScrollRestorationKey(
2463
2456
  location,
2464
- matches.map((m) => createUseMatchesMatch(m, state.loaderData))
2457
+ matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData))
2465
2458
  );
2466
2459
  return key || location.key;
2467
2460
  }
@@ -4332,22 +4325,6 @@ function hasNakedIndexQuery(search: string): boolean {
4332
4325
  return new URLSearchParams(search).getAll("index").some((v) => v === "");
4333
4326
  }
4334
4327
 
4335
- // Note: This should match the format exported by useMatches, so if you change
4336
- // this please also change that :) Eventually we'll DRY this up
4337
- function createUseMatchesMatch(
4338
- match: AgnosticDataRouteMatch,
4339
- loaderData: RouteData
4340
- ): UseMatchesMatch {
4341
- let { route, pathname, params } = match;
4342
- return {
4343
- id: route.id,
4344
- pathname,
4345
- params,
4346
- data: loaderData[route.id] as unknown,
4347
- handle: route.handle as unknown,
4348
- };
4349
- }
4350
-
4351
4328
  function getTargetMatch(
4352
4329
  matches: AgnosticDataRouteMatch[],
4353
4330
  location: Location | string
package/utils.ts CHANGED
@@ -137,21 +137,27 @@ export type Submission =
137
137
  * Arguments passed to route loader/action functions. Same for now but we keep
138
138
  * this as a private implementation detail in case they diverge in the future.
139
139
  */
140
- interface DataFunctionArgs {
140
+ interface DataFunctionArgs<Context> {
141
141
  request: Request;
142
142
  params: Params;
143
- context?: any;
143
+ context?: Context;
144
144
  }
145
145
 
146
+ // TODO: (v7) Change the defaults from any to unknown in and remove Remix wrappers:
147
+ // ActionFunction, ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs
148
+ // Also, make them a type alias instead of an interface
149
+
146
150
  /**
147
151
  * Arguments passed to loader functions
148
152
  */
149
- export interface LoaderFunctionArgs extends DataFunctionArgs {}
153
+ export interface LoaderFunctionArgs<Context = any>
154
+ extends DataFunctionArgs<Context> {}
150
155
 
151
156
  /**
152
157
  * Arguments passed to action functions
153
158
  */
154
- export interface ActionFunctionArgs extends DataFunctionArgs {}
159
+ export interface ActionFunctionArgs<Context = any>
160
+ extends DataFunctionArgs<Context> {}
155
161
 
156
162
  /**
157
163
  * Loaders and actions can return anything except `undefined` (`null` is a
@@ -163,15 +169,19 @@ type DataFunctionValue = Response | NonNullable<unknown> | null;
163
169
  /**
164
170
  * Route loader function signature
165
171
  */
166
- export interface LoaderFunction {
167
- (args: LoaderFunctionArgs): Promise<DataFunctionValue> | DataFunctionValue;
172
+ export interface LoaderFunction<Context = any> {
173
+ (args: LoaderFunctionArgs<Context>):
174
+ | Promise<DataFunctionValue>
175
+ | DataFunctionValue;
168
176
  }
169
177
 
170
178
  /**
171
179
  * Route action function signature
172
180
  */
173
- export interface ActionFunction {
174
- (args: ActionFunctionArgs): Promise<DataFunctionValue> | DataFunctionValue;
181
+ export interface ActionFunction<Context = any> {
182
+ (args: ActionFunctionArgs<Context>):
183
+ | Promise<DataFunctionValue>
184
+ | DataFunctionValue;
175
185
  }
176
186
 
177
187
  /**
@@ -350,10 +360,10 @@ type PathParam<Path extends string> =
350
360
  _PathParam<Path>;
351
361
 
352
362
  // Attempt to parse the given string segment. If it fails, then just return the
353
- // plain string type as a default fallback. Otherwise return the union of the
363
+ // plain string type as a default fallback. Otherwise, return the union of the
354
364
  // parsed string literals that were referenced as dynamic segments in the route.
355
365
  export type ParamParseKey<Segment extends string> =
356
- // if could not find path params, fallback to `string`
366
+ // if you could not find path params, fallback to `string`
357
367
  [PathParam<Segment>] extends [never] ? string : PathParam<Segment>;
358
368
 
359
369
  /**
@@ -397,7 +407,7 @@ function isIndexRoute(
397
407
  return route.index === true;
398
408
  }
399
409
 
400
- // Walk the route tree generating unique IDs where necessary so we are working
410
+ // Walk the route tree generating unique IDs where necessary, so we are working
401
411
  // solely with AgnosticDataRouteObject's within the Router
402
412
  export function convertRoutesToDataRoutes(
403
413
  routes: AgnosticRouteObject[],
@@ -490,6 +500,28 @@ export function matchRoutes<
490
500
  return matches;
491
501
  }
492
502
 
503
+ export interface UIMatch<Data = unknown, Handle = unknown> {
504
+ id: string;
505
+ pathname: string;
506
+ params: AgnosticRouteMatch["params"];
507
+ data: Data;
508
+ handle: Handle;
509
+ }
510
+
511
+ export function convertRouteMatchToUiMatch(
512
+ match: AgnosticDataRouteMatch,
513
+ loaderData: RouteData
514
+ ): UIMatch {
515
+ let { route, pathname, params } = match;
516
+ return {
517
+ id: route.id,
518
+ pathname,
519
+ params,
520
+ data: loaderData[route.id],
521
+ handle: route.handle,
522
+ };
523
+ }
524
+
493
525
  interface RouteMeta<
494
526
  RouteObjectType extends AgnosticRouteObject = AgnosticRouteObject
495
527
  > {
@@ -542,7 +574,7 @@ function flattenRoutes<
542
574
  let path = joinPaths([parentPath, meta.relativePath]);
543
575
  let routesMeta = parentsMeta.concat(meta);
544
576
 
545
- // Add the children before adding this route to the array so we traverse the
577
+ // Add the children before adding this route to the array, so we traverse the
546
578
  // route tree depth-first and child routes appear before their parents in
547
579
  // the "flattened" version.
548
580
  if (route.children && route.children.length > 0) {
@@ -619,10 +651,10 @@ function explodeOptionalSegments(path: string): string[] {
619
651
  let result: string[] = [];
620
652
 
621
653
  // All child paths with the prefix. Do this for all children before the
622
- // optional version for all children so we get consistent ordering where the
654
+ // optional version for all children, so we get consistent ordering where the
623
655
  // parent optional aspect is preferred as required. Otherwise, we can get
624
656
  // child sections interspersed where deeper optional segments are higher than
625
- // parent optional segments, where for example, /:two would explodes _earlier_
657
+ // parent optional segments, where for example, /:two would explode _earlier_
626
658
  // then /:one. By always including the parent as required _for all children_
627
659
  // first, we avoid this issue
628
660
  result.push(
@@ -631,7 +663,7 @@ function explodeOptionalSegments(path: string): string[] {
631
663
  )
632
664
  );
633
665
 
634
- // Then if this is an optional value, add all child versions without
666
+ // Then, if this is an optional value, add all child versions without
635
667
  if (isOptional) {
636
668
  result.push(...restExploded);
637
669
  }
@@ -947,7 +979,7 @@ function compilePath(
947
979
  regexpSource += "\\/*$";
948
980
  } else if (path !== "" && path !== "/") {
949
981
  // If our path is non-empty and contains anything beyond an initial slash,
950
- // then we have _some_ form of path in our regex so we should expect to
982
+ // then we have _some_ form of path in our regex, so we should expect to
951
983
  // match only if we find the end of this path segment. Look for an optional
952
984
  // non-captured trailing slash (to match a portion of the URL) or the end
953
985
  // of the path (if we've matched to the end). We used to do this with a