@tanstack/vue-router 1.168.11 → 1.168.13
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/dist/esm/Match.js +2 -2
- package/dist/esm/Match.js.map +1 -1
- package/dist/esm/Matches.d.ts +2 -2
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/Transitioner.js +11 -11
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/link.js +1 -1
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/routerStores.js +7 -7
- package/dist/esm/routerStores.js.map +1 -1
- package/dist/esm/ssr/RouterClient.js +1 -1
- package/dist/esm/ssr/RouterClient.js.map +1 -1
- package/dist/esm/ssr/renderRouterToStream.js +2 -2
- package/dist/esm/ssr/renderRouterToStream.js.map +1 -1
- package/dist/esm/ssr/renderRouterToString.js +1 -1
- package/dist/esm/ssr/renderRouterToString.js.map +1 -1
- package/dist/esm/useMatch.js +1 -1
- package/dist/esm/useMatch.js.map +1 -1
- package/dist/esm/useRouterState.js +1 -1
- package/dist/esm/useRouterState.js.map +1 -1
- package/dist/source/Match.jsx +2 -2
- package/dist/source/Match.jsx.map +1 -1
- package/dist/source/Matches.d.ts +2 -2
- package/dist/source/Matches.jsx.map +1 -1
- package/dist/source/Transitioner.jsx +11 -11
- package/dist/source/Transitioner.jsx.map +1 -1
- package/dist/source/link.jsx +1 -1
- package/dist/source/link.jsx.map +1 -1
- package/dist/source/routerStores.js +7 -7
- package/dist/source/routerStores.js.map +1 -1
- package/dist/source/ssr/RouterClient.jsx +1 -1
- package/dist/source/ssr/RouterClient.jsx.map +1 -1
- package/dist/source/ssr/renderRouterToStream.jsx +2 -2
- package/dist/source/ssr/renderRouterToStream.jsx.map +1 -1
- package/dist/source/ssr/renderRouterToString.jsx +1 -1
- package/dist/source/ssr/renderRouterToString.jsx.map +1 -1
- package/dist/source/useMatch.jsx +1 -1
- package/dist/source/useMatch.jsx.map +1 -1
- package/dist/source/useRouterState.jsx +1 -1
- package/dist/source/useRouterState.jsx.map +1 -1
- package/package.json +2 -2
- package/src/Match.tsx +3 -3
- package/src/Matches.tsx +1 -7
- package/src/Transitioner.tsx +14 -18
- package/src/link.tsx +1 -1
- package/src/routerStores.ts +7 -7
- package/src/ssr/RouterClient.tsx +1 -1
- package/src/ssr/renderRouterToStream.tsx +2 -2
- package/src/ssr/renderRouterToString.tsx +1 -1
- package/src/useMatch.tsx +1 -1
- package/src/useRouterState.tsx +1 -1
package/dist/esm/Match.js
CHANGED
|
@@ -101,7 +101,7 @@ var OnRendered = Vue.defineComponent({
|
|
|
101
101
|
if (prevHref === void 0 || prevHref !== currentHref) {
|
|
102
102
|
router.emit({
|
|
103
103
|
type: "onRendered",
|
|
104
|
-
...getLocationChangeInfo(router.stores.location.
|
|
104
|
+
...getLocationChangeInfo(router.stores.location.get(), router.stores.resolvedLocation.get())
|
|
105
105
|
});
|
|
106
106
|
prevHref = currentHref;
|
|
107
107
|
}
|
|
@@ -230,7 +230,7 @@ var Outlet = Vue.defineComponent({
|
|
|
230
230
|
const childMatchData = Vue.computed(() => {
|
|
231
231
|
const childId = childMatchIdMap.value[parentRouteId];
|
|
232
232
|
if (!childId) return null;
|
|
233
|
-
const child = router.stores.activeMatchStoresById.get(childId)?.
|
|
233
|
+
const child = router.stores.activeMatchStoresById.get(childId)?.get();
|
|
234
234
|
if (!child) return null;
|
|
235
235
|
return {
|
|
236
236
|
id: child.id,
|
package/dist/esm/Match.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Match.js","names":["Vue","createControlledPromise","getLocationChangeInfo","invariant","isNotFound","isRedirect","rootRouteId","isServer","useStore","CatchBoundary","ErrorComponent","ClientOnly","useRouter","CatchNotFound","matchContext","pendingMatchContext","routeIdContext","renderRouteNotFound","ScrollRestoration","Match","defineComponent","name","props","matchId","type","String","required","setup","router","routeId","stores","activeMatchStoresById","get","process","env","NODE_ENV","Error","isChildOfRoot","routesById","parentRoute","id","activeMatch","getMatchStoreByRouteId","value","isPendingMatchRef","pendingRouteIds","Boolean","equal","Object","is","loadedAt","matchData","computed","match","ssr","_displayPending","route","PendingComponent","options","pendingComponent","defaultPendingComponent","pendingElement","h","undefined","routeErrorComponent","errorComponent","defaultErrorComponent","routeOnCatch","onCatch","defaultOnCatch","routeNotFoundComponent","isRoot","notFoundComponent","notFoundRoute","component","hasShellComponent","shellComponent","ShellComponent","provide","matchIdRef","actualMatchId","resolvedNoSsr","shouldClientOnly","renderMatchContent","matchInner","MatchInner","content","fallback","default","error","children","getResetKey","console","warn","withScrollRestoration","Fragment","OnRendered","scrollRestoration","filter","length","location","resolvedLocation","state","__TSR_key","prevHref","watch","currentHref","latestLocation","href","emit","immediate","inject","combinedState","matchRouteId","remountFn","remountDeps","defaultRemountDeps","remountKey","loaderDeps","params","_strictParams","search","_strictSearch","JSON","stringify","status","_forcePending","_nonReactive","getMatchPromise","key","getMatch","RouteErrorComponent","reset","invalidate","info","componentStack","pendingMinMs","defaultPendingMinMs","routerMatch","minPendingPromise","setTimeout","resolve","Comp","defaultComponent","Outlet","parentRouteId","parentMatch","v","parentGlobalNotFound","globalNotFound","childMatchIdMap","childMatchIdByRouteId","childMatchData","childId","child","paramsKey","nextMatch"],"sources":["../../src/Match.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport {\n createControlledPromise,\n getLocationChangeInfo,\n invariant,\n isNotFound,\n isRedirect,\n rootRouteId,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useStore } from '@tanstack/vue-store'\nimport { CatchBoundary, ErrorComponent } from './CatchBoundary'\nimport { ClientOnly } from './ClientOnly'\nimport { useRouter } from './useRouter'\nimport { CatchNotFound } from './not-found'\nimport {\n matchContext,\n pendingMatchContext,\n routeIdContext,\n} from './matchContext'\nimport { renderRouteNotFound } from './renderRouteNotFound'\nimport { ScrollRestoration } from './scroll-restoration'\nimport type { VNode } from 'vue'\nimport type { AnyRoute, RootRouteOptions } from '@tanstack/router-core'\n\nexport const Match = Vue.defineComponent({\n name: 'Match',\n props: {\n matchId: {\n type: String,\n required: true,\n },\n },\n setup(props) {\n const router = useRouter()\n\n // Derive routeId from initial props.matchId — stable for this component's\n // lifetime. The routeId never changes for a given route position in the\n // tree, even when matchId changes (loaderDepsHash, etc).\n const routeId = router.stores.activeMatchStoresById.get(\n props.matchId,\n )?.routeId\n\n if (!routeId) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `Invariant failed: Could not find routeId for matchId \"${props.matchId}\". Please file an issue!`,\n )\n }\n\n invariant()\n }\n\n // Static route-tree check: is this route a direct child of the root?\n // parentRoute is set at build time, so no reactive tracking needed.\n const isChildOfRoot =\n (router.routesById[routeId] as AnyRoute)?.parentRoute?.id === rootRouteId\n\n // Single stable store subscription — getMatchStoreByRouteId returns a\n // cached computed store that resolves routeId → current match state\n // through the signal graph. No bridge needed.\n const activeMatch = useStore(\n router.stores.getMatchStoreByRouteId(routeId),\n (value) => value,\n )\n const isPendingMatchRef = useStore(\n router.stores.pendingRouteIds,\n (pendingRouteIds) => Boolean(pendingRouteIds[routeId]),\n { equal: Object.is },\n )\n const loadedAt = useStore(router.stores.loadedAt, (value) => value)\n\n const matchData = Vue.computed(() => {\n const match = activeMatch.value\n if (!match) {\n return null\n }\n\n return {\n matchId: match.id,\n routeId,\n loadedAt: loadedAt.value,\n ssr: match.ssr,\n _displayPending: match._displayPending,\n }\n })\n\n const route = Vue.computed(() =>\n matchData.value ? router.routesById[matchData.value.routeId] : null,\n )\n\n const PendingComponent = Vue.computed(\n () =>\n route.value?.options?.pendingComponent ??\n router?.options?.defaultPendingComponent,\n )\n\n const pendingElement = Vue.computed(() =>\n PendingComponent.value ? Vue.h(PendingComponent.value) : undefined,\n )\n\n const routeErrorComponent = Vue.computed(\n () =>\n route.value?.options?.errorComponent ??\n router?.options?.defaultErrorComponent,\n )\n\n const routeOnCatch = Vue.computed(\n () => route.value?.options?.onCatch ?? router?.options?.defaultOnCatch,\n )\n\n const routeNotFoundComponent = Vue.computed(() =>\n route.value?.isRoot\n ? // If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component\n (route.value?.options?.notFoundComponent ??\n router?.options?.notFoundRoute?.options?.component)\n : route.value?.options?.notFoundComponent,\n )\n\n const hasShellComponent = Vue.computed(() => {\n if (!route.value?.isRoot) return false\n return !!(route.value.options as RootRouteOptions).shellComponent\n })\n\n const ShellComponent = Vue.computed(() =>\n hasShellComponent.value\n ? ((route.value!.options as RootRouteOptions).shellComponent as any)\n : null,\n )\n\n // Provide routeId context (stable string) for children.\n // MatchInner, Outlet, and useMatch all consume this.\n Vue.provide(routeIdContext, routeId)\n\n // Provide reactive nearest-match context for hooks that slice the active\n // matches array relative to the current match.\n const matchIdRef = Vue.computed(\n () => activeMatch.value?.id ?? props.matchId,\n )\n Vue.provide(matchContext, matchIdRef)\n\n Vue.provide(pendingMatchContext, isPendingMatchRef)\n\n return (): VNode => {\n const actualMatchId = matchData.value?.matchId ?? props.matchId\n\n const resolvedNoSsr =\n matchData.value?.ssr === false || matchData.value?.ssr === 'data-only'\n const shouldClientOnly =\n resolvedNoSsr || !!matchData.value?._displayPending\n\n const renderMatchContent = (): VNode => {\n const matchInner = Vue.h(MatchInner, { matchId: actualMatchId })\n\n let content: VNode = shouldClientOnly\n ? Vue.h(\n ClientOnly,\n {\n fallback: pendingElement.value,\n },\n {\n default: () => matchInner,\n },\n )\n : matchInner\n\n // Wrap in NotFound boundary if needed\n if (routeNotFoundComponent.value) {\n content = Vue.h(CatchNotFound, {\n fallback: (error: any) => {\n error.routeId ??= matchData.value?.routeId as any\n\n // If the current not found handler doesn't exist or it has a\n // route ID which doesn't match the current route, rethrow the error\n if (\n !routeNotFoundComponent.value ||\n (error.routeId && error.routeId !== matchData.value?.routeId) ||\n (!error.routeId && route.value && !route.value.isRoot)\n )\n throw error\n\n return Vue.h(routeNotFoundComponent.value, error)\n },\n children: content,\n })\n }\n\n // Wrap in error boundary if needed\n if (routeErrorComponent.value) {\n content = CatchBoundary({\n getResetKey: () => matchData.value?.loadedAt ?? 0,\n errorComponent: routeErrorComponent.value || ErrorComponent,\n onCatch: (error: Error) => {\n // Forward not found errors (we don't want to show the error component for these)\n if (isNotFound(error)) {\n error.routeId ??= matchData.value?.routeId as any\n throw error\n }\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Warning: Error in route match: ${actualMatchId}`)\n }\n routeOnCatch.value?.(error)\n },\n children: content,\n })\n }\n\n // Add scroll restoration if needed\n const withScrollRestoration: Array<VNode> = [\n content,\n isChildOfRoot\n ? Vue.h(Vue.Fragment, null, [\n Vue.h(OnRendered),\n router.options.scrollRestoration &&\n (isServer ?? router.isServer)\n ? Vue.h(ScrollRestoration)\n : null,\n ])\n : null,\n ].filter(Boolean) as Array<VNode>\n\n // Return single child directly to avoid Fragment wrapper that causes hydration mismatch\n if (withScrollRestoration.length === 1) {\n return withScrollRestoration[0]!\n }\n\n return Vue.h(Vue.Fragment, null, withScrollRestoration)\n }\n\n if (!hasShellComponent.value) {\n return renderMatchContent()\n }\n\n return Vue.h(ShellComponent.value, null, {\n // Important: return a fresh VNode on each slot invocation so that shell\n // components can re-render without reusing a cached VNode instance.\n default: () => renderMatchContent(),\n })\n }\n },\n})\n\n// On Rendered can't happen above the root layout because it actually\n// renders a dummy dom element to track the rendered state of the app.\n// We render a script tag with a key that changes based on the current\n// location state.__TSR_key. Also, because it's below the root layout, it\n// allows us to fire onRendered events even after a hydration mismatch\n// error that occurred above the root layout (like bad head/link tags,\n// which is common).\nconst OnRendered = Vue.defineComponent({\n name: 'OnRendered',\n setup() {\n const router = useRouter()\n\n const location = useStore(\n router.stores.resolvedLocation,\n (resolvedLocation) => resolvedLocation?.state.__TSR_key,\n )\n\n let prevHref: string | undefined\n\n Vue.watch(\n location,\n () => {\n if (location.value) {\n const currentHref = router.latestLocation.href\n if (prevHref === undefined || prevHref !== currentHref) {\n router.emit({\n type: 'onRendered',\n ...getLocationChangeInfo(\n router.stores.location.state,\n router.stores.resolvedLocation.state,\n ),\n })\n prevHref = currentHref\n }\n }\n },\n { immediate: true },\n )\n\n return () => null\n },\n})\n\nexport const MatchInner = Vue.defineComponent({\n name: 'MatchInner',\n props: {\n matchId: {\n type: String,\n required: true,\n },\n },\n setup(props) {\n const router = useRouter()\n\n // Use routeId from context (provided by parent Match) — stable string.\n const routeId = Vue.inject(routeIdContext)!\n const activeMatch = useStore(\n router.stores.getMatchStoreByRouteId(routeId),\n (value) => value,\n )\n\n // Combined selector for match state AND remount key\n // This ensures both are computed in the same selector call with consistent data\n const combinedState = Vue.computed(() => {\n const match = activeMatch.value\n if (!match) {\n // Route no longer exists - truly navigating away\n return null\n }\n\n const matchRouteId = match.routeId as string\n\n // Compute remount key\n const remountFn =\n (router.routesById[matchRouteId] as AnyRoute).options.remountDeps ??\n router.options.defaultRemountDeps\n\n let remountKey: string | undefined\n if (remountFn) {\n const remountDeps = remountFn({\n routeId: matchRouteId,\n loaderDeps: match.loaderDeps,\n params: match._strictParams,\n search: match._strictSearch,\n })\n remountKey = remountDeps ? JSON.stringify(remountDeps) : undefined\n }\n\n return {\n routeId: matchRouteId,\n match: {\n id: match.id,\n status: match.status,\n error: match.error,\n ssr: match.ssr,\n _forcePending: match._forcePending,\n _displayPending: match._displayPending,\n _nonReactive: match._nonReactive,\n },\n remountKey,\n }\n })\n\n const route = Vue.computed(() => {\n if (!combinedState.value) return null\n return router.routesById[combinedState.value.routeId]!\n })\n\n const match = Vue.computed(() => combinedState.value?.match)\n const remountKey = Vue.computed(() => combinedState.value?.remountKey)\n\n const getMatchPromise = (\n match: {\n id: string\n _nonReactive: {\n displayPendingPromise?: Promise<void>\n minPendingPromise?: Promise<void>\n loadPromise?: Promise<void>\n }\n },\n key: 'displayPendingPromise' | 'minPendingPromise' | 'loadPromise',\n ) => {\n return (\n router.getMatch(match.id)?._nonReactive[key] ?? match._nonReactive[key]\n )\n }\n\n return (): VNode | null => {\n // If match doesn't exist, return null (component is being unmounted or not ready)\n if (!combinedState.value || !match.value || !route.value) return null\n\n // Handle different match statuses\n if (match.value._displayPending) {\n const PendingComponent =\n route.value.options.pendingComponent ??\n router.options.defaultPendingComponent\n\n return PendingComponent ? Vue.h(PendingComponent) : null\n }\n\n if (match.value._forcePending) {\n const PendingComponent =\n route.value.options.pendingComponent ??\n router.options.defaultPendingComponent\n\n return PendingComponent ? Vue.h(PendingComponent) : null\n }\n\n if (match.value.status === 'notFound') {\n if (!isNotFound(match.value.error)) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('Invariant failed: Expected a notFound error')\n }\n\n invariant()\n }\n return renderRouteNotFound(router, route.value, match.value.error)\n }\n\n if (match.value.status === 'redirected') {\n if (!isRedirect(match.value.error)) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('Invariant failed: Expected a redirect error')\n }\n\n invariant()\n }\n throw getMatchPromise(match.value, 'loadPromise')\n }\n\n if (match.value.status === 'error') {\n // Check if this route or any parent has an error component\n const RouteErrorComponent =\n route.value.options.errorComponent ??\n router.options.defaultErrorComponent\n\n // If this route has an error component, render it directly\n // This is more reliable than relying on Vue's error boundary\n if (RouteErrorComponent) {\n return Vue.h(RouteErrorComponent, {\n error: match.value.error,\n reset: () => {\n router.invalidate()\n },\n info: {\n componentStack: '',\n },\n })\n }\n\n // If there's no error component for this route, throw the error\n // so it can bubble up to the nearest parent with an error component\n throw match.value.error\n }\n\n if (match.value.status === 'pending') {\n const pendingMinMs =\n route.value.options.pendingMinMs ?? router.options.defaultPendingMinMs\n\n const routerMatch = router.getMatch(match.value.id)\n if (\n pendingMinMs &&\n routerMatch &&\n !routerMatch._nonReactive.minPendingPromise\n ) {\n // Create a promise that will resolve after the minPendingMs\n if (!(isServer ?? router.isServer)) {\n const minPendingPromise = createControlledPromise<void>()\n\n routerMatch._nonReactive.minPendingPromise = minPendingPromise\n\n setTimeout(() => {\n minPendingPromise.resolve()\n // We've handled the minPendingPromise, so we can delete it\n routerMatch._nonReactive.minPendingPromise = undefined\n }, pendingMinMs)\n }\n }\n\n // In Vue, we render the pending component directly instead of throwing a promise\n // because Vue's Suspense doesn't catch thrown promises like React does\n const PendingComponent =\n route.value.options.pendingComponent ??\n router.options.defaultPendingComponent\n\n if (PendingComponent) {\n return Vue.h(PendingComponent)\n }\n\n // If no pending component, return null while loading\n return null\n }\n\n // Success status - render the component with remount key\n const Comp =\n route.value.options.component ?? router.options.defaultComponent\n const key = remountKey.value\n\n if (Comp) {\n // Pass key as a prop - Vue.h properly handles 'key' as a special prop\n return Vue.h(Comp, key !== undefined ? { key } : undefined)\n }\n\n return Vue.h(Outlet, key !== undefined ? { key } : undefined)\n }\n },\n})\n\nexport const Outlet = Vue.defineComponent({\n name: 'Outlet',\n setup() {\n const router = useRouter()\n const parentRouteId = Vue.inject(routeIdContext)\n\n if (!parentRouteId) {\n return (): VNode | null => null\n }\n\n // Parent state via stable routeId store — single subscription\n const parentMatch = useStore(\n router.stores.getMatchStoreByRouteId(parentRouteId),\n (v) => v,\n )\n\n const route = Vue.computed(() =>\n parentMatch.value\n ? router.routesById[parentMatch.value.routeId as string]!\n : undefined,\n )\n\n const parentGlobalNotFound = Vue.computed(\n () => parentMatch.value?.globalNotFound ?? false,\n )\n\n // Child match lookup: read the child matchId from the shared derived\n // map (one reactive node for the whole tree), then grab match state\n // directly from the pool.\n const childMatchIdMap = useStore(\n router.stores.childMatchIdByRouteId,\n (v) => v,\n )\n\n const childMatchData = Vue.computed(() => {\n const childId = childMatchIdMap.value[parentRouteId]\n if (!childId) return null\n const child = router.stores.activeMatchStoresById.get(childId)?.state\n if (!child) return null\n\n return {\n id: child.id,\n // Key based on routeId + params only (not loaderDeps)\n // This ensures component recreates when params change,\n // but NOT when only loaderDeps change\n paramsKey: child.routeId + JSON.stringify(child._strictParams),\n }\n })\n\n return (): VNode | null => {\n if (parentGlobalNotFound.value) {\n if (!route.value) {\n return null\n }\n return renderRouteNotFound(router, route.value, undefined)\n }\n\n if (!childMatchData.value) {\n return null\n }\n\n const nextMatch = Vue.h(Match, {\n matchId: childMatchData.value.id,\n key: childMatchData.value.paramsKey,\n })\n\n // Note: We intentionally do NOT wrap in Suspense here.\n // The top-level Suspense in Matches already covers the root.\n // The old code compared matchId (e.g. \"__root__/\") with rootRouteId (\"__root__\")\n // which never matched, so this Suspense was effectively dead code.\n // With routeId-based lookup, parentRouteId === rootRouteId would match,\n // causing a double-Suspense that corrupts Vue's DOM during updates.\n return nextMatch\n }\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Match.js","names":["Vue","createControlledPromise","getLocationChangeInfo","invariant","isNotFound","isRedirect","rootRouteId","isServer","useStore","CatchBoundary","ErrorComponent","ClientOnly","useRouter","CatchNotFound","matchContext","pendingMatchContext","routeIdContext","renderRouteNotFound","ScrollRestoration","Match","defineComponent","name","props","matchId","type","String","required","setup","router","routeId","stores","activeMatchStoresById","get","process","env","NODE_ENV","Error","isChildOfRoot","routesById","parentRoute","id","activeMatch","getMatchStoreByRouteId","value","isPendingMatchRef","pendingRouteIds","Boolean","equal","Object","is","loadedAt","matchData","computed","match","ssr","_displayPending","route","PendingComponent","options","pendingComponent","defaultPendingComponent","pendingElement","h","undefined","routeErrorComponent","errorComponent","defaultErrorComponent","routeOnCatch","onCatch","defaultOnCatch","routeNotFoundComponent","isRoot","notFoundComponent","notFoundRoute","component","hasShellComponent","shellComponent","ShellComponent","provide","matchIdRef","actualMatchId","resolvedNoSsr","shouldClientOnly","renderMatchContent","matchInner","MatchInner","content","fallback","default","error","children","getResetKey","console","warn","withScrollRestoration","Fragment","OnRendered","scrollRestoration","filter","length","location","resolvedLocation","state","__TSR_key","prevHref","watch","currentHref","latestLocation","href","emit","immediate","inject","combinedState","matchRouteId","remountFn","remountDeps","defaultRemountDeps","remountKey","loaderDeps","params","_strictParams","search","_strictSearch","JSON","stringify","status","_forcePending","_nonReactive","getMatchPromise","key","getMatch","RouteErrorComponent","reset","invalidate","info","componentStack","pendingMinMs","defaultPendingMinMs","routerMatch","minPendingPromise","setTimeout","resolve","Comp","defaultComponent","Outlet","parentRouteId","parentMatch","v","parentGlobalNotFound","globalNotFound","childMatchIdMap","childMatchIdByRouteId","childMatchData","childId","child","paramsKey","nextMatch"],"sources":["../../src/Match.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport {\n createControlledPromise,\n getLocationChangeInfo,\n invariant,\n isNotFound,\n isRedirect,\n rootRouteId,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useStore } from '@tanstack/vue-store'\nimport { CatchBoundary, ErrorComponent } from './CatchBoundary'\nimport { ClientOnly } from './ClientOnly'\nimport { useRouter } from './useRouter'\nimport { CatchNotFound } from './not-found'\nimport {\n matchContext,\n pendingMatchContext,\n routeIdContext,\n} from './matchContext'\nimport { renderRouteNotFound } from './renderRouteNotFound'\nimport { ScrollRestoration } from './scroll-restoration'\nimport type { VNode } from 'vue'\nimport type { AnyRoute, RootRouteOptions } from '@tanstack/router-core'\n\nexport const Match = Vue.defineComponent({\n name: 'Match',\n props: {\n matchId: {\n type: String,\n required: true,\n },\n },\n setup(props) {\n const router = useRouter()\n\n // Derive routeId from initial props.matchId — stable for this component's\n // lifetime. The routeId never changes for a given route position in the\n // tree, even when matchId changes (loaderDepsHash, etc).\n const routeId = router.stores.activeMatchStoresById.get(\n props.matchId,\n )?.routeId\n\n if (!routeId) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `Invariant failed: Could not find routeId for matchId \"${props.matchId}\". Please file an issue!`,\n )\n }\n\n invariant()\n }\n\n // Static route-tree check: is this route a direct child of the root?\n // parentRoute is set at build time, so no reactive tracking needed.\n const isChildOfRoot =\n (router.routesById[routeId] as AnyRoute)?.parentRoute?.id === rootRouteId\n\n // Single stable store subscription — getMatchStoreByRouteId returns a\n // cached computed store that resolves routeId → current match state\n // through the signal graph. No bridge needed.\n const activeMatch = useStore(\n router.stores.getMatchStoreByRouteId(routeId),\n (value) => value,\n )\n const isPendingMatchRef = useStore(\n router.stores.pendingRouteIds,\n (pendingRouteIds) => Boolean(pendingRouteIds[routeId]),\n { equal: Object.is },\n )\n const loadedAt = useStore(router.stores.loadedAt, (value) => value)\n\n const matchData = Vue.computed(() => {\n const match = activeMatch.value\n if (!match) {\n return null\n }\n\n return {\n matchId: match.id,\n routeId,\n loadedAt: loadedAt.value,\n ssr: match.ssr,\n _displayPending: match._displayPending,\n }\n })\n\n const route = Vue.computed(() =>\n matchData.value ? router.routesById[matchData.value.routeId] : null,\n )\n\n const PendingComponent = Vue.computed(\n () =>\n route.value?.options?.pendingComponent ??\n router?.options?.defaultPendingComponent,\n )\n\n const pendingElement = Vue.computed(() =>\n PendingComponent.value ? Vue.h(PendingComponent.value) : undefined,\n )\n\n const routeErrorComponent = Vue.computed(\n () =>\n route.value?.options?.errorComponent ??\n router?.options?.defaultErrorComponent,\n )\n\n const routeOnCatch = Vue.computed(\n () => route.value?.options?.onCatch ?? router?.options?.defaultOnCatch,\n )\n\n const routeNotFoundComponent = Vue.computed(() =>\n route.value?.isRoot\n ? // If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component\n (route.value?.options?.notFoundComponent ??\n router?.options?.notFoundRoute?.options?.component)\n : route.value?.options?.notFoundComponent,\n )\n\n const hasShellComponent = Vue.computed(() => {\n if (!route.value?.isRoot) return false\n return !!(route.value.options as RootRouteOptions).shellComponent\n })\n\n const ShellComponent = Vue.computed(() =>\n hasShellComponent.value\n ? ((route.value!.options as RootRouteOptions).shellComponent as any)\n : null,\n )\n\n // Provide routeId context (stable string) for children.\n // MatchInner, Outlet, and useMatch all consume this.\n Vue.provide(routeIdContext, routeId)\n\n // Provide reactive nearest-match context for hooks that slice the active\n // matches array relative to the current match.\n const matchIdRef = Vue.computed(\n () => activeMatch.value?.id ?? props.matchId,\n )\n Vue.provide(matchContext, matchIdRef)\n\n Vue.provide(pendingMatchContext, isPendingMatchRef)\n\n return (): VNode => {\n const actualMatchId = matchData.value?.matchId ?? props.matchId\n\n const resolvedNoSsr =\n matchData.value?.ssr === false || matchData.value?.ssr === 'data-only'\n const shouldClientOnly =\n resolvedNoSsr || !!matchData.value?._displayPending\n\n const renderMatchContent = (): VNode => {\n const matchInner = Vue.h(MatchInner, { matchId: actualMatchId })\n\n let content: VNode = shouldClientOnly\n ? Vue.h(\n ClientOnly,\n {\n fallback: pendingElement.value,\n },\n {\n default: () => matchInner,\n },\n )\n : matchInner\n\n // Wrap in NotFound boundary if needed\n if (routeNotFoundComponent.value) {\n content = Vue.h(CatchNotFound, {\n fallback: (error: any) => {\n error.routeId ??= matchData.value?.routeId as any\n\n // If the current not found handler doesn't exist or it has a\n // route ID which doesn't match the current route, rethrow the error\n if (\n !routeNotFoundComponent.value ||\n (error.routeId && error.routeId !== matchData.value?.routeId) ||\n (!error.routeId && route.value && !route.value.isRoot)\n )\n throw error\n\n return Vue.h(routeNotFoundComponent.value, error)\n },\n children: content,\n })\n }\n\n // Wrap in error boundary if needed\n if (routeErrorComponent.value) {\n content = CatchBoundary({\n getResetKey: () => matchData.value?.loadedAt ?? 0,\n errorComponent: routeErrorComponent.value || ErrorComponent,\n onCatch: (error: Error) => {\n // Forward not found errors (we don't want to show the error component for these)\n if (isNotFound(error)) {\n error.routeId ??= matchData.value?.routeId as any\n throw error\n }\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Warning: Error in route match: ${actualMatchId}`)\n }\n routeOnCatch.value?.(error)\n },\n children: content,\n })\n }\n\n // Add scroll restoration if needed\n const withScrollRestoration: Array<VNode> = [\n content,\n isChildOfRoot\n ? Vue.h(Vue.Fragment, null, [\n Vue.h(OnRendered),\n router.options.scrollRestoration &&\n (isServer ?? router.isServer)\n ? Vue.h(ScrollRestoration)\n : null,\n ])\n : null,\n ].filter(Boolean) as Array<VNode>\n\n // Return single child directly to avoid Fragment wrapper that causes hydration mismatch\n if (withScrollRestoration.length === 1) {\n return withScrollRestoration[0]!\n }\n\n return Vue.h(Vue.Fragment, null, withScrollRestoration)\n }\n\n if (!hasShellComponent.value) {\n return renderMatchContent()\n }\n\n return Vue.h(ShellComponent.value, null, {\n // Important: return a fresh VNode on each slot invocation so that shell\n // components can re-render without reusing a cached VNode instance.\n default: () => renderMatchContent(),\n })\n }\n },\n})\n\n// On Rendered can't happen above the root layout because it actually\n// renders a dummy dom element to track the rendered state of the app.\n// We render a script tag with a key that changes based on the current\n// location state.__TSR_key. Also, because it's below the root layout, it\n// allows us to fire onRendered events even after a hydration mismatch\n// error that occurred above the root layout (like bad head/link tags,\n// which is common).\nconst OnRendered = Vue.defineComponent({\n name: 'OnRendered',\n setup() {\n const router = useRouter()\n\n const location = useStore(\n router.stores.resolvedLocation,\n (resolvedLocation) => resolvedLocation?.state.__TSR_key,\n )\n\n let prevHref: string | undefined\n\n Vue.watch(\n location,\n () => {\n if (location.value) {\n const currentHref = router.latestLocation.href\n if (prevHref === undefined || prevHref !== currentHref) {\n router.emit({\n type: 'onRendered',\n ...getLocationChangeInfo(\n router.stores.location.get(),\n router.stores.resolvedLocation.get(),\n ),\n })\n prevHref = currentHref\n }\n }\n },\n { immediate: true },\n )\n\n return () => null\n },\n})\n\nexport const MatchInner = Vue.defineComponent({\n name: 'MatchInner',\n props: {\n matchId: {\n type: String,\n required: true,\n },\n },\n setup(props) {\n const router = useRouter()\n\n // Use routeId from context (provided by parent Match) — stable string.\n const routeId = Vue.inject(routeIdContext)!\n const activeMatch = useStore(\n router.stores.getMatchStoreByRouteId(routeId),\n (value) => value,\n )\n\n // Combined selector for match state AND remount key\n // This ensures both are computed in the same selector call with consistent data\n const combinedState = Vue.computed(() => {\n const match = activeMatch.value\n if (!match) {\n // Route no longer exists - truly navigating away\n return null\n }\n\n const matchRouteId = match.routeId as string\n\n // Compute remount key\n const remountFn =\n (router.routesById[matchRouteId] as AnyRoute).options.remountDeps ??\n router.options.defaultRemountDeps\n\n let remountKey: string | undefined\n if (remountFn) {\n const remountDeps = remountFn({\n routeId: matchRouteId,\n loaderDeps: match.loaderDeps,\n params: match._strictParams,\n search: match._strictSearch,\n })\n remountKey = remountDeps ? JSON.stringify(remountDeps) : undefined\n }\n\n return {\n routeId: matchRouteId,\n match: {\n id: match.id,\n status: match.status,\n error: match.error,\n ssr: match.ssr,\n _forcePending: match._forcePending,\n _displayPending: match._displayPending,\n _nonReactive: match._nonReactive,\n },\n remountKey,\n }\n })\n\n const route = Vue.computed(() => {\n if (!combinedState.value) return null\n return router.routesById[combinedState.value.routeId]!\n })\n\n const match = Vue.computed(() => combinedState.value?.match)\n const remountKey = Vue.computed(() => combinedState.value?.remountKey)\n\n const getMatchPromise = (\n match: {\n id: string\n _nonReactive: {\n displayPendingPromise?: Promise<void>\n minPendingPromise?: Promise<void>\n loadPromise?: Promise<void>\n }\n },\n key: 'displayPendingPromise' | 'minPendingPromise' | 'loadPromise',\n ) => {\n return (\n router.getMatch(match.id)?._nonReactive[key] ?? match._nonReactive[key]\n )\n }\n\n return (): VNode | null => {\n // If match doesn't exist, return null (component is being unmounted or not ready)\n if (!combinedState.value || !match.value || !route.value) return null\n\n // Handle different match statuses\n if (match.value._displayPending) {\n const PendingComponent =\n route.value.options.pendingComponent ??\n router.options.defaultPendingComponent\n\n return PendingComponent ? Vue.h(PendingComponent) : null\n }\n\n if (match.value._forcePending) {\n const PendingComponent =\n route.value.options.pendingComponent ??\n router.options.defaultPendingComponent\n\n return PendingComponent ? Vue.h(PendingComponent) : null\n }\n\n if (match.value.status === 'notFound') {\n if (!isNotFound(match.value.error)) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('Invariant failed: Expected a notFound error')\n }\n\n invariant()\n }\n return renderRouteNotFound(router, route.value, match.value.error)\n }\n\n if (match.value.status === 'redirected') {\n if (!isRedirect(match.value.error)) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('Invariant failed: Expected a redirect error')\n }\n\n invariant()\n }\n throw getMatchPromise(match.value, 'loadPromise')\n }\n\n if (match.value.status === 'error') {\n // Check if this route or any parent has an error component\n const RouteErrorComponent =\n route.value.options.errorComponent ??\n router.options.defaultErrorComponent\n\n // If this route has an error component, render it directly\n // This is more reliable than relying on Vue's error boundary\n if (RouteErrorComponent) {\n return Vue.h(RouteErrorComponent, {\n error: match.value.error,\n reset: () => {\n router.invalidate()\n },\n info: {\n componentStack: '',\n },\n })\n }\n\n // If there's no error component for this route, throw the error\n // so it can bubble up to the nearest parent with an error component\n throw match.value.error\n }\n\n if (match.value.status === 'pending') {\n const pendingMinMs =\n route.value.options.pendingMinMs ?? router.options.defaultPendingMinMs\n\n const routerMatch = router.getMatch(match.value.id)\n if (\n pendingMinMs &&\n routerMatch &&\n !routerMatch._nonReactive.minPendingPromise\n ) {\n // Create a promise that will resolve after the minPendingMs\n if (!(isServer ?? router.isServer)) {\n const minPendingPromise = createControlledPromise<void>()\n\n routerMatch._nonReactive.minPendingPromise = minPendingPromise\n\n setTimeout(() => {\n minPendingPromise.resolve()\n // We've handled the minPendingPromise, so we can delete it\n routerMatch._nonReactive.minPendingPromise = undefined\n }, pendingMinMs)\n }\n }\n\n // In Vue, we render the pending component directly instead of throwing a promise\n // because Vue's Suspense doesn't catch thrown promises like React does\n const PendingComponent =\n route.value.options.pendingComponent ??\n router.options.defaultPendingComponent\n\n if (PendingComponent) {\n return Vue.h(PendingComponent)\n }\n\n // If no pending component, return null while loading\n return null\n }\n\n // Success status - render the component with remount key\n const Comp =\n route.value.options.component ?? router.options.defaultComponent\n const key = remountKey.value\n\n if (Comp) {\n // Pass key as a prop - Vue.h properly handles 'key' as a special prop\n return Vue.h(Comp, key !== undefined ? { key } : undefined)\n }\n\n return Vue.h(Outlet, key !== undefined ? { key } : undefined)\n }\n },\n})\n\nexport const Outlet = Vue.defineComponent({\n name: 'Outlet',\n setup() {\n const router = useRouter()\n const parentRouteId = Vue.inject(routeIdContext)\n\n if (!parentRouteId) {\n return (): VNode | null => null\n }\n\n // Parent state via stable routeId store — single subscription\n const parentMatch = useStore(\n router.stores.getMatchStoreByRouteId(parentRouteId),\n (v) => v,\n )\n\n const route = Vue.computed(() =>\n parentMatch.value\n ? router.routesById[parentMatch.value.routeId as string]!\n : undefined,\n )\n\n const parentGlobalNotFound = Vue.computed(\n () => parentMatch.value?.globalNotFound ?? false,\n )\n\n // Child match lookup: read the child matchId from the shared derived\n // map (one reactive node for the whole tree), then grab match state\n // directly from the pool.\n const childMatchIdMap = useStore(\n router.stores.childMatchIdByRouteId,\n (v) => v,\n )\n\n const childMatchData = Vue.computed(() => {\n const childId = childMatchIdMap.value[parentRouteId]\n if (!childId) return null\n const child = router.stores.activeMatchStoresById.get(childId)?.get()\n if (!child) return null\n\n return {\n id: child.id,\n // Key based on routeId + params only (not loaderDeps)\n // This ensures component recreates when params change,\n // but NOT when only loaderDeps change\n paramsKey: child.routeId + JSON.stringify(child._strictParams),\n }\n })\n\n return (): VNode | null => {\n if (parentGlobalNotFound.value) {\n if (!route.value) {\n return null\n }\n return renderRouteNotFound(router, route.value, undefined)\n }\n\n if (!childMatchData.value) {\n return null\n }\n\n const nextMatch = Vue.h(Match, {\n matchId: childMatchData.value.id,\n key: childMatchData.value.paramsKey,\n })\n\n // Note: We intentionally do NOT wrap in Suspense here.\n // The top-level Suspense in Matches already covers the root.\n // The old code compared matchId (e.g. \"__root__/\") with rootRouteId (\"__root__\")\n // which never matched, so this Suspense was effectively dead code.\n // With routeId-based lookup, parentRouteId === rootRouteId would match,\n // causing a double-Suspense that corrupts Vue's DOM during updates.\n return nextMatch\n }\n },\n})\n"],"mappings":"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"}
|
package/dist/esm/Matches.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyRouter, DeepPartial, MakeOptionalPathParams, MakeOptionalSearchParams, MakeRouteMatchUnion, MaskOptions, MatchRouteOptions,
|
|
1
|
+
import { AnyRouter, DeepPartial, MakeOptionalPathParams, MakeOptionalSearchParams, MakeRouteMatchUnion, MaskOptions, MatchRouteOptions, RegisteredRouter, ResolveRoute, ToSubOptionsProps } from '@tanstack/router-core';
|
|
2
2
|
import * as Vue from 'vue';
|
|
3
3
|
declare module '@tanstack/router-core' {
|
|
4
4
|
interface RouteMatchExtensions {
|
|
@@ -14,7 +14,7 @@ export declare const Matches: Vue.DefineComponent<{}, () => Vue.VNode<Vue.Render
|
|
|
14
14
|
export type UseMatchRouteOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends string = string, TTo extends string | undefined = undefined, TMaskFrom extends string = TFrom, TMaskTo extends string = ''> = ToSubOptionsProps<TRouter, TFrom, TTo> & DeepPartial<MakeOptionalSearchParams<TRouter, TFrom, TTo>> & DeepPartial<MakeOptionalPathParams<TRouter, TFrom, TTo>> & MaskOptions<TRouter, TMaskFrom, TMaskTo> & MatchRouteOptions;
|
|
15
15
|
export declare function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>(): <const TFrom extends string = string, const TTo extends string | undefined = undefined, const TMaskFrom extends string = TFrom, const TMaskTo extends string = "">(opts: UseMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>) => Vue.Ref<false | ResolveRoute<TRouter, TFrom, TTo>["types"]["allParams"]>;
|
|
16
16
|
export type MakeMatchRouteOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends string = string, TTo extends string | undefined = undefined, TMaskFrom extends string = TFrom, TMaskTo extends string = ''> = UseMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {
|
|
17
|
-
children?: ((params?:
|
|
17
|
+
children?: ((params?: ResolveRoute<TRouter, TFrom, TTo>['types']['allParams']) => Vue.VNode) | Vue.VNode;
|
|
18
18
|
};
|
|
19
19
|
export interface MatchRouteComponentType {
|
|
20
20
|
<TRouter extends AnyRouter = RegisteredRouter, TFrom extends string = string, TTo extends string | undefined = undefined>(props: MakeMatchRouteOptions<TRouter, TFrom, TTo>): Vue.VNode;
|
package/dist/esm/Matches.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Matches.js","names":["Vue","isServer","useStore","CatchBoundary","useRouter","useTransitionerSetup","matchContext","Match","MatchesContent","defineComponent","name","setup","h","MatchesInner","Matches","router","pendingElement","options","defaultPendingComponent","inner","document","ssr","Suspense","fallback","default","InnerWrap","errorComponentFn","props","class","error","message","String","onClick","reset","matchId","stores","firstMatchId","id","resetKey","loadedAt","matchIdRef","computed","value","provide","childElement","disableGlobalCatchBoundary","getResetKey","errorComponent","onCatch","process","env","NODE_ENV","console","warn","toString","undefined","children","useMatchRoute","routerState","matchRouteReactivity","opts","pending","caseSensitive","fuzzy","includeSearch","rest","matchRoute","MatchRoute","from","type","required","to","Boolean","slots","status","params","Fragment","useMatches","activeMatchesSnapshot","matches","select","useParentMatches","contextMatchId","inject","safeMatchId","slice","findIndex","d","useChildMatches"],"sources":["../../src/Matches.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useStore } from '@tanstack/vue-store'\nimport { CatchBoundary } from './CatchBoundary'\nimport { useRouter } from './useRouter'\nimport { useTransitionerSetup } from './Transitioner'\nimport { matchContext } from './matchContext'\nimport { Match } from './Match'\nimport type {\n AnyRouter,\n DeepPartial,\n ErrorComponentProps,\n MakeOptionalPathParams,\n MakeOptionalSearchParams,\n MakeRouteMatchUnion,\n MaskOptions,\n MatchRouteOptions,\n NoInfer,\n RegisteredRouter,\n ResolveRelativePath,\n ResolveRoute,\n RouteByPath,\n ToSubOptionsProps,\n} from '@tanstack/router-core'\n\n// Define a type for the error component function\ntype ErrorRouteComponentType = (props: ErrorComponentProps) => Vue.VNode\n\ndeclare module '@tanstack/router-core' {\n export interface RouteMatchExtensions {\n meta?: Array<Vue.ComponentOptions['meta'] | undefined>\n links?: Array<Vue.ComponentOptions['link'] | undefined>\n scripts?: Array<Vue.ComponentOptions['script'] | undefined>\n headScripts?: Array<Vue.ComponentOptions['script'] | undefined>\n }\n}\n\n// Create a component that renders MatchesInner with Transitioner's setup logic inlined.\n// This is critical for proper hydration - we call useTransitionerSetup() as a composable\n// rather than rendering it as a component, which avoids Fragment/element mismatches.\nconst MatchesContent = Vue.defineComponent({\n name: 'MatchesContent',\n setup() {\n // IMPORTANT: We need to ensure Transitioner's setup() runs.\n // Transitioner sets up critical functionality:\n // - router.startTransition\n // - History subscription via router.history.subscribe(router.load)\n // - Watchers for router events\n //\n // We inline Transitioner's setup logic here. Since Transitioner returns null,\n // we can call its setup function directly without affecting the render tree.\n // This is done by importing and calling useTransitionerSetup.\n useTransitionerSetup()\n\n return () => Vue.h(MatchesInner)\n },\n})\n\nexport const Matches = Vue.defineComponent({\n name: 'Matches',\n setup() {\n const router = useRouter()\n\n return () => {\n const pendingElement = router?.options?.defaultPendingComponent\n ? Vue.h(router.options.defaultPendingComponent)\n : null\n\n // Do not render a root Suspense during SSR or hydrating from SSR\n const inner =\n (isServer ?? router?.isServer ?? false) ||\n (typeof document !== 'undefined' && router?.ssr)\n ? Vue.h(MatchesContent)\n : Vue.h(\n Vue.Suspense,\n { fallback: pendingElement },\n {\n default: () => Vue.h(MatchesContent),\n },\n )\n\n return router?.options?.InnerWrap\n ? Vue.h(router.options.InnerWrap, null, { default: () => inner })\n : inner\n }\n },\n})\n\n// Create a simple error component function that matches ErrorRouteComponent\nconst errorComponentFn: ErrorRouteComponentType = (\n props: ErrorComponentProps,\n) => {\n return Vue.h('div', { class: 'error' }, [\n Vue.h('h1', null, 'Error'),\n Vue.h('p', null, props.error.message || String(props.error)),\n Vue.h('button', { onClick: props.reset }, 'Try Again'),\n ])\n}\n\nconst MatchesInner = Vue.defineComponent({\n name: 'MatchesInner',\n setup() {\n const router = useRouter()\n\n const matchId = useStore(router.stores.firstMatchId, (id) => id)\n const resetKey = useStore(router.stores.loadedAt, (loadedAt) => loadedAt)\n\n // Create a ref for the match id to provide\n const matchIdRef = Vue.computed(() => matchId.value)\n\n // Provide the matchId for child components using the InjectionKey\n Vue.provide(matchContext, matchIdRef)\n\n return () => {\n // Generate a placeholder element if matchId.value is not present\n const childElement = matchId.value\n ? Vue.h(Match, { matchId: matchId.value })\n : Vue.h('div')\n\n // If disableGlobalCatchBoundary is true, don't wrap in CatchBoundary\n if (router.options.disableGlobalCatchBoundary) {\n return childElement\n }\n\n return Vue.h(CatchBoundary, {\n getResetKey: () => resetKey.value,\n errorComponent: errorComponentFn,\n onCatch:\n process.env.NODE_ENV !== 'production'\n ? (error: Error) => {\n console.warn(\n `Warning: The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`,\n )\n console.warn(`Warning: ${error.message || error.toString()}`)\n }\n : undefined,\n children: childElement,\n })\n }\n },\n})\n\nexport type UseMatchRouteOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n> = ToSubOptionsProps<TRouter, TFrom, TTo> &\n DeepPartial<MakeOptionalSearchParams<TRouter, TFrom, TTo>> &\n DeepPartial<MakeOptionalPathParams<TRouter, TFrom, TTo>> &\n MaskOptions<TRouter, TMaskFrom, TMaskTo> &\n MatchRouteOptions\n\nexport function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>() {\n const router = useRouter()\n\n const routerState = useStore(\n router.stores.matchRouteReactivity,\n (value) => value,\n )\n\n return <\n const TFrom extends string = string,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n >(\n opts: UseMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n ): Vue.Ref<\n false | ResolveRoute<TRouter, TFrom, TTo>['types']['allParams']\n > => {\n const { pending, caseSensitive, fuzzy, includeSearch, ...rest } = opts\n\n const matchRoute = Vue.computed(() => {\n // Access routerState to establish dependency\n\n routerState.value\n return router.matchRoute(rest as any, {\n pending,\n caseSensitive,\n fuzzy,\n includeSearch,\n })\n })\n\n return matchRoute\n }\n}\n\nexport type MakeMatchRouteOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n> = UseMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | ((\n params?: RouteByPath<\n TRouter['routeTree'],\n ResolveRelativePath<TFrom, NoInfer<TTo>>\n >['types']['allParams'],\n ) => Vue.VNode)\n | Vue.VNode\n}\n\n// Create a type for the MatchRoute component that includes the generics\nexport interface MatchRouteComponentType {\n <\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n >(\n props: MakeMatchRouteOptions<TRouter, TFrom, TTo>,\n ): Vue.VNode\n new (): {\n $props: {\n from?: string\n to?: string\n fuzzy?: boolean\n caseSensitive?: boolean\n includeSearch?: boolean\n pending?: boolean\n }\n }\n}\n\nexport const MatchRoute = Vue.defineComponent({\n name: 'MatchRoute',\n props: {\n // Define props to match MakeMatchRouteOptions\n from: {\n type: String,\n required: false,\n },\n to: {\n type: String,\n required: false,\n },\n fuzzy: {\n type: Boolean,\n required: false,\n },\n caseSensitive: {\n type: Boolean,\n required: false,\n },\n includeSearch: {\n type: Boolean,\n required: false,\n },\n pending: {\n type: Boolean,\n required: false,\n },\n },\n setup(props, { slots }) {\n const router = useRouter()\n const status = useStore(\n router.stores.matchRouteReactivity,\n (value) => value.status,\n )\n\n return () => {\n if (!status.value) return null\n\n const matchRoute = useMatchRoute()\n const params = matchRoute(props as any).value as boolean\n\n // Create a component that renders the slot in a reactive manner\n if (!params || !slots.default) {\n return null\n }\n\n // For function slots, pass the params\n if (typeof slots.default === 'function') {\n // Use h to create a wrapper component that will call the slot function\n return Vue.h(Vue.Fragment, null, slots.default(params))\n }\n\n // For normal slots, just render them\n return Vue.h(Vue.Fragment, null, slots.default)\n }\n },\n}) as unknown as MatchRouteComponentType\n\nexport interface UseMatchesBaseOptions<TRouter extends AnyRouter, TSelected> {\n select?: (matches: Array<MakeRouteMatchUnion<TRouter>>) => TSelected\n}\n\nexport type UseMatchesResult<\n TRouter extends AnyRouter,\n TSelected,\n> = unknown extends TSelected ? Array<MakeRouteMatchUnion<TRouter>> : TSelected\n\nexport function useMatches<\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n>(\n opts?: UseMatchesBaseOptions<TRouter, TSelected>,\n): Vue.Ref<UseMatchesResult<TRouter, TSelected>> {\n const router = useRouter<TRouter>()\n return useStore(router.stores.activeMatchesSnapshot, (matches) => {\n return opts?.select\n ? opts.select(matches as Array<MakeRouteMatchUnion<TRouter>>)\n : (matches as any)\n })\n}\n\nexport function useParentMatches<\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n>(\n opts?: UseMatchesBaseOptions<TRouter, TSelected>,\n): Vue.Ref<UseMatchesResult<TRouter, TSelected>> {\n // Use matchContext with proper type\n const contextMatchId = Vue.inject<Vue.Ref<string | undefined>>(matchContext)\n const safeMatchId = Vue.computed(() => contextMatchId?.value || '')\n\n return useMatches({\n select: (matches: Array<MakeRouteMatchUnion<TRouter>>) => {\n matches = matches.slice(\n 0,\n matches.findIndex((d) => d.id === safeMatchId.value),\n )\n return opts?.select ? opts.select(matches) : matches\n },\n } as any)\n}\n\nexport function useChildMatches<\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n>(\n opts?: UseMatchesBaseOptions<TRouter, TSelected>,\n): Vue.Ref<UseMatchesResult<TRouter, TSelected>> {\n // Use matchContext with proper type\n const contextMatchId = Vue.inject<Vue.Ref<string | undefined>>(matchContext)\n const safeMatchId = Vue.computed(() => contextMatchId?.value || '')\n\n return useMatches({\n select: (matches: Array<MakeRouteMatchUnion<TRouter>>) => {\n matches = matches.slice(\n matches.findIndex((d) => d.id === safeMatchId.value) + 1,\n )\n return opts?.select ? opts.select(matches) : matches\n },\n } as any)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Matches.js","names":["Vue","isServer","useStore","CatchBoundary","useRouter","useTransitionerSetup","matchContext","Match","MatchesContent","defineComponent","name","setup","h","MatchesInner","Matches","router","pendingElement","options","defaultPendingComponent","inner","document","ssr","Suspense","fallback","default","InnerWrap","errorComponentFn","props","class","error","message","String","onClick","reset","matchId","stores","firstMatchId","id","resetKey","loadedAt","matchIdRef","computed","value","provide","childElement","disableGlobalCatchBoundary","getResetKey","errorComponent","onCatch","process","env","NODE_ENV","console","warn","toString","undefined","children","useMatchRoute","routerState","matchRouteReactivity","opts","pending","caseSensitive","fuzzy","includeSearch","rest","matchRoute","MatchRoute","from","type","required","to","Boolean","slots","status","params","Fragment","useMatches","activeMatchesSnapshot","matches","select","useParentMatches","contextMatchId","inject","safeMatchId","slice","findIndex","d","useChildMatches"],"sources":["../../src/Matches.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useStore } from '@tanstack/vue-store'\nimport { CatchBoundary } from './CatchBoundary'\nimport { useRouter } from './useRouter'\nimport { useTransitionerSetup } from './Transitioner'\nimport { matchContext } from './matchContext'\nimport { Match } from './Match'\nimport type {\n AnyRouter,\n DeepPartial,\n ErrorComponentProps,\n MakeOptionalPathParams,\n MakeOptionalSearchParams,\n MakeRouteMatchUnion,\n MaskOptions,\n MatchRouteOptions,\n RegisteredRouter,\n ResolveRoute,\n ToSubOptionsProps,\n} from '@tanstack/router-core'\n\n// Define a type for the error component function\ntype ErrorRouteComponentType = (props: ErrorComponentProps) => Vue.VNode\n\ndeclare module '@tanstack/router-core' {\n export interface RouteMatchExtensions {\n meta?: Array<Vue.ComponentOptions['meta'] | undefined>\n links?: Array<Vue.ComponentOptions['link'] | undefined>\n scripts?: Array<Vue.ComponentOptions['script'] | undefined>\n headScripts?: Array<Vue.ComponentOptions['script'] | undefined>\n }\n}\n\n// Create a component that renders MatchesInner with Transitioner's setup logic inlined.\n// This is critical for proper hydration - we call useTransitionerSetup() as a composable\n// rather than rendering it as a component, which avoids Fragment/element mismatches.\nconst MatchesContent = Vue.defineComponent({\n name: 'MatchesContent',\n setup() {\n // IMPORTANT: We need to ensure Transitioner's setup() runs.\n // Transitioner sets up critical functionality:\n // - router.startTransition\n // - History subscription via router.history.subscribe(router.load)\n // - Watchers for router events\n //\n // We inline Transitioner's setup logic here. Since Transitioner returns null,\n // we can call its setup function directly without affecting the render tree.\n // This is done by importing and calling useTransitionerSetup.\n useTransitionerSetup()\n\n return () => Vue.h(MatchesInner)\n },\n})\n\nexport const Matches = Vue.defineComponent({\n name: 'Matches',\n setup() {\n const router = useRouter()\n\n return () => {\n const pendingElement = router?.options?.defaultPendingComponent\n ? Vue.h(router.options.defaultPendingComponent)\n : null\n\n // Do not render a root Suspense during SSR or hydrating from SSR\n const inner =\n (isServer ?? router?.isServer ?? false) ||\n (typeof document !== 'undefined' && router?.ssr)\n ? Vue.h(MatchesContent)\n : Vue.h(\n Vue.Suspense,\n { fallback: pendingElement },\n {\n default: () => Vue.h(MatchesContent),\n },\n )\n\n return router?.options?.InnerWrap\n ? Vue.h(router.options.InnerWrap, null, { default: () => inner })\n : inner\n }\n },\n})\n\n// Create a simple error component function that matches ErrorRouteComponent\nconst errorComponentFn: ErrorRouteComponentType = (\n props: ErrorComponentProps,\n) => {\n return Vue.h('div', { class: 'error' }, [\n Vue.h('h1', null, 'Error'),\n Vue.h('p', null, props.error.message || String(props.error)),\n Vue.h('button', { onClick: props.reset }, 'Try Again'),\n ])\n}\n\nconst MatchesInner = Vue.defineComponent({\n name: 'MatchesInner',\n setup() {\n const router = useRouter()\n\n const matchId = useStore(router.stores.firstMatchId, (id) => id)\n const resetKey = useStore(router.stores.loadedAt, (loadedAt) => loadedAt)\n\n // Create a ref for the match id to provide\n const matchIdRef = Vue.computed(() => matchId.value)\n\n // Provide the matchId for child components using the InjectionKey\n Vue.provide(matchContext, matchIdRef)\n\n return () => {\n // Generate a placeholder element if matchId.value is not present\n const childElement = matchId.value\n ? Vue.h(Match, { matchId: matchId.value })\n : Vue.h('div')\n\n // If disableGlobalCatchBoundary is true, don't wrap in CatchBoundary\n if (router.options.disableGlobalCatchBoundary) {\n return childElement\n }\n\n return Vue.h(CatchBoundary, {\n getResetKey: () => resetKey.value,\n errorComponent: errorComponentFn,\n onCatch:\n process.env.NODE_ENV !== 'production'\n ? (error: Error) => {\n console.warn(\n `Warning: The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`,\n )\n console.warn(`Warning: ${error.message || error.toString()}`)\n }\n : undefined,\n children: childElement,\n })\n }\n },\n})\n\nexport type UseMatchRouteOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n> = ToSubOptionsProps<TRouter, TFrom, TTo> &\n DeepPartial<MakeOptionalSearchParams<TRouter, TFrom, TTo>> &\n DeepPartial<MakeOptionalPathParams<TRouter, TFrom, TTo>> &\n MaskOptions<TRouter, TMaskFrom, TMaskTo> &\n MatchRouteOptions\n\nexport function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>() {\n const router = useRouter()\n\n const routerState = useStore(\n router.stores.matchRouteReactivity,\n (value) => value,\n )\n\n return <\n const TFrom extends string = string,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n >(\n opts: UseMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n ): Vue.Ref<\n false | ResolveRoute<TRouter, TFrom, TTo>['types']['allParams']\n > => {\n const { pending, caseSensitive, fuzzy, includeSearch, ...rest } = opts\n\n const matchRoute = Vue.computed(() => {\n // Access routerState to establish dependency\n\n routerState.value\n return router.matchRoute(rest as any, {\n pending,\n caseSensitive,\n fuzzy,\n includeSearch,\n })\n })\n\n return matchRoute\n }\n}\n\nexport type MakeMatchRouteOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n> = UseMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | ((\n params?: ResolveRoute<TRouter, TFrom, TTo>['types']['allParams'],\n ) => Vue.VNode)\n | Vue.VNode\n}\n\n// Create a type for the MatchRoute component that includes the generics\nexport interface MatchRouteComponentType {\n <\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n >(\n props: MakeMatchRouteOptions<TRouter, TFrom, TTo>,\n ): Vue.VNode\n new (): {\n $props: {\n from?: string\n to?: string\n fuzzy?: boolean\n caseSensitive?: boolean\n includeSearch?: boolean\n pending?: boolean\n }\n }\n}\n\nexport const MatchRoute = Vue.defineComponent({\n name: 'MatchRoute',\n props: {\n // Define props to match MakeMatchRouteOptions\n from: {\n type: String,\n required: false,\n },\n to: {\n type: String,\n required: false,\n },\n fuzzy: {\n type: Boolean,\n required: false,\n },\n caseSensitive: {\n type: Boolean,\n required: false,\n },\n includeSearch: {\n type: Boolean,\n required: false,\n },\n pending: {\n type: Boolean,\n required: false,\n },\n },\n setup(props, { slots }) {\n const router = useRouter()\n const status = useStore(\n router.stores.matchRouteReactivity,\n (value) => value.status,\n )\n\n return () => {\n if (!status.value) return null\n\n const matchRoute = useMatchRoute()\n const params = matchRoute(props as any).value as boolean\n\n // Create a component that renders the slot in a reactive manner\n if (!params || !slots.default) {\n return null\n }\n\n // For function slots, pass the params\n if (typeof slots.default === 'function') {\n // Use h to create a wrapper component that will call the slot function\n return Vue.h(Vue.Fragment, null, slots.default(params))\n }\n\n // For normal slots, just render them\n return Vue.h(Vue.Fragment, null, slots.default)\n }\n },\n}) as unknown as MatchRouteComponentType\n\nexport interface UseMatchesBaseOptions<TRouter extends AnyRouter, TSelected> {\n select?: (matches: Array<MakeRouteMatchUnion<TRouter>>) => TSelected\n}\n\nexport type UseMatchesResult<\n TRouter extends AnyRouter,\n TSelected,\n> = unknown extends TSelected ? Array<MakeRouteMatchUnion<TRouter>> : TSelected\n\nexport function useMatches<\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n>(\n opts?: UseMatchesBaseOptions<TRouter, TSelected>,\n): Vue.Ref<UseMatchesResult<TRouter, TSelected>> {\n const router = useRouter<TRouter>()\n return useStore(router.stores.activeMatchesSnapshot, (matches) => {\n return opts?.select\n ? opts.select(matches as Array<MakeRouteMatchUnion<TRouter>>)\n : (matches as any)\n })\n}\n\nexport function useParentMatches<\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n>(\n opts?: UseMatchesBaseOptions<TRouter, TSelected>,\n): Vue.Ref<UseMatchesResult<TRouter, TSelected>> {\n // Use matchContext with proper type\n const contextMatchId = Vue.inject<Vue.Ref<string | undefined>>(matchContext)\n const safeMatchId = Vue.computed(() => contextMatchId?.value || '')\n\n return useMatches({\n select: (matches: Array<MakeRouteMatchUnion<TRouter>>) => {\n matches = matches.slice(\n 0,\n matches.findIndex((d) => d.id === safeMatchId.value),\n )\n return opts?.select ? opts.select(matches) : matches\n },\n } as any)\n}\n\nexport function useChildMatches<\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n>(\n opts?: UseMatchesBaseOptions<TRouter, TSelected>,\n): Vue.Ref<UseMatchesResult<TRouter, TSelected>> {\n // Use matchContext with proper type\n const contextMatchId = Vue.inject<Vue.Ref<string | undefined>>(matchContext)\n const safeMatchId = Vue.computed(() => contextMatchId?.value || '')\n\n return useMatches({\n select: (matches: Array<MakeRouteMatchUnion<TRouter>>) => {\n matches = matches.slice(\n matches.findIndex((d) => d.id === safeMatchId.value) + 1,\n )\n return opts?.select ? opts.select(matches) : matches\n },\n } as any)\n}\n"],"mappings":"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"}
|
package/dist/esm/Transitioner.js
CHANGED
|
@@ -33,13 +33,13 @@ function useTransitionerSetup() {
|
|
|
33
33
|
router.startTransition = (fn) => {
|
|
34
34
|
isTransitioning.value = true;
|
|
35
35
|
try {
|
|
36
|
-
router.stores.isTransitioning.
|
|
36
|
+
router.stores.isTransitioning.set(true);
|
|
37
37
|
} catch {}
|
|
38
38
|
const endTransition = () => {
|
|
39
39
|
Vue.nextTick(() => {
|
|
40
40
|
try {
|
|
41
41
|
isTransitioning.value = false;
|
|
42
|
-
router.stores.isTransitioning.
|
|
42
|
+
router.stores.isTransitioning.set(false);
|
|
43
43
|
} catch {}
|
|
44
44
|
});
|
|
45
45
|
};
|
|
@@ -74,9 +74,9 @@ function useTransitionerSetup() {
|
|
|
74
74
|
Vue.onMounted(() => {
|
|
75
75
|
isMounted.value = true;
|
|
76
76
|
if (!isAnyPending.value) {
|
|
77
|
-
if (router.stores.status.
|
|
78
|
-
router.stores.status.
|
|
79
|
-
router.stores.resolvedLocation.
|
|
77
|
+
if (router.stores.status.get() === "pending") batch(() => {
|
|
78
|
+
router.stores.status.set("idle");
|
|
79
|
+
router.stores.resolvedLocation.set(router.stores.location.get());
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
});
|
|
@@ -104,7 +104,7 @@ function useTransitionerSetup() {
|
|
|
104
104
|
try {
|
|
105
105
|
if (previousIsLoading.value.previous && !newValue) router.emit({
|
|
106
106
|
type: "onLoad",
|
|
107
|
-
...getLocationChangeInfo(router.stores.location.
|
|
107
|
+
...getLocationChangeInfo(router.stores.location.get(), router.stores.resolvedLocation.get())
|
|
108
108
|
});
|
|
109
109
|
} catch {}
|
|
110
110
|
});
|
|
@@ -113,19 +113,19 @@ function useTransitionerSetup() {
|
|
|
113
113
|
try {
|
|
114
114
|
if (previousIsPagePending.value.previous && !newValue) router.emit({
|
|
115
115
|
type: "onBeforeRouteMount",
|
|
116
|
-
...getLocationChangeInfo(router.stores.location.
|
|
116
|
+
...getLocationChangeInfo(router.stores.location.get(), router.stores.resolvedLocation.get())
|
|
117
117
|
});
|
|
118
118
|
} catch {}
|
|
119
119
|
});
|
|
120
120
|
Vue.watch(isAnyPending, (newValue) => {
|
|
121
121
|
if (!isMounted.value) return;
|
|
122
122
|
try {
|
|
123
|
-
if (!newValue && router.stores.status.
|
|
124
|
-
router.stores.status.
|
|
125
|
-
router.stores.resolvedLocation.
|
|
123
|
+
if (!newValue && router.stores.status.get() === "pending") batch(() => {
|
|
124
|
+
router.stores.status.set("idle");
|
|
125
|
+
router.stores.resolvedLocation.set(router.stores.location.get());
|
|
126
126
|
});
|
|
127
127
|
if (previousIsAnyPending.value.previous && !newValue) {
|
|
128
|
-
const changeInfo = getLocationChangeInfo(router.stores.location.
|
|
128
|
+
const changeInfo = getLocationChangeInfo(router.stores.location.get(), router.stores.resolvedLocation.get());
|
|
129
129
|
router.emit({
|
|
130
130
|
type: "onResolved",
|
|
131
131
|
...changeInfo
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transitioner.js","names":["Vue","getLocationChangeInfo","handleHashScroll","trimPathRight","isServer","batch","useStore","useRouter","usePrevious","mountLoadForRouter","router","mounted","useTransitionerSetup","isLoading","stores","value","isTransitioning","ref","hasPendingMatches","previousIsLoading","isAnyPending","computed","previousIsAnyPending","isPagePending","previousIsPagePending","startTransition","fn","setState","endTransition","nextTick","originalStartViewTransition","__tsrOriginalStartViewTransition","startViewTransition","unsubscribe","onMounted","history","subscribe","load","nextLocation","buildLocation","to","latestLocation","pathname","search","params","hash","state","_includeValidateSearch","publicHref","commitLocation","replace","isMounted","status","resolvedLocation","location","onUnmounted","window","ssr","tryLoad","err","console","error","watch","newValue","previous","emit","type","changeInfo","hrefChanged","Transitioner","defineComponent","name","setup"],"sources":["../../src/Transitioner.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport {\n getLocationChangeInfo,\n handleHashScroll,\n trimPathRight,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { batch, useStore } from '@tanstack/vue-store'\nimport { useRouter } from './useRouter'\nimport { usePrevious } from './utils'\n\n// Track mount state per router to avoid double-loading\nlet mountLoadForRouter = { router: null as any, mounted: false }\n\n/**\n * Composable that sets up router transition logic.\n * This is called from MatchesContent to set up:\n * - router.startTransition\n * - router.startViewTransition\n * - History subscription\n * - Router event watchers\n *\n * Must be called during component setup phase.\n */\nexport function useTransitionerSetup() {\n const router = useRouter()\n\n // Skip on server - no transitions needed\n if (isServer ?? router.isServer) {\n return\n }\n\n const isLoading = useStore(router.stores.isLoading, (value) => value)\n\n // Track if we're in a transition - using a ref to track async transitions\n const isTransitioning = Vue.ref(false)\n\n // Track pending state changes\n const hasPendingMatches = useStore(\n router.stores.hasPendingMatches,\n (value) => value,\n )\n\n const previousIsLoading = usePrevious(() => isLoading.value)\n\n const isAnyPending = Vue.computed(\n () => isLoading.value || isTransitioning.value || hasPendingMatches.value,\n )\n const previousIsAnyPending = usePrevious(() => isAnyPending.value)\n\n const isPagePending = Vue.computed(\n () => isLoading.value || hasPendingMatches.value,\n )\n const previousIsPagePending = usePrevious(() => isPagePending.value)\n\n // Implement startTransition similar to React/Solid\n // Vue doesn't have a native useTransition like React 18, so we simulate it\n // We also update the router state's isTransitioning flag so useMatch can check it\n router.startTransition = (fn: () => void | Promise<void>) => {\n isTransitioning.value = true\n // Also update the router state so useMatch knows we're transitioning\n try {\n router.stores.isTransitioning.setState(() => true)\n } catch {\n // Ignore errors if component is unmounted\n }\n\n // Helper to end the transition\n const endTransition = () => {\n // Use nextTick to ensure Vue has processed all reactive updates\n Vue.nextTick(() => {\n try {\n isTransitioning.value = false\n router.stores.isTransitioning.setState(() => false)\n } catch {\n // Ignore errors if component is unmounted\n }\n })\n }\n\n // Execute the function synchronously\n // The function internally may call startViewTransition which schedules async work\n // via document.startViewTransition, but we don't need to wait for it here\n // because Vue's reactivity will trigger re-renders when state changes\n fn()\n\n // End the transition on next tick to allow Vue to process reactive updates\n endTransition()\n }\n\n // Vue updates DOM asynchronously (next tick). The View Transitions API expects the\n // update callback promise to resolve only after the DOM has been updated.\n // Wrap the router-core implementation to await a Vue flush before resolving.\n const originalStartViewTransition:\n | undefined\n | ((fn: () => Promise<void>) => void) =\n (router as any).__tsrOriginalStartViewTransition ??\n router.startViewTransition\n\n ;(router as any).__tsrOriginalStartViewTransition =\n originalStartViewTransition\n\n router.startViewTransition = (fn: () => Promise<void>) => {\n return originalStartViewTransition?.(async () => {\n await fn()\n await Vue.nextTick()\n })\n }\n\n // Subscribe to location changes\n // and try to load the new location\n let unsubscribe: (() => void) | undefined\n\n Vue.onMounted(() => {\n unsubscribe = router.history.subscribe(router.load)\n\n const nextLocation = router.buildLocation({\n to: router.latestLocation.pathname,\n search: true,\n params: true,\n hash: true,\n state: true,\n _includeValidateSearch: true,\n })\n\n // Check if the current URL matches the canonical form.\n // Compare publicHref (browser-facing URL) for consistency with\n // the server-side redirect check in router.beforeLoad.\n if (\n trimPathRight(router.latestLocation.publicHref) !==\n trimPathRight(nextLocation.publicHref)\n ) {\n router.commitLocation({ ...nextLocation, replace: true })\n }\n })\n\n // Track if component is mounted to prevent updates after unmount\n const isMounted = Vue.ref(false)\n\n Vue.onMounted(() => {\n isMounted.value = true\n if (!isAnyPending.value) {\n if (router.stores.status.state === 'pending') {\n batch(() => {\n router.stores.status.setState(() => 'idle')\n router.stores.resolvedLocation.setState(\n () => router.stores.location.state,\n )\n })\n }\n }\n })\n\n Vue.onUnmounted(() => {\n isMounted.value = false\n if (unsubscribe) {\n unsubscribe()\n }\n })\n\n // Try to load the initial location\n Vue.onMounted(() => {\n if (\n (typeof window !== 'undefined' && router.ssr) ||\n (mountLoadForRouter.router === router && mountLoadForRouter.mounted)\n ) {\n return\n }\n mountLoadForRouter = { router, mounted: true }\n const tryLoad = async () => {\n try {\n await router.load()\n } catch (err) {\n console.error(err)\n }\n }\n tryLoad()\n })\n\n // Setup watchers for emitting events\n // All watchers check isMounted to prevent updates after unmount\n Vue.watch(\n () => isLoading.value,\n (newValue) => {\n if (!isMounted.value) return\n try {\n if (previousIsLoading.value.previous && !newValue) {\n router.emit({\n type: 'onLoad',\n ...getLocationChangeInfo(\n router.stores.location.state,\n router.stores.resolvedLocation.state,\n ),\n })\n }\n } catch {\n // Ignore errors if component is unmounted\n }\n },\n )\n\n Vue.watch(isPagePending, (newValue) => {\n if (!isMounted.value) return\n try {\n // emit onBeforeRouteMount\n if (previousIsPagePending.value.previous && !newValue) {\n router.emit({\n type: 'onBeforeRouteMount',\n ...getLocationChangeInfo(\n router.stores.location.state,\n router.stores.resolvedLocation.state,\n ),\n })\n }\n } catch {\n // Ignore errors if component is unmounted\n }\n })\n\n Vue.watch(isAnyPending, (newValue) => {\n if (!isMounted.value) return\n try {\n if (!newValue && router.stores.status.state === 'pending') {\n batch(() => {\n router.stores.status.setState(() => 'idle')\n router.stores.resolvedLocation.setState(\n () => router.stores.location.state,\n )\n })\n }\n\n // The router was pending and now it's not\n if (previousIsAnyPending.value.previous && !newValue) {\n const changeInfo = getLocationChangeInfo(\n router.stores.location.state,\n router.stores.resolvedLocation.state,\n )\n router.emit({\n type: 'onResolved',\n ...changeInfo,\n })\n\n if (changeInfo.hrefChanged) {\n handleHashScroll(router)\n }\n }\n } catch {\n // Ignore errors if component is unmounted\n }\n })\n}\n\n/**\n * @deprecated Use useTransitionerSetup() composable instead.\n * This component is kept for backwards compatibility but the setup logic\n * has been moved to useTransitionerSetup() for better SSR hydration.\n */\nexport const Transitioner = Vue.defineComponent({\n name: 'Transitioner',\n setup() {\n useTransitionerSetup()\n return () => null\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Transitioner.js","names":["Vue","getLocationChangeInfo","handleHashScroll","trimPathRight","isServer","batch","useStore","useRouter","usePrevious","mountLoadForRouter","router","mounted","useTransitionerSetup","isLoading","stores","value","isTransitioning","ref","hasPendingMatches","previousIsLoading","isAnyPending","computed","previousIsAnyPending","isPagePending","previousIsPagePending","startTransition","fn","set","endTransition","nextTick","originalStartViewTransition","__tsrOriginalStartViewTransition","startViewTransition","unsubscribe","onMounted","history","subscribe","load","nextLocation","buildLocation","to","latestLocation","pathname","search","params","hash","state","_includeValidateSearch","publicHref","commitLocation","replace","isMounted","status","get","resolvedLocation","location","onUnmounted","window","ssr","tryLoad","err","console","error","watch","newValue","previous","emit","type","changeInfo","hrefChanged","Transitioner","defineComponent","name","setup"],"sources":["../../src/Transitioner.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport {\n getLocationChangeInfo,\n handleHashScroll,\n trimPathRight,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { batch, useStore } from '@tanstack/vue-store'\nimport { useRouter } from './useRouter'\nimport { usePrevious } from './utils'\n\n// Track mount state per router to avoid double-loading\nlet mountLoadForRouter = { router: null as any, mounted: false }\n\n/**\n * Composable that sets up router transition logic.\n * This is called from MatchesContent to set up:\n * - router.startTransition\n * - router.startViewTransition\n * - History subscription\n * - Router event watchers\n *\n * Must be called during component setup phase.\n */\nexport function useTransitionerSetup() {\n const router = useRouter()\n\n // Skip on server - no transitions needed\n if (isServer ?? router.isServer) {\n return\n }\n\n const isLoading = useStore(router.stores.isLoading, (value) => value)\n\n // Track if we're in a transition - using a ref to track async transitions\n const isTransitioning = Vue.ref(false)\n\n // Track pending state changes\n const hasPendingMatches = useStore(\n router.stores.hasPendingMatches,\n (value) => value,\n )\n\n const previousIsLoading = usePrevious(() => isLoading.value)\n\n const isAnyPending = Vue.computed(\n () => isLoading.value || isTransitioning.value || hasPendingMatches.value,\n )\n const previousIsAnyPending = usePrevious(() => isAnyPending.value)\n\n const isPagePending = Vue.computed(\n () => isLoading.value || hasPendingMatches.value,\n )\n const previousIsPagePending = usePrevious(() => isPagePending.value)\n\n // Implement startTransition similar to React/Solid\n // Vue doesn't have a native useTransition like React 18, so we simulate it\n // We also update the router state's isTransitioning flag so useMatch can check it\n router.startTransition = (fn: () => void | Promise<void>) => {\n isTransitioning.value = true\n // Also update the router state so useMatch knows we're transitioning\n try {\n router.stores.isTransitioning.set(true)\n } catch {\n // Ignore errors if component is unmounted\n }\n\n // Helper to end the transition\n const endTransition = () => {\n // Use nextTick to ensure Vue has processed all reactive updates\n Vue.nextTick(() => {\n try {\n isTransitioning.value = false\n router.stores.isTransitioning.set(false)\n } catch {\n // Ignore errors if component is unmounted\n }\n })\n }\n\n // Execute the function synchronously\n // The function internally may call startViewTransition which schedules async work\n // via document.startViewTransition, but we don't need to wait for it here\n // because Vue's reactivity will trigger re-renders when state changes\n fn()\n\n // End the transition on next tick to allow Vue to process reactive updates\n endTransition()\n }\n\n // Vue updates DOM asynchronously (next tick). The View Transitions API expects the\n // update callback promise to resolve only after the DOM has been updated.\n // Wrap the router-core implementation to await a Vue flush before resolving.\n const originalStartViewTransition:\n | undefined\n | ((fn: () => Promise<void>) => void) =\n (router as any).__tsrOriginalStartViewTransition ??\n router.startViewTransition\n\n ;(router as any).__tsrOriginalStartViewTransition =\n originalStartViewTransition\n\n router.startViewTransition = (fn: () => Promise<void>) => {\n return originalStartViewTransition?.(async () => {\n await fn()\n await Vue.nextTick()\n })\n }\n\n // Subscribe to location changes\n // and try to load the new location\n let unsubscribe: (() => void) | undefined\n\n Vue.onMounted(() => {\n unsubscribe = router.history.subscribe(router.load)\n\n const nextLocation = router.buildLocation({\n to: router.latestLocation.pathname,\n search: true,\n params: true,\n hash: true,\n state: true,\n _includeValidateSearch: true,\n })\n\n // Check if the current URL matches the canonical form.\n // Compare publicHref (browser-facing URL) for consistency with\n // the server-side redirect check in router.beforeLoad.\n if (\n trimPathRight(router.latestLocation.publicHref) !==\n trimPathRight(nextLocation.publicHref)\n ) {\n router.commitLocation({ ...nextLocation, replace: true })\n }\n })\n\n // Track if component is mounted to prevent updates after unmount\n const isMounted = Vue.ref(false)\n\n Vue.onMounted(() => {\n isMounted.value = true\n if (!isAnyPending.value) {\n if (router.stores.status.get() === 'pending') {\n batch(() => {\n router.stores.status.set('idle')\n router.stores.resolvedLocation.set(router.stores.location.get())\n })\n }\n }\n })\n\n Vue.onUnmounted(() => {\n isMounted.value = false\n if (unsubscribe) {\n unsubscribe()\n }\n })\n\n // Try to load the initial location\n Vue.onMounted(() => {\n if (\n (typeof window !== 'undefined' && router.ssr) ||\n (mountLoadForRouter.router === router && mountLoadForRouter.mounted)\n ) {\n return\n }\n mountLoadForRouter = { router, mounted: true }\n const tryLoad = async () => {\n try {\n await router.load()\n } catch (err) {\n console.error(err)\n }\n }\n tryLoad()\n })\n\n // Setup watchers for emitting events\n // All watchers check isMounted to prevent updates after unmount\n Vue.watch(\n () => isLoading.value,\n (newValue) => {\n if (!isMounted.value) return\n try {\n if (previousIsLoading.value.previous && !newValue) {\n router.emit({\n type: 'onLoad',\n ...getLocationChangeInfo(\n router.stores.location.get(),\n router.stores.resolvedLocation.get(),\n ),\n })\n }\n } catch {\n // Ignore errors if component is unmounted\n }\n },\n )\n\n Vue.watch(isPagePending, (newValue) => {\n if (!isMounted.value) return\n try {\n // emit onBeforeRouteMount\n if (previousIsPagePending.value.previous && !newValue) {\n router.emit({\n type: 'onBeforeRouteMount',\n ...getLocationChangeInfo(\n router.stores.location.get(),\n router.stores.resolvedLocation.get(),\n ),\n })\n }\n } catch {\n // Ignore errors if component is unmounted\n }\n })\n\n Vue.watch(isAnyPending, (newValue) => {\n if (!isMounted.value) return\n try {\n if (!newValue && router.stores.status.get() === 'pending') {\n batch(() => {\n router.stores.status.set('idle')\n router.stores.resolvedLocation.set(router.stores.location.get())\n })\n }\n\n // The router was pending and now it's not\n if (previousIsAnyPending.value.previous && !newValue) {\n const changeInfo = getLocationChangeInfo(\n router.stores.location.get(),\n router.stores.resolvedLocation.get(),\n )\n router.emit({\n type: 'onResolved',\n ...changeInfo,\n })\n\n if (changeInfo.hrefChanged) {\n handleHashScroll(router)\n }\n }\n } catch {\n // Ignore errors if component is unmounted\n }\n })\n}\n\n/**\n * @deprecated Use useTransitionerSetup() composable instead.\n * This component is kept for backwards compatibility but the setup logic\n * has been moved to useTransitionerSetup() for better SSR hydration.\n */\nexport const Transitioner = Vue.defineComponent({\n name: 'Transitioner',\n setup() {\n useTransitionerSetup()\n return () => null\n },\n})\n"],"mappings":"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"}
|
package/dist/esm/link.js
CHANGED