Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/router-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"node": ">=12"
},
"dependencies": {
"@tanstack/devtools-event-client": "0.2.1",
"@tanstack/history": "workspace:*",
"@tanstack/store": "^0.7.0",
"cookie-es": "^1.2.2",
Expand All @@ -90,4 +91,4 @@
"devDependencies": {
"esbuild": "^0.25.0"
}
}
}
9 changes: 9 additions & 0 deletions packages/router-core/src/eventClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { EventClient } from "@tanstack/devtools-event-client";

interface RouterEventMap {
"tanstack-router:state-change": any,
}

export const routerEventClient = new EventClient<RouterEventMap>({
pluginId: "tanstack-router"
})
1 change: 1 addition & 0 deletions packages/router-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,3 +412,4 @@ export type {
ValidateUseSearchResult,
ValidateUseParamsResult,
} from './typePrimitives'
export { routerEventClient } from "./eventClient"
154 changes: 79 additions & 75 deletions packages/router-core/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { defaultParseSearch, defaultStringifySearch } from './searchParams'
import { rootRouteId } from './root'
import { isRedirect, redirect } from './redirect'
import { createLRUCache } from './lru-cache'
import { routerEventClient } from './eventClient'
import type { ParsePathnameCache, Segment } from './path'
import type { SearchParser, SearchSerializer } from './searchParams'
import type { AnyRedirect, ResolvedRedirect } from './redirect'
Expand Down Expand Up @@ -108,10 +109,10 @@ export type DefaultRemountDepsFn<TRouteTree extends AnyRoute> = (
opts: MakeRemountDepsOptionsUnion<TRouteTree>,
) => any

export interface DefaultRouterOptionsExtensions {}
export interface DefaultRouterOptionsExtensions { }

export interface RouterOptionsExtensions
extends DefaultRouterOptionsExtensions {}
extends DefaultRouterOptionsExtensions { }

export interface RouterOptions<
TRouteTree extends AnyRoute,
Expand Down Expand Up @@ -518,12 +519,12 @@ export type InferRouterContext<TRouteTree extends AnyRoute> =

export type RouterContextOptions<TRouteTree extends AnyRoute> =
AnyContext extends InferRouterContext<TRouteTree>
? {
context?: InferRouterContext<TRouteTree>
}
: {
context: InferRouterContext<TRouteTree>
}
? {
context?: InferRouterContext<TRouteTree>
}
: {
context: InferRouterContext<TRouteTree>
}

export type RouterConstructorOptions<
TRouteTree extends AnyRoute,
Expand Down Expand Up @@ -695,14 +696,14 @@ export type AnyRouter = RouterCore<any, any, any, any, any>

export interface ViewTransitionOptions {
types:
| Array<string>
| ((locationChangeInfo: {
fromLocation?: ParsedLocation
toLocation: ParsedLocation
pathChanged: boolean
hrefChanged: boolean
hashChanged: boolean
}) => Array<string>)
| Array<string>
| ((locationChangeInfo: {
fromLocation?: ParsedLocation
toLocation: ParsedLocation
pathChanged: boolean
hrefChanged: boolean
hashChanged: boolean
}) => Array<string>)
}

export function defaultSerializeError(err: unknown) {
Expand All @@ -713,7 +714,7 @@ export function defaultSerializeError(err: unknown) {
}

if (process.env.NODE_ENV === 'development') {
;(obj as any).stack = err.stack
; (obj as any).stack = err.stack
}

return obj
Expand Down Expand Up @@ -748,12 +749,12 @@ export type CreateRouterFn = <
options: undefined extends number
? 'strictNullChecks must be enabled in tsconfig.json'
: RouterConstructorOptions<
TRouteTree,
TTrailingSlashOption,
TDefaultStructuralSharingOption,
TRouterHistory,
TDehydrated
>,
TRouteTree,
TTrailingSlashOption,
TDefaultStructuralSharingOption,
TRouterHistory,
TDehydrated
>,
) => RouterCore<
TRouteTree,
TTrailingSlashOption,
Expand Down Expand Up @@ -827,6 +828,9 @@ export class RouterCore<
parseSearch: options.parseSearch ?? defaultParseSearch,
})

this.__store.subscribe((state) => {
routerEventClient.emit("state-change", state.currentVal)
})
if (typeof document !== 'undefined') {
self.__TSR_ROUTER__ = this
}
Expand Down Expand Up @@ -868,11 +872,11 @@ export class RouterCore<

this.pathParamsDecodeCharMap = this.options.pathParamsAllowedCharacters
? new Map(
this.options.pathParamsAllowedCharacters.map((char) => [
encodeURIComponent(char),
char,
]),
)
this.options.pathParamsAllowedCharacters.map((char) => [
encodeURIComponent(char),
char,
]),
)
: undefined

