@tanstack/react-router 0.0.1-beta.53 → 0.0.1-beta.55
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/index.js +48 -73
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.js +18 -89
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +66 -76
- package/build/types/index.d.ts +5 -17
- package/build/umd/index.development.js +263 -613
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +23 -4
- package/build/umd/index.production.js.map +1 -1
- package/package.json +3 -5
- package/src/index.tsx +16 -84
- package/build/cjs/useStore.js +0 -64
- package/build/cjs/useStore.js.map +0 -1
- package/src/useStore.ts +0 -70
|
@@ -59,10 +59,56 @@
|
|
|
59
59
|
throw new Error(value);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
function n(n){for(var r=arguments.length,t=Array(r>1?r-1:0),e=1;e<r;e++)t[e-1]=arguments[e];{var i=Y[n],o=i?"function"==typeof i?i.apply(null,t):i:"unknown error nr: "+n;throw Error("[Immer] "+o)}}function r(n){return !!n&&!!n[Q]}function t(n){var r;return !!n&&(function(n){if(!n||"object"!=typeof n)return !1;var r=Object.getPrototypeOf(n);if(null===r)return !0;var t=Object.hasOwnProperty.call(r,"constructor")&&r.constructor;return t===Object||"function"==typeof t&&Function.toString.call(t)===Z}(n)||Array.isArray(n)||!!n[L]||!!(null===(r=n.constructor)||void 0===r?void 0:r[L])||s(n)||v(n))}function i(n,r,t){void 0===t&&(t=!1),0===o(n)?(t?Object.keys:nn)(n).forEach((function(e){t&&"symbol"==typeof e||r(e,n[e],n);})):n.forEach((function(t,e){return r(e,t,n)}));}function o(n){var r=n[Q];return r?r.i>3?r.i-4:r.i:Array.isArray(n)?1:s(n)?2:v(n)?3:0}function u(n,r){return 2===o(n)?n.has(r):Object.prototype.hasOwnProperty.call(n,r)}function a(n,r){return 2===o(n)?n.get(r):n[r]}function f(n,r,t){var e=o(n);2===e?n.set(r,t):3===e?(n.delete(r),n.add(t)):n[r]=t;}function c(n,r){return n===r?0!==n||1/n==1/r:n!=n&&r!=r}function s(n){return X&&n instanceof Map}function v(n){return q&&n instanceof Set}function p(n){return n.o||n.t}function l(n){if(Array.isArray(n))return Array.prototype.slice.call(n);var r=rn(n);delete r[Q];for(var t=nn(r),e=0;e<t.length;e++){var i=t[e],o=r[i];!1===o.writable&&(o.writable=!0,o.configurable=!0),(o.get||o.set)&&(r[i]={configurable:!0,writable:!0,enumerable:o.enumerable,value:n[i]});}return Object.create(Object.getPrototypeOf(n),r)}function d(n,e){return void 0===e&&(e=!1),y(n)||r(n)||!t(n)?n:(o(n)>1&&(n.set=n.add=n.clear=n.delete=h),Object.freeze(n),e&&i(n,(function(n,r){return d(r,!0)}),!0),n)}function h(){n(2);}function y(n){return null==n||"object"!=typeof n||Object.isFrozen(n)}function b(r){var t=tn[r];return t||n(18,r),t}function _(){return U||n(0),U}function j(n,r){r&&(b("Patches"),n.u=[],n.s=[],n.v=r);}function O(n){g(n),n.p.forEach(S),n.p=null;}function g(n){n===U&&(U=n.l);}function w(n){return U={p:[],l:U,h:n,m:!0,_:0}}function S(n){var r=n[Q];0===r.i||1===r.i?r.j():r.O=!0;}function P(r,e){e._=e.p.length;var i=e.p[0],o=void 0!==r&&r!==i;return e.h.g||b("ES5").S(e,r,o),o?(i[Q].P&&(O(e),n(4)),t(r)&&(r=M(e,r),e.l||x(e,r)),e.u&&b("Patches").M(i[Q].t,r,e.u,e.s)):r=M(e,i,[]),O(e),e.u&&e.v(e.u,e.s),r!==H?r:void 0}function M(n,r,t){if(y(r))return r;var e=r[Q];if(!e)return i(r,(function(i,o){return A(n,e,r,i,o,t)}),!0),r;if(e.A!==n)return r;if(!e.P)return x(n,e.t,!0),e.t;if(!e.I){e.I=!0,e.A._--;var o=4===e.i||5===e.i?e.o=l(e.k):e.o;i(3===e.i?new Set(o):o,(function(r,i){return A(n,e,o,r,i,t)})),x(n,o,!1),t&&n.u&&b("Patches").R(e,t,n.u,n.s);}return e.o}function A(e,i,o,a,c,s){if(c===o&&n(5),r(c)){var v=M(e,c,s&&i&&3!==i.i&&!u(i.D,a)?s.concat(a):void 0);if(f(o,a,v),!r(v))return;e.m=!1;}if(t(c)&&!y(c)){if(!e.h.F&&e._<1)return;M(e,c),i&&i.A.l||x(e,c);}}function x(n,r,t){void 0===t&&(t=!1),n.h.F&&n.m&&d(r,t);}function z(n,r){var t=n[Q];return (t?p(t):n)[r]}function I(n,r){if(r in n)for(var t=Object.getPrototypeOf(n);t;){var e=Object.getOwnPropertyDescriptor(t,r);if(e)return e;t=Object.getPrototypeOf(t);}}function k(n){n.P||(n.P=!0,n.l&&k(n.l));}function E(n){n.o||(n.o=l(n.t));}function R(n,r,t){var e=s(r)?b("MapSet").N(r,t):v(r)?b("MapSet").T(r,t):n.g?function(n,r){var t=Array.isArray(n),e={i:t?1:0,A:r?r.A:_(),P:!1,I:!1,D:{},l:r,t:n,k:null,o:null,j:null,C:!1},i=e,o=en;t&&(i=[e],o=on);var u=Proxy.revocable(i,o),a=u.revoke,f=u.proxy;return e.k=f,e.j=a,f}(r,t):b("ES5").J(r,t);return (t?t.A:_()).p.push(e),e}function D(e){return r(e)||n(22,e),function n(r){if(!t(r))return r;var e,u=r[Q],c=o(r);if(u){if(!u.P&&(u.i<4||!b("ES5").K(u)))return u.t;u.I=!0,e=F(r,c),u.I=!1;}else e=F(r,c);return i(e,(function(r,t){u&&a(u.t,r)===t||f(e,r,n(t));})),3===c?new Set(e):e}(e)}function F(n,r){switch(r){case 2:return new Map(n);case 3:return Array.from(n)}return l(n)}var G,U,W="undefined"!=typeof Symbol&&"symbol"==typeof Symbol("x"),X="undefined"!=typeof Map,q="undefined"!=typeof Set,B="undefined"!=typeof Proxy&&void 0!==Proxy.revocable&&"undefined"!=typeof Reflect,H=W?Symbol.for("immer-nothing"):((G={})["immer-nothing"]=!0,G),L=W?Symbol.for("immer-draftable"):"__$immer_draftable",Q=W?Symbol.for("immer-state"):"__$immer_state",Y={0:"Illegal state",1:"Immer drafts cannot have computed properties",2:"This object has been frozen and should not be mutated",3:function(n){return "Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? "+n},4:"An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.",5:"Immer forbids circular references",6:"The first or second argument to `produce` must be a function",7:"The third argument to `produce` must be a function or undefined",8:"First argument to `createDraft` must be a plain object, an array, or an immerable object",9:"First argument to `finishDraft` must be a draft returned by `createDraft`",10:"The given draft is already finalized",11:"Object.defineProperty() cannot be used on an Immer draft",12:"Object.setPrototypeOf() cannot be used on an Immer draft",13:"Immer only supports deleting array indices",14:"Immer only supports setting array indices and the 'length' property",15:function(n){return "Cannot apply patch, path doesn't resolve: "+n},16:'Sets cannot have "replace" patches.',17:function(n){return "Unsupported patch operation: "+n},18:function(n){return "The plugin for '"+n+"' has not been loaded into Immer. To enable the plugin, import and call `enable"+n+"()` when initializing your application."},20:"Cannot use proxies if Proxy, Proxy.revocable or Reflect are not available",21:function(n){return "produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '"+n+"'"},22:function(n){return "'current' expects a draft, got: "+n},23:function(n){return "'original' expects a draft, got: "+n},24:"Patching reserved attributes like __proto__, prototype and constructor is not allowed"},Z=""+Object.prototype.constructor,nn="undefined"!=typeof Reflect&&Reflect.ownKeys?Reflect.ownKeys:void 0!==Object.getOwnPropertySymbols?function(n){return Object.getOwnPropertyNames(n).concat(Object.getOwnPropertySymbols(n))}:Object.getOwnPropertyNames,rn=Object.getOwnPropertyDescriptors||function(n){var r={};return nn(n).forEach((function(t){r[t]=Object.getOwnPropertyDescriptor(n,t);})),r},tn={},en={get:function(n,r){if(r===Q)return n;var e=p(n);if(!u(e,r))return function(n,r,t){var e,i=I(r,t);return i?"value"in i?i.value:null===(e=i.get)||void 0===e?void 0:e.call(n.k):void 0}(n,e,r);var i=e[r];return n.I||!t(i)?i:i===z(n.t,r)?(E(n),n.o[r]=R(n.A.h,i,n)):i},has:function(n,r){return r in p(n)},ownKeys:function(n){return Reflect.ownKeys(p(n))},set:function(n,r,t){var e=I(p(n),r);if(null==e?void 0:e.set)return e.set.call(n.k,t),!0;if(!n.P){var i=z(p(n),r),o=null==i?void 0:i[Q];if(o&&o.t===t)return n.o[r]=t,n.D[r]=!1,!0;if(c(t,i)&&(void 0!==t||u(n.t,r)))return !0;E(n),k(n);}return n.o[r]===t&&"number"!=typeof t&&(void 0!==t||r in n.o)||(n.o[r]=t,n.D[r]=!0,!0)},deleteProperty:function(n,r){return void 0!==z(n.t,r)||r in n.t?(n.D[r]=!1,E(n),k(n)):delete n.D[r],n.o&&delete n.o[r],!0},getOwnPropertyDescriptor:function(n,r){var t=p(n),e=Reflect.getOwnPropertyDescriptor(t,r);return e?{writable:!0,configurable:1!==n.i||"length"!==r,enumerable:e.enumerable,value:t[r]}:e},defineProperty:function(){n(11);},getPrototypeOf:function(n){return Object.getPrototypeOf(n.t)},setPrototypeOf:function(){n(12);}},on={};i(en,(function(n,r){on[n]=function(){return arguments[0]=arguments[0][0],r.apply(this,arguments)};})),on.deleteProperty=function(r,t){return isNaN(parseInt(t))&&n(13),on.set.call(this,r,t,void 0)},on.set=function(r,t,e){return "length"!==t&&isNaN(parseInt(t))&&n(14),en.set.call(this,r[0],t,e,r[0])};var un=function(){function e(r){var e=this;this.g=B,this.F=!0,this.produce=function(r,i,o){if("function"==typeof r&&"function"!=typeof i){var u=i;i=r;var a=e;return function(n){var r=this;void 0===n&&(n=u);for(var t=arguments.length,e=Array(t>1?t-1:0),o=1;o<t;o++)e[o-1]=arguments[o];return a.produce(n,(function(n){var t;return (t=i).call.apply(t,[r,n].concat(e))}))}}var f;if("function"!=typeof i&&n(6),void 0!==o&&"function"!=typeof o&&n(7),t(r)){var c=w(e),s=R(e,r,void 0),v=!0;try{f=i(s),v=!1;}finally{v?O(c):g(c);}return "undefined"!=typeof Promise&&f instanceof Promise?f.then((function(n){return j(c,o),P(n,c)}),(function(n){throw O(c),n})):(j(c,o),P(f,c))}if(!r||"object"!=typeof r){if(void 0===(f=i(r))&&(f=r),f===H&&(f=void 0),e.F&&d(f,!0),o){var p=[],l=[];b("Patches").M(r,f,p,l),o(p,l);}return f}n(21,r);},this.produceWithPatches=function(n,r){if("function"==typeof n)return function(r){for(var t=arguments.length,i=Array(t>1?t-1:0),o=1;o<t;o++)i[o-1]=arguments[o];return e.produceWithPatches(r,(function(r){return n.apply(void 0,[r].concat(i))}))};var t,i,o=e.produce(n,r,(function(n,r){t=n,i=r;}));return "undefined"!=typeof Promise&&o instanceof Promise?o.then((function(n){return [n,t,i]})):[o,t,i]},"boolean"==typeof(null==r?void 0:r.useProxies)&&this.setUseProxies(r.useProxies),"boolean"==typeof(null==r?void 0:r.autoFreeze)&&this.setAutoFreeze(r.autoFreeze);}var i=e.prototype;return i.createDraft=function(e){t(e)||n(8),r(e)&&(e=D(e));var i=w(this),o=R(this,e,void 0);return o[Q].C=!0,g(i),o},i.finishDraft=function(r,t){var e=r&&r[Q];(e&&e.C||n(9),e.I&&n(10));var i=e.A;return j(i,t),P(void 0,i)},i.setAutoFreeze=function(n){this.F=n;},i.setUseProxies=function(r){r&&!B&&n(20),this.g=r;},i.applyPatches=function(n,t){var e;for(e=t.length-1;e>=0;e--){var i=t[e];if(0===i.path.length&&"replace"===i.op){n=i.value;break}}e>-1&&(t=t.slice(e+1));var o=b("Patches").$;return r(n)?o(n,t):this.produce(n,(function(n){return o(n,t)}))},e}(),an=new un,fn=an.produce;an.produceWithPatches.bind(an);var sn=an.setAutoFreeze.bind(an);an.setUseProxies.bind(an);an.applyPatches.bind(an);an.createDraft.bind(an);an.finishDraft.bind(an);
|
|
62
|
+
/**
|
|
63
|
+
* store
|
|
64
|
+
*
|
|
65
|
+
* Copyright (c) TanStack
|
|
66
|
+
*
|
|
67
|
+
* This source code is licensed under the MIT license found in the
|
|
68
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
69
|
+
*
|
|
70
|
+
* @license MIT
|
|
71
|
+
*/
|
|
72
|
+
class Store {
|
|
73
|
+
listeners = new Set();
|
|
74
|
+
batching = false;
|
|
75
|
+
queue = [];
|
|
76
|
+
constructor(initialState, options) {
|
|
77
|
+
this.state = initialState;
|
|
78
|
+
this.options = options;
|
|
79
|
+
}
|
|
80
|
+
subscribe = listener => {
|
|
81
|
+
this.listeners.add(listener);
|
|
82
|
+
const unsub = this.options?.onSubscribe?.(listener, this);
|
|
83
|
+
return () => {
|
|
84
|
+
this.listeners.delete(listener);
|
|
85
|
+
unsub?.();
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
setState = updater => {
|
|
89
|
+
const previous = this.state;
|
|
90
|
+
this.state = this.options?.updateFn ? this.options.updateFn(previous)(updater) : updater(previous);
|
|
91
|
+
this.queue.push(() => {
|
|
92
|
+
this.listeners.forEach(listener => listener(this.state, previous));
|
|
93
|
+
this.options?.onUpdate?.(this.state, previous);
|
|
94
|
+
});
|
|
95
|
+
this.#flush();
|
|
96
|
+
};
|
|
97
|
+
#flush = () => {
|
|
98
|
+
if (this.batching) return;
|
|
99
|
+
this.queue.forEach(cb => cb());
|
|
100
|
+
this.queue = [];
|
|
101
|
+
};
|
|
102
|
+
batch = cb => {
|
|
103
|
+
this.batching = true;
|
|
104
|
+
cb();
|
|
105
|
+
this.batching = false;
|
|
106
|
+
this.#flush();
|
|
107
|
+
};
|
|
108
|
+
}
|
|
63
109
|
|
|
64
110
|
/**
|
|
65
|
-
* router
|
|
111
|
+
* router
|
|
66
112
|
*
|
|
67
113
|
* Copyright (c) TanStack
|
|
68
114
|
*
|
|
@@ -239,6 +285,66 @@
|
|
|
239
285
|
}, {});
|
|
240
286
|
}
|
|
241
287
|
|
|
288
|
+
/**
|
|
289
|
+
* This function returns `a` if `b` is deeply equal.
|
|
290
|
+
* If not, it will replace any deeply equal children of `b` with those of `a`.
|
|
291
|
+
* This can be used for structural sharing between immutable JSON values for example.
|
|
292
|
+
* Do not use this with signals
|
|
293
|
+
*/
|
|
294
|
+
function replaceEqualDeep(prev, _next) {
|
|
295
|
+
if (prev === _next) {
|
|
296
|
+
return prev;
|
|
297
|
+
}
|
|
298
|
+
const next = _next;
|
|
299
|
+
const array = Array.isArray(prev) && Array.isArray(next);
|
|
300
|
+
if (array || isPlainObject(prev) && isPlainObject(next)) {
|
|
301
|
+
const prevSize = array ? prev.length : Object.keys(prev).length;
|
|
302
|
+
const nextItems = array ? next : Object.keys(next);
|
|
303
|
+
const nextSize = nextItems.length;
|
|
304
|
+
const copy = array ? [] : {};
|
|
305
|
+
let equalItems = 0;
|
|
306
|
+
for (let i = 0; i < nextSize; i++) {
|
|
307
|
+
const key = array ? i : nextItems[i];
|
|
308
|
+
copy[key] = replaceEqualDeep(prev[key], next[key]);
|
|
309
|
+
if (copy[key] === prev[key]) {
|
|
310
|
+
equalItems++;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return prevSize === nextSize && equalItems === prevSize ? prev : copy;
|
|
314
|
+
}
|
|
315
|
+
return next;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Copied from: https://github.com/jonschlinkert/is-plain-object
|
|
319
|
+
function isPlainObject(o) {
|
|
320
|
+
if (!hasObjectPrototype(o)) {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// If has modified constructor
|
|
325
|
+
const ctor = o.constructor;
|
|
326
|
+
if (typeof ctor === 'undefined') {
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// If has modified prototype
|
|
331
|
+
const prot = ctor.prototype;
|
|
332
|
+
if (!hasObjectPrototype(prot)) {
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// If constructor does not have an Object-specific method
|
|
337
|
+
if (!prot.hasOwnProperty('isPrototypeOf')) {
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Most likely a plain Object
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
function hasObjectPrototype(o) {
|
|
345
|
+
return Object.prototype.toString.call(o) === '[object Object]';
|
|
346
|
+
}
|
|
347
|
+
|
|
242
348
|
function joinPaths(paths) {
|
|
243
349
|
return cleanPath(paths.filter(Boolean).join('/'));
|
|
244
350
|
}
|
|
@@ -515,204 +621,11 @@
|
|
|
515
621
|
};
|
|
516
622
|
};
|
|
517
623
|
|
|
518
|
-
|
|
519
|
-
let queue = [];
|
|
520
|
-
let batching = false;
|
|
521
|
-
function flush() {
|
|
522
|
-
if (batching) return;
|
|
523
|
-
queue.forEach(cb => cb());
|
|
524
|
-
queue = [];
|
|
525
|
-
}
|
|
526
|
-
function createStore(initialState, debug) {
|
|
527
|
-
const listeners = new Set();
|
|
528
|
-
const store = {
|
|
529
|
-
state: initialState,
|
|
530
|
-
subscribe: listener => {
|
|
531
|
-
listeners.add(listener);
|
|
532
|
-
return () => listeners.delete(listener);
|
|
533
|
-
},
|
|
534
|
-
setState: updater => {
|
|
535
|
-
const previous = store.state;
|
|
536
|
-
store.state = fn(d => {
|
|
537
|
-
updater(d);
|
|
538
|
-
})(previous);
|
|
539
|
-
if (debug) console.log(store.state);
|
|
540
|
-
queue.push(() => listeners.forEach(listener => listener(store.state, previous)));
|
|
541
|
-
flush();
|
|
542
|
-
}
|
|
543
|
-
};
|
|
544
|
-
return store;
|
|
545
|
-
}
|
|
546
|
-
function batch(cb) {
|
|
547
|
-
batching = true;
|
|
548
|
-
cb();
|
|
549
|
-
batching = false;
|
|
550
|
-
flush();
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// /**
|
|
554
|
-
// * This function converts a store to an immutable value, which is
|
|
555
|
-
// * more complex than you think. On first read, (when prev is undefined)
|
|
556
|
-
// * every value must be recursively touched so tracking is "deep".
|
|
557
|
-
// * Every object/array structure must also be cloned to
|
|
558
|
-
// * have a new reference, otherwise it will get mutated by subsequent
|
|
559
|
-
// * store updates.
|
|
560
|
-
// *
|
|
561
|
-
// * In the case that prev is supplied, we have to do deep comparisons
|
|
562
|
-
// * between prev and next objects/array references and if they are deeply
|
|
563
|
-
// * equal, we can return the prev version for referential equality.
|
|
564
|
-
// */
|
|
565
|
-
// export function storeToImmutable<T>(prev: any, next: T): T {
|
|
566
|
-
// const cache = new Map()
|
|
567
|
-
|
|
568
|
-
// // Visit all nodes
|
|
569
|
-
// // clone all next structures
|
|
570
|
-
// // from bottom up, if prev === next, return prev
|
|
571
|
-
|
|
572
|
-
// function recurse(prev: any, next: any) {
|
|
573
|
-
// if (cache.has(next)) {
|
|
574
|
-
// return cache.get(next)
|
|
575
|
-
// }
|
|
576
|
-
|
|
577
|
-
// const prevIsArray = Array.isArray(prev)
|
|
578
|
-
// const nextIsArray = Array.isArray(next)
|
|
579
|
-
// const prevIsObj = isPlainObject(prev)
|
|
580
|
-
// const nextIsObj = isPlainObject(next)
|
|
581
|
-
// const nextIsComplex = nextIsArray || nextIsObj
|
|
582
|
-
|
|
583
|
-
// const isArray = prevIsArray && nextIsArray
|
|
584
|
-
// const isObj = prevIsObj && nextIsObj
|
|
585
|
-
|
|
586
|
-
// const isSameStructure = isArray || isObj
|
|
587
|
-
|
|
588
|
-
// if (nextIsComplex) {
|
|
589
|
-
// const prevSize = isArray
|
|
590
|
-
// ? prev.length
|
|
591
|
-
// : isObj
|
|
592
|
-
// ? Object.keys(prev).length
|
|
593
|
-
// : -1
|
|
594
|
-
// const nextKeys = isArray ? next : Object.keys(next)
|
|
595
|
-
// const nextSize = nextKeys.length
|
|
596
|
-
|
|
597
|
-
// let changed = false
|
|
598
|
-
// const copy: any = nextIsArray ? [] : {}
|
|
599
|
-
|
|
600
|
-
// for (let i = 0; i < nextSize; i++) {
|
|
601
|
-
// const key = isArray ? i : nextKeys[i]
|
|
602
|
-
// const prevValue = isSameStructure ? prev[key] : undefined
|
|
603
|
-
// const nextValue = next[key]
|
|
604
|
-
|
|
605
|
-
// // Recurse the new value
|
|
606
|
-
// try {
|
|
607
|
-
// console.count(key)
|
|
608
|
-
// copy[key] = recurse(prevValue, nextValue)
|
|
609
|
-
// } catch {}
|
|
610
|
-
|
|
611
|
-
// // If the new value has changed reference,
|
|
612
|
-
// // mark the obj/array as changed
|
|
613
|
-
// if (!changed && copy[key] !== prevValue) {
|
|
614
|
-
// changed = true
|
|
615
|
-
// }
|
|
616
|
-
// }
|
|
617
|
-
|
|
618
|
-
// // No items have changed!
|
|
619
|
-
// // If something has changed, return a clone of the next obj/array
|
|
620
|
-
// if (changed || prevSize !== nextSize) {
|
|
621
|
-
// cache.set(next, copy)
|
|
622
|
-
// return copy
|
|
623
|
-
// }
|
|
624
|
-
|
|
625
|
-
// // If they are exactly the same, return the prev obj/array
|
|
626
|
-
// cache.set(next, prev)
|
|
627
|
-
// return prev
|
|
628
|
-
// }
|
|
629
|
-
|
|
630
|
-
// cache.set(next, next)
|
|
631
|
-
// return next
|
|
632
|
-
// }
|
|
633
|
-
|
|
634
|
-
// return recurse(prev, next)
|
|
635
|
-
// }
|
|
636
|
-
|
|
637
|
-
/**
|
|
638
|
-
* This function returns `a` if `b` is deeply equal.
|
|
639
|
-
* If not, it will replace any deeply equal children of `b` with those of `a`.
|
|
640
|
-
* This can be used for structural sharing between immutable JSON values for example.
|
|
641
|
-
* Do not use this with signals
|
|
642
|
-
*/
|
|
643
|
-
function replaceEqualDeep(prev, _next) {
|
|
644
|
-
if (prev === _next) {
|
|
645
|
-
return prev;
|
|
646
|
-
}
|
|
647
|
-
const next = _next;
|
|
648
|
-
const array = Array.isArray(prev) && Array.isArray(next);
|
|
649
|
-
if (array || isPlainObject(prev) && isPlainObject(next)) {
|
|
650
|
-
const prevSize = array ? prev.length : Object.keys(prev).length;
|
|
651
|
-
const nextItems = array ? next : Object.keys(next);
|
|
652
|
-
const nextSize = nextItems.length;
|
|
653
|
-
const copy = array ? [] : {};
|
|
654
|
-
let equalItems = 0;
|
|
655
|
-
for (let i = 0; i < nextSize; i++) {
|
|
656
|
-
const key = array ? i : nextItems[i];
|
|
657
|
-
copy[key] = replaceEqualDeep(prev[key], next[key]);
|
|
658
|
-
if (copy[key] === prev[key]) {
|
|
659
|
-
equalItems++;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
return prevSize === nextSize && equalItems === prevSize ? prev : copy;
|
|
663
|
-
}
|
|
664
|
-
return next;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
// Copied from: https://github.com/jonschlinkert/is-plain-object
|
|
668
|
-
function isPlainObject(o) {
|
|
669
|
-
if (!hasObjectPrototype(o)) {
|
|
670
|
-
return false;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
// If has modified constructor
|
|
674
|
-
const ctor = o.constructor;
|
|
675
|
-
if (typeof ctor === 'undefined') {
|
|
676
|
-
return true;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
// If has modified prototype
|
|
680
|
-
const prot = ctor.prototype;
|
|
681
|
-
if (!hasObjectPrototype(prot)) {
|
|
682
|
-
return false;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
// If constructor does not have an Object-specific method
|
|
686
|
-
if (!prot.hasOwnProperty('isPrototypeOf')) {
|
|
687
|
-
return false;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
// Most likely a plain Object
|
|
691
|
-
return true;
|
|
692
|
-
}
|
|
693
|
-
function hasObjectPrototype(o) {
|
|
694
|
-
return Object.prototype.toString.call(o) === '[object Object]';
|
|
695
|
-
}
|
|
696
|
-
function trackDeep(obj) {
|
|
697
|
-
const seen = new Set();
|
|
698
|
-
JSON.stringify(obj, (_, value) => {
|
|
699
|
-
if (typeof value === 'function') {
|
|
700
|
-
return undefined;
|
|
701
|
-
}
|
|
702
|
-
if (typeof value === 'object' && value !== null) {
|
|
703
|
-
if (seen.has(value)) return;
|
|
704
|
-
seen.add(value);
|
|
705
|
-
}
|
|
706
|
-
return value;
|
|
707
|
-
});
|
|
708
|
-
return obj;
|
|
709
|
-
}
|
|
624
|
+
//
|
|
710
625
|
|
|
711
626
|
const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
|
|
712
627
|
class RouteMatch {
|
|
713
628
|
abortController = new AbortController();
|
|
714
|
-
#latestId = '';
|
|
715
|
-
#resolve = () => {};
|
|
716
629
|
onLoaderDataListeners = new Set();
|
|
717
630
|
constructor(router, route, opts) {
|
|
718
631
|
Object.assign(this, {
|
|
@@ -721,80 +634,49 @@
|
|
|
721
634
|
id: opts.id,
|
|
722
635
|
pathname: opts.pathname,
|
|
723
636
|
params: opts.params,
|
|
724
|
-
store:
|
|
637
|
+
store: new Store({
|
|
638
|
+
updatedAt: 0,
|
|
725
639
|
routeSearch: {},
|
|
726
640
|
search: {},
|
|
727
|
-
status: 'idle'
|
|
728
|
-
routeLoaderData: {},
|
|
729
|
-
loaderData: {},
|
|
730
|
-
isFetching: false,
|
|
731
|
-
invalid: false,
|
|
732
|
-
invalidAt: Infinity
|
|
641
|
+
status: 'idle'
|
|
733
642
|
})
|
|
734
643
|
});
|
|
735
|
-
if (!this
|
|
736
|
-
this.store.setState(s =>
|
|
644
|
+
if (!this.#hasLoaders()) {
|
|
645
|
+
this.store.setState(s => ({
|
|
646
|
+
...s,
|
|
647
|
+
status: 'success'
|
|
648
|
+
}));
|
|
737
649
|
}
|
|
738
650
|
}
|
|
739
|
-
setLoaderData = loaderData => {
|
|
740
|
-
batch(() => {
|
|
741
|
-
this.store.setState(s => {
|
|
742
|
-
s.routeLoaderData = loaderData;
|
|
743
|
-
});
|
|
744
|
-
this.#updateLoaderData();
|
|
745
|
-
});
|
|
746
|
-
};
|
|
747
651
|
cancel = () => {
|
|
748
652
|
this.abortController?.abort();
|
|
749
653
|
};
|
|
750
|
-
load = async
|
|
751
|
-
const now = Date.now();
|
|
752
|
-
const minMaxAge = loaderOpts?.preload ? Math.max(loaderOpts?.maxAge, loaderOpts?.gcMaxAge) : 0;
|
|
753
|
-
|
|
754
|
-
// If this is a preload, add it to the preload cache
|
|
755
|
-
if (loaderOpts?.preload && minMaxAge > 0) {
|
|
756
|
-
// If the match is currently active, don't preload it
|
|
757
|
-
if (this.router.store.state.currentMatches.find(d => d.id === this.id)) {
|
|
758
|
-
return;
|
|
759
|
-
}
|
|
760
|
-
this.router.store.setState(s => {
|
|
761
|
-
s.matchCache[this.id] = {
|
|
762
|
-
gc: now + loaderOpts.gcMaxAge,
|
|
763
|
-
match: this
|
|
764
|
-
};
|
|
765
|
-
});
|
|
766
|
-
}
|
|
767
|
-
|
|
654
|
+
load = async () => {
|
|
768
655
|
// If the match is invalid, errored or idle, trigger it to load
|
|
769
|
-
if (this.store.state.status
|
|
770
|
-
|
|
771
|
-
await this.fetch({
|
|
772
|
-
maxAge
|
|
773
|
-
});
|
|
656
|
+
if (this.store.state.status !== 'pending') {
|
|
657
|
+
await this.fetch();
|
|
774
658
|
}
|
|
775
659
|
};
|
|
776
|
-
|
|
777
|
-
|
|
660
|
+
#latestId = '';
|
|
661
|
+
fetch = async () => {
|
|
662
|
+
this.__loadPromise = Promise.resolve().then(async () => {
|
|
778
663
|
const loadId = '' + Date.now() + Math.random();
|
|
779
664
|
this.#latestId = loadId;
|
|
780
|
-
const checkLatest = () =>
|
|
665
|
+
const checkLatest = () => {
|
|
666
|
+
return loadId !== this.#latestId ? this.__loadPromise : undefined;
|
|
667
|
+
};
|
|
781
668
|
let latestPromise;
|
|
782
|
-
batch(() => {
|
|
669
|
+
this.store.batch(() => {
|
|
783
670
|
// If the match was in an error state, set it
|
|
784
671
|
// to a loading state again. Otherwise, keep it
|
|
785
672
|
// as loading or resolved
|
|
786
673
|
if (this.store.state.status === 'idle') {
|
|
787
|
-
this.store.setState(s =>
|
|
674
|
+
this.store.setState(s => ({
|
|
675
|
+
...s,
|
|
676
|
+
status: 'pending'
|
|
677
|
+
}));
|
|
788
678
|
}
|
|
789
|
-
|
|
790
|
-
// We started loading the route, so it's no longer invalid
|
|
791
|
-
this.store.setState(s => s.invalid = false);
|
|
792
679
|
});
|
|
793
|
-
|
|
794
|
-
// We are now fetching, even if it's in the background of a
|
|
795
|
-
// resolved state
|
|
796
|
-
this.store.setState(s => s.isFetching = true);
|
|
797
|
-
this.#resolve = resolve;
|
|
798
680
|
const componentsPromise = (async () => {
|
|
799
681
|
// then run all component and data loaders in parallel
|
|
800
682
|
// For each component type, potentially load it asynchronously
|
|
@@ -806,103 +688,61 @@
|
|
|
806
688
|
}
|
|
807
689
|
}));
|
|
808
690
|
})();
|
|
809
|
-
const dataPromise = Promise.resolve().then(
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
this.
|
|
815
|
-
}
|
|
816
|
-
this.store.setState(s => {
|
|
817
|
-
s.error = undefined;
|
|
818
|
-
s.status = 'success';
|
|
819
|
-
s.updatedAt = Date.now();
|
|
820
|
-
s.invalidAt = s.updatedAt + (opts?.maxAge ?? this.route.options.loaderMaxAge ?? this.router.options.defaultLoaderMaxAge ?? 0);
|
|
821
|
-
});
|
|
822
|
-
return this.store.state.routeLoaderData;
|
|
823
|
-
} catch (err) {
|
|
824
|
-
if (latestPromise = checkLatest()) return latestPromise;
|
|
825
|
-
{
|
|
826
|
-
console.error(err);
|
|
827
|
-
}
|
|
828
|
-
this.store.setState(s => {
|
|
829
|
-
s.error = err;
|
|
830
|
-
s.status = 'error';
|
|
831
|
-
s.updatedAt = Date.now();
|
|
691
|
+
const dataPromise = Promise.resolve().then(() => {
|
|
692
|
+
if (this.route.options.onLoad) {
|
|
693
|
+
return this.route.options.onLoad({
|
|
694
|
+
params: this.params,
|
|
695
|
+
search: this.store.state.search,
|
|
696
|
+
signal: this.abortController.signal
|
|
832
697
|
});
|
|
833
|
-
throw err;
|
|
834
698
|
}
|
|
699
|
+
return;
|
|
835
700
|
});
|
|
836
|
-
const after = async () => {
|
|
837
|
-
if (latestPromise = checkLatest()) return latestPromise;
|
|
838
|
-
this.store.setState(s => s.isFetching = false);
|
|
839
|
-
this.#resolve();
|
|
840
|
-
delete this.__loadPromise;
|
|
841
|
-
};
|
|
842
701
|
try {
|
|
843
|
-
await
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
702
|
+
await componentsPromise;
|
|
703
|
+
await dataPromise;
|
|
704
|
+
if (latestPromise = checkLatest()) return await latestPromise;
|
|
705
|
+
this.store.setState(s => ({
|
|
706
|
+
...s,
|
|
707
|
+
error: undefined,
|
|
708
|
+
status: 'success',
|
|
709
|
+
updatedAt: Date.now()
|
|
710
|
+
}));
|
|
711
|
+
} catch (err) {
|
|
712
|
+
this.store.setState(s => ({
|
|
713
|
+
...s,
|
|
714
|
+
error: err,
|
|
715
|
+
status: 'error',
|
|
716
|
+
updatedAt: Date.now()
|
|
717
|
+
}));
|
|
718
|
+
} finally {
|
|
719
|
+
delete this.__loadPromise;
|
|
847
720
|
}
|
|
848
721
|
});
|
|
849
722
|
return this.__loadPromise;
|
|
850
723
|
};
|
|
851
|
-
|
|
852
|
-
this.
|
|
853
|
-
if (this.router.store.state.currentMatches.find(d => d.id === this.id)) {
|
|
854
|
-
await this.load();
|
|
855
|
-
}
|
|
856
|
-
};
|
|
857
|
-
__hasLoaders = () => {
|
|
858
|
-
return !!(this.route.options.loader || componentTypes.some(d => this.route.options[d]?.preload));
|
|
859
|
-
};
|
|
860
|
-
getIsInvalid = () => {
|
|
861
|
-
const now = Date.now();
|
|
862
|
-
return this.store.state.invalid || this.store.state.invalidAt < now;
|
|
863
|
-
};
|
|
864
|
-
#updateLoaderData = () => {
|
|
865
|
-
this.store.setState(s => {
|
|
866
|
-
s.loaderData = replaceEqualDeep(s.loaderData, {
|
|
867
|
-
...this.parentMatch?.store.state.loaderData,
|
|
868
|
-
...s.routeLoaderData
|
|
869
|
-
});
|
|
870
|
-
});
|
|
871
|
-
this.onLoaderDataListeners.forEach(listener => listener());
|
|
724
|
+
#hasLoaders = () => {
|
|
725
|
+
return !!(this.route.options.onLoad || componentTypes.some(d => this.route.options[d]?.preload));
|
|
872
726
|
};
|
|
873
727
|
__setParentMatch = parentMatch => {
|
|
874
728
|
if (!this.parentMatch && parentMatch) {
|
|
875
729
|
this.parentMatch = parentMatch;
|
|
876
|
-
this.parentMatch.__onLoaderData(() => {
|
|
877
|
-
this.#updateLoaderData();
|
|
878
|
-
});
|
|
879
730
|
}
|
|
880
731
|
};
|
|
881
|
-
__onLoaderData = listener => {
|
|
882
|
-
this.onLoaderDataListeners.add(listener);
|
|
883
|
-
// return () => this.onLoaderDataListeners.delete(listener)
|
|
884
|
-
};
|
|
885
|
-
|
|
886
732
|
__validate = () => {
|
|
887
733
|
// Validate the search params and stabilize them
|
|
888
734
|
const parentSearch = this.parentMatch?.store.state.search ?? this.router.store.state.latestLocation.search;
|
|
889
735
|
try {
|
|
890
|
-
const prevSearch = this.store.state.routeSearch;
|
|
891
736
|
const validator = typeof this.route.options.validateSearch === 'object' ? this.route.options.validateSearch.parse : this.route.options.validateSearch;
|
|
892
737
|
let nextSearch = validator?.(parentSearch) ?? {};
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
738
|
+
this.store.setState(s => ({
|
|
739
|
+
...s,
|
|
740
|
+
routeSearch: nextSearch,
|
|
741
|
+
search: {
|
|
742
|
+
...parentSearch,
|
|
743
|
+
...nextSearch
|
|
897
744
|
}
|
|
898
|
-
|
|
899
|
-
s.routeSearch = nextSearch;
|
|
900
|
-
s.search = {
|
|
901
|
-
...parentSearch,
|
|
902
|
-
...nextSearch
|
|
903
|
-
};
|
|
904
|
-
});
|
|
905
|
-
});
|
|
745
|
+
}));
|
|
906
746
|
componentTypes.map(async type => {
|
|
907
747
|
const component = this.route.options[type];
|
|
908
748
|
if (typeof this[type] !== 'function') {
|
|
@@ -915,10 +755,11 @@
|
|
|
915
755
|
cause: err
|
|
916
756
|
});
|
|
917
757
|
error.code = 'INVALID_SEARCH_PARAMS';
|
|
918
|
-
this.store.setState(s => {
|
|
919
|
-
s
|
|
920
|
-
|
|
921
|
-
|
|
758
|
+
this.store.setState(s => ({
|
|
759
|
+
...s,
|
|
760
|
+
status: 'error',
|
|
761
|
+
error: error
|
|
762
|
+
}));
|
|
922
763
|
|
|
923
764
|
// Do not proceed with loading the route
|
|
924
765
|
return;
|
|
@@ -1001,9 +842,6 @@
|
|
|
1001
842
|
resolveNavigation = () => {};
|
|
1002
843
|
constructor(options) {
|
|
1003
844
|
this.options = {
|
|
1004
|
-
defaultLoaderGcMaxAge: 5 * 60 * 1000,
|
|
1005
|
-
defaultLoaderMaxAge: 0,
|
|
1006
|
-
defaultPreloadMaxAge: 2000,
|
|
1007
845
|
defaultPreloadDelay: 50,
|
|
1008
846
|
context: undefined,
|
|
1009
847
|
...options,
|
|
@@ -1011,7 +849,7 @@
|
|
|
1011
849
|
parseSearch: options?.parseSearch ?? defaultParseSearch,
|
|
1012
850
|
fetchServerDataFn: options?.fetchServerDataFn ?? defaultFetchServerDataFn
|
|
1013
851
|
};
|
|
1014
|
-
this.store =
|
|
852
|
+
this.store = new Store(getInitialRouterState());
|
|
1015
853
|
this.basepath = '';
|
|
1016
854
|
this.update(options);
|
|
1017
855
|
|
|
@@ -1057,10 +895,12 @@
|
|
|
1057
895
|
this.#unsubHistory();
|
|
1058
896
|
}
|
|
1059
897
|
this.history = this.options.history ?? (isServer ? createMemoryHistory() : createBrowserHistory());
|
|
1060
|
-
this
|
|
1061
|
-
|
|
1062
|
-
s
|
|
1063
|
-
|
|
898
|
+
const parsedLocation = this.#parseLocation();
|
|
899
|
+
this.store.setState(s => ({
|
|
900
|
+
...s,
|
|
901
|
+
latestLocation: parsedLocation,
|
|
902
|
+
currentLocation: parsedLocation
|
|
903
|
+
}));
|
|
1064
904
|
this.#unsubHistory = this.history.listen(() => {
|
|
1065
905
|
this.load(this.#parseLocation(this.store.state.latestLocation));
|
|
1066
906
|
});
|
|
@@ -1100,23 +940,25 @@
|
|
|
1100
940
|
// Cancel any pending matches
|
|
1101
941
|
this.cancelMatches();
|
|
1102
942
|
let matches;
|
|
1103
|
-
batch(() => {
|
|
943
|
+
this.store.batch(() => {
|
|
1104
944
|
if (next) {
|
|
1105
945
|
// Ingest the new location
|
|
1106
|
-
this.store.setState(s => {
|
|
1107
|
-
s
|
|
1108
|
-
|
|
946
|
+
this.store.setState(s => ({
|
|
947
|
+
...s,
|
|
948
|
+
latestLocation: next
|
|
949
|
+
}));
|
|
1109
950
|
}
|
|
1110
951
|
|
|
1111
952
|
// Match the routes
|
|
1112
953
|
matches = this.matchRoutes(this.store.state.latestLocation.pathname, {
|
|
1113
954
|
strictParseParams: true
|
|
1114
955
|
});
|
|
1115
|
-
this.store.setState(s => {
|
|
1116
|
-
s
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
956
|
+
this.store.setState(s => ({
|
|
957
|
+
...s,
|
|
958
|
+
status: 'pending',
|
|
959
|
+
pendingMatches: matches,
|
|
960
|
+
pendingLocation: this.store.state.latestLocation
|
|
961
|
+
}));
|
|
1120
962
|
});
|
|
1121
963
|
|
|
1122
964
|
// Load the matches
|
|
@@ -1151,20 +993,12 @@
|
|
|
1151
993
|
});
|
|
1152
994
|
|
|
1153
995
|
// Clear non-loading error states when match leaves
|
|
1154
|
-
if (d.store.state.status === 'error'
|
|
1155
|
-
|
|
1156
|
-
s
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
const gc = Math.max(d.route.options.loaderGcMaxAge ?? this.options.defaultLoaderGcMaxAge ?? 0, d.route.options.loaderMaxAge ?? this.options.defaultLoaderMaxAge ?? 0);
|
|
1161
|
-
if (gc > 0) {
|
|
1162
|
-
this.store.setState(s => {
|
|
1163
|
-
s.matchCache[d.id] = {
|
|
1164
|
-
gc: gc == Infinity ? Number.MAX_SAFE_INTEGER : now + gc,
|
|
1165
|
-
match: d
|
|
1166
|
-
};
|
|
1167
|
-
});
|
|
996
|
+
if (d.store.state.status === 'error') {
|
|
997
|
+
this.store.setState(s => ({
|
|
998
|
+
...s,
|
|
999
|
+
status: 'idle',
|
|
1000
|
+
error: undefined
|
|
1001
|
+
}));
|
|
1168
1002
|
}
|
|
1169
1003
|
});
|
|
1170
1004
|
staying.forEach(d => {
|
|
@@ -1178,41 +1012,20 @@
|
|
|
1178
1012
|
params: d.params,
|
|
1179
1013
|
search: d.store.state.search
|
|
1180
1014
|
});
|
|
1181
|
-
delete this.store.state.matchCache[d.id]
|
|
1182
|
-
});
|
|
1183
|
-
this.store.setState(s => {
|
|
1184
|
-
Object.assign(s, {
|
|
1185
|
-
status: 'idle',
|
|
1186
|
-
currentLocation: this.store.state.latestLocation,
|
|
1187
|
-
currentMatches: matches,
|
|
1188
|
-
pendingLocation: undefined,
|
|
1189
|
-
pendingMatches: undefined
|
|
1190
|
-
});
|
|
1015
|
+
// delete this.store.state.matchCache[d.id] // TODO:
|
|
1191
1016
|
});
|
|
1017
|
+
|
|
1018
|
+
this.store.setState(s => ({
|
|
1019
|
+
...s,
|
|
1020
|
+
status: 'idle',
|
|
1021
|
+
currentLocation: this.store.state.latestLocation,
|
|
1022
|
+
currentMatches: matches,
|
|
1023
|
+
pendingLocation: undefined,
|
|
1024
|
+
pendingMatches: undefined
|
|
1025
|
+
}));
|
|
1192
1026
|
this.options.onRouteChange?.();
|
|
1193
1027
|
this.resolveNavigation();
|
|
1194
1028
|
};
|
|
1195
|
-
cleanMatchCache = () => {
|
|
1196
|
-
const now = Date.now();
|
|
1197
|
-
this.store.setState(s => {
|
|
1198
|
-
Object.keys(s.matchCache).forEach(matchId => {
|
|
1199
|
-
const entry = s.matchCache[matchId];
|
|
1200
|
-
|
|
1201
|
-
// Don't remove loading matches
|
|
1202
|
-
if (entry.match.store.state.status === 'loading') {
|
|
1203
|
-
return;
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
// Do not remove successful matches that are still valid
|
|
1207
|
-
if (entry.gc > 0 && entry.gc > now) {
|
|
1208
|
-
return;
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
// Everything else gets removed
|
|
1212
|
-
delete s.matchCache[matchId];
|
|
1213
|
-
});
|
|
1214
|
-
});
|
|
1215
|
-
};
|
|
1216
1029
|
getRoute = id => {
|
|
1217
1030
|
const route = this.routesById[id];
|
|
1218
1031
|
invariant(route, `Route with id "${id}" not found`);
|
|
@@ -1226,15 +1039,13 @@
|
|
|
1226
1039
|
await this.loadMatches(matches);
|
|
1227
1040
|
return matches;
|
|
1228
1041
|
};
|
|
1229
|
-
preloadRoute = async (navigateOpts = this.store.state.latestLocation
|
|
1042
|
+
preloadRoute = async (navigateOpts = this.store.state.latestLocation) => {
|
|
1230
1043
|
const next = this.buildNext(navigateOpts);
|
|
1231
1044
|
const matches = this.matchRoutes(next.pathname, {
|
|
1232
1045
|
strictParseParams: true
|
|
1233
1046
|
});
|
|
1234
1047
|
await this.loadMatches(matches, {
|
|
1235
|
-
preload: true
|
|
1236
|
-
maxAge: loaderOpts.maxAge ?? this.options.defaultPreloadMaxAge ?? this.options.defaultLoaderMaxAge ?? 0,
|
|
1237
|
-
gcMaxAge: loaderOpts.gcMaxAge ?? this.options.defaultPreloadGcMaxAge ?? this.options.defaultLoaderGcMaxAge ?? 0
|
|
1048
|
+
preload: true
|
|
1238
1049
|
});
|
|
1239
1050
|
return matches;
|
|
1240
1051
|
};
|
|
@@ -1288,7 +1099,9 @@
|
|
|
1288
1099
|
foundRoutes.forEach(foundRoute => {
|
|
1289
1100
|
const interpolatedPath = interpolatePath(foundRoute.path, params);
|
|
1290
1101
|
const matchId = interpolatePath(foundRoute.id, params, true);
|
|
1291
|
-
const match = existingMatches.find(d => d.id === matchId) ||
|
|
1102
|
+
const match = existingMatches.find(d => d.id === matchId) ||
|
|
1103
|
+
// this.store.state.matchCache[matchId]?.match || // TODO:
|
|
1104
|
+
new RouteMatch(this, foundRoute, {
|
|
1292
1105
|
id: matchId,
|
|
1293
1106
|
params,
|
|
1294
1107
|
pathname: joinPaths([this.basepath, interpolatedPath])
|
|
@@ -1305,7 +1118,7 @@
|
|
|
1305
1118
|
return matches;
|
|
1306
1119
|
};
|
|
1307
1120
|
loadMatches = async (resolvedMatches, loaderOpts) => {
|
|
1308
|
-
this.cleanMatchCache()
|
|
1121
|
+
// this.cleanMatchCache()
|
|
1309
1122
|
resolvedMatches.forEach(async match => {
|
|
1310
1123
|
// Validate the match (loads search params etc)
|
|
1311
1124
|
match.__validate();
|
|
@@ -1331,7 +1144,7 @@
|
|
|
1331
1144
|
if (search.__data?.matchId && search.__data.matchId !== match.id) {
|
|
1332
1145
|
return;
|
|
1333
1146
|
}
|
|
1334
|
-
match.load(
|
|
1147
|
+
match.load();
|
|
1335
1148
|
if (match.store.state.status !== 'success' && match.__loadPromise) {
|
|
1336
1149
|
// Wait for the first sign of activity from the match
|
|
1337
1150
|
await match.__loadPromise;
|
|
@@ -1342,41 +1155,6 @@
|
|
|
1342
1155
|
});
|
|
1343
1156
|
await Promise.all(matchPromises);
|
|
1344
1157
|
};
|
|
1345
|
-
loadMatchData = async routeMatch => {
|
|
1346
|
-
if (isServer || !this.options.useServerData) {
|
|
1347
|
-
return (await routeMatch.route.options.loader?.({
|
|
1348
|
-
// parentLoaderPromise: routeMatch.parentMatch.dataPromise,
|
|
1349
|
-
params: routeMatch.params,
|
|
1350
|
-
search: routeMatch.store.state.routeSearch,
|
|
1351
|
-
signal: routeMatch.abortController.signal
|
|
1352
|
-
})) || {};
|
|
1353
|
-
} else {
|
|
1354
|
-
// Refresh:
|
|
1355
|
-
// '/dashboard'
|
|
1356
|
-
// '/dashboard/invoices/'
|
|
1357
|
-
// '/dashboard/invoices/123'
|
|
1358
|
-
|
|
1359
|
-
// New:
|
|
1360
|
-
// '/dashboard/invoices/456'
|
|
1361
|
-
|
|
1362
|
-
// TODO: batch requests when possible
|
|
1363
|
-
|
|
1364
|
-
const res = await this.options.fetchServerDataFn({
|
|
1365
|
-
router: this,
|
|
1366
|
-
routeMatch
|
|
1367
|
-
});
|
|
1368
|
-
return res;
|
|
1369
|
-
}
|
|
1370
|
-
};
|
|
1371
|
-
invalidateRoute = async opts => {
|
|
1372
|
-
const next = this.buildNext(opts);
|
|
1373
|
-
const unloadedMatchIds = this.matchRoutes(next.pathname).map(d => d.id);
|
|
1374
|
-
await Promise.allSettled([...this.store.state.currentMatches, ...(this.store.state.pendingMatches ?? [])].map(async match => {
|
|
1375
|
-
if (unloadedMatchIds.includes(match.id)) {
|
|
1376
|
-
return match.invalidate();
|
|
1377
|
-
}
|
|
1378
|
-
}));
|
|
1379
|
-
};
|
|
1380
1158
|
reload = () => {
|
|
1381
1159
|
this.navigate({
|
|
1382
1160
|
fromCurrent: true,
|
|
@@ -1401,7 +1179,7 @@
|
|
|
1401
1179
|
// If this `to` is a valid external URL, return
|
|
1402
1180
|
// null for LinkUtils
|
|
1403
1181
|
const toString = String(to);
|
|
1404
|
-
const fromString = String(from);
|
|
1182
|
+
const fromString = typeof from === 'undefined' ? from : String(from);
|
|
1405
1183
|
let isExternal;
|
|
1406
1184
|
try {
|
|
1407
1185
|
new URL(`${toString}`);
|
|
@@ -1494,9 +1272,6 @@
|
|
|
1494
1272
|
const handleClick = e => {
|
|
1495
1273
|
if (!disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!target || target === '_self') && e.button === 0) {
|
|
1496
1274
|
e.preventDefault();
|
|
1497
|
-
if (pathIsEqual && !search && !hash) {
|
|
1498
|
-
this.invalidateRoute(nextOpts);
|
|
1499
|
-
}
|
|
1500
1275
|
|
|
1501
1276
|
// All is well? Navigate!
|
|
1502
1277
|
this.#commitLocation(nextOpts);
|
|
@@ -1506,10 +1281,7 @@
|
|
|
1506
1281
|
// The click handler
|
|
1507
1282
|
const handleFocus = e => {
|
|
1508
1283
|
if (preload) {
|
|
1509
|
-
this.preloadRoute(nextOpts
|
|
1510
|
-
maxAge: userPreloadMaxAge,
|
|
1511
|
-
gcMaxAge: userPreloadGcMaxAge
|
|
1512
|
-
}).catch(err => {
|
|
1284
|
+
this.preloadRoute(nextOpts).catch(err => {
|
|
1513
1285
|
console.warn(err);
|
|
1514
1286
|
console.warn('Error preloading route! ☝️');
|
|
1515
1287
|
});
|
|
@@ -1523,10 +1295,7 @@
|
|
|
1523
1295
|
}
|
|
1524
1296
|
target.preloadTimeout = setTimeout(() => {
|
|
1525
1297
|
target.preloadTimeout = null;
|
|
1526
|
-
this.preloadRoute(nextOpts
|
|
1527
|
-
maxAge: userPreloadMaxAge,
|
|
1528
|
-
gcMaxAge: userPreloadGcMaxAge
|
|
1529
|
-
}).catch(err => {
|
|
1298
|
+
this.preloadRoute(nextOpts).catch(err => {
|
|
1530
1299
|
console.warn(err);
|
|
1531
1300
|
console.warn('Error preloading route! ☝️');
|
|
1532
1301
|
});
|
|
@@ -1558,7 +1327,7 @@
|
|
|
1558
1327
|
currentMatches: this.store.state.currentMatches.map(match => ({
|
|
1559
1328
|
id: match.id,
|
|
1560
1329
|
state: {
|
|
1561
|
-
...pick(match.store.state, ['status'
|
|
1330
|
+
...pick(match.store.state, ['status'])
|
|
1562
1331
|
}
|
|
1563
1332
|
}))
|
|
1564
1333
|
},
|
|
@@ -1567,7 +1336,6 @@
|
|
|
1567
1336
|
};
|
|
1568
1337
|
hydrate = dehydratedRouter => {
|
|
1569
1338
|
this.store.setState(s => {
|
|
1570
|
-
// Update the context TODO: make this part of state?
|
|
1571
1339
|
this.options.context = dehydratedRouter.context;
|
|
1572
1340
|
|
|
1573
1341
|
// Match the routes
|
|
@@ -1576,54 +1344,20 @@
|
|
|
1576
1344
|
});
|
|
1577
1345
|
currentMatches.forEach((match, index) => {
|
|
1578
1346
|
const dehydratedMatch = dehydratedRouter.state.currentMatches[index];
|
|
1579
|
-
invariant(dehydratedMatch && dehydratedMatch.id === match.id, 'Oh no! There was a hydration mismatch when attempting to
|
|
1580
|
-
match.store.setState(s => {
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1347
|
+
invariant(dehydratedMatch && dehydratedMatch.id === match.id, 'Oh no! There was a hydration mismatch when attempting to hydrate the state of the router! 😬');
|
|
1348
|
+
match.store.setState(s => ({
|
|
1349
|
+
...s,
|
|
1350
|
+
...dehydratedMatch.state
|
|
1351
|
+
}));
|
|
1584
1352
|
});
|
|
1585
1353
|
currentMatches.forEach(match => match.__validate());
|
|
1586
|
-
|
|
1354
|
+
return {
|
|
1355
|
+
...s,
|
|
1587
1356
|
...dehydratedRouter.state,
|
|
1588
1357
|
currentMatches
|
|
1589
|
-
}
|
|
1358
|
+
};
|
|
1590
1359
|
});
|
|
1591
1360
|
};
|
|
1592
|
-
getLoader = opts => {
|
|
1593
|
-
const id = opts.from || '/';
|
|
1594
|
-
const route = this.getRoute(id);
|
|
1595
|
-
if (!route) return undefined;
|
|
1596
|
-
let loader = this.store.state.loaders[id] || (() => {
|
|
1597
|
-
this.store.setState(s => {
|
|
1598
|
-
s.loaders[id] = {
|
|
1599
|
-
pending: [],
|
|
1600
|
-
fetch: async loaderContext => {
|
|
1601
|
-
if (!route) {
|
|
1602
|
-
return;
|
|
1603
|
-
}
|
|
1604
|
-
const loaderState = {
|
|
1605
|
-
loadedAt: Date.now(),
|
|
1606
|
-
loaderContext
|
|
1607
|
-
};
|
|
1608
|
-
this.store.setState(s => {
|
|
1609
|
-
s.loaders[id].current = loaderState;
|
|
1610
|
-
s.loaders[id].latest = loaderState;
|
|
1611
|
-
s.loaders[id].pending.push(loaderState);
|
|
1612
|
-
});
|
|
1613
|
-
try {
|
|
1614
|
-
return await route.options.loader?.(loaderContext);
|
|
1615
|
-
} finally {
|
|
1616
|
-
this.store.setState(s => {
|
|
1617
|
-
s.loaders[id].pending = s.loaders[id].pending.filter(d => d !== loaderState);
|
|
1618
|
-
});
|
|
1619
|
-
}
|
|
1620
|
-
}
|
|
1621
|
-
};
|
|
1622
|
-
});
|
|
1623
|
-
return this.store.state.loaders[id];
|
|
1624
|
-
})();
|
|
1625
|
-
return loader;
|
|
1626
|
-
};
|
|
1627
1361
|
#buildRouteTree = rootRouteConfig => {
|
|
1628
1362
|
const recurseRoutes = (routeConfigs, parent) => {
|
|
1629
1363
|
return routeConfigs.map((routeConfig, i) => {
|
|
@@ -1747,17 +1481,24 @@
|
|
|
1747
1481
|
latestLocation: null,
|
|
1748
1482
|
currentLocation: null,
|
|
1749
1483
|
currentMatches: [],
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1484
|
+
lastUpdated: Date.now()
|
|
1485
|
+
// matchCache: {}, // TODO:
|
|
1486
|
+
// get isFetching() {
|
|
1487
|
+
// return (
|
|
1488
|
+
// this.status === 'loading' ||
|
|
1489
|
+
// this.currentMatches.some((d) => d.store.state.isFetching)
|
|
1490
|
+
// )
|
|
1491
|
+
// },
|
|
1492
|
+
// get isPreloading() {
|
|
1493
|
+
// return Object.values(this.matchCache).some(
|
|
1494
|
+
// (d) =>
|
|
1495
|
+
// d.match.store.state.isFetching &&
|
|
1496
|
+
// !this.currentMatches.find((dd) => dd.id === d.match.id),
|
|
1497
|
+
// )
|
|
1498
|
+
// },
|
|
1759
1499
|
};
|
|
1760
1500
|
}
|
|
1501
|
+
|
|
1761
1502
|
function isCtrlEvent(e) {
|
|
1762
1503
|
return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
|
|
1763
1504
|
}
|
|
@@ -1770,76 +1511,16 @@
|
|
|
1770
1511
|
});
|
|
1771
1512
|
}
|
|
1772
1513
|
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
s.submissions = [];
|
|
1784
|
-
});
|
|
1785
|
-
},
|
|
1786
|
-
submit: async payload => {
|
|
1787
|
-
const submission = {
|
|
1788
|
-
submittedAt: Date.now(),
|
|
1789
|
-
status: 'pending',
|
|
1790
|
-
payload: payload,
|
|
1791
|
-
invalidate: () => {
|
|
1792
|
-
setSubmission(s => {
|
|
1793
|
-
s.isInvalid = true;
|
|
1794
|
-
});
|
|
1795
|
-
},
|
|
1796
|
-
getIsLatest: () => store.state.submissions[store.state.submissions.length - 1]?.submittedAt === submission.submittedAt
|
|
1797
|
-
};
|
|
1798
|
-
const setSubmission = updater => {
|
|
1799
|
-
store.setState(s => {
|
|
1800
|
-
const a = s.submissions.find(d => d.submittedAt === submission.submittedAt);
|
|
1801
|
-
invariant(a, 'Could not find submission in store');
|
|
1802
|
-
updater(a);
|
|
1803
|
-
});
|
|
1804
|
-
};
|
|
1805
|
-
store.setState(s => {
|
|
1806
|
-
s.submissions.push(submission);
|
|
1807
|
-
s.submissions.reverse();
|
|
1808
|
-
s.submissions = s.submissions.slice(0, options.maxSubmissions ?? 10);
|
|
1809
|
-
s.submissions.reverse();
|
|
1810
|
-
});
|
|
1811
|
-
const after = async () => {
|
|
1812
|
-
options.onEachSettled?.(submission);
|
|
1813
|
-
if (submission.getIsLatest()) await options.onLatestSettled?.(submission);
|
|
1814
|
-
};
|
|
1815
|
-
try {
|
|
1816
|
-
const res = await options.action?.(submission.payload);
|
|
1817
|
-
setSubmission(s => {
|
|
1818
|
-
s.response = res;
|
|
1819
|
-
});
|
|
1820
|
-
await options.onEachSuccess?.(submission);
|
|
1821
|
-
if (submission.getIsLatest()) await options.onLatestSuccess?.(submission);
|
|
1822
|
-
await after();
|
|
1823
|
-
setSubmission(s => {
|
|
1824
|
-
s.status = 'success';
|
|
1825
|
-
});
|
|
1826
|
-
return res;
|
|
1827
|
-
} catch (err) {
|
|
1828
|
-
console.error(err);
|
|
1829
|
-
setSubmission(s => {
|
|
1830
|
-
s.error = err;
|
|
1831
|
-
});
|
|
1832
|
-
await options.onEachError?.(submission);
|
|
1833
|
-
if (submission.getIsLatest()) await options.onLatestError?.(submission);
|
|
1834
|
-
await after();
|
|
1835
|
-
setSubmission(s => {
|
|
1836
|
-
s.status = 'error';
|
|
1837
|
-
});
|
|
1838
|
-
throw err;
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
};
|
|
1842
|
-
}
|
|
1514
|
+
/**
|
|
1515
|
+
* react-store
|
|
1516
|
+
*
|
|
1517
|
+
* Copyright (c) TanStack
|
|
1518
|
+
*
|
|
1519
|
+
* This source code is licensed under the MIT license found in the
|
|
1520
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
1521
|
+
*
|
|
1522
|
+
* @license MIT
|
|
1523
|
+
*/
|
|
1843
1524
|
|
|
1844
1525
|
function useStore(store, selector = d => d, compareShallow) {
|
|
1845
1526
|
const slice = withSelector.useSyncExternalStoreWithSelector(store.subscribe, () => store.state, () => store.state, selector, compareShallow ? shallow : undefined);
|
|
@@ -2066,12 +1747,6 @@
|
|
|
2066
1747
|
invariant(resolvedRoute, `Could not find a route for route "${routeId}"! Did you forget to add it to your route config?`);
|
|
2067
1748
|
return resolvedRoute;
|
|
2068
1749
|
}
|
|
2069
|
-
function useLoaderData(opts) {
|
|
2070
|
-
const match = useMatch(opts);
|
|
2071
|
-
invariant(match, `Could not find ${opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
|
|
2072
|
-
useStore(match.store, d => opts?.track?.(d.loaderData) ?? d.loaderData);
|
|
2073
|
-
return match.store.state.loaderData;
|
|
2074
|
-
}
|
|
2075
1750
|
function useSearch(opts) {
|
|
2076
1751
|
const match = useMatch(opts);
|
|
2077
1752
|
useStore(match.store, d => opts?.track?.(d.search) ?? d.search);
|
|
@@ -2144,7 +1819,7 @@
|
|
|
2144
1819
|
if (props.match.store.state.status === 'success') {
|
|
2145
1820
|
return /*#__PURE__*/React__namespace.createElement(props.match.component ?? router.options.defaultComponent ?? Outlet);
|
|
2146
1821
|
}
|
|
2147
|
-
if (props.match.store.state.status === '
|
|
1822
|
+
if (props.match.store.state.status === 'pending') {
|
|
2148
1823
|
throw props.match.__loadPromise;
|
|
2149
1824
|
}
|
|
2150
1825
|
invariant(false, 'Idle routeMatch status encountered during rendering! You should never see this. File an issue!');
|
|
@@ -2189,34 +1864,24 @@
|
|
|
2189
1864
|
// router's location key changes.
|
|
2190
1865
|
function CatchBoundaryInner(props) {
|
|
2191
1866
|
const [activeErrorState, setActiveErrorState] = React__namespace.useState(props.errorState);
|
|
2192
|
-
useRouter();
|
|
1867
|
+
const router = useRouter();
|
|
2193
1868
|
const errorComponent = props.errorComponent ?? DefaultErrorBoundary;
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
// }
|
|
2204
|
-
// })
|
|
2205
|
-
|
|
2206
|
-
// return dispose
|
|
2207
|
-
// })
|
|
2208
|
-
// }
|
|
2209
|
-
|
|
2210
|
-
// return
|
|
2211
|
-
// }, [activeErrorState])
|
|
2212
|
-
|
|
1869
|
+
const prevKeyRef = React__namespace.useRef('');
|
|
1870
|
+
React__namespace.useEffect(() => {
|
|
1871
|
+
if (activeErrorState) {
|
|
1872
|
+
if (router.store.state.currentLocation.key !== prevKeyRef.current) {
|
|
1873
|
+
setActiveErrorState({});
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
prevKeyRef.current = router.store.state.currentLocation.key;
|
|
1877
|
+
}, [activeErrorState, router.store.state.currentLocation.key]);
|
|
2213
1878
|
React__namespace.useEffect(() => {
|
|
2214
1879
|
if (props.errorState.error) {
|
|
2215
1880
|
setActiveErrorState(props.errorState);
|
|
2216
1881
|
}
|
|
2217
|
-
props.reset()
|
|
1882
|
+
// props.reset()
|
|
2218
1883
|
}, [props.errorState.error]);
|
|
2219
|
-
if (props.errorState.error) {
|
|
1884
|
+
if (props.errorState.error && activeErrorState.error) {
|
|
2220
1885
|
return /*#__PURE__*/React__namespace.createElement(errorComponent, activeErrorState);
|
|
2221
1886
|
}
|
|
2222
1887
|
return props.children;
|
|
@@ -2247,16 +1912,6 @@
|
|
|
2247
1912
|
}
|
|
2248
1913
|
}, error.message) : null)));
|
|
2249
1914
|
}
|
|
2250
|
-
function useAction(action, opts) {
|
|
2251
|
-
useStore(action.store, d => opts?.track?.(d) ?? d, true);
|
|
2252
|
-
const [ref] = React__namespace.useState({});
|
|
2253
|
-
Object.assign(ref, {
|
|
2254
|
-
...action,
|
|
2255
|
-
latestSubmission: action.store.state.submissions[action.store.state.submissions.length - 1],
|
|
2256
|
-
pendingSubmissions: React__namespace.useMemo(() => action.store.state.submissions.filter(d => d.status === 'pending'), [action.store.state.submissions])
|
|
2257
|
-
});
|
|
2258
|
-
return ref;
|
|
2259
|
-
}
|
|
2260
1915
|
|
|
2261
1916
|
// TODO: While we migrate away from the history package, these need to be disabled
|
|
2262
1917
|
// export function usePrompt(message: string, when: boolean | any): void {
|
|
@@ -2294,14 +1949,11 @@
|
|
|
2294
1949
|
exports.RouteMatch = RouteMatch;
|
|
2295
1950
|
exports.Router = Router;
|
|
2296
1951
|
exports.RouterProvider = RouterProvider;
|
|
2297
|
-
exports.batch = batch;
|
|
2298
1952
|
exports.cleanPath = cleanPath;
|
|
2299
|
-
exports.createAction = createAction;
|
|
2300
1953
|
exports.createBrowserHistory = createBrowserHistory;
|
|
2301
1954
|
exports.createHashHistory = createHashHistory;
|
|
2302
1955
|
exports.createMemoryHistory = createMemoryHistory;
|
|
2303
1956
|
exports.createRouteConfig = createRouteConfig;
|
|
2304
|
-
exports.createStore = createStore;
|
|
2305
1957
|
exports.decode = decode;
|
|
2306
1958
|
exports.defaultFetchServerDataFn = defaultFetchServerDataFn;
|
|
2307
1959
|
exports.defaultParseSearch = defaultParseSearch;
|
|
@@ -2310,6 +1962,7 @@
|
|
|
2310
1962
|
exports.functionalUpdate = functionalUpdate;
|
|
2311
1963
|
exports.interpolatePath = interpolatePath;
|
|
2312
1964
|
exports.invariant = invariant;
|
|
1965
|
+
exports.isPlainObject = isPlainObject;
|
|
2313
1966
|
exports.joinPaths = joinPaths;
|
|
2314
1967
|
exports.last = last;
|
|
2315
1968
|
exports.lazy = lazy;
|
|
@@ -2324,13 +1977,10 @@
|
|
|
2324
1977
|
exports.rootRouteId = rootRouteId;
|
|
2325
1978
|
exports.routerContext = routerContext;
|
|
2326
1979
|
exports.stringifySearchWith = stringifySearchWith;
|
|
2327
|
-
exports.trackDeep = trackDeep;
|
|
2328
1980
|
exports.trimPath = trimPath;
|
|
2329
1981
|
exports.trimPathLeft = trimPathLeft;
|
|
2330
1982
|
exports.trimPathRight = trimPathRight;
|
|
2331
|
-
exports.useAction = useAction;
|
|
2332
1983
|
exports.useLinkProps = useLinkProps;
|
|
2333
|
-
exports.useLoaderData = useLoaderData;
|
|
2334
1984
|
exports.useMatch = useMatch;
|
|
2335
1985
|
exports.useMatchRoute = useMatchRoute;
|
|
2336
1986
|
exports.useMatches = useMatches;
|