@tanstack/react-router 1.136.3 → 1.136.5

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.
@@ -142,12 +142,27 @@ const useTags = () => {
142
142
  })),
143
143
  structuralSharing: true
144
144
  });
145
+ let serverHeadScript = void 0;
146
+ if (router.serverSsr) {
147
+ const bufferedScripts = router.serverSsr.takeBufferedScripts();
148
+ if (bufferedScripts) {
149
+ serverHeadScript = {
150
+ tag: "script",
151
+ attrs: {
152
+ nonce,
153
+ className: "$tsr"
154
+ },
155
+ children: bufferedScripts
156
+ };
157
+ }
158
+ }
145
159
  return uniqBy(
146
160
  [
147
161
  ...meta,
148
162
  ...preloadMeta,
149
163
  ...links,
150
164
  ...styles,
165
+ ...serverHeadScript ? [serverHeadScript] : [],
151
166
  ...headScripts
152
167
  ],
153
168
  (d) => {
@@ -1 +1 @@
1
- {"version":3,"file":"HeadContent.cjs","sources":["../../src/HeadContent.tsx"],"sourcesContent":["import * as React from 'react'\nimport { Asset } from './Asset'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\n/**\n * Build the list of head/link/meta/script tags to render for active matches.\n * Used internally by `HeadContent`.\n */\nexport const useTags = () => {\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n const routeMeta = useRouterState({\n select: (state) => {\n return state.matches.map((match) => match.meta!).filter(Boolean)\n },\n })\n\n const meta: Array<RouterManagedTag> = React.useMemo(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n for (let i = routeMeta.length - 1; i >= 0; i--) {\n const metas = routeMeta[i]!\n for (let j = metas.length - 1; j >= 0; j--) {\n const m = metas[j]\n if (!m) continue\n\n if (m.title) {\n if (!title) {\n title = {\n tag: 'title',\n children: m.title,\n }\n }\n } else {\n const attribute = m.name ?? m.property\n if (attribute) {\n if (metaByAttribute[attribute]) {\n continue\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n nonce,\n },\n })\n }\n }\n }\n\n if (title) {\n resultMeta.push(title)\n }\n\n if (nonce) {\n resultMeta.push({\n tag: 'meta',\n attrs: {\n property: 'csp-nonce',\n content: nonce,\n },\n })\n }\n resultMeta.reverse()\n\n return resultMeta\n }, [routeMeta, nonce])\n\n const links = useRouterState({\n select: (state) => {\n const constructed = state.matches\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n nonce,\n },\n })) satisfies Array<RouterManagedTag>\n\n const manifest = router.ssr?.manifest\n\n // These are the assets extracted from the ViteManifest\n // using the `startManifestPlugin`\n const assets = state.matches\n .map((match) => manifest?.routes[match.routeId]?.assets ?? [])\n .filter(Boolean)\n .flat(1)\n .filter((asset) => asset.tag === 'link')\n .map(\n (asset) =>\n ({\n tag: 'link',\n attrs: {\n ...asset.attrs,\n suppressHydrationWarning: true,\n nonce,\n },\n }) satisfies RouterManagedTag,\n )\n\n return [...constructed, ...assets]\n },\n structuralSharing: true as any,\n })\n\n const preloadMeta = useRouterState({\n select: (state) => {\n const preloadMeta: Array<RouterManagedTag> = []\n\n state.matches\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n router.ssr?.manifest?.routes[route.id]?.preloads\n ?.filter(Boolean)\n .forEach((preload) => {\n preloadMeta.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n nonce,\n },\n })\n }),\n )\n\n return preloadMeta\n },\n structuralSharing: true as any,\n })\n\n const styles = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.styles!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...attrs }) => ({\n tag: 'style',\n attrs,\n children,\n nonce,\n })),\n structuralSharing: true as any,\n })\n\n const headScripts = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.headScripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script',\n attrs: {\n ...script,\n nonce,\n },\n children,\n })),\n structuralSharing: true as any,\n })\n\n return uniqBy(\n [\n ...meta,\n ...preloadMeta,\n ...links,\n ...styles,\n ...headScripts,\n ] as Array<RouterManagedTag>,\n (d) => {\n return JSON.stringify(d)\n },\n )\n}\n\n/**\n * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.\n * It should be rendered in the `<head>` of your document.\n */\n/**\n * Render route-managed head tags (title, meta, links, styles, head scripts).\n * Place inside the document head of your app shell.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/document-head-management\n */\nexport function HeadContent() {\n const tags = useTags()\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n return tags.map((tag) => (\n <Asset {...tag} key={`tsr-meta-${JSON.stringify(tag)}`} nonce={nonce} />\n ))\n}\n\nfunction uniqBy<T>(arr: Array<T>, fn: (item: T) => string) {\n const seen = new Set<string>()\n return arr.filter((item) => {\n const key = fn(item)\n if (seen.has(key)) {\n return false\n }\n seen.add(key)\n return true\n })\n}\n"],"names":["useRouter","useRouterState","React","preloadMeta","createElement","Asset"],"mappings":"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"}
1
+ {"version":3,"file":"HeadContent.cjs","sources":["../../src/HeadContent.tsx"],"sourcesContent":["import * as React from 'react'\nimport { Asset } from './Asset'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\n/**\n * Build the list of head/link/meta/script tags to render for active matches.\n * Used internally by `HeadContent`.\n */\nexport const useTags = () => {\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n const routeMeta = useRouterState({\n select: (state) => {\n return state.matches.map((match) => match.meta!).filter(Boolean)\n },\n })\n\n const meta: Array<RouterManagedTag> = React.useMemo(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n for (let i = routeMeta.length - 1; i >= 0; i--) {\n const metas = routeMeta[i]!\n for (let j = metas.length - 1; j >= 0; j--) {\n const m = metas[j]\n if (!m) continue\n\n if (m.title) {\n if (!title) {\n title = {\n tag: 'title',\n children: m.title,\n }\n }\n } else {\n const attribute = m.name ?? m.property\n if (attribute) {\n if (metaByAttribute[attribute]) {\n continue\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n nonce,\n },\n })\n }\n }\n }\n\n if (title) {\n resultMeta.push(title)\n }\n\n if (nonce) {\n resultMeta.push({\n tag: 'meta',\n attrs: {\n property: 'csp-nonce',\n content: nonce,\n },\n })\n }\n resultMeta.reverse()\n\n return resultMeta\n }, [routeMeta, nonce])\n\n const links = useRouterState({\n select: (state) => {\n const constructed = state.matches\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n nonce,\n },\n })) satisfies Array<RouterManagedTag>\n\n const manifest = router.ssr?.manifest\n\n // These are the assets extracted from the ViteManifest\n // using the `startManifestPlugin`\n const assets = state.matches\n .map((match) => manifest?.routes[match.routeId]?.assets ?? [])\n .filter(Boolean)\n .flat(1)\n .filter((asset) => asset.tag === 'link')\n .map(\n (asset) =>\n ({\n tag: 'link',\n attrs: {\n ...asset.attrs,\n suppressHydrationWarning: true,\n nonce,\n },\n }) satisfies RouterManagedTag,\n )\n\n return [...constructed, ...assets]\n },\n structuralSharing: true as any,\n })\n\n const preloadMeta = useRouterState({\n select: (state) => {\n const preloadMeta: Array<RouterManagedTag> = []\n\n state.matches\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n router.ssr?.manifest?.routes[route.id]?.preloads\n ?.filter(Boolean)\n .forEach((preload) => {\n preloadMeta.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n nonce,\n },\n })\n }),\n )\n\n return preloadMeta\n },\n structuralSharing: true as any,\n })\n\n const styles = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.styles!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...attrs }) => ({\n tag: 'style',\n attrs,\n children,\n nonce,\n })),\n structuralSharing: true as any,\n })\n\n const headScripts: Array<RouterManagedTag> = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.headScripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script',\n attrs: {\n ...script,\n nonce,\n },\n children,\n })),\n structuralSharing: true as any,\n })\n\n let serverHeadScript: RouterManagedTag | undefined = undefined\n\n if (router.serverSsr) {\n const bufferedScripts = router.serverSsr.takeBufferedScripts()\n if (bufferedScripts) {\n serverHeadScript = {\n tag: 'script',\n attrs: {\n nonce,\n className: '$tsr',\n },\n children: bufferedScripts,\n }\n }\n }\n\n return uniqBy(\n [\n ...meta,\n ...preloadMeta,\n ...links,\n ...styles,\n ...(serverHeadScript ? [serverHeadScript] : []),\n ...headScripts,\n ] as Array<RouterManagedTag>,\n (d) => {\n return JSON.stringify(d)\n },\n )\n}\n\n/**\n * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.\n * It should be rendered in the `<head>` of your document.\n */\n/**\n * Render route-managed head tags (title, meta, links, styles, head scripts).\n * Place inside the document head of your app shell.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/document-head-management\n */\nexport function HeadContent() {\n const tags = useTags()\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n return tags.map((tag) => (\n <Asset {...tag} key={`tsr-meta-${JSON.stringify(tag)}`} nonce={nonce} />\n ))\n}\n\nfunction uniqBy<T>(arr: Array<T>, fn: (item: T) => string) {\n const seen = new Set<string>()\n return arr.filter((item) => {\n const key = fn(item)\n if (seen.has(key)) {\n return false\n }\n seen.add(key)\n return true\n })\n}\n"],"names":["useRouter","useRouterState","React","preloadMeta","createElement","Asset"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ScriptOnce.cjs","sources":["../../src/ScriptOnce.tsx"],"sourcesContent":["import { useRouter } from './useRouter'\n\n/**\n * Server-only helper to emit a script tag exactly once during SSR.\n * Appends an internal marker to signal hydration completion.\n */\nexport function ScriptOnce({ children }: { children: string }) {\n const router = useRouter()\n if (!router.isServer) {\n return null\n }\n\n return (\n <script\n nonce={router.options.ssr?.nonce}\n className=\"$tsr\"\n dangerouslySetInnerHTML={{\n __html: [children].filter(Boolean).join('\\n') + ';$_TSR.c()',\n }}\n />\n )\n}\n"],"names":["useRouter","jsx"],"mappings":";;;;AAMO,SAAS,WAAW,EAAE,YAAkC;AAC7D,QAAM,SAASA,UAAAA,UAAA;AACf,MAAI,CAAC,OAAO,UAAU;AACpB,WAAO;AAAA,EACT;AAEA,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO,OAAO,QAAQ,KAAK;AAAA,MAC3B,WAAU;AAAA,MACV,yBAAyB;AAAA,QACvB,QAAQ,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,IAAI;AAAA,MAAA;AAAA,IAClD;AAAA,EAAA;AAGN;;"}
1
+ {"version":3,"file":"ScriptOnce.cjs","sources":["../../src/ScriptOnce.tsx"],"sourcesContent":["import { useRouter } from './useRouter'\n\n/**\n * Server-only helper to emit a script tag exactly once during SSR.\n */\nexport function ScriptOnce({ children }: { children: string }) {\n const router = useRouter()\n if (!router.isServer) {\n return null\n }\n\n return (\n <script\n nonce={router.options.ssr?.nonce}\n className=\"$tsr\"\n dangerouslySetInnerHTML={{\n __html: [children].filter(Boolean).join('\\n') + ';$_TSR.c()',\n }}\n />\n )\n}\n"],"names":["useRouter","jsx"],"mappings":";;;;AAKO,SAAS,WAAW,EAAE,YAAkC;AAC7D,QAAM,SAASA,UAAAA,UAAA;AACf,MAAI,CAAC,OAAO,UAAU;AACpB,WAAO;AAAA,EACT;AAEA,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO,OAAO,QAAQ,KAAK;AAAA,MAC3B,WAAU;AAAA,MACV,yBAAyB;AAAA,QACvB,QAAQ,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,IAAI;AAAA,MAAA;AAAA,IAClD;AAAA,EAAA;AAGN;;"}
@@ -1,6 +1,5 @@
1
1
  /**
2
2
  * Server-only helper to emit a script tag exactly once during SSR.
3
- * Appends an internal marker to signal hydration completion.
4
3
  */
5
4
  export declare function ScriptOnce({ children }: {
6
5
  children: string;
@@ -130,22 +130,10 @@ Object.defineProperty(exports, "lazyFn", {
130
130
  enumerable: true,
131
131
  get: () => routerCore.lazyFn
132
132
  });
133
- Object.defineProperty(exports, "matchByPath", {
134
- enumerable: true,
135
- get: () => routerCore.matchByPath
136
- });
137
- Object.defineProperty(exports, "matchPathname", {
138
- enumerable: true,
139
- get: () => routerCore.matchPathname
140
- });
141
133
  Object.defineProperty(exports, "notFound", {
142
134
  enumerable: true,
143
135
  get: () => routerCore.notFound
144
136
  });
145
- Object.defineProperty(exports, "parsePathname", {
146
- enumerable: true,
147
- get: () => routerCore.parsePathname
148
- });
149
137
  Object.defineProperty(exports, "parseSearchWith", {
150
138
  enumerable: true,
151
139
  get: () => routerCore.parseSearchWith
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +1,5 @@
1
- export { defer, TSR_DEFERRED_PROMISE, isMatch, joinPaths, cleanPath, trimPathLeft, trimPathRight, trimPath, resolvePath, parsePathname, interpolatePath, matchPathname, matchByPath, rootRouteId, defaultSerializeError, defaultParseSearch, defaultStringifySearch, parseSearchWith, stringifySearchWith, functionalUpdate, replaceEqualDeep, isPlainObject, isPlainArray, deepEqual, createControlledPromise, retainSearchParams, stripSearchParams, createSerializationAdapter, } from '@tanstack/router-core';
2
- export type { AnyRoute, DeferredPromiseState, DeferredPromise, ParsedLocation, RemoveTrailingSlashes, RemoveLeadingSlashes, ActiveOptions, Segment, ResolveRelativePath, RootRouteId, AnyPathParams, ResolveParams, ResolveOptionalParams, ResolveRequiredParams, SearchSchemaInput, AnyContext, RouteContext, PreloadableObj, RoutePathOptions, StaticDataRouteOption, RoutePathOptionsIntersection, UpdatableStaticRouteOption, MetaDescriptor, RouteLinkEntry, ParseParamsFn, SearchFilter, ResolveId, InferFullSearchSchema, InferFullSearchSchemaInput, ErrorRouteProps, ErrorComponentProps, NotFoundRouteProps, TrimPath, TrimPathLeft, TrimPathRight, StringifyParamsFn, ParamsOptions, InferAllParams, InferAllContext, LooseReturnType, LooseAsyncReturnType, ContextReturnType, ContextAsyncReturnType, ResolveLoaderData, ResolveRouteContext, SearchSerializer, SearchParser, TrailingSlashOption, Manifest, RouterManagedTag, ControlledPromise, Constrain, Expand, MergeAll, Assign, IntersectAssign, ResolveValidatorInput, ResolveValidatorOutput, Register, AnyValidator, DefaultValidator, ValidatorFn, AnySchema, AnyValidatorAdapter, AnyValidatorFn, AnyValidatorObj, ResolveValidatorInputFn, ResolveValidatorOutputFn, ResolveSearchValidatorInput, ResolveSearchValidatorInputFn, Validator, ValidatorAdapter, ValidatorObj, FileRoutesByPath, RouteById, RootRouteOptions, CreateFileRoute, SerializationAdapter, AnySerializationAdapter, } from '@tanstack/router-core';
1
+ export { defer, TSR_DEFERRED_PROMISE, isMatch, joinPaths, cleanPath, trimPathLeft, trimPathRight, trimPath, resolvePath, interpolatePath, rootRouteId, defaultSerializeError, defaultParseSearch, defaultStringifySearch, parseSearchWith, stringifySearchWith, functionalUpdate, replaceEqualDeep, isPlainObject, isPlainArray, deepEqual, createControlledPromise, retainSearchParams, stripSearchParams, createSerializationAdapter, } from '@tanstack/router-core';
2
+ export type { AnyRoute, DeferredPromiseState, DeferredPromise, ParsedLocation, RemoveTrailingSlashes, RemoveLeadingSlashes, ActiveOptions, ResolveRelativePath, RootRouteId, AnyPathParams, ResolveParams, ResolveOptionalParams, ResolveRequiredParams, SearchSchemaInput, AnyContext, RouteContext, PreloadableObj, RoutePathOptions, StaticDataRouteOption, RoutePathOptionsIntersection, UpdatableStaticRouteOption, MetaDescriptor, RouteLinkEntry, ParseParamsFn, SearchFilter, ResolveId, InferFullSearchSchema, InferFullSearchSchemaInput, ErrorRouteProps, ErrorComponentProps, NotFoundRouteProps, TrimPath, TrimPathLeft, TrimPathRight, StringifyParamsFn, ParamsOptions, InferAllParams, InferAllContext, LooseReturnType, LooseAsyncReturnType, ContextReturnType, ContextAsyncReturnType, ResolveLoaderData, ResolveRouteContext, SearchSerializer, SearchParser, TrailingSlashOption, Manifest, RouterManagedTag, ControlledPromise, Constrain, Expand, MergeAll, Assign, IntersectAssign, ResolveValidatorInput, ResolveValidatorOutput, Register, AnyValidator, DefaultValidator, ValidatorFn, AnySchema, AnyValidatorAdapter, AnyValidatorFn, AnyValidatorObj, ResolveValidatorInputFn, ResolveValidatorOutputFn, ResolveSearchValidatorInput, ResolveSearchValidatorInputFn, Validator, ValidatorAdapter, ValidatorObj, FileRoutesByPath, RouteById, RootRouteOptions, CreateFileRoute, SerializationAdapter, AnySerializationAdapter, } from '@tanstack/router-core';
3
3
  export { createHistory, createBrowserHistory, createHashHistory, createMemoryHistory, } from '@tanstack/history';
4
4
  export type { BlockerFn, HistoryLocation, RouterHistory, ParsedPath, HistoryState, } from '@tanstack/history';
5
5
  export { useAwaited, Await } from './awaited.cjs';
@@ -76,10 +76,7 @@ function useBlocker(opts, condition) {
76
76
  const blockerFnComposed = async (blockerFnArgs) => {
77
77
  function getLocation(location) {
78
78
  const parsedLocation = router.parseLocation(location);
79
- const matchedRoutes = router.getMatchedRoutes(
80
- parsedLocation.pathname,
81
- void 0
82
- );
79
+ const matchedRoutes = router.getMatchedRoutes(parsedLocation.pathname);
83
80
  if (matchedRoutes.foundRoute === void 0) {
84
81
  throw new Error(`No route found for location ${location.href}`);
85
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useBlocker.cjs","sources":["../../src/useBlocker.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useRouter } from './useRouter'\nimport type {\n BlockerFnArgs,\n HistoryAction,\n HistoryLocation,\n} from '@tanstack/history'\nimport type {\n AnyRoute,\n AnyRouter,\n ParseRoute,\n RegisteredRouter,\n} from '@tanstack/router-core'\n\ninterface ShouldBlockFnLocation<\n out TRouteId,\n out TFullPath,\n out TAllParams,\n out TFullSearchSchema,\n> {\n routeId: TRouteId\n fullPath: TFullPath\n pathname: string\n params: TAllParams\n search: TFullSearchSchema\n}\n\ntype AnyShouldBlockFnLocation = ShouldBlockFnLocation<any, any, any, any>\ntype MakeShouldBlockFnLocationUnion<\n TRouter extends AnyRouter = RegisteredRouter,\n TRoute extends AnyRoute = ParseRoute<TRouter['routeTree']>,\n> = TRoute extends any\n ? ShouldBlockFnLocation<\n TRoute['id'],\n TRoute['fullPath'],\n TRoute['types']['allParams'],\n TRoute['types']['fullSearchSchema']\n >\n : never\n\ntype BlockerResolver<TRouter extends AnyRouter = RegisteredRouter> =\n | {\n status: 'blocked'\n current: MakeShouldBlockFnLocationUnion<TRouter>\n next: MakeShouldBlockFnLocationUnion<TRouter>\n action: HistoryAction\n proceed: () => void\n reset: () => void\n }\n | {\n status: 'idle'\n current: undefined\n next: undefined\n action: undefined\n proceed: undefined\n reset: undefined\n }\n\ntype ShouldBlockFnArgs<TRouter extends AnyRouter = RegisteredRouter> = {\n current: MakeShouldBlockFnLocationUnion<TRouter>\n next: MakeShouldBlockFnLocationUnion<TRouter>\n action: HistoryAction\n}\n\nexport type ShouldBlockFn<TRouter extends AnyRouter = RegisteredRouter> = (\n args: ShouldBlockFnArgs<TRouter>,\n) => boolean | Promise<boolean>\nexport type UseBlockerOpts<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n> = {\n shouldBlockFn: ShouldBlockFn<TRouter>\n enableBeforeUnload?: boolean | (() => boolean)\n disabled?: boolean\n withResolver?: TWithResolver\n}\n\ntype LegacyBlockerFn = () => Promise<any> | any\ntype LegacyBlockerOpts = {\n blockerFn?: LegacyBlockerFn\n condition?: boolean | any\n}\n\nfunction _resolveBlockerOpts(\n opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,\n condition?: boolean | any,\n): UseBlockerOpts {\n if (opts === undefined) {\n return {\n shouldBlockFn: () => true,\n withResolver: false,\n }\n }\n\n if ('shouldBlockFn' in opts) {\n return opts\n }\n\n if (typeof opts === 'function') {\n const shouldBlock = Boolean(condition ?? true)\n\n const _customBlockerFn = async () => {\n if (shouldBlock) return await opts()\n return false\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: false,\n }\n }\n\n const shouldBlock = Boolean(opts.condition ?? true)\n const fn = opts.blockerFn\n\n const _customBlockerFn = async () => {\n if (shouldBlock && fn !== undefined) {\n return await fn()\n }\n return shouldBlock\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: fn === undefined,\n }\n}\n\nexport function useBlocker<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = false,\n>(\n opts: UseBlockerOpts<TRouter, TWithResolver>,\n): TWithResolver extends true ? BlockerResolver<TRouter> : void\n\n/**\n * @deprecated Use the shouldBlockFn property instead\n */\nexport function useBlocker(blockerFnOrOpts?: LegacyBlockerOpts): BlockerResolver\n\n/**\n * @deprecated Use the UseBlockerOpts object syntax instead\n */\nexport function useBlocker(\n blockerFn?: LegacyBlockerFn,\n condition?: boolean | any,\n): BlockerResolver\n\nexport function useBlocker(\n opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,\n condition?: boolean | any,\n): BlockerResolver | void {\n const {\n shouldBlockFn,\n enableBeforeUnload = true,\n disabled = false,\n withResolver = false,\n } = _resolveBlockerOpts(opts, condition)\n\n const router = useRouter()\n const { history } = router\n\n const [resolver, setResolver] = React.useState<BlockerResolver>({\n status: 'idle',\n current: undefined,\n next: undefined,\n action: undefined,\n proceed: undefined,\n reset: undefined,\n })\n\n React.useEffect(() => {\n const blockerFnComposed = async (blockerFnArgs: BlockerFnArgs) => {\n function getLocation(\n location: HistoryLocation,\n ): AnyShouldBlockFnLocation {\n const parsedLocation = router.parseLocation(location)\n const matchedRoutes = router.getMatchedRoutes(\n parsedLocation.pathname,\n undefined,\n )\n if (matchedRoutes.foundRoute === undefined) {\n throw new Error(`No route found for location ${location.href}`)\n }\n return {\n routeId: matchedRoutes.foundRoute.id,\n fullPath: matchedRoutes.foundRoute.fullPath,\n pathname: parsedLocation.pathname,\n params: matchedRoutes.routeParams,\n search: parsedLocation.search,\n }\n }\n\n const current = getLocation(blockerFnArgs.currentLocation)\n const next = getLocation(blockerFnArgs.nextLocation)\n\n const shouldBlock = await shouldBlockFn({\n action: blockerFnArgs.action,\n current,\n next,\n })\n if (!withResolver) {\n return shouldBlock\n }\n\n if (!shouldBlock) {\n return false\n }\n\n const promise = new Promise<boolean>((resolve) => {\n setResolver({\n status: 'blocked',\n current,\n next,\n action: blockerFnArgs.action,\n proceed: () => resolve(false),\n reset: () => resolve(true),\n })\n })\n\n const canNavigateAsync = await promise\n setResolver({\n status: 'idle',\n current: undefined,\n next: undefined,\n action: undefined,\n proceed: undefined,\n reset: undefined,\n })\n\n return canNavigateAsync\n }\n\n return disabled\n ? undefined\n : history.block({ blockerFn: blockerFnComposed, enableBeforeUnload })\n }, [\n shouldBlockFn,\n enableBeforeUnload,\n disabled,\n withResolver,\n history,\n router,\n ])\n\n return resolver\n}\n\nconst _resolvePromptBlockerArgs = (\n props: PromptProps | LegacyPromptProps,\n): UseBlockerOpts => {\n if ('shouldBlockFn' in props) {\n return { ...props }\n }\n\n const shouldBlock = Boolean(props.condition ?? true)\n const fn = props.blockerFn\n\n const _customBlockerFn = async () => {\n if (shouldBlock && fn !== undefined) {\n return await fn()\n }\n return shouldBlock\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: fn === undefined,\n }\n}\n\nexport function Block<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n>(opts: PromptProps<TRouter, TWithResolver>): React.ReactNode\n\n/**\n * @deprecated Use the UseBlockerOpts property instead\n */\nexport function Block(opts: LegacyPromptProps): React.ReactNode\n\nexport function Block(opts: PromptProps | LegacyPromptProps): React.ReactNode {\n const { children, ...rest } = opts\n const args = _resolvePromptBlockerArgs(rest)\n\n const resolver = useBlocker(args)\n return children\n ? typeof children === 'function'\n ? children(resolver as any)\n : children\n : null\n}\n\ntype LegacyPromptProps = {\n blockerFn?: LegacyBlockerFn\n condition?: boolean | any\n children?: React.ReactNode | ((params: BlockerResolver) => React.ReactNode)\n}\n\ntype PromptProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n TParams = TWithResolver extends true ? BlockerResolver<TRouter> : void,\n> = UseBlockerOpts<TRouter, TWithResolver> & {\n children?: React.ReactNode | ((params: TParams) => React.ReactNode)\n}\n"],"names":["shouldBlock","_customBlockerFn","useRouter","React"],"mappings":"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"}
1
+ {"version":3,"file":"useBlocker.cjs","sources":["../../src/useBlocker.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useRouter } from './useRouter'\nimport type {\n BlockerFnArgs,\n HistoryAction,\n HistoryLocation,\n} from '@tanstack/history'\nimport type {\n AnyRoute,\n AnyRouter,\n ParseRoute,\n RegisteredRouter,\n} from '@tanstack/router-core'\n\ninterface ShouldBlockFnLocation<\n out TRouteId,\n out TFullPath,\n out TAllParams,\n out TFullSearchSchema,\n> {\n routeId: TRouteId\n fullPath: TFullPath\n pathname: string\n params: TAllParams\n search: TFullSearchSchema\n}\n\ntype AnyShouldBlockFnLocation = ShouldBlockFnLocation<any, any, any, any>\ntype MakeShouldBlockFnLocationUnion<\n TRouter extends AnyRouter = RegisteredRouter,\n TRoute extends AnyRoute = ParseRoute<TRouter['routeTree']>,\n> = TRoute extends any\n ? ShouldBlockFnLocation<\n TRoute['id'],\n TRoute['fullPath'],\n TRoute['types']['allParams'],\n TRoute['types']['fullSearchSchema']\n >\n : never\n\ntype BlockerResolver<TRouter extends AnyRouter = RegisteredRouter> =\n | {\n status: 'blocked'\n current: MakeShouldBlockFnLocationUnion<TRouter>\n next: MakeShouldBlockFnLocationUnion<TRouter>\n action: HistoryAction\n proceed: () => void\n reset: () => void\n }\n | {\n status: 'idle'\n current: undefined\n next: undefined\n action: undefined\n proceed: undefined\n reset: undefined\n }\n\ntype ShouldBlockFnArgs<TRouter extends AnyRouter = RegisteredRouter> = {\n current: MakeShouldBlockFnLocationUnion<TRouter>\n next: MakeShouldBlockFnLocationUnion<TRouter>\n action: HistoryAction\n}\n\nexport type ShouldBlockFn<TRouter extends AnyRouter = RegisteredRouter> = (\n args: ShouldBlockFnArgs<TRouter>,\n) => boolean | Promise<boolean>\nexport type UseBlockerOpts<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n> = {\n shouldBlockFn: ShouldBlockFn<TRouter>\n enableBeforeUnload?: boolean | (() => boolean)\n disabled?: boolean\n withResolver?: TWithResolver\n}\n\ntype LegacyBlockerFn = () => Promise<any> | any\ntype LegacyBlockerOpts = {\n blockerFn?: LegacyBlockerFn\n condition?: boolean | any\n}\n\nfunction _resolveBlockerOpts(\n opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,\n condition?: boolean | any,\n): UseBlockerOpts {\n if (opts === undefined) {\n return {\n shouldBlockFn: () => true,\n withResolver: false,\n }\n }\n\n if ('shouldBlockFn' in opts) {\n return opts\n }\n\n if (typeof opts === 'function') {\n const shouldBlock = Boolean(condition ?? true)\n\n const _customBlockerFn = async () => {\n if (shouldBlock) return await opts()\n return false\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: false,\n }\n }\n\n const shouldBlock = Boolean(opts.condition ?? true)\n const fn = opts.blockerFn\n\n const _customBlockerFn = async () => {\n if (shouldBlock && fn !== undefined) {\n return await fn()\n }\n return shouldBlock\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: fn === undefined,\n }\n}\n\nexport function useBlocker<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = false,\n>(\n opts: UseBlockerOpts<TRouter, TWithResolver>,\n): TWithResolver extends true ? BlockerResolver<TRouter> : void\n\n/**\n * @deprecated Use the shouldBlockFn property instead\n */\nexport function useBlocker(blockerFnOrOpts?: LegacyBlockerOpts): BlockerResolver\n\n/**\n * @deprecated Use the UseBlockerOpts object syntax instead\n */\nexport function useBlocker(\n blockerFn?: LegacyBlockerFn,\n condition?: boolean | any,\n): BlockerResolver\n\nexport function useBlocker(\n opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,\n condition?: boolean | any,\n): BlockerResolver | void {\n const {\n shouldBlockFn,\n enableBeforeUnload = true,\n disabled = false,\n withResolver = false,\n } = _resolveBlockerOpts(opts, condition)\n\n const router = useRouter()\n const { history } = router\n\n const [resolver, setResolver] = React.useState<BlockerResolver>({\n status: 'idle',\n current: undefined,\n next: undefined,\n action: undefined,\n proceed: undefined,\n reset: undefined,\n })\n\n React.useEffect(() => {\n const blockerFnComposed = async (blockerFnArgs: BlockerFnArgs) => {\n function getLocation(\n location: HistoryLocation,\n ): AnyShouldBlockFnLocation {\n const parsedLocation = router.parseLocation(location)\n const matchedRoutes = router.getMatchedRoutes(parsedLocation.pathname)\n if (matchedRoutes.foundRoute === undefined) {\n throw new Error(`No route found for location ${location.href}`)\n }\n return {\n routeId: matchedRoutes.foundRoute.id,\n fullPath: matchedRoutes.foundRoute.fullPath,\n pathname: parsedLocation.pathname,\n params: matchedRoutes.routeParams,\n search: parsedLocation.search,\n }\n }\n\n const current = getLocation(blockerFnArgs.currentLocation)\n const next = getLocation(blockerFnArgs.nextLocation)\n\n const shouldBlock = await shouldBlockFn({\n action: blockerFnArgs.action,\n current,\n next,\n })\n if (!withResolver) {\n return shouldBlock\n }\n\n if (!shouldBlock) {\n return false\n }\n\n const promise = new Promise<boolean>((resolve) => {\n setResolver({\n status: 'blocked',\n current,\n next,\n action: blockerFnArgs.action,\n proceed: () => resolve(false),\n reset: () => resolve(true),\n })\n })\n\n const canNavigateAsync = await promise\n setResolver({\n status: 'idle',\n current: undefined,\n next: undefined,\n action: undefined,\n proceed: undefined,\n reset: undefined,\n })\n\n return canNavigateAsync\n }\n\n return disabled\n ? undefined\n : history.block({ blockerFn: blockerFnComposed, enableBeforeUnload })\n }, [\n shouldBlockFn,\n enableBeforeUnload,\n disabled,\n withResolver,\n history,\n router,\n ])\n\n return resolver\n}\n\nconst _resolvePromptBlockerArgs = (\n props: PromptProps | LegacyPromptProps,\n): UseBlockerOpts => {\n if ('shouldBlockFn' in props) {\n return { ...props }\n }\n\n const shouldBlock = Boolean(props.condition ?? true)\n const fn = props.blockerFn\n\n const _customBlockerFn = async () => {\n if (shouldBlock && fn !== undefined) {\n return await fn()\n }\n return shouldBlock\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: fn === undefined,\n }\n}\n\nexport function Block<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n>(opts: PromptProps<TRouter, TWithResolver>): React.ReactNode\n\n/**\n * @deprecated Use the UseBlockerOpts property instead\n */\nexport function Block(opts: LegacyPromptProps): React.ReactNode\n\nexport function Block(opts: PromptProps | LegacyPromptProps): React.ReactNode {\n const { children, ...rest } = opts\n const args = _resolvePromptBlockerArgs(rest)\n\n const resolver = useBlocker(args)\n return children\n ? typeof children === 'function'\n ? children(resolver as any)\n : children\n : null\n}\n\ntype LegacyPromptProps = {\n blockerFn?: LegacyBlockerFn\n condition?: boolean | any\n children?: React.ReactNode | ((params: BlockerResolver) => React.ReactNode)\n}\n\ntype PromptProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n TParams = TWithResolver extends true ? BlockerResolver<TRouter> : void,\n> = UseBlockerOpts<TRouter, TWithResolver> & {\n children?: React.ReactNode | ((params: TParams) => React.ReactNode)\n}\n"],"names":["shouldBlock","_customBlockerFn","useRouter","React"],"mappings":"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"}
@@ -124,12 +124,27 @@ const useTags = () => {
124
124
  })),
125
125
  structuralSharing: true
126
126
  });
127
+ let serverHeadScript = void 0;
128
+ if (router.serverSsr) {
129
+ const bufferedScripts = router.serverSsr.takeBufferedScripts();
130
+ if (bufferedScripts) {
131
+ serverHeadScript = {
132
+ tag: "script",
133
+ attrs: {
134
+ nonce,
135
+ className: "$tsr"
136
+ },
137
+ children: bufferedScripts
138
+ };
139
+ }
140
+ }
127
141
  return uniqBy(
128
142
  [
129
143
  ...meta,
130
144
  ...preloadMeta,
131
145
  ...links,
132
146
  ...styles,
147
+ ...serverHeadScript ? [serverHeadScript] : [],
133
148
  ...headScripts
134
149
  ],
135
150
  (d) => {
@@ -1 +1 @@
1
- {"version":3,"file":"HeadContent.js","sources":["../../src/HeadContent.tsx"],"sourcesContent":["import * as React from 'react'\nimport { Asset } from './Asset'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\n/**\n * Build the list of head/link/meta/script tags to render for active matches.\n * Used internally by `HeadContent`.\n */\nexport const useTags = () => {\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n const routeMeta = useRouterState({\n select: (state) => {\n return state.matches.map((match) => match.meta!).filter(Boolean)\n },\n })\n\n const meta: Array<RouterManagedTag> = React.useMemo(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n for (let i = routeMeta.length - 1; i >= 0; i--) {\n const metas = routeMeta[i]!\n for (let j = metas.length - 1; j >= 0; j--) {\n const m = metas[j]\n if (!m) continue\n\n if (m.title) {\n if (!title) {\n title = {\n tag: 'title',\n children: m.title,\n }\n }\n } else {\n const attribute = m.name ?? m.property\n if (attribute) {\n if (metaByAttribute[attribute]) {\n continue\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n nonce,\n },\n })\n }\n }\n }\n\n if (title) {\n resultMeta.push(title)\n }\n\n if (nonce) {\n resultMeta.push({\n tag: 'meta',\n attrs: {\n property: 'csp-nonce',\n content: nonce,\n },\n })\n }\n resultMeta.reverse()\n\n return resultMeta\n }, [routeMeta, nonce])\n\n const links = useRouterState({\n select: (state) => {\n const constructed = state.matches\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n nonce,\n },\n })) satisfies Array<RouterManagedTag>\n\n const manifest = router.ssr?.manifest\n\n // These are the assets extracted from the ViteManifest\n // using the `startManifestPlugin`\n const assets = state.matches\n .map((match) => manifest?.routes[match.routeId]?.assets ?? [])\n .filter(Boolean)\n .flat(1)\n .filter((asset) => asset.tag === 'link')\n .map(\n (asset) =>\n ({\n tag: 'link',\n attrs: {\n ...asset.attrs,\n suppressHydrationWarning: true,\n nonce,\n },\n }) satisfies RouterManagedTag,\n )\n\n return [...constructed, ...assets]\n },\n structuralSharing: true as any,\n })\n\n const preloadMeta = useRouterState({\n select: (state) => {\n const preloadMeta: Array<RouterManagedTag> = []\n\n state.matches\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n router.ssr?.manifest?.routes[route.id]?.preloads\n ?.filter(Boolean)\n .forEach((preload) => {\n preloadMeta.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n nonce,\n },\n })\n }),\n )\n\n return preloadMeta\n },\n structuralSharing: true as any,\n })\n\n const styles = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.styles!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...attrs }) => ({\n tag: 'style',\n attrs,\n children,\n nonce,\n })),\n structuralSharing: true as any,\n })\n\n const headScripts = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.headScripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script',\n attrs: {\n ...script,\n nonce,\n },\n children,\n })),\n structuralSharing: true as any,\n })\n\n return uniqBy(\n [\n ...meta,\n ...preloadMeta,\n ...links,\n ...styles,\n ...headScripts,\n ] as Array<RouterManagedTag>,\n (d) => {\n return JSON.stringify(d)\n },\n )\n}\n\n/**\n * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.\n * It should be rendered in the `<head>` of your document.\n */\n/**\n * Render route-managed head tags (title, meta, links, styles, head scripts).\n * Place inside the document head of your app shell.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/document-head-management\n */\nexport function HeadContent() {\n const tags = useTags()\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n return tags.map((tag) => (\n <Asset {...tag} key={`tsr-meta-${JSON.stringify(tag)}`} nonce={nonce} />\n ))\n}\n\nfunction uniqBy<T>(arr: Array<T>, fn: (item: T) => string) {\n const seen = new Set<string>()\n return arr.filter((item) => {\n const key = fn(item)\n if (seen.has(key)) {\n return false\n }\n seen.add(key)\n return true\n })\n}\n"],"names":["preloadMeta"],"mappings":"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"}
1
+ {"version":3,"file":"HeadContent.js","sources":["../../src/HeadContent.tsx"],"sourcesContent":["import * as React from 'react'\nimport { Asset } from './Asset'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\n/**\n * Build the list of head/link/meta/script tags to render for active matches.\n * Used internally by `HeadContent`.\n */\nexport const useTags = () => {\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n const routeMeta = useRouterState({\n select: (state) => {\n return state.matches.map((match) => match.meta!).filter(Boolean)\n },\n })\n\n const meta: Array<RouterManagedTag> = React.useMemo(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n for (let i = routeMeta.length - 1; i >= 0; i--) {\n const metas = routeMeta[i]!\n for (let j = metas.length - 1; j >= 0; j--) {\n const m = metas[j]\n if (!m) continue\n\n if (m.title) {\n if (!title) {\n title = {\n tag: 'title',\n children: m.title,\n }\n }\n } else {\n const attribute = m.name ?? m.property\n if (attribute) {\n if (metaByAttribute[attribute]) {\n continue\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n nonce,\n },\n })\n }\n }\n }\n\n if (title) {\n resultMeta.push(title)\n }\n\n if (nonce) {\n resultMeta.push({\n tag: 'meta',\n attrs: {\n property: 'csp-nonce',\n content: nonce,\n },\n })\n }\n resultMeta.reverse()\n\n return resultMeta\n }, [routeMeta, nonce])\n\n const links = useRouterState({\n select: (state) => {\n const constructed = state.matches\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n nonce,\n },\n })) satisfies Array<RouterManagedTag>\n\n const manifest = router.ssr?.manifest\n\n // These are the assets extracted from the ViteManifest\n // using the `startManifestPlugin`\n const assets = state.matches\n .map((match) => manifest?.routes[match.routeId]?.assets ?? [])\n .filter(Boolean)\n .flat(1)\n .filter((asset) => asset.tag === 'link')\n .map(\n (asset) =>\n ({\n tag: 'link',\n attrs: {\n ...asset.attrs,\n suppressHydrationWarning: true,\n nonce,\n },\n }) satisfies RouterManagedTag,\n )\n\n return [...constructed, ...assets]\n },\n structuralSharing: true as any,\n })\n\n const preloadMeta = useRouterState({\n select: (state) => {\n const preloadMeta: Array<RouterManagedTag> = []\n\n state.matches\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n router.ssr?.manifest?.routes[route.id]?.preloads\n ?.filter(Boolean)\n .forEach((preload) => {\n preloadMeta.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n nonce,\n },\n })\n }),\n )\n\n return preloadMeta\n },\n structuralSharing: true as any,\n })\n\n const styles = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.styles!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...attrs }) => ({\n tag: 'style',\n attrs,\n children,\n nonce,\n })),\n structuralSharing: true as any,\n })\n\n const headScripts: Array<RouterManagedTag> = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.headScripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script',\n attrs: {\n ...script,\n nonce,\n },\n children,\n })),\n structuralSharing: true as any,\n })\n\n let serverHeadScript: RouterManagedTag | undefined = undefined\n\n if (router.serverSsr) {\n const bufferedScripts = router.serverSsr.takeBufferedScripts()\n if (bufferedScripts) {\n serverHeadScript = {\n tag: 'script',\n attrs: {\n nonce,\n className: '$tsr',\n },\n children: bufferedScripts,\n }\n }\n }\n\n return uniqBy(\n [\n ...meta,\n ...preloadMeta,\n ...links,\n ...styles,\n ...(serverHeadScript ? [serverHeadScript] : []),\n ...headScripts,\n ] as Array<RouterManagedTag>,\n (d) => {\n return JSON.stringify(d)\n },\n )\n}\n\n/**\n * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.\n * It should be rendered in the `<head>` of your document.\n */\n/**\n * Render route-managed head tags (title, meta, links, styles, head scripts).\n * Place inside the document head of your app shell.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/document-head-management\n */\nexport function HeadContent() {\n const tags = useTags()\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n return tags.map((tag) => (\n <Asset {...tag} key={`tsr-meta-${JSON.stringify(tag)}`} nonce={nonce} />\n ))\n}\n\nfunction uniqBy<T>(arr: Array<T>, fn: (item: T) => string) {\n const seen = new Set<string>()\n return arr.filter((item) => {\n const key = fn(item)\n if (seen.has(key)) {\n return false\n }\n seen.add(key)\n return true\n })\n}\n"],"names":["preloadMeta"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  /**
2
2
  * Server-only helper to emit a script tag exactly once during SSR.
3
- * Appends an internal marker to signal hydration completion.
4
3
  */
5
4
  export declare function ScriptOnce({ children }: {
6
5
  children: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ScriptOnce.js","sources":["../../src/ScriptOnce.tsx"],"sourcesContent":["import { useRouter } from './useRouter'\n\n/**\n * Server-only helper to emit a script tag exactly once during SSR.\n * Appends an internal marker to signal hydration completion.\n */\nexport function ScriptOnce({ children }: { children: string }) {\n const router = useRouter()\n if (!router.isServer) {\n return null\n }\n\n return (\n <script\n nonce={router.options.ssr?.nonce}\n className=\"$tsr\"\n dangerouslySetInnerHTML={{\n __html: [children].filter(Boolean).join('\\n') + ';$_TSR.c()',\n }}\n />\n )\n}\n"],"names":[],"mappings":";;AAMO,SAAS,WAAW,EAAE,YAAkC;AAC7D,QAAM,SAAS,UAAA;AACf,MAAI,CAAC,OAAO,UAAU;AACpB,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO,OAAO,QAAQ,KAAK;AAAA,MAC3B,WAAU;AAAA,MACV,yBAAyB;AAAA,QACvB,QAAQ,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,IAAI;AAAA,MAAA;AAAA,IAClD;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"ScriptOnce.js","sources":["../../src/ScriptOnce.tsx"],"sourcesContent":["import { useRouter } from './useRouter'\n\n/**\n * Server-only helper to emit a script tag exactly once during SSR.\n */\nexport function ScriptOnce({ children }: { children: string }) {\n const router = useRouter()\n if (!router.isServer) {\n return null\n }\n\n return (\n <script\n nonce={router.options.ssr?.nonce}\n className=\"$tsr\"\n dangerouslySetInnerHTML={{\n __html: [children].filter(Boolean).join('\\n') + ';$_TSR.c()',\n }}\n />\n )\n}\n"],"names":[],"mappings":";;AAKO,SAAS,WAAW,EAAE,YAAkC;AAC7D,QAAM,SAAS,UAAA;AACf,MAAI,CAAC,OAAO,UAAU;AACpB,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO,OAAO,QAAQ,KAAK;AAAA,MAC3B,WAAU;AAAA,MACV,yBAAyB;AAAA,QACvB,QAAQ,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,IAAI;AAAA,MAAA;AAAA,IAClD;AAAA,EAAA;AAGN;"}
@@ -1,5 +1,5 @@
1
- export { defer, TSR_DEFERRED_PROMISE, isMatch, joinPaths, cleanPath, trimPathLeft, trimPathRight, trimPath, resolvePath, parsePathname, interpolatePath, matchPathname, matchByPath, rootRouteId, defaultSerializeError, defaultParseSearch, defaultStringifySearch, parseSearchWith, stringifySearchWith, functionalUpdate, replaceEqualDeep, isPlainObject, isPlainArray, deepEqual, createControlledPromise, retainSearchParams, stripSearchParams, createSerializationAdapter, } from '@tanstack/router-core';
2
- export type { AnyRoute, DeferredPromiseState, DeferredPromise, ParsedLocation, RemoveTrailingSlashes, RemoveLeadingSlashes, ActiveOptions, Segment, ResolveRelativePath, RootRouteId, AnyPathParams, ResolveParams, ResolveOptionalParams, ResolveRequiredParams, SearchSchemaInput, AnyContext, RouteContext, PreloadableObj, RoutePathOptions, StaticDataRouteOption, RoutePathOptionsIntersection, UpdatableStaticRouteOption, MetaDescriptor, RouteLinkEntry, ParseParamsFn, SearchFilter, ResolveId, InferFullSearchSchema, InferFullSearchSchemaInput, ErrorRouteProps, ErrorComponentProps, NotFoundRouteProps, TrimPath, TrimPathLeft, TrimPathRight, StringifyParamsFn, ParamsOptions, InferAllParams, InferAllContext, LooseReturnType, LooseAsyncReturnType, ContextReturnType, ContextAsyncReturnType, ResolveLoaderData, ResolveRouteContext, SearchSerializer, SearchParser, TrailingSlashOption, Manifest, RouterManagedTag, ControlledPromise, Constrain, Expand, MergeAll, Assign, IntersectAssign, ResolveValidatorInput, ResolveValidatorOutput, Register, AnyValidator, DefaultValidator, ValidatorFn, AnySchema, AnyValidatorAdapter, AnyValidatorFn, AnyValidatorObj, ResolveValidatorInputFn, ResolveValidatorOutputFn, ResolveSearchValidatorInput, ResolveSearchValidatorInputFn, Validator, ValidatorAdapter, ValidatorObj, FileRoutesByPath, RouteById, RootRouteOptions, CreateFileRoute, SerializationAdapter, AnySerializationAdapter, } from '@tanstack/router-core';
1
+ export { defer, TSR_DEFERRED_PROMISE, isMatch, joinPaths, cleanPath, trimPathLeft, trimPathRight, trimPath, resolvePath, interpolatePath, rootRouteId, defaultSerializeError, defaultParseSearch, defaultStringifySearch, parseSearchWith, stringifySearchWith, functionalUpdate, replaceEqualDeep, isPlainObject, isPlainArray, deepEqual, createControlledPromise, retainSearchParams, stripSearchParams, createSerializationAdapter, } from '@tanstack/router-core';
2
+ export type { AnyRoute, DeferredPromiseState, DeferredPromise, ParsedLocation, RemoveTrailingSlashes, RemoveLeadingSlashes, ActiveOptions, ResolveRelativePath, RootRouteId, AnyPathParams, ResolveParams, ResolveOptionalParams, ResolveRequiredParams, SearchSchemaInput, AnyContext, RouteContext, PreloadableObj, RoutePathOptions, StaticDataRouteOption, RoutePathOptionsIntersection, UpdatableStaticRouteOption, MetaDescriptor, RouteLinkEntry, ParseParamsFn, SearchFilter, ResolveId, InferFullSearchSchema, InferFullSearchSchemaInput, ErrorRouteProps, ErrorComponentProps, NotFoundRouteProps, TrimPath, TrimPathLeft, TrimPathRight, StringifyParamsFn, ParamsOptions, InferAllParams, InferAllContext, LooseReturnType, LooseAsyncReturnType, ContextReturnType, ContextAsyncReturnType, ResolveLoaderData, ResolveRouteContext, SearchSerializer, SearchParser, TrailingSlashOption, Manifest, RouterManagedTag, ControlledPromise, Constrain, Expand, MergeAll, Assign, IntersectAssign, ResolveValidatorInput, ResolveValidatorOutput, Register, AnyValidator, DefaultValidator, ValidatorFn, AnySchema, AnyValidatorAdapter, AnyValidatorFn, AnyValidatorObj, ResolveValidatorInputFn, ResolveValidatorOutputFn, ResolveSearchValidatorInput, ResolveSearchValidatorInputFn, Validator, ValidatorAdapter, ValidatorObj, FileRoutesByPath, RouteById, RootRouteOptions, CreateFileRoute, SerializationAdapter, AnySerializationAdapter, } from '@tanstack/router-core';
3
3
  export { createHistory, createBrowserHistory, createHashHistory, createMemoryHistory, } from '@tanstack/history';
4
4
  export type { BlockerFn, HistoryLocation, RouterHistory, ParsedPath, HistoryState, } from '@tanstack/history';
5
5
  export { useAwaited, Await } from './awaited.js';
package/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { PathParamError, SearchParamError, TSR_DEFERRED_PROMISE, cleanPath, componentTypes, composeRewrites, createControlledPromise, createRouterConfig, createSerializationAdapter, deepEqual, defaultParseSearch, defaultSerializeError, defaultStringifySearch, defer, functionalUpdate, getInitialRouterState, interpolatePath, isMatch, isNotFound, isPlainArray, isPlainObject, isRedirect, joinPaths, lazyFn, matchByPath, matchPathname, notFound, parsePathname, parseSearchWith, redirect, replaceEqualDeep, resolvePath, retainSearchParams, rootRouteId, stringifySearchWith, stripSearchParams, trimPath, trimPathLeft, trimPathRight } from "@tanstack/router-core";
1
+ import { PathParamError, SearchParamError, TSR_DEFERRED_PROMISE, cleanPath, componentTypes, composeRewrites, createControlledPromise, createRouterConfig, createSerializationAdapter, deepEqual, defaultParseSearch, defaultSerializeError, defaultStringifySearch, defer, functionalUpdate, getInitialRouterState, interpolatePath, isMatch, isNotFound, isPlainArray, isPlainObject, isRedirect, joinPaths, lazyFn, notFound, parseSearchWith, redirect, replaceEqualDeep, resolvePath, retainSearchParams, rootRouteId, stringifySearchWith, stripSearchParams, trimPath, trimPathLeft, trimPathRight } from "@tanstack/router-core";
2
2
  import { createBrowserHistory, createHashHistory, createHistory, createMemoryHistory } from "@tanstack/history";
3
3
  import { Await, useAwaited } from "./awaited.js";
4
4
  import { CatchBoundary, ErrorComponent } from "./CatchBoundary.js";
@@ -102,11 +102,8 @@ export {
102
102
  lazyFn,
103
103
  lazyRouteComponent,
104
104
  linkOptions,
105
- matchByPath,
106
105
  matchContext,
107
- matchPathname,
108
106
  notFound,
109
- parsePathname,
110
107
  parseSearchWith,
111
108
  redirect,
112
109
  replaceEqualDeep,
@@ -57,10 +57,7 @@ function useBlocker(opts, condition) {
57
57
  const blockerFnComposed = async (blockerFnArgs) => {
58
58
  function getLocation(location) {
59
59
  const parsedLocation = router.parseLocation(location);
60
- const matchedRoutes = router.getMatchedRoutes(
61
- parsedLocation.pathname,
62
- void 0
63
- );
60
+ const matchedRoutes = router.getMatchedRoutes(parsedLocation.pathname);
64
61
  if (matchedRoutes.foundRoute === void 0) {
65
62
  throw new Error(`No route found for location ${location.href}`);
66
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useBlocker.js","sources":["../../src/useBlocker.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useRouter } from './useRouter'\nimport type {\n BlockerFnArgs,\n HistoryAction,\n HistoryLocation,\n} from '@tanstack/history'\nimport type {\n AnyRoute,\n AnyRouter,\n ParseRoute,\n RegisteredRouter,\n} from '@tanstack/router-core'\n\ninterface ShouldBlockFnLocation<\n out TRouteId,\n out TFullPath,\n out TAllParams,\n out TFullSearchSchema,\n> {\n routeId: TRouteId\n fullPath: TFullPath\n pathname: string\n params: TAllParams\n search: TFullSearchSchema\n}\n\ntype AnyShouldBlockFnLocation = ShouldBlockFnLocation<any, any, any, any>\ntype MakeShouldBlockFnLocationUnion<\n TRouter extends AnyRouter = RegisteredRouter,\n TRoute extends AnyRoute = ParseRoute<TRouter['routeTree']>,\n> = TRoute extends any\n ? ShouldBlockFnLocation<\n TRoute['id'],\n TRoute['fullPath'],\n TRoute['types']['allParams'],\n TRoute['types']['fullSearchSchema']\n >\n : never\n\ntype BlockerResolver<TRouter extends AnyRouter = RegisteredRouter> =\n | {\n status: 'blocked'\n current: MakeShouldBlockFnLocationUnion<TRouter>\n next: MakeShouldBlockFnLocationUnion<TRouter>\n action: HistoryAction\n proceed: () => void\n reset: () => void\n }\n | {\n status: 'idle'\n current: undefined\n next: undefined\n action: undefined\n proceed: undefined\n reset: undefined\n }\n\ntype ShouldBlockFnArgs<TRouter extends AnyRouter = RegisteredRouter> = {\n current: MakeShouldBlockFnLocationUnion<TRouter>\n next: MakeShouldBlockFnLocationUnion<TRouter>\n action: HistoryAction\n}\n\nexport type ShouldBlockFn<TRouter extends AnyRouter = RegisteredRouter> = (\n args: ShouldBlockFnArgs<TRouter>,\n) => boolean | Promise<boolean>\nexport type UseBlockerOpts<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n> = {\n shouldBlockFn: ShouldBlockFn<TRouter>\n enableBeforeUnload?: boolean | (() => boolean)\n disabled?: boolean\n withResolver?: TWithResolver\n}\n\ntype LegacyBlockerFn = () => Promise<any> | any\ntype LegacyBlockerOpts = {\n blockerFn?: LegacyBlockerFn\n condition?: boolean | any\n}\n\nfunction _resolveBlockerOpts(\n opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,\n condition?: boolean | any,\n): UseBlockerOpts {\n if (opts === undefined) {\n return {\n shouldBlockFn: () => true,\n withResolver: false,\n }\n }\n\n if ('shouldBlockFn' in opts) {\n return opts\n }\n\n if (typeof opts === 'function') {\n const shouldBlock = Boolean(condition ?? true)\n\n const _customBlockerFn = async () => {\n if (shouldBlock) return await opts()\n return false\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: false,\n }\n }\n\n const shouldBlock = Boolean(opts.condition ?? true)\n const fn = opts.blockerFn\n\n const _customBlockerFn = async () => {\n if (shouldBlock && fn !== undefined) {\n return await fn()\n }\n return shouldBlock\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: fn === undefined,\n }\n}\n\nexport function useBlocker<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = false,\n>(\n opts: UseBlockerOpts<TRouter, TWithResolver>,\n): TWithResolver extends true ? BlockerResolver<TRouter> : void\n\n/**\n * @deprecated Use the shouldBlockFn property instead\n */\nexport function useBlocker(blockerFnOrOpts?: LegacyBlockerOpts): BlockerResolver\n\n/**\n * @deprecated Use the UseBlockerOpts object syntax instead\n */\nexport function useBlocker(\n blockerFn?: LegacyBlockerFn,\n condition?: boolean | any,\n): BlockerResolver\n\nexport function useBlocker(\n opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,\n condition?: boolean | any,\n): BlockerResolver | void {\n const {\n shouldBlockFn,\n enableBeforeUnload = true,\n disabled = false,\n withResolver = false,\n } = _resolveBlockerOpts(opts, condition)\n\n const router = useRouter()\n const { history } = router\n\n const [resolver, setResolver] = React.useState<BlockerResolver>({\n status: 'idle',\n current: undefined,\n next: undefined,\n action: undefined,\n proceed: undefined,\n reset: undefined,\n })\n\n React.useEffect(() => {\n const blockerFnComposed = async (blockerFnArgs: BlockerFnArgs) => {\n function getLocation(\n location: HistoryLocation,\n ): AnyShouldBlockFnLocation {\n const parsedLocation = router.parseLocation(location)\n const matchedRoutes = router.getMatchedRoutes(\n parsedLocation.pathname,\n undefined,\n )\n if (matchedRoutes.foundRoute === undefined) {\n throw new Error(`No route found for location ${location.href}`)\n }\n return {\n routeId: matchedRoutes.foundRoute.id,\n fullPath: matchedRoutes.foundRoute.fullPath,\n pathname: parsedLocation.pathname,\n params: matchedRoutes.routeParams,\n search: parsedLocation.search,\n }\n }\n\n const current = getLocation(blockerFnArgs.currentLocation)\n const next = getLocation(blockerFnArgs.nextLocation)\n\n const shouldBlock = await shouldBlockFn({\n action: blockerFnArgs.action,\n current,\n next,\n })\n if (!withResolver) {\n return shouldBlock\n }\n\n if (!shouldBlock) {\n return false\n }\n\n const promise = new Promise<boolean>((resolve) => {\n setResolver({\n status: 'blocked',\n current,\n next,\n action: blockerFnArgs.action,\n proceed: () => resolve(false),\n reset: () => resolve(true),\n })\n })\n\n const canNavigateAsync = await promise\n setResolver({\n status: 'idle',\n current: undefined,\n next: undefined,\n action: undefined,\n proceed: undefined,\n reset: undefined,\n })\n\n return canNavigateAsync\n }\n\n return disabled\n ? undefined\n : history.block({ blockerFn: blockerFnComposed, enableBeforeUnload })\n }, [\n shouldBlockFn,\n enableBeforeUnload,\n disabled,\n withResolver,\n history,\n router,\n ])\n\n return resolver\n}\n\nconst _resolvePromptBlockerArgs = (\n props: PromptProps | LegacyPromptProps,\n): UseBlockerOpts => {\n if ('shouldBlockFn' in props) {\n return { ...props }\n }\n\n const shouldBlock = Boolean(props.condition ?? true)\n const fn = props.blockerFn\n\n const _customBlockerFn = async () => {\n if (shouldBlock && fn !== undefined) {\n return await fn()\n }\n return shouldBlock\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: fn === undefined,\n }\n}\n\nexport function Block<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n>(opts: PromptProps<TRouter, TWithResolver>): React.ReactNode\n\n/**\n * @deprecated Use the UseBlockerOpts property instead\n */\nexport function Block(opts: LegacyPromptProps): React.ReactNode\n\nexport function Block(opts: PromptProps | LegacyPromptProps): React.ReactNode {\n const { children, ...rest } = opts\n const args = _resolvePromptBlockerArgs(rest)\n\n const resolver = useBlocker(args)\n return children\n ? typeof children === 'function'\n ? children(resolver as any)\n : children\n : null\n}\n\ntype LegacyPromptProps = {\n blockerFn?: LegacyBlockerFn\n condition?: boolean | any\n children?: React.ReactNode | ((params: BlockerResolver) => React.ReactNode)\n}\n\ntype PromptProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n TParams = TWithResolver extends true ? BlockerResolver<TRouter> : void,\n> = UseBlockerOpts<TRouter, TWithResolver> & {\n children?: React.ReactNode | ((params: TParams) => React.ReactNode)\n}\n"],"names":["shouldBlock","_customBlockerFn"],"mappings":"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"}
1
+ {"version":3,"file":"useBlocker.js","sources":["../../src/useBlocker.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useRouter } from './useRouter'\nimport type {\n BlockerFnArgs,\n HistoryAction,\n HistoryLocation,\n} from '@tanstack/history'\nimport type {\n AnyRoute,\n AnyRouter,\n ParseRoute,\n RegisteredRouter,\n} from '@tanstack/router-core'\n\ninterface ShouldBlockFnLocation<\n out TRouteId,\n out TFullPath,\n out TAllParams,\n out TFullSearchSchema,\n> {\n routeId: TRouteId\n fullPath: TFullPath\n pathname: string\n params: TAllParams\n search: TFullSearchSchema\n}\n\ntype AnyShouldBlockFnLocation = ShouldBlockFnLocation<any, any, any, any>\ntype MakeShouldBlockFnLocationUnion<\n TRouter extends AnyRouter = RegisteredRouter,\n TRoute extends AnyRoute = ParseRoute<TRouter['routeTree']>,\n> = TRoute extends any\n ? ShouldBlockFnLocation<\n TRoute['id'],\n TRoute['fullPath'],\n TRoute['types']['allParams'],\n TRoute['types']['fullSearchSchema']\n >\n : never\n\ntype BlockerResolver<TRouter extends AnyRouter = RegisteredRouter> =\n | {\n status: 'blocked'\n current: MakeShouldBlockFnLocationUnion<TRouter>\n next: MakeShouldBlockFnLocationUnion<TRouter>\n action: HistoryAction\n proceed: () => void\n reset: () => void\n }\n | {\n status: 'idle'\n current: undefined\n next: undefined\n action: undefined\n proceed: undefined\n reset: undefined\n }\n\ntype ShouldBlockFnArgs<TRouter extends AnyRouter = RegisteredRouter> = {\n current: MakeShouldBlockFnLocationUnion<TRouter>\n next: MakeShouldBlockFnLocationUnion<TRouter>\n action: HistoryAction\n}\n\nexport type ShouldBlockFn<TRouter extends AnyRouter = RegisteredRouter> = (\n args: ShouldBlockFnArgs<TRouter>,\n) => boolean | Promise<boolean>\nexport type UseBlockerOpts<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n> = {\n shouldBlockFn: ShouldBlockFn<TRouter>\n enableBeforeUnload?: boolean | (() => boolean)\n disabled?: boolean\n withResolver?: TWithResolver\n}\n\ntype LegacyBlockerFn = () => Promise<any> | any\ntype LegacyBlockerOpts = {\n blockerFn?: LegacyBlockerFn\n condition?: boolean | any\n}\n\nfunction _resolveBlockerOpts(\n opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,\n condition?: boolean | any,\n): UseBlockerOpts {\n if (opts === undefined) {\n return {\n shouldBlockFn: () => true,\n withResolver: false,\n }\n }\n\n if ('shouldBlockFn' in opts) {\n return opts\n }\n\n if (typeof opts === 'function') {\n const shouldBlock = Boolean(condition ?? true)\n\n const _customBlockerFn = async () => {\n if (shouldBlock) return await opts()\n return false\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: false,\n }\n }\n\n const shouldBlock = Boolean(opts.condition ?? true)\n const fn = opts.blockerFn\n\n const _customBlockerFn = async () => {\n if (shouldBlock && fn !== undefined) {\n return await fn()\n }\n return shouldBlock\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: fn === undefined,\n }\n}\n\nexport function useBlocker<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = false,\n>(\n opts: UseBlockerOpts<TRouter, TWithResolver>,\n): TWithResolver extends true ? BlockerResolver<TRouter> : void\n\n/**\n * @deprecated Use the shouldBlockFn property instead\n */\nexport function useBlocker(blockerFnOrOpts?: LegacyBlockerOpts): BlockerResolver\n\n/**\n * @deprecated Use the UseBlockerOpts object syntax instead\n */\nexport function useBlocker(\n blockerFn?: LegacyBlockerFn,\n condition?: boolean | any,\n): BlockerResolver\n\nexport function useBlocker(\n opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,\n condition?: boolean | any,\n): BlockerResolver | void {\n const {\n shouldBlockFn,\n enableBeforeUnload = true,\n disabled = false,\n withResolver = false,\n } = _resolveBlockerOpts(opts, condition)\n\n const router = useRouter()\n const { history } = router\n\n const [resolver, setResolver] = React.useState<BlockerResolver>({\n status: 'idle',\n current: undefined,\n next: undefined,\n action: undefined,\n proceed: undefined,\n reset: undefined,\n })\n\n React.useEffect(() => {\n const blockerFnComposed = async (blockerFnArgs: BlockerFnArgs) => {\n function getLocation(\n location: HistoryLocation,\n ): AnyShouldBlockFnLocation {\n const parsedLocation = router.parseLocation(location)\n const matchedRoutes = router.getMatchedRoutes(parsedLocation.pathname)\n if (matchedRoutes.foundRoute === undefined) {\n throw new Error(`No route found for location ${location.href}`)\n }\n return {\n routeId: matchedRoutes.foundRoute.id,\n fullPath: matchedRoutes.foundRoute.fullPath,\n pathname: parsedLocation.pathname,\n params: matchedRoutes.routeParams,\n search: parsedLocation.search,\n }\n }\n\n const current = getLocation(blockerFnArgs.currentLocation)\n const next = getLocation(blockerFnArgs.nextLocation)\n\n const shouldBlock = await shouldBlockFn({\n action: blockerFnArgs.action,\n current,\n next,\n })\n if (!withResolver) {\n return shouldBlock\n }\n\n if (!shouldBlock) {\n return false\n }\n\n const promise = new Promise<boolean>((resolve) => {\n setResolver({\n status: 'blocked',\n current,\n next,\n action: blockerFnArgs.action,\n proceed: () => resolve(false),\n reset: () => resolve(true),\n })\n })\n\n const canNavigateAsync = await promise\n setResolver({\n status: 'idle',\n current: undefined,\n next: undefined,\n action: undefined,\n proceed: undefined,\n reset: undefined,\n })\n\n return canNavigateAsync\n }\n\n return disabled\n ? undefined\n : history.block({ blockerFn: blockerFnComposed, enableBeforeUnload })\n }, [\n shouldBlockFn,\n enableBeforeUnload,\n disabled,\n withResolver,\n history,\n router,\n ])\n\n return resolver\n}\n\nconst _resolvePromptBlockerArgs = (\n props: PromptProps | LegacyPromptProps,\n): UseBlockerOpts => {\n if ('shouldBlockFn' in props) {\n return { ...props }\n }\n\n const shouldBlock = Boolean(props.condition ?? true)\n const fn = props.blockerFn\n\n const _customBlockerFn = async () => {\n if (shouldBlock && fn !== undefined) {\n return await fn()\n }\n return shouldBlock\n }\n\n return {\n shouldBlockFn: _customBlockerFn,\n enableBeforeUnload: shouldBlock,\n withResolver: fn === undefined,\n }\n}\n\nexport function Block<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n>(opts: PromptProps<TRouter, TWithResolver>): React.ReactNode\n\n/**\n * @deprecated Use the UseBlockerOpts property instead\n */\nexport function Block(opts: LegacyPromptProps): React.ReactNode\n\nexport function Block(opts: PromptProps | LegacyPromptProps): React.ReactNode {\n const { children, ...rest } = opts\n const args = _resolvePromptBlockerArgs(rest)\n\n const resolver = useBlocker(args)\n return children\n ? typeof children === 'function'\n ? children(resolver as any)\n : children\n : null\n}\n\ntype LegacyPromptProps = {\n blockerFn?: LegacyBlockerFn\n condition?: boolean | any\n children?: React.ReactNode | ((params: BlockerResolver) => React.ReactNode)\n}\n\ntype PromptProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TWithResolver extends boolean = boolean,\n TParams = TWithResolver extends true ? BlockerResolver<TRouter> : void,\n> = UseBlockerOpts<TRouter, TWithResolver> & {\n children?: React.ReactNode | ((params: TParams) => React.ReactNode)\n}\n"],"names":["shouldBlock","_customBlockerFn"],"mappings":"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"}