@tanstack/router-core 0.0.1-beta.1 → 0.0.1-beta.11

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.
@@ -23,9 +23,22 @@ var utils = require('./utils.js');
23
23
 
24
24
  var _window$document;
25
25
  // Detect if we're in the DOM
26
- const isServer = Boolean(typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement)); // This is the default history object if none is defined
27
-
28
- const createDefaultHistory = () => !isServer ? index.createBrowserHistory() : index.createMemoryHistory();
26
+ const isServer = typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement); // This is the default history object if none is defined
27
+
28
+ const createDefaultHistory = () => isServer ? index.createMemoryHistory() : index.createBrowserHistory();
29
+
30
+ function getInitialRouterState() {
31
+ return {
32
+ status: 'idle',
33
+ location: null,
34
+ matches: [],
35
+ actions: {},
36
+ loaders: {},
37
+ lastUpdated: Date.now(),
38
+ isFetching: false,
39
+ isPreloading: false
40
+ };
41
+ }
29
42
 
30
43
  function createRouter(userOptions) {
31
44
  var _userOptions$stringif, _userOptions$parseSea;
@@ -46,7 +59,6 @@ function createRouter(userOptions) {
46
59
  history,
47
60
  options: originalOptions,
48
61
  listeners: [],
49
- removeActionQueue: [],
50
62
  // Resolved after construction
51
63
  basepath: '',
52
64
  routeTree: undefined,
@@ -57,16 +69,10 @@ function createRouter(userOptions) {
57
69
  navigationPromise: Promise.resolve(),
58
70
  resolveNavigation: () => {},
59
71
  matchCache: {},
60
- state: {
61
- status: 'idle',
62
- location: null,
63
- matches: [],
64
- actions: {},
65
- loaders: {},
66
- loaderData: {},
67
- lastUpdated: Date.now(),
68
- isFetching: false,
69
- isPreloading: false
72
+ state: getInitialRouterState(),
73
+ reset: () => {
74
+ router.state = getInitialRouterState();
75
+ router.notify();
70
76
  },
71
77
  startedLoadingAt: Date.now(),
72
78
  subscribe: listener => {
@@ -83,8 +89,28 @@ function createRouter(userOptions) {
83
89
  isFetching: router.state.status === 'loading' || router.state.matches.some(d => d.isFetching),
84
90
  isPreloading: Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId))
85
91
  });
86
- route.cascadeLoaderData(router.state.matches);
87
- router.listeners.forEach(listener => listener());
92
+ cascadeLoaderData(router.state.matches);
93
+ router.listeners.forEach(listener => listener(router));
94
+ },
95
+ dehydrateState: () => {
96
+ return _rollupPluginBabelHelpers["extends"]({}, utils.pick(router.state, ['status', 'location', 'lastUpdated']), {
97
+ matches: router.state.matches.map(match => utils.pick(match, ['matchId', 'status', 'routeLoaderData', 'loaderData', 'isInvalid', 'invalidAt']))
98
+ });
99
+ },
100
+ hydrateState: dehydratedState => {
101
+ // Match the routes
102
+ const matches = router.matchRoutes(router.location.pathname, {
103
+ strictParseParams: true
104
+ });
105
+ matches.forEach((match, index) => {
106
+ const dehydratedMatch = dehydratedState.matches[index];
107
+ tinyInvariant["default"](dehydratedMatch, 'Oh no! Dehydrated route matches did not match the active state of the router 😬');
108
+ Object.assign(match, dehydratedMatch);
109
+ });
110
+ router.loadMatches(matches);
111
+ router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, dehydratedState, {
112
+ matches
113
+ });
88
114
  },
