@tanstack/react-router 0.0.1-beta.193 → 0.0.1-beta.195
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/build/cjs/react.js +3 -14
- package/build/cjs/react.js.map +1 -1
- package/build/esm/index.js +3 -14
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +98 -98
- package/build/types/react.d.ts +24 -26
- package/build/umd/index.development.js +94 -30
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -2
- package/src/react.tsx +24 -76
|
@@ -238,13 +238,13 @@
|
|
|
238
238
|
push: (path, state) => {
|
|
239
239
|
assignKey(state);
|
|
240
240
|
queueTask(() => {
|
|
241
|
-
opts.pushState(path, state);
|
|
241
|
+
opts.pushState(path, state, onUpdate);
|
|
242
242
|
});
|
|
243
243
|
},
|
|
244
244
|
replace: (path, state) => {
|
|
245
245
|
assignKey(state);
|
|
246
246
|
queueTask(() => {
|
|
247
|
-
opts.replaceState(path, state);
|
|
247
|
+
opts.replaceState(path, state, onUpdate);
|
|
248
248
|
});
|
|
249
249
|
},
|
|
250
250
|
go: index => {
|
|
@@ -276,7 +276,8 @@
|
|
|
276
276
|
stopBlocking();
|
|
277
277
|
}
|
|
278
278
|
};
|
|
279
|
-
}
|
|
279
|
+
},
|
|
280
|
+
flush: () => opts.flush?.()
|
|
280
281
|
};
|
|
281
282
|
}
|
|
282
283
|
function assignKey(state) {
|
|
@@ -289,25 +290,100 @@
|
|
|
289
290
|
// }
|
|
290
291
|
}
|
|
291
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Creates a history object that can be used to interact with the browser's
|
|
295
|
+
* navigation. This is a lightweight API wrapping the browser's native methods.
|
|
296
|
+
* It is designed to work with TanStack Router, but could be used as a standalone API as well.
|
|
297
|
+
* IMPORTANT: This API implements history throttling via a microtask to prevent
|
|
298
|
+
* excessive calls to the history API. In some browsers, calling history.pushState or
|
|
299
|
+
* history.replaceState in quick succession can cause the browser to ignore subsequent
|
|
300
|
+
* calls. This API smooths out those differences and ensures that your application
|
|
301
|
+
* state will *eventually* match the browser state. In most cases, this is not a problem,
|
|
302
|
+
* but if you need to ensure that the browser state is up to date, you can use the
|
|
303
|
+
* `history.flush` method to immediately flush all pending state changes to the browser URL.
|
|
304
|
+
* @param opts
|
|
305
|
+
* @param opts.getHref A function that returns the current href (path + search + hash)
|
|
306
|
+
* @param opts.createHref A function that takes a path and returns a href (path + search + hash)
|
|
307
|
+
* @returns A history instance
|
|
308
|
+
*/
|
|
292
309
|
function createBrowserHistory(opts) {
|
|
293
310
|
const getHref = opts?.getHref ?? (() => `${window.location.pathname}${window.location.search}${window.location.hash}`);
|
|
294
311
|
const createHref = opts?.createHref ?? (path => path);
|
|
295
|
-
|
|
312
|
+
let currentLocation = parseLocation(getHref(), window.history.state);
|
|
313
|
+
const getLocation = () => currentLocation;
|
|
314
|
+
let next;
|
|
315
|
+
|
|
316
|
+
// Because we are proactively updating the location
|
|
317
|
+
// in memory before actually updating the browser history,
|
|
318
|
+
// we need to track when we are doing this so we don't
|
|
319
|
+
// notify subscribers twice on the last update.
|
|
320
|
+
let tracking = true;
|
|
321
|
+
|
|
322
|
+
// We need to track the current scheduled update to prevent
|
|
323
|
+
// multiple updates from being scheduled at the same time.
|
|
324
|
+
let scheduled;
|
|
325
|
+
|
|
326
|
+
// This function is a wrapper to prevent any of the callback's
|
|
327
|
+
// side effects from causing a subscriber notification
|
|
328
|
+
const untrack = fn => {
|
|
329
|
+
tracking = false;
|
|
330
|
+
fn();
|
|
331
|
+
tracking = true;
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// This function flushes the next update to the browser history
|
|
335
|
+
const flush = () => {
|
|
336
|
+
// Do not notify subscribers about this push/replace call
|
|
337
|
+
untrack(() => {
|
|
338
|
+
if (!next) return;
|
|
339
|
+
window.history[next.isPush ? 'pushState' : 'replaceState'](next.state, '', next.href);
|
|
340
|
+
// Reset the nextIsPush flag and clear the scheduled update
|
|
341
|
+
next = undefined;
|
|
342
|
+
scheduled = undefined;
|
|
343
|
+
});
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
// This function queues up a call to update the browser history
|
|
347
|
+
const queueHistoryAction = (type, path, state, onUpdate) => {
|
|
348
|
+
const href = createHref(path);
|
|
349
|
+
|
|
350
|
+
// Update the location in memory
|
|
351
|
+
currentLocation = parseLocation(href, state);
|
|
352
|
+
|
|
353
|
+
// Keep track of the next location we need to flush to the URL
|
|
354
|
+
next = {
|
|
355
|
+
href,
|
|
356
|
+
state,
|
|
357
|
+
isPush: next?.isPush || type === 'push'
|
|
358
|
+
};
|
|
359
|
+
// Notify subscribers
|
|
360
|
+
onUpdate();
|
|
361
|
+
if (!scheduled) {
|
|
362
|
+
// Schedule an update to the browser history
|
|
363
|
+
scheduled = Promise.resolve().then(() => flush());
|
|
364
|
+
}
|
|
365
|
+
};
|
|
296
366
|
return createHistory({
|
|
297
367
|
getLocation,
|
|
298
368
|
subscriber: onUpdate => {
|
|
299
|
-
window.addEventListener(pushStateEvent,
|
|
300
|
-
|
|
369
|
+
window.addEventListener(pushStateEvent, () => {
|
|
370
|
+
currentLocation = parseLocation(getHref(), window.history.state);
|
|
371
|
+
onUpdate();
|
|
372
|
+
});
|
|
373
|
+
window.addEventListener(popStateEvent, () => {
|
|
374
|
+
currentLocation = parseLocation(getHref(), window.history.state);
|
|
375
|
+
onUpdate();
|
|
376
|
+
});
|
|
301
377
|
var pushState = window.history.pushState;
|
|
302
378
|
window.history.pushState = function () {
|
|
303
379
|
let res = pushState.apply(history, arguments);
|
|
304
|
-
onUpdate();
|
|
380
|
+
if (tracking) onUpdate();
|
|
305
381
|
return res;
|
|
306
382
|
};
|
|
307
383
|
var replaceState = window.history.replaceState;
|
|
308
384
|
window.history.replaceState = function () {
|
|
309
385
|
let res = replaceState.apply(history, arguments);
|
|
310
|
-
onUpdate();
|
|
386
|
+
if (tracking) onUpdate();
|
|
311
387
|
return res;
|
|
312
388
|
};
|
|
313
389
|
return () => {
|
|
@@ -317,16 +393,13 @@
|
|
|
317
393
|
window.removeEventListener(popStateEvent, onUpdate);
|
|
318
394
|
};
|
|
319
395
|
},
|
|
320
|
-
pushState: (path, state) =>
|
|
321
|
-
|
|
322
|
-
},
|
|
323
|
-
replaceState: (path, state) => {
|
|
324
|
-
window.history.replaceState(state, '', createHref(path));
|
|
325
|
-
},
|
|
396
|
+
pushState: (path, state, onUpdate) => queueHistoryAction('push', path, state, onUpdate),
|
|
397
|
+
replaceState: (path, state, onUpdate) => queueHistoryAction('replace', path, state, onUpdate),
|
|
326
398
|
back: () => window.history.back(),
|
|
327
399
|
forward: () => window.history.forward(),
|
|
328
400
|
go: n => window.history.go(n),
|
|
329
|
-
createHref: path => createHref(path)
|
|
401
|
+
createHref: path => createHref(path),
|
|
402
|
+
flush
|
|
330
403
|
});
|
|
331
404
|
}
|
|
332
405
|
function createHashHistory() {
|
|
@@ -383,6 +456,8 @@
|
|
|
383
456
|
return (Math.random() + 1).toString(36).substring(7);
|
|
384
457
|
}
|
|
385
458
|
|
|
459
|
+
// export type Expand<T> = T
|
|
460
|
+
|
|
386
461
|
// type Compute<T> = { [K in keyof T]: T[K] } | never
|
|
387
462
|
|
|
388
463
|
// type AllKeys<T> = T extends any ? keyof T : never
|
|
@@ -1409,7 +1484,7 @@
|
|
|
1409
1484
|
};
|
|
1410
1485
|
this.setRouteMatch(match.id, s => ({
|
|
1411
1486
|
...s,
|
|
1412
|
-
context
|
|
1487
|
+
context: replaceEqualDeep(s.context, context)
|
|
1413
1488
|
}));
|
|
1414
1489
|
} catch (err) {
|
|
1415
1490
|
handleError(err, 'BEFORE_LOAD');
|
|
@@ -2287,6 +2362,7 @@
|
|
|
2287
2362
|
return _extends.apply(this, arguments);
|
|
2288
2363
|
}
|
|
2289
2364
|
|
|
2365
|
+
const useLayoutEffect$1 = typeof window !== 'undefined' ? React__namespace.useLayoutEffect : React__namespace.useEffect;
|
|
2290
2366
|
Route.__onInit = route => {
|
|
2291
2367
|
Object.assign(route, {
|
|
2292
2368
|
useMatch: (opts = {}) => {
|
|
@@ -2301,18 +2377,11 @@
|
|
|
2301
2377
|
from: route.id
|
|
2302
2378
|
});
|
|
2303
2379
|
},
|
|
2304
|
-
useContext: (opts = {}) => {
|
|
2305
|
-
return useMatch({
|
|
2306
|
-
...opts,
|
|
2307
|
-
from: route.id,
|
|
2308
|
-
select: d => opts?.select ? opts.select(d.context) : d.context
|
|
2309
|
-
});
|
|
2310
|
-
},
|
|
2311
2380
|
useRouteContext: (opts = {}) => {
|
|
2312
2381
|
return useMatch({
|
|
2313
2382
|
...opts,
|
|
2314
2383
|
from: route.id,
|
|
2315
|
-
select: d => opts?.select ? opts.select(d.
|
|
2384
|
+
select: d => opts?.select ? opts.select(d.context) : d.context
|
|
2316
2385
|
});
|
|
2317
2386
|
},
|
|
2318
2387
|
useSearch: (opts = {}) => {
|
|
@@ -2459,7 +2528,7 @@
|
|
|
2459
2528
|
});
|
|
2460
2529
|
function Navigate(props) {
|
|
2461
2530
|
const router = useRouter();
|
|
2462
|
-
|
|
2531
|
+
useLayoutEffect$1(() => {
|
|
2463
2532
|
router.navigate(props);
|
|
2464
2533
|
}, []);
|
|
2465
2534
|
return null;
|
|
@@ -2502,7 +2571,6 @@
|
|
|
2502
2571
|
return /*#__PURE__*/React__namespace.createElement(ErrorComponent, {
|
|
2503
2572
|
...props,
|
|
2504
2573
|
useMatch: route.useMatch,
|
|
2505
|
-
useContext: route.useContext,
|
|
2506
2574
|
useRouteContext: route.useRouteContext,
|
|
2507
2575
|
useSearch: route.useSearch,
|
|
2508
2576
|
useParams: route.useParams
|
|
@@ -2647,7 +2715,6 @@
|
|
|
2647
2715
|
return /*#__PURE__*/React__namespace.createElement(routeErrorComponent, {
|
|
2648
2716
|
...props,
|
|
2649
2717
|
useMatch: route.useMatch,
|
|
2650
|
-
useContext: route.useContext,
|
|
2651
2718
|
useRouteContext: route.useRouteContext,
|
|
2652
2719
|
useSearch: route.useSearch,
|
|
2653
2720
|
useParams: route.useParams
|
|
@@ -2658,7 +2725,6 @@
|
|
|
2658
2725
|
}, /*#__PURE__*/React__namespace.createElement(ResolvedSuspenseBoundary, {
|
|
2659
2726
|
fallback: /*#__PURE__*/React__namespace.createElement(PendingComponent, {
|
|
2660
2727
|
useMatch: route.useMatch,
|
|
2661
|
-
useContext: route.useContext,
|
|
2662
2728
|
useRouteContext: route.useRouteContext,
|
|
2663
2729
|
useSearch: route.useSearch,
|
|
2664
2730
|
useParams: route.useParams
|
|
@@ -2693,7 +2759,6 @@
|
|
|
2693
2759
|
return /*#__PURE__*/React__namespace.createElement(PendingComponent, {
|
|
2694
2760
|
useLoader: route.useLoader,
|
|
2695
2761
|
useMatch: route.useMatch,
|
|
2696
|
-
useContext: route.useContext,
|
|
2697
2762
|
useRouteContext: route.useRouteContext,
|
|
2698
2763
|
useSearch: route.useSearch,
|
|
2699
2764
|
useParams: route.useParams
|
|
@@ -2705,7 +2770,6 @@
|
|
|
2705
2770
|
return /*#__PURE__*/React__namespace.createElement(comp, {
|
|
2706
2771
|
useLoader: route.useLoader,
|
|
2707
2772
|
useMatch: route.useMatch,
|
|
2708
|
-
useContext: route.useContext,
|
|
2709
2773
|
useRouteContext: route.useRouteContext,
|
|
2710
2774
|
useSearch: route.useSearch,
|
|
2711
2775
|
useParams: route.useParams
|