if (
Expand All @@ -898,8 +902,8 @@ export class RouterCore<
this.options.history ??
((this.isServer
? createMemoryHistory({
initialEntries: [this.basepath || '/'],
})
initialEntries: [this.basepath || '/'],
})
: createBrowserHistory()) as TRouterHistory)
this.updateLatestLocation()
}
Expand Down Expand Up @@ -1085,7 +1089,7 @@ export class RouterCore<
foundRoute
? foundRoute.path !== '/' && routeParams['**']
: // Or if we didn't find a route and we have left over path
trimPathRight(next.pathname)
trimPathRight(next.pathname)
) {
// If the user has defined an (old) 404 route, use it
if (this.options.notFoundRoute) {
Expand Down Expand Up @@ -1259,9 +1263,9 @@ export class RouterCore<
} else {
const status =
route.options.loader ||
route.options.beforeLoad ||
route.lazyFn ||
routeNeedsPreload(route)
route.options.beforeLoad ||
route.lazyFn ||
routeNeedsPreload(route)
? 'pending'
: 'success'

Expand Down Expand Up @@ -1480,9 +1484,9 @@ export class RouterCore<
: (dest.params ?? true) === true
? fromParams
: {
...fromParams,
...functionalUpdate(dest.params as any, fromParams),
}
...fromParams,
...functionalUpdate(dest.params as any, fromParams),
}

// Interpolate the path first to get the actual resolved path, then match against that
const interpolatedNextTo = interpolatePath({
Expand Down Expand Up @@ -1667,7 +1671,7 @@ export class RouterCore<
'__hashScrollIntoViewOptions',
] as const
ignoredProps.forEach((prop) => {
;(next.state as any)[prop] = this.latestLocation.state[prop]
; (next.state as any)[prop] = this.latestLocation.state[prop]
})
const isEqual = deepEqual(next.state, this.latestLocation.state)
ignoredProps.forEach((prop) => {
Expand Down Expand Up @@ -1781,7 +1785,7 @@ export class RouterCore<
try {
new URL(`${href}`)
reloadDocument = true
} catch {}
} catch { }
}

if (reloadDocument) {
Expand Down Expand Up @@ -1936,18 +1940,18 @@ export class RouterCore<
this.clearExpiredCache()
})

//
;(
[
[exitingMatches, 'onLeave'],
[enteringMatches, 'onEnter'],
[stayingMatches, 'onStay'],
] as const
).forEach(([matches, hook]) => {
matches.forEach((match) => {
this.looseRoutesById[match.routeId]!.options[hook]?.(match)
//
; (
[
[exitingMatches, 'onLeave'],
[enteringMatches, 'onEnter'],
[stayingMatches, 'onStay'],
] as const
).forEach(([matches, hook]) => {
matches.forEach((match) => {
this.looseRoutesById[match.routeId]!.options[hook]?.(match)
})
})
})
})
},
})
Expand Down Expand Up @@ -2035,11 +2039,11 @@ export class RouterCore<
const resolvedViewTransitionTypes =
typeof shouldViewTransition.types === 'function'
? shouldViewTransition.types(
getLocationChangeInfo({
resolvedLocation: prevLocation,
location: next,
}),
)
getLocationChangeInfo({
resolvedLocation: prevLocation,
location: next,
}),
)
: shouldViewTransition.types

startViewTransitionParams = {
Expand Down Expand Up @@ -2148,7 +2152,7 @@ export class RouterCore<
}))

if (!(err as any).routeId) {
;(err as any).routeId = match.routeId
; (err as any).routeId = match.routeId
}

match._nonReactive.loadPromise?.resolve()
Expand Down Expand Up @@ -2185,7 +2189,7 @@ export class RouterCore<

try {
await new Promise<void>((resolveAll, rejectAll) => {
;(async () => {
; (async () => {
try {
const handleSerialError = (
index: number,
Expand Down Expand Up @@ -2326,7 +2330,7 @@ export class RouterCore<
// Update the match and prematurely resolve the loadMatches promise so that
// the pending component can start rendering
triggerOnReady()
} catch {}
} catch { }
}, pendingMs)
match._nonReactive.pendingTimeout = pendingTimeout
}
Expand Down Expand Up @@ -2696,19 +2700,19 @@ export class RouterCore<
// Do nothing
} else if (loaderShouldRunAsync && !sync) {
loaderIsRunningAsync = true
;(async () => {
try {
await runLoader()
const match = this.getMatch(matchId)!
match._nonReactive.loaderPromise?.resolve()
match._nonReactive.loadPromise?.resolve()
match._nonReactive.loaderPromise = undefined
} catch (err) {
if (isRedirect(err)) {
await this.navigate(err.options)
; (async () => {
try {
await runLoader()
const match = this.getMatch(matchId)!
match._nonReactive.loaderPromise?.resolve()
match._nonReactive.loadPromise?.resolve()
match._nonReactive.loaderPromise = undefined
} catch (err) {
if (isRedirect(err)) {
await this.navigate(err.options)
}
}
}
})()
})()
} else if (
status !== 'success' ||
(loaderShouldRunAsync && sync)
Expand Down Expand Up @@ -2978,9 +2982,9 @@ export class RouterCore<
...location,
to: location.to
? this.resolvePathWithBase(
(location.from || '') as string,
location.to as string,
)
(location.from || '') as string,
location.to as string,
)
: undefined,
params: location.params || {},
leaveParams: true,
Expand Down Expand Up @@ -3101,9 +3105,9 @@ export class RouterCore<
}
}

export class SearchParamError extends Error {}
export class SearchParamError extends Error { }

export class PathParamError extends Error {}
export class PathParamError extends Error { }

const normalize = (str: string) =>
str.endsWith('/') && str.length > 1 ? str.slice(0, -1) : str
Expand Down
5 changes: 3 additions & 2 deletions packages/router-devtools-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"node": ">=12"
},
"dependencies": {
"@tanstack/devtools-event-client": "^0.2.1",
"clsx": "^2.1.1",
"goober": "^2.1.16",
"solid-js": "^1.9.5"
Expand All @@ -70,10 +71,10 @@
"vite-plugin-solid": "^2.11.6"
},
"peerDependencies": {
"tiny-invariant": "^1.3.3",
"@tanstack/router-core": "workspace:^",
"csstype": "^3.0.10",
"solid-js": ">=1.9.5"
"solid-js": ">=1.9.5",
"tiny-invariant": "^1.3.3"
},
"peerDependenciesMeta": {
"csstype": {
Expand Down
Loading