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

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()
127
+
103
128
 
104
- const unsub = history.listen(event => {
105
- router.loadLocation(router.__.parseLocation(event.location, router.location));
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
192
+ } // Cancel any pending matches
154
193
 
155
194
 
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
- }
165
-
166
- if (action.current === actionState) {
167
- action.current = undefined;
168
- }
169
- });
170
- router.removeActionQueue = []; // Cancel any pending matches
171
-
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, {
@@ -204,19 +227,24 @@ function createRouter(userOptions) {
204
227
  });
205
228
  const now = Date.now();
206
229
  exiting.forEach(d => {
207
- var _ref2, _d$options$loaderGcMa, _ref3, _d$options$loaderMaxA;
230
+ var _ref, _d$options$loaderGcMa, _ref2, _d$options$loaderMaxA;
208
231
 
209
232
  d.__.onExit == null ? void 0 : d.__.onExit({
210
233
  params: d.params,
211
234
  search: d.routeSearch
212
- }); // Clear idle error states when match leaves
235
+ }); // // Clear actions
236
+ // if (d.action) {
237
+ // d.action.current = undefined
238
+ // d.action.submissions = []
239
+ // }
240
+ // Clear idle error states when match leaves
213
241
 
214
242
  if (d.status === 'error' && !d.isFetching) {
215
243
  d.status = 'idle';
216
244
  d.error = undefined;
217
245
  }
218
246
 
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);
247
+ 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
248
 
221
249
  if (gc > 0) {
222
250
  router.matchCache[d.matchId] = {
@@ -240,18 +268,20 @@ function createRouter(userOptions) {
240
268
  search: d.search
241
269
  });
242
270
  delete router.matchCache[d.matchId];
243
- });
244
-
245
- if (matches.some(d => d.status === 'loading')) {
246
- router.notify();
247
- await Promise.all(matches.map(d => d.__.loaderPromise || Promise.resolve()));
248
- }
271
+ }); // router.notify()
249
272
 
250
273
  if (router.startedLoadingAt !== id) {
251
274
  // Ignore side-effects of match loading
252
275
  return;
253
276
  }
254
277
 
278
+ matches.forEach(match => {
279
+ // Clear actions
280
+ if (match.action) {
281
+ match.action.current = undefined;
282
+ match.action.submissions = [];
283
+ }
284
+ });
255
285
  router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, {
256
286
  location: router.location,
257
287
  matches,
@@ -292,7 +322,7 @@ function createRouter(userOptions) {
292
322
  return matches;
293
323
  },
294
324
  preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
295
- var _ref4, _ref5, _loaderOpts$maxAge, _ref6, _ref7, _loaderOpts$gcMaxAge;
325
+ var _ref3, _ref4, _loaderOpts$maxAge, _ref5, _ref6, _loaderOpts$gcMaxAge;
296
326
 
297
327
  if (navigateOpts === void 0) {
298
328
  navigateOpts = router.location;
@@ -304,8 +334,8 @@ function createRouter(userOptions) {
304
334
  });
305
335
  await router.loadMatches(matches, {
306
336
  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
337
+ maxAge: (_ref3 = (_ref4 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref4 : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0,
338
+ gcMaxAge: (_ref5 = (_ref6 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref6 : router.options.defaultLoaderGcMaxAge) != null ? _ref5 : 0
309
339
  });
310
340
  return matches;
311
341
  },
@@ -395,7 +425,7 @@ function createRouter(userOptions) {
395
425
  };
396
426
 
397
427
  recurse([router.routeTree]);
398
- route.cascadeLoaderData(matches);
428
+ cascadeLoaderData(matches);
399
429
  return matches;
400
430
  },
401
431
  loadMatches: async (resolvedMatches, loaderOpts) => {
@@ -407,9 +437,12 @@ function createRouter(userOptions) {
407
437
 
408
438
  if (match.status === 'loading') {
409
439
  // 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
440
+ if (loaderOpts != null && loaderOpts.withPending) match.__.startPending();
441
+ }
412
442
 
443
+ if (match.__.loadPromise) {
444
+ // Wait for the first sign of activity from the match
445
+ // This might be completion, error, or a pending state
413
446
  await match.__.loadPromise;
414
447
  }
415
448
  });
@@ -460,7 +493,7 @@ function createRouter(userOptions) {
460
493
  to: next.pathname
461
494
  }));
462
495
  },
463
- navigate: async _ref8 => {
496
+ navigate: async _ref7 => {
464
497
  let {
465
498
  from,
466
499
  to = '.',
@@ -468,7 +501,7 @@ function createRouter(userOptions) {
468
501
  hash,
469
502
  replace,
470
503
  params
471
- } = _ref8;
504
+ } = _ref7;
472
505
  // If this link simply reloads the current route,
473
506
  // make sure it has a new key so it will trigger a data refresh
474
507
  // If this `to` is a valid external URL, return
@@ -492,8 +525,8 @@ function createRouter(userOptions) {
492
525
  params
493
526
  });
494
527
  },
495
- buildLink: _ref9 => {
496
- var _preload, _ref10;
528
+ buildLink: _ref8 => {
529
+ var _preload, _ref9;
497
530
 
498
531
  let {
499
532
  from,
@@ -509,7 +542,7 @@ function createRouter(userOptions) {
509
542
  preloadGcMaxAge: userPreloadGcMaxAge,
510
543
  preloadDelay: userPreloadDelay,
511
544
  disabled
512
- } = _ref9;
545
+ } = _ref8;
513
546
 
514
547
  // If this link simply reloads the current route,
515
548
  // make sure it has a new key so it will trigger a data refresh
@@ -533,7 +566,7 @@ function createRouter(userOptions) {
533
566
  };
534
567
  const next = router.buildNext(nextOpts);
535
568
  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
569
+ const preloadDelay = (_ref9 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref9 : 0; // Compare path/hash for matches
537
570
 
538
571
  const pathIsEqual = router.state.location.pathname === next.pathname;
539
572
  const currentPathSplit = router.state.location.pathname.split('/');
@@ -634,11 +667,7 @@ function createRouter(userOptions) {
634
667
  const recurseRoutes = (routeConfigs, parent) => {
635
668
  return routeConfigs.map(routeConfig => {
636
669
  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
-
670
+ const route$1 = route.createRoute(routeConfig, routeOptions, parent, router);
642
671
  const existingRoute = router.routesById[route$1.routeId];
643
672
 
644
673
  if (existingRoute) {
@@ -773,8 +802,6 @@ function createRouter(userOptions) {
773
802
  }
774
803
  }
775
804
  };
776
- router.location = router.__.parseLocation(history.location);
777
- router.state.location = router.location;
778
805
  router.update(userOptions); // Allow frameworks to hook into the router creation
779
806
 
780
807
  router.options.createRouter == null ? void 0 : router.options.createRouter(router);
@@ -785,5 +812,15 @@ function isCtrlEvent(e) {
785
812
  return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
786
813
  }
787
814
 
815
+ function cascadeLoaderData(matches) {
816
+ matches.forEach((match, index) => {
817
+ const parent = matches[index - 1];
818
+
819
+ if (parent) {
820
+ match.loaderData = utils.replaceEqualDeep(match.loaderData, _rollupPluginBabelHelpers["extends"]({}, parent.loaderData, match.routeLoaderData));
821
+ }
822
+ });
823
+ }
824
+
788
825
  exports.createRouter = createRouter;
789
826
  //# sourceMappingURL=router.js.map