@tanstack/router-core
Advanced tools
Comparing version 0.0.1-beta.194 to 0.0.1-beta.195
@@ -80,3 +80,3 @@ /** | ||
queueTask(() => { | ||
opts.pushState(path, state); | ||
opts.pushState(path, state, onUpdate); | ||
}); | ||
@@ -87,3 +87,3 @@ }, | ||
queueTask(() => { | ||
opts.replaceState(path, state); | ||
opts.replaceState(path, state, onUpdate); | ||
}); | ||
@@ -120,3 +120,4 @@ }, | ||
}; | ||
} | ||
}, | ||
flush: () => opts.flush?.() | ||
}; | ||
@@ -134,15 +135,90 @@ } | ||
/** | ||
* Creates a history object that can be used to interact with the browser's | ||
* navigation. This is a lightweight API wrapping the browser's native methods. | ||
* It is designed to work with TanStack Router, but could be used as a standalone API as well. | ||
* IMPORTANT: This API implements history throttling via a microtask to prevent | ||
* excessive calls to the history API. In some browsers, calling history.pushState or | ||
* history.replaceState in quick succession can cause the browser to ignore subsequent | ||
* calls. This API smooths out those differences and ensures that your application | ||
* state will *eventually* match the browser state. In most cases, this is not a problem, | ||
* but if you need to ensure that the browser state is up to date, you can use the | ||
* `history.flush` method to immediately flush all pending state changes to the browser URL. | ||
* @param opts | ||
* @param opts.getHref A function that returns the current href (path + search + hash) | ||
* @param opts.createHref A function that takes a path and returns a href (path + search + hash) | ||
* @returns A history instance | ||
*/ | ||
function createBrowserHistory(opts) { | ||
const getHref = opts?.getHref ?? (() => `${window.location.pathname}${window.location.search}${window.location.hash}`); | ||
const createHref = opts?.createHref ?? (path => path); | ||
const getLocation = () => parseLocation(getHref(), window.history.state); | ||
let currentLocation = parseLocation(getHref(), window.history.state); | ||
const getLocation = () => currentLocation; | ||
let next; | ||
// Because we are proactively updating the location | ||
// in memory before actually updating the browser history, | ||
// we need to track when we are doing this so we don't | ||
// notify subscribers twice on the last update. | ||
let tracking = true; | ||
// We need to track the current scheduled update to prevent | ||
// multiple updates from being scheduled at the same time. | ||
let scheduled; | ||
// This function is a wrapper to prevent any of the callback's | ||
// side effects from causing a subscriber notification | ||
const untrack = fn => { | ||
tracking = false; | ||
fn(); | ||
tracking = true; | ||
}; | ||
// This function flushes the next update to the browser history | ||
const flush = () => { | ||
// Do not notify subscribers about this push/replace call | ||
untrack(() => { | ||
if (!next) return; | ||
window.history[next.isPush ? 'pushState' : 'replaceState'](next.state, '', next.href); | ||
// Reset the nextIsPush flag and clear the scheduled update | ||
next = undefined; | ||
scheduled = undefined; | ||
}); | ||
}; | ||
// This function queues up a call to update the browser history | ||
const queueHistoryAction = (type, path, state, onUpdate) => { | ||
const href = createHref(path); | ||
// Update the location in memory | ||
currentLocation = parseLocation(href, state); | ||
// Keep track of the next location we need to flush to the URL | ||
next = { | ||
href, | ||
state, | ||
isPush: next?.isPush || type === 'push' | ||
}; | ||
// Notify subscribers | ||
onUpdate(); | ||
if (!scheduled) { | ||
// Schedule an update to the browser history | ||
scheduled = Promise.resolve().then(() => flush()); | ||
} | ||
}; | ||
return createHistory({ | ||
getLocation, | ||
subscriber: onUpdate => { | ||
window.addEventListener(pushStateEvent, onUpdate); | ||
window.addEventListener(popStateEvent, onUpdate); | ||
window.addEventListener(pushStateEvent, () => { | ||
currentLocation = parseLocation(getHref(), window.history.state); | ||
onUpdate(); | ||
}); | ||
window.addEventListener(popStateEvent, () => { | ||
currentLocation = parseLocation(getHref(), window.history.state); | ||
onUpdate(); | ||
}); | ||
var pushState = window.history.pushState; | ||
window.history.pushState = function () { | ||
let res = pushState.apply(history, arguments); | ||
onUpdate(); | ||
if (tracking) onUpdate(); | ||
return res; | ||
@@ -153,3 +229,3 @@ }; | ||
let res = replaceState.apply(history, arguments); | ||
onUpdate(); | ||
if (tracking) onUpdate(); | ||
return res; | ||
@@ -164,12 +240,9 @@ }; | ||
}, | ||
pushState: (path, state) => { | ||
window.history.pushState(state, '', createHref(path)); | ||
}, | ||
replaceState: (path, state) => { | ||
window.history.replaceState(state, '', createHref(path)); | ||
}, | ||
pushState: (path, state, onUpdate) => queueHistoryAction('push', path, state, onUpdate), | ||
replaceState: (path, state, onUpdate) => queueHistoryAction('replace', path, state, onUpdate), | ||
back: () => window.history.back(), | ||
forward: () => window.history.forward(), | ||
go: n => window.history.go(n), | ||
createHref: path => createHref(path) | ||
createHref: path => createHref(path), | ||
flush | ||
}); | ||
@@ -176,0 +249,0 @@ } |
@@ -15,2 +15,4 @@ /** | ||
// export type Expand<T> = T | ||
// type Compute<T> = { [K in keyof T]: T[K] } | never | ||
@@ -17,0 +19,0 @@ |
@@ -14,11 +14,11 @@ { | ||
"name": "tiny-invariant@1.3.1/node_modules/tiny-invariant/dist/esm/tiny-invariant.js", | ||
"uid": "f4cb-31" | ||
"uid": "435c-31" | ||
}, | ||
{ | ||
"name": "tiny-warning@1.0.3/node_modules/tiny-warning/dist/tiny-warning.esm.js", | ||
"uid": "f4cb-33" | ||
"uid": "435c-33" | ||
}, | ||
{ | ||
"name": "@tanstack+store@0.0.1/node_modules/@tanstack/store/build/esm/index.js", | ||
"uid": "f4cb-47" | ||
"uid": "435c-47" | ||
} | ||
@@ -31,43 +31,43 @@ ] | ||
{ | ||
"uid": "f4cb-35", | ||
"uid": "435c-35", | ||
"name": "history.ts" | ||
}, | ||
{ | ||
"uid": "f4cb-37", | ||
"uid": "435c-37", | ||
"name": "utils.ts" | ||
}, | ||
{ | ||
"uid": "f4cb-39", | ||
"uid": "435c-39", | ||
"name": "path.ts" | ||
}, | ||
{ | ||
"uid": "f4cb-41", | ||
"uid": "435c-41", | ||
"name": "qss.ts" | ||
}, | ||
{ | ||
"uid": "f4cb-43", | ||
"uid": "435c-43", | ||
"name": "route.ts" | ||
}, | ||
{ | ||
"uid": "f4cb-45", | ||
"uid": "435c-45", | ||
"name": "fileRoute.ts" | ||
}, | ||
{ | ||
"uid": "f4cb-49", | ||
"uid": "435c-49", | ||
"name": "searchParams.ts" | ||
}, | ||
{ | ||
"uid": "f4cb-51", | ||
"uid": "435c-51", | ||
"name": "router.ts" | ||
}, | ||
{ | ||
"uid": "f4cb-53", | ||
"uid": "435c-53", | ||
"name": "scroll-restoration.ts" | ||
}, | ||
{ | ||
"uid": "f4cb-55", | ||
"uid": "435c-55", | ||
"name": "defer.ts" | ||
}, | ||
{ | ||
"uid": "f4cb-57", | ||
"uid": "435c-57", | ||
"name": "index.ts" | ||
@@ -83,92 +83,92 @@ } | ||
"nodeParts": { | ||
"f4cb-31": { | ||
"435c-31": { | ||
"renderedLength": 199, | ||
"gzipLength": 134, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-30" | ||
"mainUid": "435c-30" | ||
}, | ||
"f4cb-33": { | ||
"435c-33": { | ||
"renderedLength": 48, | ||
"gzipLength": 65, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-32" | ||
"mainUid": "435c-32" | ||
}, | ||
"f4cb-35": { | ||
"renderedLength": 6556, | ||
"gzipLength": 1615, | ||
"435c-35": { | ||
"renderedLength": 9853, | ||
"gzipLength": 2695, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-34" | ||
"mainUid": "435c-34" | ||
}, | ||
"f4cb-37": { | ||
"renderedLength": 3236, | ||
"gzipLength": 1130, | ||
"435c-37": { | ||
"renderedLength": 3270, | ||
"gzipLength": 1141, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-36" | ||
"mainUid": "435c-36" | ||
}, | ||
"f4cb-39": { | ||
"435c-39": { | ||
"renderedLength": 6028, | ||
"gzipLength": 1423, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-38" | ||
"mainUid": "435c-38" | ||
}, | ||
"f4cb-41": { | ||
"435c-41": { | ||
"renderedLength": 1371, | ||
"gzipLength": 552, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-40" | ||
"mainUid": "435c-40" | ||
}, | ||
"f4cb-43": { | ||
"435c-43": { | ||
"renderedLength": 2598, | ||
"gzipLength": 916, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-42" | ||
"mainUid": "435c-42" | ||
}, | ||
"f4cb-45": { | ||
"435c-45": { | ||
"renderedLength": 223, | ||
"gzipLength": 143, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-44" | ||
"mainUid": "435c-44" | ||
}, | ||
"f4cb-47": { | ||
"435c-47": { | ||
"renderedLength": 1969, | ||
"gzipLength": 653, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-46" | ||
"mainUid": "435c-46" | ||
}, | ||
"f4cb-49": { | ||
"435c-49": { | ||
"renderedLength": 1826, | ||
"gzipLength": 579, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-48" | ||
"mainUid": "435c-48" | ||
}, | ||
"f4cb-51": { | ||
"435c-51": { | ||
"renderedLength": 45441, | ||
"gzipLength": 10068, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-50" | ||
"mainUid": "435c-50" | ||
}, | ||
"f4cb-53": { | ||
"435c-53": { | ||
"renderedLength": 4436, | ||
"gzipLength": 1192, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-52" | ||
"mainUid": "435c-52" | ||
}, | ||
"f4cb-55": { | ||
"435c-55": { | ||
"renderedLength": 682, | ||
"gzipLength": 314, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-54" | ||
"mainUid": "435c-54" | ||
}, | ||
"f4cb-57": { | ||
"435c-57": { | ||
"renderedLength": 0, | ||
"gzipLength": 0, | ||
"brotliLength": 0, | ||
"mainUid": "f4cb-56" | ||
"mainUid": "435c-56" | ||
} | ||
}, | ||
"nodeMetas": { | ||
"f4cb-30": { | ||
"435c-30": { | ||
"id": "/node_modules/.pnpm/tiny-invariant@1.3.1/node_modules/tiny-invariant/dist/esm/tiny-invariant.js", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-31" | ||
"index.production.js": "435c-31" | ||
}, | ||
@@ -178,16 +178,16 @@ "imported": [], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
}, | ||
{ | ||
"uid": "f4cb-42" | ||
"uid": "435c-42" | ||
}, | ||
{ | ||
"uid": "f4cb-50" | ||
"uid": "435c-50" | ||
} | ||
] | ||
}, | ||
"f4cb-32": { | ||
"435c-32": { | ||
"id": "/node_modules/.pnpm/tiny-warning@1.0.3/node_modules/tiny-warning/dist/tiny-warning.esm.js", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-33" | ||
"index.production.js": "435c-33" | ||
}, | ||
@@ -197,10 +197,10 @@ "imported": [], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
} | ||
] | ||
}, | ||
"f4cb-34": { | ||
"435c-34": { | ||
"id": "/packages/router-core/src/history.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-35" | ||
"index.production.js": "435c-35" | ||
}, | ||
@@ -210,13 +210,13 @@ "imported": [], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
}, | ||
{ | ||
"uid": "f4cb-50" | ||
"uid": "435c-50" | ||
} | ||
] | ||
}, | ||
"f4cb-36": { | ||
"435c-36": { | ||
"id": "/packages/router-core/src/utils.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-37" | ||
"index.production.js": "435c-37" | ||
}, | ||
@@ -226,20 +226,20 @@ "imported": [], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
}, | ||
{ | ||
"uid": "f4cb-38" | ||
"uid": "435c-38" | ||
}, | ||
{ | ||
"uid": "f4cb-50" | ||
"uid": "435c-50" | ||
} | ||
] | ||
}, | ||
"f4cb-38": { | ||
"435c-38": { | ||
"id": "/packages/router-core/src/path.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-39" | ||
"index.production.js": "435c-39" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "f4cb-36" | ||
"uid": "435c-36" | ||
} | ||
@@ -249,16 +249,16 @@ ], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
}, | ||
{ | ||
"uid": "f4cb-42" | ||
"uid": "435c-42" | ||
}, | ||
{ | ||
"uid": "f4cb-50" | ||
"uid": "435c-50" | ||
} | ||
] | ||
}, | ||
"f4cb-40": { | ||
"435c-40": { | ||
"id": "/packages/router-core/src/qss.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-41" | ||
"index.production.js": "435c-41" | ||
}, | ||
@@ -268,20 +268,20 @@ "imported": [], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
}, | ||
{ | ||
"uid": "f4cb-48" | ||
"uid": "435c-48" | ||
} | ||
] | ||
}, | ||
"f4cb-42": { | ||
"435c-42": { | ||
"id": "/packages/router-core/src/route.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-43" | ||
"index.production.js": "435c-43" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "f4cb-30" | ||
"uid": "435c-30" | ||
}, | ||
{ | ||
"uid": "f4cb-38" | ||
"uid": "435c-38" | ||
} | ||
@@ -291,17 +291,17 @@ ], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
}, | ||
{ | ||
"uid": "f4cb-44" | ||
"uid": "435c-44" | ||
} | ||
] | ||
}, | ||
"f4cb-44": { | ||
"435c-44": { | ||
"id": "/packages/router-core/src/fileRoute.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-45" | ||
"index.production.js": "435c-45" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "f4cb-42" | ||
"uid": "435c-42" | ||
} | ||
@@ -311,10 +311,10 @@ ], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
} | ||
] | ||
}, | ||
"f4cb-46": { | ||
"435c-46": { | ||
"id": "/node_modules/.pnpm/@tanstack+store@0.0.1/node_modules/@tanstack/store/build/esm/index.js", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-47" | ||
"index.production.js": "435c-47" | ||
}, | ||
@@ -324,14 +324,14 @@ "imported": [], | ||
{ | ||
"uid": "f4cb-50" | ||
"uid": "435c-50" | ||
} | ||
] | ||
}, | ||
"f4cb-48": { | ||
"435c-48": { | ||
"id": "/packages/router-core/src/searchParams.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-49" | ||
"index.production.js": "435c-49" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "f4cb-40" | ||
"uid": "435c-40" | ||
} | ||
@@ -341,32 +341,32 @@ ], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
}, | ||
{ | ||
"uid": "f4cb-50" | ||
"uid": "435c-50" | ||
} | ||
] | ||
}, | ||
"f4cb-50": { | ||
"435c-50": { | ||
"id": "/packages/router-core/src/router.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-51" | ||
"index.production.js": "435c-51" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "f4cb-46" | ||
"uid": "435c-46" | ||
}, | ||
{ | ||
"uid": "f4cb-30" | ||
"uid": "435c-30" | ||
}, | ||
{ | ||
"uid": "f4cb-38" | ||
"uid": "435c-38" | ||
}, | ||
{ | ||
"uid": "f4cb-48" | ||
"uid": "435c-48" | ||
}, | ||
{ | ||
"uid": "f4cb-36" | ||
"uid": "435c-36" | ||
}, | ||
{ | ||
"uid": "f4cb-34" | ||
"uid": "435c-34" | ||
} | ||
@@ -376,10 +376,10 @@ ], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
} | ||
] | ||
}, | ||
"f4cb-52": { | ||
"435c-52": { | ||
"id": "/packages/router-core/src/scroll-restoration.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-53" | ||
"index.production.js": "435c-53" | ||
}, | ||
@@ -389,10 +389,10 @@ "imported": [], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
} | ||
] | ||
}, | ||
"f4cb-54": { | ||
"435c-54": { | ||
"id": "/packages/router-core/src/defer.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-55" | ||
"index.production.js": "435c-55" | ||
}, | ||
@@ -402,53 +402,53 @@ "imported": [], | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
} | ||
] | ||
}, | ||
"f4cb-56": { | ||
"435c-56": { | ||
"id": "/packages/router-core/src/index.ts", | ||
"moduleParts": { | ||
"index.production.js": "f4cb-57" | ||
"index.production.js": "435c-57" | ||
}, | ||
"imported": [ | ||
{ | ||
"uid": "f4cb-30" | ||
"uid": "435c-30" | ||
}, | ||
{ | ||
"uid": "f4cb-32" | ||
"uid": "435c-32" | ||
}, | ||
{ | ||
"uid": "f4cb-34" | ||
"uid": "435c-34" | ||
}, | ||
{ | ||
"uid": "f4cb-58" | ||
"uid": "435c-58" | ||
}, | ||
{ | ||
"uid": "f4cb-38" | ||
"uid": "435c-38" | ||
}, | ||
{ | ||
"uid": "f4cb-40" | ||
"uid": "435c-40" | ||
}, | ||
{ | ||
"uid": "f4cb-42" | ||
"uid": "435c-42" | ||
}, | ||
{ | ||
"uid": "f4cb-44" | ||
"uid": "435c-44" | ||
}, | ||
{ | ||
"uid": "f4cb-59" | ||
"uid": "435c-59" | ||
}, | ||
{ | ||
"uid": "f4cb-50" | ||
"uid": "435c-50" | ||
}, | ||
{ | ||
"uid": "f4cb-48" | ||
"uid": "435c-48" | ||
}, | ||
{ | ||
"uid": "f4cb-36" | ||
"uid": "435c-36" | ||
}, | ||
{ | ||
"uid": "f4cb-52" | ||
"uid": "435c-52" | ||
}, | ||
{ | ||
"uid": "f4cb-54" | ||
"uid": "435c-54" | ||
} | ||
@@ -459,3 +459,3 @@ ], | ||
}, | ||
"f4cb-58": { | ||
"435c-58": { | ||
"id": "/packages/router-core/src/link.ts", | ||
@@ -466,7 +466,7 @@ "moduleParts": {}, | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
} | ||
] | ||
}, | ||
"f4cb-59": { | ||
"435c-59": { | ||
"id": "/packages/router-core/src/routeInfo.ts", | ||
@@ -477,3 +477,3 @@ "moduleParts": {}, | ||
{ | ||
"uid": "f4cb-56" | ||
"uid": "435c-56" | ||
} | ||
@@ -480,0 +480,0 @@ ] |
@@ -11,2 +11,3 @@ export interface RouterHistory { | ||
block: (blockerFn: BlockerFn) => () => void; | ||
flush: () => void; | ||
} | ||
@@ -28,2 +29,18 @@ export interface HistoryLocation extends ParsedPath { | ||
type BlockerFn = (retry: () => void, cancel: () => void) => void; | ||
/** | ||
* Creates a history object that can be used to interact with the browser's | ||
* navigation. This is a lightweight API wrapping the browser's native methods. | ||
* It is designed to work with TanStack Router, but could be used as a standalone API as well. | ||
* IMPORTANT: This API implements history throttling via a microtask to prevent | ||
* excessive calls to the history API. In some browsers, calling history.pushState or | ||
* history.replaceState in quick succession can cause the browser to ignore subsequent | ||
* calls. This API smooths out those differences and ensures that your application | ||
* state will *eventually* match the browser state. In most cases, this is not a problem, | ||
* but if you need to ensure that the browser state is up to date, you can use the | ||
* `history.flush` method to immediately flush all pending state changes to the browser URL. | ||
* @param opts | ||
* @param opts.getHref A function that returns the current href (path + search + hash) | ||
* @param opts.createHref A function that takes a path and returns a href (path + search + hash) | ||
* @returns A history instance | ||
*/ | ||
export declare function createBrowserHistory(opts?: { | ||
@@ -30,0 +47,0 @@ getHref?: () => string; |
@@ -14,30 +14,30 @@ import { RoutePaths } from './routeInfo'; | ||
} | ||
export interface RegisterRouteComponent<TLoader = unknown, TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> { | ||
export interface RegisterRouteComponent<TLoader = unknown, TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> { | ||
} | ||
export interface RegisterErrorRouteComponent<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> { | ||
export interface RegisterErrorRouteComponent<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> { | ||
} | ||
export interface RegisterPendingRouteComponent<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> { | ||
export interface RegisterPendingRouteComponent<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> { | ||
} | ||
export interface RegisterRouteProps<TLoader = unknown, TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> { | ||
export interface RegisterRouteProps<TLoader = unknown, TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> { | ||
} | ||
export interface RegisterErrorRouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> { | ||
export interface RegisterErrorRouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> { | ||
} | ||
export interface RegisterPendingRouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> { | ||
export interface RegisterPendingRouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> { | ||
} | ||
export type RegisteredRouteComponent<TLoader = unknown, TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> = RegisterRouteComponent<TLoader, TFullSearchSchema, TAllParams, TRouteContext, TAllContext> extends { | ||
export type RegisteredRouteComponent<TLoader = unknown, TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> = RegisterRouteComponent<TLoader, TFullSearchSchema, TAllParams, TAllContext> extends { | ||
RouteComponent: infer T; | ||
} ? T : () => unknown; | ||
export type RegisteredErrorRouteComponent<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> = RegisterErrorRouteComponent<TFullSearchSchema, TAllParams, TRouteContext, TAllContext> extends { | ||
export type RegisteredErrorRouteComponent<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> = RegisterErrorRouteComponent<TFullSearchSchema, TAllParams, TAllContext> extends { | ||
ErrorRouteComponent: infer T; | ||
} ? T : () => unknown; | ||
export type RegisteredPendingRouteComponent<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> = RegisterPendingRouteComponent<TFullSearchSchema, TAllParams, TRouteContext, TAllContext> extends { | ||
export type RegisteredPendingRouteComponent<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> = RegisterPendingRouteComponent<TFullSearchSchema, TAllParams, TAllContext> extends { | ||
PendingRouteComponent: infer T; | ||
} ? T : () => unknown; | ||
export type RegisteredRouteProps<TLoader = unknown, TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> = RegisterRouteProps<TLoader, TFullSearchSchema, TAllParams, TRouteContext, TAllContext> extends { | ||
export type RegisteredRouteProps<TLoader = unknown, TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> = RegisterRouteProps<TLoader, TFullSearchSchema, TAllParams, TAllContext> extends { | ||
RouteProps: infer T; | ||
} ? T : {}; | ||
export type RegisteredErrorRouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> = RegisterRouteProps<TFullSearchSchema, TAllParams, TRouteContext, TAllContext> extends { | ||
export type RegisteredErrorRouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> = RegisterRouteProps<TFullSearchSchema, TAllParams, TAllContext> extends { | ||
ErrorRouteProps: infer T; | ||
} ? T : {}; | ||
export type RegisteredPendingRouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TRouteContext extends Record<string, any> = AnyContext, TAllContext extends Record<string, any> = AnyContext> = RegisterRouteProps<TFullSearchSchema, TAllParams, TRouteContext, TAllContext> extends { | ||
export type RegisteredPendingRouteProps<TFullSearchSchema extends Record<string, any> = AnySearchSchema, TAllParams extends AnyPathParams = AnyPathParams, TAllContext extends Record<string, any> = AnyContext> = RegisterRouteProps<TFullSearchSchema, TAllParams, TAllContext> extends { | ||
PendingRouteProps: infer T; | ||
@@ -59,4 +59,4 @@ } ? T : {}; | ||
}; | ||
export type AnyRouteProps = RegisteredRouteProps<any, any, any, any, any>; | ||
export type RouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TLoaderContext extends Record<string, any> = AnyContext, TLoader = unknown, TSearchSchema extends Record<string, any> = {}, TFullSearchSchema extends Record<string, any> = TSearchSchema, TParams extends AnyPathParams = AnyPathParams, TAllParams extends AnyPathParams = TParams, TRouteContext extends RouteContext = RouteContext, TAllContext extends Record<string, any> = AnyContext> = BaseRouteOptions<TParentRoute, TCustomId, TPath, TLoaderContext, TLoader, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext> & UpdatableRouteOptions<TLoader, TSearchSchema, TFullSearchSchema, TAllParams, TRouteContext, TAllContext>; | ||
export type AnyRouteProps = RegisteredRouteProps<any, any, any, any>; | ||
export type RouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TLoaderContext extends Record<string, any> = AnyContext, TLoader = unknown, TSearchSchema extends Record<string, any> = {}, TFullSearchSchema extends Record<string, any> = TSearchSchema, TParams extends AnyPathParams = AnyPathParams, TAllParams extends AnyPathParams = TParams, TRouteContext extends RouteContext = RouteContext, TAllContext extends Record<string, any> = AnyContext> = BaseRouteOptions<TParentRoute, TCustomId, TPath, TLoaderContext, TLoader, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext> & UpdatableRouteOptions<TLoader, TFullSearchSchema, TAllParams, TAllContext>; | ||
export type ParamsFallback<TPath extends string, TParams> = unknown extends TParams ? Record<ParsePathParams<TPath>, string> : TParams; | ||
@@ -90,8 +90,8 @@ export type BaseRouteOptions<TParentRoute extends AnyRoute = AnyRoute, TCustomId extends string = string, TPath extends string = string, TLoaderContext extends Record<string, any> = AnyContext, TLoader = unknown, TSearchSchema extends Record<string, any> = {}, TFullSearchSchema extends Record<string, any> = TSearchSchema, TParams extends AnyPathParams = {}, TAllParams = ParamsFallback<TPath, TParams>, TRouteContext extends RouteContext = RouteContext, TAllContext extends Record<string, any> = AnyContext> = RoutePathOptions<TCustomId, TPath> & { | ||
}) => Promise<TRouteContext> | TRouteContext | void; | ||
export type UpdatableRouteOptions<TLoader, TSearchSchema extends Record<string, any>, TFullSearchSchema extends Record<string, any>, TAllParams extends AnyPathParams, TRouteContext extends Record<string, any>, TAllContext extends Record<string, any>> = MetaOptions & { | ||
export type UpdatableRouteOptions<TLoader, TFullSearchSchema extends Record<string, any>, TAllParams extends AnyPathParams, TAllContext extends Record<string, any>> = MetaOptions & { | ||
caseSensitive?: boolean; | ||
wrapInSuspense?: boolean; | ||
component?: RegisteredRouteComponent<TLoader, TFullSearchSchema, TAllParams, TRouteContext, TAllContext>; | ||
errorComponent?: RegisteredErrorRouteComponent<TFullSearchSchema, TAllParams, TRouteContext, TAllContext>; | ||
pendingComponent?: RegisteredPendingRouteComponent<TFullSearchSchema, TAllParams, TRouteContext, TAllContext>; | ||
component?: RegisteredRouteComponent<TLoader, TFullSearchSchema, TAllParams, TAllContext>; | ||
errorComponent?: RegisteredErrorRouteComponent<TFullSearchSchema, TAllParams, TAllContext>; | ||
pendingComponent?: RegisteredPendingRouteComponent<TFullSearchSchema, TAllParams, TAllContext>; | ||
preSearchFilters?: SearchFilter<TFullSearchSchema>[]; | ||
@@ -129,3 +129,3 @@ postSearchFilters?: SearchFilter<TFullSearchSchema>[]; | ||
params: TAllParams; | ||
context: DeepMergeAll<[TAllContext, TLoaderContext, TRouteContext]>; | ||
context: Expand<DeepMergeAll<[TAllContext, TLoaderContext, TRouteContext]>>; | ||
} | ||
@@ -205,3 +205,3 @@ export type SearchFilter<T, U = T> = (prev: T) => U; | ||
rank: number; | ||
constructor(options: RouteOptions<TParentRoute, TCustomId, TPath, TLoaderContext, TLoader, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext> & UpdatableRouteOptions<TLoader, TSearchSchema, TFullSearchSchema, TAllParams, TRouteContext, TAllContext>); | ||
constructor(options: RouteOptions<TParentRoute, TCustomId, TPath, TLoaderContext, TLoader, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext> & UpdatableRouteOptions<TLoader, TFullSearchSchema, TAllParams, TAllContext>); | ||
init: (opts: { | ||
@@ -212,3 +212,3 @@ originalIndex: number; | ||
addChildren: <TNewChildren extends AnyRoute[]>(children: TNewChildren) => Route<TParentRoute, TPath, TFullPath, TCustomId, TId, TLoaderContext, TLoader, TSearchSchema, TFullSearchSchema, TParams, TAllParams, TRouteContext, TAllContext, TRouterContext, TNewChildren, TRouteTree>; | ||
update: (options: UpdatableRouteOptions<TLoader, TSearchSchema, TFullSearchSchema, TAllParams, TRouteContext, TAllContext>) => this; | ||
update: (options: UpdatableRouteOptions<TLoader, TFullSearchSchema, TAllParams, TAllContext>) => this; | ||
static __onInit: (route: any) => void; | ||
@@ -215,0 +215,0 @@ } |
@@ -21,3 +21,3 @@ import { AnyRoute, Route } from './route'; | ||
export type RoutePaths<TRouteTree extends AnyRoute> = ParseRoute<TRouteTree>['fullPath'] | '/'; | ||
export type FullSearchSchema<TRouteTree extends AnyRoute> = Partial<Expand<UnionToIntersection<ParseRoute<TRouteTree>['types']['fullSearchSchema']> & {}>>; | ||
export type FullSearchSchema<TRouteTree extends AnyRoute> = Partial<Expand<UnionToIntersection<ParseRoute<TRouteTree>['types']['fullSearchSchema']>>>; | ||
export type AllParams<TRouteTree extends AnyRoute> = Expand<UnionToIntersection<ParseRoute<TRouteTree>['types']['allParams']>>; |
@@ -78,5 +78,5 @@ import { Store } from '@tanstack/store'; | ||
reloadOnWindowFocus?: boolean; | ||
defaultComponent?: RegisteredRouteComponent<unknown, AnySearchSchema, AnyPathParams, AnyContext, AnyContext>; | ||
defaultErrorComponent?: RegisteredErrorRouteComponent<AnySearchSchema, AnyPathParams, AnyContext, AnyContext>; | ||
defaultPendingComponent?: RegisteredPendingRouteComponent<AnySearchSchema, AnyPathParams, AnyContext, AnyContext>; | ||
defaultComponent?: RegisteredRouteComponent<unknown, AnySearchSchema, AnyPathParams, AnyContext>; | ||
defaultErrorComponent?: RegisteredErrorRouteComponent<AnySearchSchema, AnyPathParams, AnyContext>; | ||
defaultPendingComponent?: RegisteredPendingRouteComponent<AnySearchSchema, AnyPathParams, AnyContext>; | ||
defaultMaxAge?: number; | ||
@@ -83,0 +83,0 @@ defaultGcMaxAge?: number; |
@@ -11,3 +11,3 @@ /** | ||
*/ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).RouterCore={})}(this,(function(t){"use strict";function e(t,e){if(!t)throw new Error("Invariant failed")}const s="pushstate",o="popstate",r="beforeunload",a=t=>(t.preventDefault(),t.returnValue=""),n=()=>{removeEventListener(r,a,{capture:!0})};function i(t){let e=t.getLocation(),s=()=>{},o=new Set,i=[],h=[];const d=()=>{if(i.length)i[0]?.(d,(()=>{i=[],n()}));else{for(;h.length;)h.shift()?.();t.subscriber||u()}},l=t=>{h.push(t),d()},u=()=>{e=t.getLocation(),o.forEach((t=>t()))};return{get location(){return e},subscribe:e=>(0===o.size&&(s="function"==typeof t.subscriber?t.subscriber(u):()=>{}),o.add(e),()=>{o.delete(e),0===o.size&&s()}),push:(e,s)=>{c(s),l((()=>{t.pushState(e,s)}))},replace:(e,s)=>{c(s),l((()=>{t.replaceState(e,s)}))},go:e=>{l((()=>{t.go(e)}))},back:()=>{l((()=>{t.back()}))},forward:()=>{l((()=>{t.forward()}))},createHref:e=>t.createHref(e),block:t=>(i.push(t),1===i.length&&addEventListener(r,a,{capture:!0}),()=>{i=i.filter((e=>e!==t)),i.length||n()})}}function c(t){t.key=u()}function h(t){const e=t?.getHref??(()=>`${window.location.pathname}${window.location.search}${window.location.hash}`),r=t?.createHref??(t=>t);return i({getLocation:()=>l(e(),window.history.state),subscriber:t=>{window.addEventListener(s,t),window.addEventListener(o,t);var e=window.history.pushState;window.history.pushState=function(){let s=e.apply(history,arguments);return t(),s};var r=window.history.replaceState;return window.history.replaceState=function(){let e=r.apply(history,arguments);return t(),e},()=>{window.history.pushState=e,window.history.replaceState=r,window.removeEventListener(s,t),window.removeEventListener(o,t)}},pushState:(t,e)=>{window.history.pushState(e,"",r(t))},replaceState:(t,e)=>{window.history.replaceState(e,"",r(t))},back:()=>window.history.back(),forward:()=>window.history.forward(),go:t=>window.history.go(t),createHref:t=>r(t)})}function d(t={initialEntries:["/"]}){const e=t.initialEntries;let s=t.initialIndex??e.length-1,o={key:u()};return i({getLocation:()=>l(e[s],o),subscriber:!1,pushState:(t,r)=>{o=r,e.push(t),s++},replaceState:(t,r)=>{o=r,e[s]=t},back:()=>{s--},forward:()=>{s=Math.min(s+1,e.length-1)},go:t=>window.history.go(t),createHref:t=>t})}function l(t,e){let s=t.indexOf("#"),o=t.indexOf("?");return{href:t,pathname:t.substring(0,s>0?o>0?Math.min(s,o):s:o>0?o:t.length),hash:s>-1?t.substring(s):"",search:o>-1?t.slice(o,-1===s?void 0:s):"",state:e||{}}}function u(){return(Math.random()+1).toString(36).substring(7)}function p(t){return t[t.length-1]}function f(t,e){return"function"==typeof t?t(e):t}function m(t,e){return e.reduce(((e,s)=>(e[s]=t[s],e)),{})}function y(t,e){if(t===e)return t;const s=e,o=Array.isArray(t)&&Array.isArray(s);if(o||g(t)&&g(s)){const e=o?t.length:Object.keys(t).length,r=o?s:Object.keys(s),a=r.length,n=o?[]:{};let i=0;for(let e=0;e<a;e++){const a=o?e:r[e];n[a]=y(t[a],s[a]),n[a]===t[a]&&i++}return e===a&&i===e?t:n}return s}function g(t){if(!w(t))return!1;const e=t.constructor;if(void 0===e)return!0;const s=e.prototype;return!!w(s)&&!!s.hasOwnProperty("isPrototypeOf")}function w(t){return"[object Object]"===Object.prototype.toString.call(t)}function v(t,e){return t===e||typeof t==typeof e&&(g(t)&&g(e)?!Object.keys(e).some((s=>!v(t[s],e[s]))):!(!Array.isArray(t)||!Array.isArray(e))&&(t.length===e.length&&t.every(((t,s)=>v(t,e[s])))))}function _(t){return b(t.filter(Boolean).join("/"))}function b(t){return t.replace(/\/{2,}/g,"/")}function S(t){return"/"===t?t:t.replace(/^\/{1,}/,"")}function R(t){return"/"===t?t:t.replace(/\/{1,}$/,"")}function I(t){return R(S(t))}function M(t,e,s){e=e.replace(new RegExp(`^${t}`),"/"),s=s.replace(new RegExp(`^${t}`),"/");let o=x(e);const r=x(s);r.forEach(((t,e)=>{if("/"===t.value)e?e===r.length-1&&o.push(t):o=[t];else if(".."===t.value)o.length>1&&"/"===p(o)?.value&&o.pop(),o.pop();else{if("."===t.value)return;o.push(t)}}));return b(_([t,...o.map((t=>t.value))]))}function x(t){if(!t)return[];const e=[];if("/"===(t=b(t)).slice(0,1)&&(t=t.substring(1),e.push({type:"pathname",value:"/"})),!t)return e;const s=t.split("/").filter(Boolean);return e.push(...s.map((t=>"$"===t||"*"===t?{type:"wildcard",value:t}:"$"===t.charAt(0)?{type:"param",value:t}:{type:"pathname",value:t}))),"/"===t.slice(-1)&&(t=t.substring(1),e.push({type:"pathname",value:"/"})),e}function E(t,e,s=!1){return _(x(t).map((t=>{if("wildcard"===t.type){const o=e[t.value];return s?`${t.value}${o??""}`:o}return"param"===t.type?e[t.value.substring(1)]??"":t.value})))}function L(t,e,s){const o=P(t,e,s);if(!s.to||o)return o??{}}function P(t,e,s){e="/"!=t?e.substring(t.length):e;const o=`${s.to??"$"}`,r=x(e),a=x(o);e.startsWith("/")||r.unshift({type:"pathname",value:"/"}),o.startsWith("/")||a.unshift({type:"pathname",value:"/"});const n={};return(()=>{for(let t=0;t<Math.max(r.length,a.length);t++){const e=r[t],o=a[t],i=t>=r.length-1,c=t>=a.length-1;if(o){if("wildcard"===o.type)return!!e?.value&&(n["*"]=_(r.slice(t).map((t=>t.value))),!0);if("pathname"===o.type){if("/"===o.value&&!e?.value)return!0;if(e)if(s.caseSensitive){if(o.value!==e.value)return!1}else if(o.value.toLowerCase()!==e.value.toLowerCase())return!1}if(!e)return!1;if("param"===o.type){if("/"===e?.value)return!1;"$"!==e.value.charAt(0)&&(n[o.value.substring(1)]=e.value)}}if(!i&&c)return!!s.fuzzy}return!0})()?n:void 0}function A(t,e){var s,o,r,a="";for(s in t)if(void 0!==(r=t[s]))if(Array.isArray(r))for(o=0;o<r.length;o++)a&&(a+="&"),a+=encodeURIComponent(s)+"="+encodeURIComponent(r[o]);else a&&(a+="&"),a+=encodeURIComponent(s)+"="+encodeURIComponent(r);return(e||"")+a}function O(t){if(!t)return"";var e=decodeURIComponent(t);return"false"!==e&&("true"===e||(0*+e==0&&+e+""===e?+e:e))}function D(t){for(var e,s,o={},r=t.split("&");e=r.shift();)void 0!==o[s=(e=e.split("=")).shift()]?o[s]=[].concat(o[s],O(e.shift())):o[s]=O(e.shift());return o}const B="__root__";class C{constructor(t){this.options=t||{},this.isRoot=!t?.getParentRoute,C.__onInit(this)}init=t=>{this.originalIndex=t.originalIndex,this.router=t.router;const s=this.options,o=!s?.path&&!s?.id;this.parentRoute=this.options?.getParentRoute?.(),o?this.path=B:e(this.parentRoute);let r=o?B:s.path;r&&"/"!==r&&(r=I(r));const a=s?.id||r;let n=o?B:_([this.parentRoute.id===B?"":this.parentRoute.id,a]);r===B&&(r="/"),n!==B&&(n=_(["/",n]));const i=n===B?"/":_([this.parentRoute.fullPath,r]);this.path=r,this.id=n,this.fullPath=i,this.to=i};addChildren=t=>(this.children=t,this);update=t=>(Object.assign(this.options,t),this);static __onInit=t=>{}}class $ extends C{constructor(t){super(t)}} | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).RouterCore={})}(this,(function(t){"use strict";function e(t,e){if(!t)throw new Error("Invariant failed")}const s="pushstate",o="popstate",r="beforeunload",a=t=>(t.preventDefault(),t.returnValue=""),n=()=>{removeEventListener(r,a,{capture:!0})};function i(t){let e=t.getLocation(),s=()=>{},o=new Set,i=[],h=[];const d=()=>{if(i.length)i[0]?.(d,(()=>{i=[],n()}));else{for(;h.length;)h.shift()?.();t.subscriber||u()}},l=t=>{h.push(t),d()},u=()=>{e=t.getLocation(),o.forEach((t=>t()))};return{get location(){return e},subscribe:e=>(0===o.size&&(s="function"==typeof t.subscriber?t.subscriber(u):()=>{}),o.add(e),()=>{o.delete(e),0===o.size&&s()}),push:(e,s)=>{c(s),l((()=>{t.pushState(e,s,u)}))},replace:(e,s)=>{c(s),l((()=>{t.replaceState(e,s,u)}))},go:e=>{l((()=>{t.go(e)}))},back:()=>{l((()=>{t.back()}))},forward:()=>{l((()=>{t.forward()}))},createHref:e=>t.createHref(e),block:t=>(i.push(t),1===i.length&&addEventListener(r,a,{capture:!0}),()=>{i=i.filter((e=>e!==t)),i.length||n()}),flush:()=>t.flush?.()}}function c(t){t.key=u()}function h(t){const e=t?.getHref??(()=>`${window.location.pathname}${window.location.search}${window.location.hash}`),r=t?.createHref??(t=>t);let a=l(e(),window.history.state);let n,c,h=!0;const d=()=>{h=!1,(()=>{n&&(window.history[n.isPush?"pushState":"replaceState"](n.state,"",n.href),n=void 0,c=void 0)})(),h=!0},u=(t,e,s,o)=>{const i=r(e);a=l(i,s),n={href:i,state:s,isPush:n?.isPush||"push"===t},o(),c||(c=Promise.resolve().then((()=>d())))};return i({getLocation:()=>a,subscriber:t=>{window.addEventListener(s,(()=>{a=l(e(),window.history.state),t()})),window.addEventListener(o,(()=>{a=l(e(),window.history.state),t()}));var r=window.history.pushState;window.history.pushState=function(){let e=r.apply(history,arguments);return h&&t(),e};var n=window.history.replaceState;return window.history.replaceState=function(){let e=n.apply(history,arguments);return h&&t(),e},()=>{window.history.pushState=r,window.history.replaceState=n,window.removeEventListener(s,t),window.removeEventListener(o,t)}},pushState:(t,e,s)=>u("push",t,e,s),replaceState:(t,e,s)=>u("replace",t,e,s),back:()=>window.history.back(),forward:()=>window.history.forward(),go:t=>window.history.go(t),createHref:t=>r(t),flush:d})}function d(t={initialEntries:["/"]}){const e=t.initialEntries;let s=t.initialIndex??e.length-1,o={key:u()};return i({getLocation:()=>l(e[s],o),subscriber:!1,pushState:(t,r)=>{o=r,e.push(t),s++},replaceState:(t,r)=>{o=r,e[s]=t},back:()=>{s--},forward:()=>{s=Math.min(s+1,e.length-1)},go:t=>window.history.go(t),createHref:t=>t})}function l(t,e){let s=t.indexOf("#"),o=t.indexOf("?");return{href:t,pathname:t.substring(0,s>0?o>0?Math.min(s,o):s:o>0?o:t.length),hash:s>-1?t.substring(s):"",search:o>-1?t.slice(o,-1===s?void 0:s):"",state:e||{}}}function u(){return(Math.random()+1).toString(36).substring(7)}function p(t){return t[t.length-1]}function f(t,e){return"function"==typeof t?t(e):t}function m(t,e){return e.reduce(((e,s)=>(e[s]=t[s],e)),{})}function y(t,e){if(t===e)return t;const s=e,o=Array.isArray(t)&&Array.isArray(s);if(o||g(t)&&g(s)){const e=o?t.length:Object.keys(t).length,r=o?s:Object.keys(s),a=r.length,n=o?[]:{};let i=0;for(let e=0;e<a;e++){const a=o?e:r[e];n[a]=y(t[a],s[a]),n[a]===t[a]&&i++}return e===a&&i===e?t:n}return s}function g(t){if(!w(t))return!1;const e=t.constructor;if(void 0===e)return!0;const s=e.prototype;return!!w(s)&&!!s.hasOwnProperty("isPrototypeOf")}function w(t){return"[object Object]"===Object.prototype.toString.call(t)}function v(t,e){return t===e||typeof t==typeof e&&(g(t)&&g(e)?!Object.keys(e).some((s=>!v(t[s],e[s]))):!(!Array.isArray(t)||!Array.isArray(e))&&(t.length===e.length&&t.every(((t,s)=>v(t,e[s])))))}function _(t){return b(t.filter(Boolean).join("/"))}function b(t){return t.replace(/\/{2,}/g,"/")}function S(t){return"/"===t?t:t.replace(/^\/{1,}/,"")}function R(t){return"/"===t?t:t.replace(/\/{1,}$/,"")}function I(t){return R(S(t))}function M(t,e,s){e=e.replace(new RegExp(`^${t}`),"/"),s=s.replace(new RegExp(`^${t}`),"/");let o=x(e);const r=x(s);r.forEach(((t,e)=>{if("/"===t.value)e?e===r.length-1&&o.push(t):o=[t];else if(".."===t.value)o.length>1&&"/"===p(o)?.value&&o.pop(),o.pop();else{if("."===t.value)return;o.push(t)}}));return b(_([t,...o.map((t=>t.value))]))}function x(t){if(!t)return[];const e=[];if("/"===(t=b(t)).slice(0,1)&&(t=t.substring(1),e.push({type:"pathname",value:"/"})),!t)return e;const s=t.split("/").filter(Boolean);return e.push(...s.map((t=>"$"===t||"*"===t?{type:"wildcard",value:t}:"$"===t.charAt(0)?{type:"param",value:t}:{type:"pathname",value:t}))),"/"===t.slice(-1)&&(t=t.substring(1),e.push({type:"pathname",value:"/"})),e}function E(t,e,s=!1){return _(x(t).map((t=>{if("wildcard"===t.type){const o=e[t.value];return s?`${t.value}${o??""}`:o}return"param"===t.type?e[t.value.substring(1)]??"":t.value})))}function L(t,e,s){const o=P(t,e,s);if(!s.to||o)return o??{}}function P(t,e,s){e="/"!=t?e.substring(t.length):e;const o=`${s.to??"$"}`,r=x(e),a=x(o);e.startsWith("/")||r.unshift({type:"pathname",value:"/"}),o.startsWith("/")||a.unshift({type:"pathname",value:"/"});const n={};return(()=>{for(let t=0;t<Math.max(r.length,a.length);t++){const e=r[t],o=a[t],i=t>=r.length-1,c=t>=a.length-1;if(o){if("wildcard"===o.type)return!!e?.value&&(n["*"]=_(r.slice(t).map((t=>t.value))),!0);if("pathname"===o.type){if("/"===o.value&&!e?.value)return!0;if(e)if(s.caseSensitive){if(o.value!==e.value)return!1}else if(o.value.toLowerCase()!==e.value.toLowerCase())return!1}if(!e)return!1;if("param"===o.type){if("/"===e?.value)return!1;"$"!==e.value.charAt(0)&&(n[o.value.substring(1)]=e.value)}}if(!i&&c)return!!s.fuzzy}return!0})()?n:void 0}function A(t,e){var s,o,r,a="";for(s in t)if(void 0!==(r=t[s]))if(Array.isArray(r))for(o=0;o<r.length;o++)a&&(a+="&"),a+=encodeURIComponent(s)+"="+encodeURIComponent(r[o]);else a&&(a+="&"),a+=encodeURIComponent(s)+"="+encodeURIComponent(r);return(e||"")+a}function O(t){if(!t)return"";var e=decodeURIComponent(t);return"false"!==e&&("true"===e||(0*+e==0&&+e+""===e?+e:e))}function D(t){for(var e,s,o={},r=t.split("&");e=r.shift();)void 0!==o[s=(e=e.split("=")).shift()]?o[s]=[].concat(o[s],O(e.shift())):o[s]=O(e.shift());return o}const B="__root__";class C{constructor(t){this.options=t||{},this.isRoot=!t?.getParentRoute,C.__onInit(this)}init=t=>{this.originalIndex=t.originalIndex,this.router=t.router;const s=this.options,o=!s?.path&&!s?.id;this.parentRoute=this.options?.getParentRoute?.(),o?this.path=B:e(this.parentRoute);let r=o?B:s.path;r&&"/"!==r&&(r=I(r));const a=s?.id||r;let n=o?B:_([this.parentRoute.id===B?"":this.parentRoute.id,a]);r===B&&(r="/"),n!==B&&(n=_(["/",n]));const i=n===B?"/":_([this.parentRoute.fullPath,r]);this.path=r,this.id=n,this.fullPath=i,this.to=i};addChildren=t=>(this.children=t,this);update=t=>(Object.assign(this.options,t),this);static __onInit=t=>{}}class $ extends C{constructor(t){super(t)}} | ||
/** | ||
@@ -14,0 +14,0 @@ * @tanstack/store/src/index.ts |
{ | ||
"name": "@tanstack/router-core", | ||
"author": "Tanner Linsley", | ||
"version": "0.0.1-beta.194", | ||
"version": "0.0.1-beta.195", | ||
"license": "MIT", | ||
@@ -6,0 +6,0 @@ "repository": "tanstack/router", |
@@ -133,10 +133,3 @@ import { ParsePathParams } from './link' | ||
> & | ||
UpdatableRouteOptions< | ||
TLoader, | ||
TSearchSchema, | ||
TFullSearchSchema, | ||
TAllParams, | ||
TRouteContext, | ||
TContext | ||
>, | ||
UpdatableRouteOptions<TLoader, TFullSearchSchema, TAllParams, TContext>, | ||
): Route< | ||
@@ -143,0 +136,0 @@ TParentRoute, |
@@ -15,2 +15,3 @@ // While the public API was clearly inspired by the "history" npm package, | ||
block: (blockerFn: BlockerFn) => () => void | ||
flush: () => void | ||
} | ||
@@ -56,4 +57,4 @@ | ||
subscriber: false | ((onUpdate: () => void) => () => void) | ||
pushState: (path: string, state: any) => void | ||
replaceState: (path: string, state: any) => void | ||
pushState: (path: string, state: any, onUpdate: () => void) => void | ||
replaceState: (path: string, state: any, onUpdate: () => void) => void | ||
go: (n: number) => void | ||
@@ -63,2 +64,3 @@ back: () => void | ||
createHref: (path: string) => string | ||
flush?: () => void | ||
}): RouterHistory { | ||
@@ -122,3 +124,3 @@ let location = opts.getLocation() | ||
queueTask(() => { | ||
opts.pushState(path, state) | ||
opts.pushState(path, state, onUpdate) | ||
}) | ||
@@ -129,3 +131,3 @@ }, | ||
queueTask(() => { | ||
opts.replaceState(path, state) | ||
opts.replaceState(path, state, onUpdate) | ||
}) | ||
@@ -166,2 +168,3 @@ }, | ||
}, | ||
flush: () => opts.flush?.(), | ||
} | ||
@@ -180,2 +183,18 @@ } | ||
/** | ||
* Creates a history object that can be used to interact with the browser's | ||
* navigation. This is a lightweight API wrapping the browser's native methods. | ||
* It is designed to work with TanStack Router, but could be used as a standalone API as well. | ||
* IMPORTANT: This API implements history throttling via a microtask to prevent | ||
* excessive calls to the history API. In some browsers, calling history.pushState or | ||
* history.replaceState in quick succession can cause the browser to ignore subsequent | ||
* calls. This API smooths out those differences and ensures that your application | ||
* state will *eventually* match the browser state. In most cases, this is not a problem, | ||
* but if you need to ensure that the browser state is up to date, you can use the | ||
* `history.flush` method to immediately flush all pending state changes to the browser URL. | ||
* @param opts | ||
* @param opts.getHref A function that returns the current href (path + search + hash) | ||
* @param opts.createHref A function that takes a path and returns a href (path + search + hash) | ||
* @returns A history instance | ||
*/ | ||
export function createBrowserHistory(opts?: { | ||
@@ -192,9 +211,89 @@ getHref?: () => string | ||
const getLocation = () => parseLocation(getHref(), window.history.state) | ||
let currentLocation = parseLocation(getHref(), window.history.state) | ||
const getLocation = () => currentLocation | ||
let next: | ||
| undefined | ||
| { | ||
// This is the latest location that we were attempting to push/replace | ||
href: string | ||
// This is the latest state that we were attempting to push/replace | ||
state: any | ||
// This is the latest type that we were attempting to push/replace | ||
isPush: boolean | ||
} | ||
// Because we are proactively updating the location | ||
// in memory before actually updating the browser history, | ||
// we need to track when we are doing this so we don't | ||
// notify subscribers twice on the last update. | ||
let tracking = true | ||
// We need to track the current scheduled update to prevent | ||
// multiple updates from being scheduled at the same time. | ||
let scheduled: Promise<void> | undefined | ||
// This function is a wrapper to prevent any of the callback's | ||
// side effects from causing a subscriber notification | ||
const untrack = (fn: () => void) => { | ||
tracking = false | ||
fn() | ||
tracking = true | ||
} | ||
// This function flushes the next update to the browser history | ||
const flush = () => { | ||
// Do not notify subscribers about this push/replace call | ||
untrack(() => { | ||
if (!next) return | ||
window.history[next.isPush ? 'pushState' : 'replaceState']( | ||
next.state, | ||
'', | ||
next.href, | ||
) | ||
// Reset the nextIsPush flag and clear the scheduled update | ||
next = undefined | ||
scheduled = undefined | ||
}) | ||
} | ||
// This function queues up a call to update the browser history | ||
const queueHistoryAction = ( | ||
type: 'push' | 'replace', | ||
path: string, | ||
state: any, | ||
onUpdate: () => void, | ||
) => { | ||
const href = createHref(path) | ||
// Update the location in memory | ||
currentLocation = parseLocation(href, state) | ||
// Keep track of the next location we need to flush to the URL | ||
next = { | ||
href, | ||
state, | ||
isPush: next?.isPush || type === 'push', | ||
} | ||
// Notify subscribers | ||
onUpdate() | ||
if (!scheduled) { | ||
// Schedule an update to the browser history | ||
scheduled = Promise.resolve().then(() => flush()) | ||
} | ||
} | ||
return createHistory({ | ||
getLocation, | ||
subscriber: (onUpdate) => { | ||
window.addEventListener(pushStateEvent, onUpdate) | ||
window.addEventListener(popStateEvent, onUpdate) | ||
window.addEventListener(pushStateEvent, () => { | ||
currentLocation = parseLocation(getHref(), window.history.state) | ||
onUpdate() | ||
}) | ||
window.addEventListener(popStateEvent, () => { | ||
currentLocation = parseLocation(getHref(), window.history.state) | ||
onUpdate() | ||
}) | ||
@@ -204,3 +303,3 @@ var pushState = window.history.pushState | ||
let res = pushState.apply(history, arguments as any) | ||
onUpdate() | ||
if (tracking) onUpdate() | ||
return res | ||
@@ -211,3 +310,3 @@ } | ||
let res = replaceState.apply(history, arguments as any) | ||
onUpdate() | ||
if (tracking) onUpdate() | ||
return res | ||
@@ -223,8 +322,6 @@ } | ||
}, | ||
pushState: (path, state) => { | ||
window.history.pushState(state, '', createHref(path)) | ||
}, | ||
replaceState: (path, state) => { | ||
window.history.replaceState(state, '', createHref(path)) | ||
}, | ||
pushState: (path, state, onUpdate) => | ||
queueHistoryAction('push', path, state, onUpdate), | ||
replaceState: (path, state, onUpdate) => | ||
queueHistoryAction('replace', path, state, onUpdate), | ||
back: () => window.history.back(), | ||
@@ -234,2 +331,3 @@ forward: () => window.history.forward(), | ||
createHref: (path) => createHref(path), | ||
flush, | ||
}) | ||
@@ -236,0 +334,0 @@ } |
@@ -27,3 +27,2 @@ import invariant from 'tiny-invariant' | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
@@ -36,3 +35,2 @@ > { | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
@@ -45,3 +43,2 @@ > { | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
@@ -56,3 +53,2 @@ > { | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
@@ -65,3 +61,2 @@ > { | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
@@ -75,3 +70,2 @@ > { | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
@@ -86,3 +80,2 @@ > { | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
@@ -93,3 +86,2 @@ > = RegisterRouteComponent< | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
@@ -105,3 +97,2 @@ > extends { | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
@@ -111,3 +102,2 @@ > = RegisterErrorRouteComponent< | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
@@ -123,3 +113,2 @@ > extends { | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
@@ -129,3 +118,2 @@ > = RegisterPendingRouteComponent< | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
@@ -142,3 +130,2 @@ > extends { | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
@@ -149,3 +136,2 @@ > = RegisterRouteProps< | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
@@ -161,10 +147,4 @@ > extends { | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
> = RegisterRouteProps< | ||
TFullSearchSchema, | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
> extends { | ||
> = RegisterRouteProps<TFullSearchSchema, TAllParams, TAllContext> extends { | ||
ErrorRouteProps: infer T | ||
@@ -178,10 +158,4 @@ } | ||
TAllParams extends AnyPathParams = AnyPathParams, | ||
TRouteContext extends Record<string, any> = AnyContext, | ||
TAllContext extends Record<string, any> = AnyContext, | ||
> = RegisterRouteProps< | ||
TFullSearchSchema, | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
> extends { | ||
> = RegisterRouteProps<TFullSearchSchema, TAllParams, TAllContext> extends { | ||
PendingRouteProps: infer T | ||
@@ -213,3 +187,3 @@ } | ||
export type AnyRouteProps = RegisteredRouteProps<any, any, any, any, any> | ||
export type AnyRouteProps = RegisteredRouteProps<any, any, any, any> | ||
@@ -241,10 +215,3 @@ export type RouteOptions< | ||
> & | ||
UpdatableRouteOptions< | ||
TLoader, | ||
TSearchSchema, | ||
TFullSearchSchema, | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
> | ||
UpdatableRouteOptions<TLoader, TFullSearchSchema, TAllParams, TAllContext> | ||
@@ -341,6 +308,4 @@ export type ParamsFallback< | ||
TLoader, | ||
TSearchSchema extends Record<string, any>, | ||
TFullSearchSchema extends Record<string, any>, | ||
TAllParams extends AnyPathParams, | ||
TRouteContext extends Record<string, any>, | ||
TAllContext extends Record<string, any>, | ||
@@ -357,3 +322,2 @@ > = MetaOptions & { | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
@@ -365,3 +329,2 @@ > | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
@@ -373,3 +336,2 @@ > // | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
@@ -463,3 +425,3 @@ > | ||
params: TAllParams | ||
context: DeepMergeAll<[TAllContext, TLoaderContext, TRouteContext]> | ||
context: Expand<DeepMergeAll<[TAllContext, TLoaderContext, TRouteContext]>> | ||
} | ||
@@ -661,6 +623,4 @@ | ||
TLoader, | ||
TSearchSchema, | ||
TFullSearchSchema, | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
@@ -770,6 +730,4 @@ >, | ||
TLoader, | ||
TSearchSchema, | ||
TFullSearchSchema, | ||
TAllParams, | ||
TRouteContext, | ||
TAllContext | ||
@@ -776,0 +734,0 @@ >, |
@@ -64,5 +64,3 @@ import { AnyRoute, Route } from './route' | ||
Expand< | ||
UnionToIntersection< | ||
ParseRoute<TRouteTree>['types']['fullSearchSchema'] | ||
> & {} | ||
UnionToIntersection<ParseRoute<TRouteTree>['types']['fullSearchSchema']> | ||
> | ||
@@ -69,0 +67,0 @@ > |
@@ -166,3 +166,2 @@ import { Store } from '@tanstack/store' | ||
AnyPathParams, | ||
AnyContext, | ||
AnyContext | ||
@@ -173,3 +172,2 @@ > | ||
AnyPathParams, | ||
AnyContext, | ||
AnyContext | ||
@@ -180,3 +178,2 @@ > | ||
AnyPathParams, | ||
AnyContext, | ||
AnyContext | ||
@@ -183,0 +180,0 @@ > |
@@ -22,2 +22,3 @@ export type NoInfer<T> = [T][T extends any ? 0 : never] | ||
// export type Expand<T> = T | ||
export type Expand<T> = T extends object | ||
@@ -24,0 +25,0 @@ ? T extends infer O |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1376529
12359