89
115
  mount: () => {
90
116
  const next = router.__.buildLocation({
@@ -97,12 +123,11 @@ function createRouter(userOptions) {
97
123
 
98
124
  if (next.href !== router.location.href) {
99
125
  router.__.commitLocation(next, true);
100
- } else {
101
- router.loadLocation();
102
- }
126
+ } // router.load()
103
127
 
104
- const unsub = history.listen(event => {
105
- router.loadLocation(router.__.parseLocation(event.location, router.location));
128
+
129
+ const unsub = router.history.listen(event => {
130
+ router.load(router.__.parseLocation(event.location, router.location));
106
131
  }); // addEventListener does not exist in React Native, but window does
107
132
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
108
133
 
@@ -113,16 +138,30 @@ function createRouter(userOptions) {
113
138
  }
114
139
 
115
140
  return () => {
116
- unsub(); // Be sure to unsubscribe if a new handler is set
141
+ unsub();
117
142
 
118
- window.removeEventListener('visibilitychange', router.onFocus);
119
- window.removeEventListener('focus', router.onFocus);
143
+ if (!isServer && window.removeEventListener) {
144
+ // Be sure to unsubscribe if a new handler is set
145
+ window.removeEventListener('visibilitychange', router.onFocus);
146
+ window.removeEventListener('focus', router.onFocus);
147
+ }
120
148
  };
121
149
  },
122
150
  onFocus: () => {
123
- router.loadLocation();
151
+ router.load();
124
152
  },
125
153
  update: opts => {
154
+ const newHistory = (opts == null ? void 0 : opts.history) !== router.history;
155
+
156
+ if (!router.location || newHistory) {
157
+ if (opts != null && opts.history) {
158
+ router.history = opts.history;
159
+ }
160
+
161
+ router.location = router.__.parseLocation(router.history.location);
162
+ router.state.location = router.location;
163
+ }
164
+
126
165
  Object.assign(router.options, opts);
127
166
  const {
128
167
  basepath,
@@ -143,35 +182,19 @@ function createRouter(userOptions) {
143
182
  match.cancel();
144
183
  });
145
184
  },
146
- loadLocation: async next => {
185
+ load: async next => {
147
186
  const id = Math.random();
148
187
  router.startedLoadingAt = id;
149
188
 
150
189
  if (next) {
151
190
  // Ingest the new location
152
191
  router.location = next;
153
- } // Clear out old actions
154
-
155
-
156
- router.removeActionQueue.forEach(_ref => {
157
- let {
158
- action,
159
- actionState
160
- } = _ref;
161
-
162
- if (router.state.currentAction === actionState) {
163
- router.state.currentAction = undefined;
164
- }
192
+ } // Cancel any pending matches
165
193
 
166
- if (action.current === actionState) {
167
- action.current = undefined;
168
- }
169
- });
170
- router.removeActionQueue = []; // Cancel any pending matches
171
194
 
172
195
  router.cancelMatches(); // Match the routes
173
196
 
174
- const matches = router.matchRoutes(location.pathname, {
197
+ const matches = router.matchRoutes(router.location.pathname, {
175
198
  strictParseParams: true
176
199
  });
177
200
  router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, {
@@ -202,9 +225,12 @@ function createRouter(userOptions) {
202
225
  exiting.push(d);
203
226
  }
204
227
  });
228
+ const entering = matches.filter(d => {
229
+ return !previousMatches.find(dd => dd.matchId === d.matchId);
230
+ });
205
231
  const now = Date.now();
206
232
  exiting.forEach(d => {
207
- var _ref2, _d$options$loaderGcMa, _ref3, _d$options$loaderMaxA;
233
+ var _ref, _d$options$loaderGcMa, _ref2, _d$options$loaderMaxA;
208
234
 
209
235
  d.__.onExit == null ? void 0 : d.__.onExit({
210
236
  params: d.params,
@@ -216,7 +242,7 @@ function createRouter(userOptions) {
216
242
  d.error = undefined;
217
243
  }
218
244
 
219
- const gc = Math.max((_ref2 = (_d$options$loaderGcMa = d.options.loaderGcMaxAge) != null ? _d$options$loaderGcMa : router.options.defaultLoaderGcMaxAge) != null ? _ref2 : 0, (_ref3 = (_d$options$loaderMaxA = d.options.loaderMaxAge) != null ? _d$options$loaderMaxA : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0);
245
+ const gc = Math.max((_ref = (_d$options$loaderGcMa = d.options.loaderGcMaxAge) != null ? _d$options$loaderGcMa : router.options.defaultLoaderGcMaxAge) != null ? _ref : 0, (_ref2 = (_d$options$loaderMaxA = d.options.loaderMaxAge) != null ? _d$options$loaderMaxA : router.options.defaultLoaderMaxAge) != null ? _ref2 : 0);
220
246
 
221
247
  if (gc > 0) {
222
248
  router.matchCache[d.matchId] = {
@@ -231,9 +257,6 @@ function createRouter(userOptions) {
231
257
  search: d.routeSearch
232
258
  });
233
259
  });
234
- const entering = matches.filter(d => {
235
- return !previousMatches.find(dd => dd.matchId === d.matchId);
236
- });
237
260
  entering.forEach(d => {
238
261
  d.__.onExit = d.options.onMatch == null ? void 0 : d.options.onMatch({
239
262
  params: d.params,
@@ -242,16 +265,18 @@ function createRouter(userOptions) {
242
265
  delete router.matchCache[d.matchId];
243
266
  });
244
267
 
245
- if (matches.some(d => d.status === 'loading')) {
246
- router.notify();
247
- await Promise.all(matches.map(d => d.__.loaderPromise || Promise.resolve()));
248
- }
249
-
250
268
  if (router.startedLoadingAt !== id) {
251
269
  // Ignore side-effects of match loading
252
270
  return;
253
271
  }
254
272
 
273
+ matches.forEach(match => {
274
+ // Clear actions
275
+ if (match.action) {
276
+ match.action.current = undefined;
277
+ match.action.submissions = [];
278
+ }
279
+ });
255
280
  router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, {
256
281
  location: router.location,
257
282
  matches,
@@ -292,7 +317,7 @@ function createRouter(userOptions) {
292
317
  return matches;
293
318
  },
294
319
  preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
295
- var _ref4, _ref5, _loaderOpts$maxAge, _ref6, _ref7, _loaderOpts$gcMaxAge;
320
+ var _ref3, _ref4, _loaderOpts$maxAge, _ref5, _ref6, _loaderOpts$gcMaxAge;
296
321
 
297
322
  if (navigateOpts === void 0) {
298
323
  navigateOpts = router.location;
@@ -304,8 +329,8 @@ function createRouter(userOptions) {
304
329
  });
305
330
  await router.loadMatches(matches, {
306
331
  preload: true,
307
- maxAge: (_ref4 = (_ref5 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref5 : router.options.defaultLoaderMaxAge) != null ? _ref4 : 0,
308
- gcMaxAge: (_ref6 = (_ref7 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref7 : router.options.defaultLoaderGcMaxAge) != null ? _ref6 : 0
332
+ maxAge: (_ref3 = (_ref4 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref4 : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0,
333
+ gcMaxAge: (_ref5 = (_ref6 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref6 : router.options.defaultLoaderGcMaxAge) != null ? _ref5 : 0
309
334
  });
310
335
  return matches;
311
336
  },
@@ -395,7 +420,7 @@ function createRouter(userOptions) {
395
420
  };
396
421
 
397
422
  recurse([router.routeTree]);
398
- route.cascadeLoaderData(matches);
423
+ cascadeLoaderData(matches);
399
424
  return matches;
400
425
  },
401
426
  loadMatches: async (resolvedMatches, loaderOpts) => {
@@ -407,9 +432,12 @@ function createRouter(userOptions) {
407
432
 
408
433
  if (match.status === 'loading') {
409
434
  // If requested, start the pending timers
410
- if (loaderOpts != null && loaderOpts.withPending) match.__.startPending(); // Wait for the first sign of activity from the match
411
- // This might be completion, error, or a pending state
435
+ if (loaderOpts != null && loaderOpts.withPending) match.__.startPending();
436
+ }
412
437
 
438
+ if (match.__.loadPromise) {
439
+ // Wait for the first sign of activity from the match
440
+ // This might be completion, error, or a pending state
413
441
  await match.__.loadPromise;
414
442
  }
415
443
  });
@@ -460,7 +488,7 @@ function createRouter(userOptions) {
460
488
  to: next.pathname
461
489
  }));
462
490
  },
463
- navigate: async _ref8 => {
491
+ navigate: async _ref7 => {
464
492
  let {
465
493
  from,
466
494
  to = '.',
@@ -468,7 +496,7 @@ function createRouter(userOptions) {
468
496
  hash,
469
497
  replace,
470
498
  params
471
- } = _ref8;
499
+ } = _ref7;
472
500
  // If this link simply reloads the current route,
473
501
  // make sure it has a new key so it will trigger a data refresh
474
502
  // If this `to` is a valid external URL, return
@@ -492,8 +520,8 @@ function createRouter(userOptions) {
492
520
  params
493
521
  });
494
522
  },
495
- buildLink: _ref9 => {
496
- var _preload, _ref10;
523
+ buildLink: _ref8 => {
524
+ var _preload, _ref9;
497
525
 
498
526
  let {
499
527
  from,
@@ -509,7 +537,7 @@ function createRouter(userOptions) {
509
537
  preloadGcMaxAge: userPreloadGcMaxAge,
510
538
  preloadDelay: userPreloadDelay,
511
539
  disabled
512
- } = _ref9;
540
+ } = _ref8;
513
541
 
514
542
  // If this link simply reloads the current route,
515
543
  // make sure it has a new key so it will trigger a data refresh
@@ -533,7 +561,7 @@ function createRouter(userOptions) {
533
561
  };
534
562
  const next = router.buildNext(nextOpts);
535
563
  preload = (_preload = preload) != null ? _preload : router.options.defaultPreload;
536
- const preloadDelay = (_ref10 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref10 : 0; // Compare path/hash for matches
564
+ const preloadDelay = (_ref9 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref9 : 0; // Compare path/hash for matches
537
565
 
538
566
  const pathIsEqual = router.state.location.pathname === next.pathname;
539
567
  const currentPathSplit = router.state.location.pathname.split('/');
@@ -634,11 +662,7 @@ function createRouter(userOptions) {
634
662
  const recurseRoutes = (routeConfigs, parent) => {
635
663
  return routeConfigs.map(routeConfig => {
636
664
  const routeOptions = routeConfig.options;
637
- const route$1 = route.createRoute(routeConfig, routeOptions, parent, router); // {
638
- // pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
639
- // pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
640
- // }
641
-
665
+ const route$1 = route.createRoute(routeConfig, routeOptions, parent, router);
642
666
  const existingRoute = router.routesById[route$1.routeId];
643
667
 
644
668
  if (existingRoute) {
@@ -773,8 +797,6 @@ function createRouter(userOptions) {
773
797
  }
774
798
  }
775
799
  };
776
- router.location = router.__.parseLocation(history.location);
777
- router.state.location = router.location;
778
800
  router.update(userOptions); // Allow frameworks to hook into the router creation
779
801
 
780
802
  router.options.createRouter == null ? void 0 : router.options.createRouter(router);
@@ -785,5 +807,15 @@ function isCtrlEvent(e) {
785
807
  return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
786
808
  }
787
809
 
810
+ function cascadeLoaderData(matches) {
811
+ matches.forEach((match, index) => {
812
+ const parent = matches[index - 1];
813
+
814
+ if (parent) {
815
+ match.loaderData = utils.replaceEqualDeep(match.loaderData, _rollupPluginBabelHelpers["extends"]({}, parent.loaderData, match.routeLoaderData));
816
+ }
817
+ });
818
+ }
819
+
788
820
  exports.createRouter = createRouter;
789
821
  //# sourceMappingURL=router.js.map