@tanstack/solid-router 1.167.4 → 1.168.0

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.
Files changed (177) hide show
  1. package/dist/cjs/Match.cjs +244 -223
  2. package/dist/cjs/Match.cjs.map +1 -1
  3. package/dist/cjs/Match.d.cts +1 -3
  4. package/dist/cjs/Matches.cjs +32 -31
  5. package/dist/cjs/Matches.cjs.map +1 -1
  6. package/dist/cjs/Scripts.cjs +10 -8
  7. package/dist/cjs/Scripts.cjs.map +1 -1
  8. package/dist/cjs/Scripts.d.cts +2 -1
  9. package/dist/cjs/Transitioner.cjs +26 -26
  10. package/dist/cjs/Transitioner.cjs.map +1 -1
  11. package/dist/cjs/headContentUtils.cjs +15 -15
  12. package/dist/cjs/headContentUtils.cjs.map +1 -1
  13. package/dist/cjs/index.cjs +1 -1
  14. package/dist/cjs/index.dev.cjs +1 -1
  15. package/dist/cjs/link.cjs +119 -84
  16. package/dist/cjs/link.cjs.map +1 -1
  17. package/dist/cjs/matchContext.cjs +7 -5
  18. package/dist/cjs/matchContext.cjs.map +1 -1
  19. package/dist/cjs/matchContext.d.cts +8 -2
  20. package/dist/cjs/not-found.cjs +8 -4
  21. package/dist/cjs/not-found.cjs.map +1 -1
  22. package/dist/cjs/not-found.d.cts +1 -1
  23. package/dist/cjs/router.cjs +2 -1
  24. package/dist/cjs/router.cjs.map +1 -1
  25. package/dist/cjs/routerStores.cjs +67 -0
  26. package/dist/cjs/routerStores.cjs.map +1 -0
  27. package/dist/cjs/routerStores.d.cts +10 -0
  28. package/dist/cjs/ssr/RouterClient.cjs +1 -1
  29. package/dist/cjs/ssr/RouterClient.cjs.map +1 -1
  30. package/dist/cjs/ssr/renderRouterToStream.cjs +1 -1
  31. package/dist/cjs/ssr/renderRouterToStream.cjs.map +1 -1
  32. package/dist/cjs/ssr/renderRouterToString.cjs +2 -2
  33. package/dist/cjs/ssr/renderRouterToString.cjs.map +1 -1
  34. package/dist/cjs/ssr/renderRouterToString.d.cts +1 -1
  35. package/dist/cjs/useCanGoBack.cjs +6 -2
  36. package/dist/cjs/useCanGoBack.cjs.map +1 -1
  37. package/dist/cjs/useCanGoBack.d.cts +2 -1
  38. package/dist/cjs/useLoaderDeps.cjs +2 -3
  39. package/dist/cjs/useLoaderDeps.cjs.map +1 -1
  40. package/dist/cjs/useLocation.cjs +13 -2
  41. package/dist/cjs/useLocation.cjs.map +1 -1
  42. package/dist/cjs/useMatch.cjs +17 -15
  43. package/dist/cjs/useMatch.cjs.map +1 -1
  44. package/dist/cjs/useParams.cjs +1 -1
  45. package/dist/cjs/useParams.cjs.map +1 -1
  46. package/dist/cjs/useRouterState.cjs +12 -19
  47. package/dist/cjs/useRouterState.cjs.map +1 -1
  48. package/dist/cjs/useSearch.cjs +2 -1
  49. package/dist/cjs/useSearch.cjs.map +1 -1
  50. package/dist/cjs/utils.cjs +0 -14
  51. package/dist/cjs/utils.cjs.map +1 -1
  52. package/dist/cjs/utils.d.cts +0 -4
  53. package/dist/esm/Match.d.ts +1 -3
  54. package/dist/esm/Match.js +245 -224
  55. package/dist/esm/Match.js.map +1 -1
  56. package/dist/esm/Matches.js +34 -33
  57. package/dist/esm/Matches.js.map +1 -1
  58. package/dist/esm/Scripts.d.ts +2 -1
  59. package/dist/esm/Scripts.js +8 -7
  60. package/dist/esm/Scripts.js.map +1 -1
  61. package/dist/esm/Transitioner.js +26 -26
  62. package/dist/esm/Transitioner.js.map +1 -1
  63. package/dist/esm/headContentUtils.js +15 -15
  64. package/dist/esm/headContentUtils.js.map +1 -1
  65. package/dist/esm/index.dev.js +1 -1
  66. package/dist/esm/index.js +1 -1
  67. package/dist/esm/link.js +120 -85
  68. package/dist/esm/link.js.map +1 -1
  69. package/dist/esm/matchContext.d.ts +8 -2
  70. package/dist/esm/matchContext.js +7 -4
  71. package/dist/esm/matchContext.js.map +1 -1
  72. package/dist/esm/not-found.d.ts +1 -1
  73. package/dist/esm/not-found.js +6 -3
  74. package/dist/esm/not-found.js.map +1 -1
  75. package/dist/esm/router.js +2 -1
  76. package/dist/esm/router.js.map +1 -1
  77. package/dist/esm/routerStores.d.ts +10 -0
  78. package/dist/esm/routerStores.js +65 -0
  79. package/dist/esm/routerStores.js.map +1 -0
  80. package/dist/esm/ssr/RouterClient.js +1 -1
  81. package/dist/esm/ssr/RouterClient.js.map +1 -1
  82. package/dist/esm/ssr/renderRouterToStream.js +1 -1
  83. package/dist/esm/ssr/renderRouterToStream.js.map +1 -1
  84. package/dist/esm/ssr/renderRouterToString.d.ts +1 -1
  85. package/dist/esm/ssr/renderRouterToString.js +2 -2
  86. package/dist/esm/ssr/renderRouterToString.js.map +1 -1
  87. package/dist/esm/useCanGoBack.d.ts +2 -1
  88. package/dist/esm/useCanGoBack.js +4 -2
  89. package/dist/esm/useCanGoBack.js.map +1 -1
  90. package/dist/esm/useLoaderDeps.js +2 -3
  91. package/dist/esm/useLoaderDeps.js.map +1 -1
  92. package/dist/esm/useLocation.js +11 -2
  93. package/dist/esm/useLocation.js.map +1 -1
  94. package/dist/esm/useMatch.js +18 -16
  95. package/dist/esm/useMatch.js.map +1 -1
  96. package/dist/esm/useParams.js +1 -1
  97. package/dist/esm/useParams.js.map +1 -1
  98. package/dist/esm/useRouterState.js +10 -18
  99. package/dist/esm/useRouterState.js.map +1 -1
  100. package/dist/esm/useSearch.js +2 -1
  101. package/dist/esm/useSearch.js.map +1 -1
  102. package/dist/esm/utils.d.ts +0 -4
  103. package/dist/esm/utils.js +1 -14
  104. package/dist/esm/utils.js.map +1 -1
  105. package/dist/source/Match.d.ts +1 -3
  106. package/dist/source/Match.jsx +246 -237
  107. package/dist/source/Match.jsx.map +1 -1
  108. package/dist/source/Matches.jsx +42 -44
  109. package/dist/source/Matches.jsx.map +1 -1
  110. package/dist/source/Scripts.d.ts +2 -1
  111. package/dist/source/Scripts.jsx +31 -36
  112. package/dist/source/Scripts.jsx.map +1 -1
  113. package/dist/source/Transitioner.jsx +26 -31
  114. package/dist/source/Transitioner.jsx.map +1 -1
  115. package/dist/source/headContentUtils.jsx +64 -72
  116. package/dist/source/headContentUtils.jsx.map +1 -1
  117. package/dist/source/link.jsx +136 -107
  118. package/dist/source/link.jsx.map +1 -1
  119. package/dist/source/matchContext.d.ts +8 -2
  120. package/dist/source/matchContext.jsx +7 -3
  121. package/dist/source/matchContext.jsx.map +1 -1
  122. package/dist/source/not-found.d.ts +1 -1
  123. package/dist/source/not-found.jsx +6 -5
  124. package/dist/source/not-found.jsx.map +1 -1
  125. package/dist/source/router.js +2 -1
  126. package/dist/source/router.js.map +1 -1
  127. package/dist/source/routerStores.d.ts +10 -0
  128. package/dist/source/routerStores.js +71 -0
  129. package/dist/source/routerStores.js.map +1 -0
  130. package/dist/source/ssr/RouterClient.jsx +1 -1
  131. package/dist/source/ssr/RouterClient.jsx.map +1 -1
  132. package/dist/source/ssr/renderRouterToStream.jsx +1 -1
  133. package/dist/source/ssr/renderRouterToStream.jsx.map +1 -1
  134. package/dist/source/ssr/renderRouterToString.d.ts +1 -1
  135. package/dist/source/ssr/renderRouterToString.jsx +2 -2
  136. package/dist/source/ssr/renderRouterToString.jsx.map +1 -1
  137. package/dist/source/useCanGoBack.d.ts +2 -1
  138. package/dist/source/useCanGoBack.js +4 -2
  139. package/dist/source/useCanGoBack.js.map +1 -1
  140. package/dist/source/useLoaderDeps.jsx +2 -3
  141. package/dist/source/useLoaderDeps.jsx.map +1 -1
  142. package/dist/source/useLocation.jsx +13 -3
  143. package/dist/source/useLocation.jsx.map +1 -1
  144. package/dist/source/useMatch.jsx +30 -27
  145. package/dist/source/useMatch.jsx.map +1 -1
  146. package/dist/source/useParams.jsx +1 -1
  147. package/dist/source/useParams.jsx.map +1 -1
  148. package/dist/source/useRouterState.jsx +12 -33
  149. package/dist/source/useRouterState.jsx.map +1 -1
  150. package/dist/source/useSearch.jsx +2 -1
  151. package/dist/source/useSearch.jsx.map +1 -1
  152. package/dist/source/utils.d.ts +0 -4
  153. package/dist/source/utils.js +0 -13
  154. package/dist/source/utils.js.map +1 -1
  155. package/package.json +2 -3
  156. package/skills/solid-router/SKILL.md +2 -0
  157. package/src/Match.tsx +351 -304
  158. package/src/Matches.tsx +49 -52
  159. package/src/Scripts.tsx +40 -41
  160. package/src/Transitioner.tsx +67 -66
  161. package/src/headContentUtils.tsx +89 -91
  162. package/src/link.tsx +179 -141
  163. package/src/matchContext.tsx +16 -7
  164. package/src/not-found.tsx +6 -6
  165. package/src/router.ts +2 -1
  166. package/src/routerStores.ts +107 -0
  167. package/src/ssr/RouterClient.tsx +1 -1
  168. package/src/ssr/renderRouterToStream.tsx +1 -1
  169. package/src/ssr/renderRouterToString.tsx +2 -2
  170. package/src/useCanGoBack.ts +6 -2
  171. package/src/useLoaderDeps.tsx +2 -3
  172. package/src/useLocation.tsx +18 -5
  173. package/src/useMatch.tsx +36 -43
  174. package/src/useParams.tsx +2 -3
  175. package/src/useRouterState.tsx +17 -41
  176. package/src/useSearch.tsx +2 -1
  177. package/src/utils.ts +0 -20
@@ -1,6 +1,5 @@
1
1
  const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
2
2
  const require_useRouter = require("./useRouter.cjs");
3
- const require_useRouterState = require("./useRouterState.cjs");
4
3
  let _tanstack_router_core = require("@tanstack/router-core");
5
4
  let solid_js = require("solid-js");
6
5
  solid_js = require_runtime.__toESM(solid_js);
@@ -12,9 +11,8 @@ solid_js = require_runtime.__toESM(solid_js);
12
11
  var useTags = () => {
13
12
  const router = require_useRouter.useRouter();
14
13
  const nonce = router.options.ssr?.nonce;
15
- const routeMeta = require_useRouterState.useRouterState({ select: (state) => {
16
- return state.matches.map((match) => match.meta).filter(Boolean);
17
- } });
14
+ const activeMatches = solid_js.createMemo(() => router.stores.activeMatchesSnapshot.state);
15
+ const routeMeta = solid_js.createMemo(() => activeMatches().map((match) => match.meta).filter(Boolean));
18
16
  const meta = solid_js.createMemo(() => {
19
17
  const resultMeta = [];
20
18
  const metaByAttribute = {};
@@ -63,8 +61,9 @@ var useTags = () => {
63
61
  resultMeta.reverse();
64
62
  return resultMeta;
65
63
  });
66
- const links = require_useRouterState.useRouterState({ select: (state) => {
67
- const constructed = state.matches.map((match) => match.links).filter(Boolean).flat(1).map((link) => ({
64
+ const links = solid_js.createMemo(() => {
65
+ const matches = activeMatches();
66
+ const constructed = matches.map((match) => match.links).filter(Boolean).flat(1).map((link) => ({
68
67
  tag: "link",
69
68
  attrs: {
70
69
  ...link,
@@ -72,7 +71,7 @@ var useTags = () => {
72
71
  }
73
72
  }));
74
73
  const manifest = router.ssr?.manifest;
75
- const assets = state.matches.map((match) => manifest?.routes[match.routeId]?.assets ?? []).filter(Boolean).flat(1).filter((asset) => asset.tag === "link").map((asset) => ({
74
+ const assets = matches.map((match) => manifest?.routes[match.routeId]?.assets ?? []).filter(Boolean).flat(1).filter((asset) => asset.tag === "link").map((asset) => ({
76
75
  tag: "link",
77
76
  attrs: {
78
77
  ...asset.attrs,
@@ -80,10 +79,11 @@ var useTags = () => {
80
79
  }
81
80
  }));
82
81
  return [...constructed, ...assets];
83
- } });
84
- const preloadLinks = require_useRouterState.useRouterState({ select: (state) => {
82
+ });
83
+ const preloadLinks = solid_js.createMemo(() => {
84
+ const matches = activeMatches();
85
85
  const preloadLinks = [];
86
- state.matches.map((match) => router.looseRoutesById[match.routeId]).forEach((route) => router.ssr?.manifest?.routes[route.id]?.preloads?.filter(Boolean).forEach((preload) => {
86
+ matches.map((match) => router.looseRoutesById[match.routeId]).forEach((route) => router.ssr?.manifest?.routes[route.id]?.preloads?.filter(Boolean).forEach((preload) => {
87
87
  preloadLinks.push({
88
88
  tag: "link",
89
89
  attrs: {
@@ -94,23 +94,23 @@ var useTags = () => {
94
94
  });
95
95
  }));
96
96
  return preloadLinks;
97
- } });
98
- const styles = require_useRouterState.useRouterState({ select: (state) => state.matches.map((match) => match.styles).flat(1).filter(Boolean).map(({ children, ...style }) => ({
97
+ });
98
+ const styles = solid_js.createMemo(() => activeMatches().map((match) => match.styles).flat(1).filter(Boolean).map(({ children, ...style }) => ({
99
99
  tag: "style",
100
100
  attrs: {
101
101
  ...style,
102
102
  nonce
103
103
  },
104
104
  children
105
- })) });
106
- const headScripts = require_useRouterState.useRouterState({ select: (state) => state.matches.map((match) => match.headScripts).flat(1).filter(Boolean).map(({ children, ...script }) => ({
105
+ })));
106
+ const headScripts = solid_js.createMemo(() => activeMatches().map((match) => match.headScripts).flat(1).filter(Boolean).map(({ children, ...script }) => ({
107
107
  tag: "script",
108
108
  attrs: {
109
109
  ...script,
110
110
  nonce
111
111
  },
112
112
  children
113
- })) });
113
+ })));
114
114
  return () => uniqBy([
115
115
  ...meta(),
116
116
  ...preloadLinks(),
@@ -1 +1 @@
1
- {"version":3,"file":"headContentUtils.cjs","names":["Solid","escapeHtml","useRouter","useRouterState","RouterManagedTag","useTags","router","nonce","options","ssr","routeMeta","select","state","matches","map","match","meta","filter","Boolean","Accessor","Array","createMemo","resultMeta","metaByAttribute","Record","title","routeMetasArray","i","length","metas","j","m","tag","children","json","JSON","stringify","push","attrs","type","attribute","name","property","content","reverse","links","constructed","flat","link","manifest","assets","routes","routeId","asset","preloadLinks","looseRoutesById","forEach","route","id","preloads","preload","rel","href","styles","style","headScripts","script","uniqBy","d","arr","T","fn","item","seen","Set","key","has","add"],"sources":["../../src/headContentUtils.tsx"],"sourcesContent":["import * as Solid from 'solid-js'\nimport { escapeHtml } from '@tanstack/router-core'\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: Solid.Accessor<Array<RouterManagedTag>> = Solid.createMemo(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n const routeMetasArray = routeMeta()\n for (let i = routeMetasArray.length - 1; i >= 0; i--) {\n const metas = routeMetasArray[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 if ('script:ld+json' in m) {\n // Handle JSON-LD structured data\n // Content is HTML-escaped to prevent XSS when injected via innerHTML\n try {\n const json = JSON.stringify(m['script:ld+json'])\n resultMeta.push({\n tag: 'script',\n attrs: {\n type: 'application/ld+json',\n },\n children: escapeHtml(json),\n })\n } catch {\n // Skip invalid JSON-LD objects\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 (router.options.ssr?.nonce) {\n resultMeta.push({\n tag: 'meta',\n attrs: {\n property: 'csp-nonce',\n content: router.options.ssr.nonce,\n },\n })\n }\n resultMeta.reverse()\n\n return resultMeta\n })\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 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: { ...asset.attrs, nonce },\n }) satisfies RouterManagedTag,\n )\n\n return [...constructed, ...assets]\n },\n })\n\n const preloadLinks = useRouterState({\n select: (state) => {\n const preloadLinks: 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 preloadLinks.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n nonce,\n },\n })\n }),\n )\n\n return preloadLinks\n },\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, ...style }) => ({\n tag: 'style',\n attrs: {\n ...style,\n nonce,\n },\n children,\n })),\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 })\n\n return () =>\n uniqBy(\n [\n ...meta(),\n ...preloadLinks(),\n ...links(),\n ...styles(),\n ...headScripts(),\n ] as Array<RouterManagedTag>,\n (d) => {\n return JSON.stringify(d)\n },\n )\n}\n\nexport function 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"],"mappings":"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"}
1
+ {"version":3,"file":"headContentUtils.cjs","names":["Solid","escapeHtml","useRouter","RouterManagedTag","useTags","router","nonce","options","ssr","activeMatches","createMemo","stores","activeMatchesSnapshot","state","routeMeta","map","match","meta","filter","Boolean","Accessor","Array","resultMeta","metaByAttribute","Record","title","routeMetasArray","i","length","metas","j","m","tag","children","json","JSON","stringify","push","attrs","type","attribute","name","property","content","reverse","links","matches","constructed","flat","link","manifest","assets","routes","routeId","asset","preloadLinks","looseRoutesById","forEach","route","id","preloads","preload","rel","href","styles","style","headScripts","script","uniqBy","d","arr","T","fn","item","seen","Set","key","has","add"],"sources":["../../src/headContentUtils.tsx"],"sourcesContent":["import * as Solid from 'solid-js'\nimport { escapeHtml } from '@tanstack/router-core'\nimport { useRouter } from './useRouter'\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 activeMatches = Solid.createMemo(\n () => router.stores.activeMatchesSnapshot.state,\n )\n const routeMeta = Solid.createMemo(() =>\n activeMatches()\n .map((match) => match.meta!)\n .filter(Boolean),\n )\n\n const meta: Solid.Accessor<Array<RouterManagedTag>> = Solid.createMemo(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n const routeMetasArray = routeMeta()\n for (let i = routeMetasArray.length - 1; i >= 0; i--) {\n const metas = routeMetasArray[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 if ('script:ld+json' in m) {\n // Handle JSON-LD structured data\n // Content is HTML-escaped to prevent XSS when injected via innerHTML\n try {\n const json = JSON.stringify(m['script:ld+json'])\n resultMeta.push({\n tag: 'script',\n attrs: {\n type: 'application/ld+json',\n },\n children: escapeHtml(json),\n })\n } catch {\n // Skip invalid JSON-LD objects\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 (router.options.ssr?.nonce) {\n resultMeta.push({\n tag: 'meta',\n attrs: {\n property: 'csp-nonce',\n content: router.options.ssr.nonce,\n },\n })\n }\n resultMeta.reverse()\n\n return resultMeta\n })\n\n const links = Solid.createMemo(() => {\n const matches = activeMatches()\n const constructed = 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 const assets = 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: { ...asset.attrs, nonce },\n }) satisfies RouterManagedTag,\n )\n\n return [...constructed, ...assets]\n })\n\n const preloadLinks = Solid.createMemo(() => {\n const matches = activeMatches()\n const preloadLinks: Array<RouterManagedTag> = []\n\n 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 preloadLinks.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n nonce,\n },\n })\n }),\n )\n\n return preloadLinks\n })\n\n const styles = Solid.createMemo(() =>\n (\n activeMatches()\n .map((match) => match.styles!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...style }) => ({\n tag: 'style',\n attrs: {\n ...style,\n nonce,\n },\n children,\n })),\n )\n\n const headScripts = Solid.createMemo(() =>\n (\n activeMatches()\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 )\n\n return () =>\n uniqBy(\n [\n ...meta(),\n ...preloadLinks(),\n ...links(),\n ...styles(),\n ...headScripts(),\n ] as Array<RouterManagedTag>,\n (d) => {\n return JSON.stringify(d)\n },\n )\n}\n\nexport function 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"],"mappings":";;;;;;;;;;AASA,IAAaI,gBAAgB;CAC3B,MAAMC,SAASH,kBAAAA,WAAW;CAC1B,MAAMI,QAAQD,OAAOE,QAAQC,KAAKF;CAClC,MAAMG,gBAAgBT,SAAMU,iBACpBL,OAAOM,OAAOC,sBAAsBC,MAC3C;CACD,MAAMC,YAAYd,SAAMU,iBACtBD,eAAe,CACZM,KAAKC,UAAUA,MAAMC,KAAM,CAC3BC,OAAOC,QACZ,CAAC;CAED,MAAMF,OAAgDjB,SAAMU,iBAAiB;EAC3E,MAAMY,aAAsC,EAAE;EAC9C,MAAMC,kBAAwC,EAAE;EAChD,IAAIE;EACJ,MAAMC,kBAAkBZ,WAAW;AACnC,OAAK,IAAIa,IAAID,gBAAgBE,SAAS,GAAGD,KAAK,GAAGA,KAAK;GACpD,MAAME,QAAQH,gBAAgBC;AAC9B,QAAK,IAAIG,IAAID,MAAMD,SAAS,GAAGE,KAAK,GAAGA,KAAK;IAC1C,MAAMC,IAAIF,MAAMC;AAChB,QAAI,CAACC,EAAG;AAER,QAAIA,EAAEN;SACA,CAACA,MACHA,SAAQ;MACNO,KAAK;MACLC,UAAUF,EAAEN;MACb;eAEM,oBAAoBM,EAG7B,KAAI;KACF,MAAMG,OAAOC,KAAKC,UAAUL,EAAE,kBAAkB;AAChDT,gBAAWe,KAAK;MACdL,KAAK;MACLM,OAAO,EACLC,MAAM,uBACP;MACDN,WAAAA,GAAAA,sBAAAA,YAAqBC,KAAI;MAC1B,CAAC;YACI;SAGH;KACL,MAAMM,YAAYT,EAAEU,QAAQV,EAAEW;AAC9B,SAAIF,UACF,KAAIjB,gBAAgBiB,WAClB;SAEAjB,iBAAgBiB,aAAa;AAIjClB,gBAAWe,KAAK;MACdL,KAAK;MACLM,OAAO;OACL,GAAGP;OACHzB;OACF;MACD,CAAC;;;;AAKR,MAAImB,MACFH,YAAWe,KAAKZ,MAAM;AAGxB,MAAIpB,OAAOE,QAAQC,KAAKF,MACtBgB,YAAWe,KAAK;GACdL,KAAK;GACLM,OAAO;IACLI,UAAU;IACVC,SAAStC,OAAOE,QAAQC,IAAIF;IAC9B;GACD,CAAC;AAEJgB,aAAWsB,SAAS;AAEpB,SAAOtB;GACP;CAEF,MAAMuB,QAAQ7C,SAAMU,iBAAiB;EACnC,MAAMoC,UAAUrC,eAAe;EAC/B,MAAMsC,cAAcD,QACjB/B,KAAKC,UAAUA,MAAM6B,MAAO,CAC5B3B,OAAOC,QAAQ,CACf6B,KAAK,EAAE,CACPjC,KAAKkC,UAAU;GACdjB,KAAK;GACLM,OAAO;IACL,GAAGW;IACH3C;IACF;GACD,EAAE;EAEL,MAAM4C,WAAW7C,OAAOG,KAAK0C;EAE7B,MAAMC,SAASL,QACZ/B,KAAKC,UAAUkC,UAAUE,OAAOpC,MAAMqC,UAAUF,UAAU,EAAE,CAAC,CAC7DjC,OAAOC,QAAQ,CACf6B,KAAK,EAAE,CACP9B,QAAQoC,UAAUA,MAAMtB,QAAQ,OAAO,CACvCjB,KACEuC,WACE;GACCtB,KAAK;GACLM,OAAO;IAAE,GAAGgB,MAAMhB;IAAOhC;IAAM;GAChC,EACJ;AAEH,SAAO,CAAC,GAAGyC,aAAa,GAAGI,OAAO;GAClC;CAEF,MAAMI,eAAevD,SAAMU,iBAAiB;EAC1C,MAAMoC,UAAUrC,eAAe;EAC/B,MAAM8C,eAAwC,EAAE;AAEhDT,UACG/B,KAAKC,UAAUX,OAAOmD,gBAAgBxC,MAAMqC,SAAU,CACtDI,SAASC,UACRrD,OAAOG,KAAK0C,UAAUE,OAAOM,MAAMC,KAAKC,UACpC1C,OAAOC,QAAQ,CAChBsC,SAASI,YAAY;AACpBN,gBAAalB,KAAK;IAChBL,KAAK;IACLM,OAAO;KACLwB,KAAK;KACLC,MAAMF;KACNvD;KACF;IACD,CAAC;IAER,CAAC;AAEH,SAAOiD;GACP;CAEF,MAAMS,SAAShE,SAAMU,iBAEjBD,eAAe,CACZM,KAAKC,UAAUA,MAAMgD,OAAQ,CAC7BhB,KAAK,EAAE,CACP9B,OAAOC,QAAQ,CAClBJ,KAAK,EAAEkB,UAAU,GAAGgC,aAAa;EACjCjC,KAAK;EACLM,OAAO;GACL,GAAG2B;GACH3D;GACD;EACD2B;EACD,EACH,CAAC;CAED,MAAMiC,cAAclE,SAAMU,iBAEtBD,eAAe,CACZM,KAAKC,UAAUA,MAAMkD,YAAa,CAClClB,KAAK,EAAE,CACP9B,OAAOC,QAAQ,CAClBJ,KAAK,EAAEkB,UAAU,GAAGkC,cAAc;EAClCnC,KAAK;EACLM,OAAO;GACL,GAAG6B;GACH7D;GACD;EACD2B;EACD,EACH,CAAC;AAED,cACEmC,OACE;EACE,GAAGnD,MAAM;EACT,GAAGsC,cAAc;EACjB,GAAGV,OAAO;EACV,GAAGmB,QAAQ;EACX,GAAGE,aAAa;EACjB,GACAG,MAAM;AACL,SAAOlC,KAAKC,UAAUiC,EAAE;GAE3B;;AAGL,SAAgBD,OAAUE,KAAeE,IAAyB;CAChE,MAAME,uBAAO,IAAIC,KAAa;AAC9B,QAAOL,IAAIpD,QAAQuD,SAAS;EAC1B,MAAMG,MAAMJ,GAAGC,KAAK;AACpB,MAAIC,KAAKG,IAAID,IAAI,CACf,QAAO;AAETF,OAAKI,IAAIF,IAAI;AACb,SAAO;GACP"}
@@ -4,7 +4,6 @@ const require_awaited = require("./awaited.cjs");
4
4
  const require_CatchBoundary = require("./CatchBoundary.cjs");
5
5
  const require_ClientOnly = require("./ClientOnly.cjs");
6
6
  const require_useRouter = require("./useRouter.cjs");
7
- const require_useRouterState = require("./useRouterState.cjs");
8
7
  const require_link = require("./link.cjs");
9
8
  const require_useMatch = require("./useMatch.cjs");
10
9
  const require_useLoaderData = require("./useLoaderData.cjs");
@@ -24,6 +23,7 @@ const require_router = require("./router.cjs");
24
23
  const require_RouterProvider = require("./RouterProvider.cjs");
25
24
  const require_ScrollRestoration = require("./ScrollRestoration.cjs");
26
25
  const require_useBlocker = require("./useBlocker.cjs");
26
+ const require_useRouterState = require("./useRouterState.cjs");
27
27
  const require_useLocation = require("./useLocation.cjs");
28
28
  const require_useCanGoBack = require("./useCanGoBack.cjs");
29
29
  const require_Asset = require("./Asset.cjs");
@@ -4,7 +4,6 @@ const require_awaited = require("./awaited.cjs");
4
4
  const require_CatchBoundary = require("./CatchBoundary.cjs");
5
5
  const require_ClientOnly = require("./ClientOnly.cjs");
6
6
  const require_useRouter = require("./useRouter.cjs");
7
- const require_useRouterState = require("./useRouterState.cjs");
8
7
  const require_link = require("./link.cjs");
9
8
  const require_useMatch = require("./useMatch.cjs");
10
9
  const require_useLoaderData = require("./useLoaderData.cjs");
@@ -24,6 +23,7 @@ const require_router = require("./router.cjs");
24
23
  const require_RouterProvider = require("./RouterProvider.cjs");
25
24
  const require_ScrollRestoration = require("./ScrollRestoration.cjs");
26
25
  const require_useBlocker = require("./useBlocker.cjs");
26
+ const require_useRouterState = require("./useRouterState.cjs");
27
27
  const require_useLocation = require("./useLocation.cjs");
28
28
  const require_useCanGoBack = require("./useCanGoBack.cjs");
29
29
  const require_Asset = require("./Asset.cjs");
package/dist/cjs/link.cjs CHANGED
@@ -1,7 +1,6 @@
1
1
  const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
2
2
  const require_ClientOnly = require("./ClientOnly.cjs");
3
3
  const require_useRouter = require("./useRouter.cjs");
4
- const require_useRouterState = require("./useRouterState.cjs");
5
4
  const require_utils = require("./utils.cjs");
6
5
  let _tanstack_router_core = require("@tanstack/router-core");
7
6
  let solid_js_web = require("solid-js/web");
@@ -10,7 +9,7 @@ solid_js = require_runtime.__toESM(solid_js);
10
9
  let _solid_primitives_refs = require("@solid-primitives/refs");
11
10
  let _tanstack_router_core_isServer = require("@tanstack/router-core/isServer");
12
11
  //#region src/link.tsx
13
- var _tmpl$ = /* @__PURE__ */ (0, solid_js_web.template)(`<svg><a>`);
12
+ var _tmpl$ = /* @__PURE__ */ (0, solid_js_web.template)(`<svg><a>`), _tmpl$2 = /* @__PURE__ */ (0, solid_js_web.template)(`<a>`);
14
13
  var timeoutMap = /* @__PURE__ */ new WeakMap();
15
14
  function useLinkProps(options) {
16
15
  const router = require_useRouter.useRouter();
@@ -19,8 +18,8 @@ function useLinkProps(options) {
19
18
  const hasHydrated = require_ClientOnly.useHydrated();
20
19
  let hasRenderFetched = false;
21
20
  const [local, rest] = solid_js.splitProps(solid_js.mergeProps({
22
- activeProps: () => ({ class: "active" }),
23
- inactiveProps: () => ({})
21
+ activeProps: STATIC_ACTIVE_PROPS_GET,
22
+ inactiveProps: STATIC_INACTIVE_PROPS_GET
24
23
  }, options), [
25
24
  "activeProps",
26
25
  "inactiveProps",
@@ -56,25 +55,14 @@ function useLinkProps(options) {
56
55
  "reloadDocument",
57
56
  "unsafeRelative"
58
57
  ]);
59
- const currentLocation = require_useRouterState.useRouterState({ select: (s) => s.location });
60
- const buildLocationKey = require_useRouterState.useRouterState({ select: (s) => {
61
- const leaf = s.matches[s.matches.length - 1];
62
- return {
63
- search: leaf?.search,
64
- hash: s.location.hash,
65
- path: leaf?.pathname
66
- };
67
- } });
68
- const from = options.from;
69
- const _options = () => {
70
- return {
71
- ...options,
72
- from
73
- };
74
- };
58
+ const currentLocation = solid_js.createMemo(() => router.stores.location.state, void 0, { equals: (prev, next) => prev.href === next.href });
59
+ const _options = () => options;
75
60
  const next = solid_js.createMemo(() => {
76
- buildLocationKey();
77
- return router.buildLocation(_options());
61
+ const options = {
62
+ _fromLocation: currentLocation(),
63
+ ..._options()
64
+ };
65
+ return solid_js.untrack(() => router.buildLocation(options));
78
66
  });
79
67
  const hrefOption = solid_js.createMemo(() => {
80
68
  if (_options().disabled) return void 0;
@@ -99,7 +87,8 @@ function useLinkProps(options) {
99
87
  return _href.href;
100
88
  }
101
89
  const to = _options().to;
102
- if (typeof to === "string" && to.charCodeAt(0) === 47 && to.charCodeAt(1) !== 47) return void 0;
90
+ if (isSafeInternal(to)) return void 0;
91
+ if (typeof to !== "string" || to.indexOf(":") === -1) return void 0;
103
92
  try {
104
93
  new URL(to);
105
94
  if ((0, _tanstack_router_core.isDangerousProtocol)(to, router.protocolAllowlist)) {
@@ -116,22 +105,29 @@ function useLinkProps(options) {
116
105
  const preloadDelay = () => local.preloadDelay ?? router.options.defaultPreloadDelay ?? 0;
117
106
  const isActive = solid_js.createMemo(() => {
118
107
  if (externalLink()) return false;
119
- if (local.activeOptions?.exact) {
120
- if (!(0, _tanstack_router_core.exactPathTest)(currentLocation().pathname, next().pathname, router.basepath)) return false;
108
+ const activeOptions = local.activeOptions;
109
+ const current = currentLocation();
110
+ const nextLocation = next();
111
+ if (activeOptions?.exact) {
112
+ if (!(0, _tanstack_router_core.exactPathTest)(current.pathname, nextLocation.pathname, router.basepath)) return false;
121
113
  } else {
122
- const currentPathSplit = (0, _tanstack_router_core.removeTrailingSlash)(currentLocation().pathname, router.basepath).split("/");
123
- if (!((0, _tanstack_router_core.removeTrailingSlash)(next()?.pathname, router.basepath)?.split("/"))?.every((d, i) => d === currentPathSplit[i])) return false;
114
+ const currentPath = (0, _tanstack_router_core.removeTrailingSlash)(current.pathname, router.basepath);
115
+ const nextPath = (0, _tanstack_router_core.removeTrailingSlash)(nextLocation.pathname, router.basepath);
116
+ if (!(currentPath.startsWith(nextPath) && (currentPath.length === nextPath.length || currentPath[nextPath.length] === "/"))) return false;
124
117
  }
125
- if (local.activeOptions?.includeSearch ?? true) {
126
- if (!(0, _tanstack_router_core.deepEqual)(currentLocation().search, next().search, {
127
- partial: !local.activeOptions?.exact,
128
- ignoreUndefined: !local.activeOptions?.explicitUndefined
118
+ if (activeOptions?.includeSearch ?? true) {
119
+ if (!(0, _tanstack_router_core.deepEqual)(current.search, nextLocation.search, {
120
+ partial: !activeOptions?.exact,
121
+ ignoreUndefined: !activeOptions?.explicitUndefined
129
122
  })) return false;
130
123
  }
131
- if (local.activeOptions?.includeHash) return (shouldHydrateHash && !hasHydrated() ? "" : currentLocation().hash) === next().hash;
124
+ if (activeOptions?.includeHash) return (shouldHydrateHash && !hasHydrated() ? "" : current.hash) === nextLocation.hash;
132
125
  return true;
133
126
  });
134
- const doPreload = () => router.preloadRoute(_options()).catch((err) => {
127
+ const doPreload = () => router.preloadRoute({
128
+ ..._options(),
129
+ _builtLocation: next()
130
+ }).catch((err) => {
135
131
  console.warn(err);
136
132
  console.warn(_tanstack_router_core.preloadWarning);
137
133
  });
@@ -211,62 +207,89 @@ function useLinkProps(options) {
211
207
  timeoutMap.delete(eventTarget);
212
208
  }
213
209
  };
214
- /** Call a JSX.EventHandlerUnion with the event. */
215
- function callHandler(event, handler) {
216
- if (handler) if (typeof handler === "function") handler(event);
217
- else handler[0](handler[1], event);
218
- return event.defaultPrevented;
219
- }
220
- function composeEventHandlers(handlers) {
221
- return (event) => {
222
- for (const handler of handlers) callHandler(event, handler);
223
- };
224
- }
225
- const resolvedActiveProps = () => isActive() ? (0, _tanstack_router_core.functionalUpdate)(local.activeProps, {}) ?? {} : {};
226
- const resolvedInactiveProps = () => isActive() ? {} : (0, _tanstack_router_core.functionalUpdate)(local.inactiveProps, {});
227
- const resolvedClassName = () => [
228
- local.class,
229
- resolvedActiveProps().class,
230
- resolvedInactiveProps().class
231
- ].filter(Boolean).join(" ");
232
- const resolvedStyle = () => ({
233
- ...local.style,
234
- ...resolvedActiveProps().style,
235
- ...resolvedInactiveProps().style
236
- });
237
- return solid_js.mergeProps(propsSafeToSpread, resolvedActiveProps, resolvedInactiveProps, () => {
238
- return {
210
+ const simpleStyling = solid_js.createMemo(() => local.activeProps === STATIC_ACTIVE_PROPS_GET && local.inactiveProps === STATIC_INACTIVE_PROPS_GET && local.class === void 0 && local.style === void 0);
211
+ const onClick = createComposedHandler(() => local.onClick, handleClick);
212
+ const onBlur = createComposedHandler(() => local.onBlur, handleLeave);
213
+ const onFocus = createComposedHandler(() => local.onFocus, enqueueIntentPreload);
214
+ const onMouseEnter = createComposedHandler(() => local.onMouseEnter, enqueueIntentPreload);
215
+ const onMouseOver = createComposedHandler(() => local.onMouseOver, enqueueIntentPreload);
216
+ const onMouseLeave = createComposedHandler(() => local.onMouseLeave, handleLeave);
217
+ const onMouseOut = createComposedHandler(() => local.onMouseOut, handleLeave);
218
+ const onTouchStart = createComposedHandler(() => local.onTouchStart, handleTouchStart);
219
+ const resolvedProps = solid_js.createMemo(() => {
220
+ const active = isActive();
221
+ const base = {
239
222
  href: hrefOption()?.href,
240
223
  ref: (0, _solid_primitives_refs.mergeRefs)(setRef, _options().ref),
241
- onClick: composeEventHandlers([local.onClick, handleClick]),
242
- onBlur: composeEventHandlers([local.onBlur, handleLeave]),
243
- onFocus: composeEventHandlers([local.onFocus, enqueueIntentPreload]),
244
- onMouseEnter: composeEventHandlers([local.onMouseEnter, enqueueIntentPreload]),
245
- onMouseOver: composeEventHandlers([local.onMouseOver, enqueueIntentPreload]),
246
- onMouseLeave: composeEventHandlers([local.onMouseLeave, handleLeave]),
247
- onMouseOut: composeEventHandlers([local.onMouseOut, handleLeave]),
248
- onTouchStart: composeEventHandlers([local.onTouchStart, handleTouchStart]),
224
+ onClick,
225
+ onBlur,
226
+ onFocus,
227
+ onMouseEnter,
228
+ onMouseOver,
229
+ onMouseLeave,
230
+ onMouseOut,
231
+ onTouchStart,
249
232
  disabled: !!local.disabled,
250
233
  target: local.target,
251
- ...(() => {
252
- const s = resolvedStyle();
253
- return Object.keys(s).length ? { style: s } : {};
254
- })(),
255
- ...(() => {
256
- const c = resolvedClassName();
257
- return c ? { class: c } : {};
258
- })(),
259
- ...local.disabled && {
260
- role: "link",
261
- "aria-disabled": true
262
- },
263
- ...isActive() && {
264
- "data-status": "active",
265
- "aria-current": "page"
266
- },
267
- ...isTransitioning() && { "data-transitioning": "transitioning" }
234
+ ...local.disabled && STATIC_DISABLED_PROPS,
235
+ ...isTransitioning() && STATIC_TRANSITIONING_ATTRIBUTES
236
+ };
237
+ if (simpleStyling()) return {
238
+ ...base,
239
+ ...active && STATIC_DEFAULT_ACTIVE_ATTRIBUTES
240
+ };
241
+ const activeProps = active ? (0, _tanstack_router_core.functionalUpdate)(local.activeProps, {}) ?? EMPTY_OBJECT : EMPTY_OBJECT;
242
+ const inactiveProps = active ? EMPTY_OBJECT : (0, _tanstack_router_core.functionalUpdate)(local.inactiveProps, {});
243
+ const style = {
244
+ ...local.style,
245
+ ...activeProps.style,
246
+ ...inactiveProps.style
247
+ };
248
+ const className = [
249
+ local.class,
250
+ activeProps.class,
251
+ inactiveProps.class
252
+ ].filter(Boolean).join(" ");
253
+ return {
254
+ ...activeProps,
255
+ ...inactiveProps,
256
+ ...base,
257
+ ...Object.keys(style).length ? { style } : void 0,
258
+ ...className ? { class: className } : void 0,
259
+ ...active && STATIC_ACTIVE_ATTRIBUTES
268
260
  };
269
261
  });
262
+ return solid_js.mergeProps(propsSafeToSpread, resolvedProps);
263
+ }
264
+ var STATIC_ACTIVE_PROPS = { class: "active" };
265
+ var STATIC_ACTIVE_PROPS_GET = () => STATIC_ACTIVE_PROPS;
266
+ var EMPTY_OBJECT = {};
267
+ var STATIC_INACTIVE_PROPS_GET = () => EMPTY_OBJECT;
268
+ var STATIC_DEFAULT_ACTIVE_ATTRIBUTES = {
269
+ class: "active",
270
+ "data-status": "active",
271
+ "aria-current": "page"
272
+ };
273
+ var STATIC_DISABLED_PROPS = {
274
+ role: "link",
275
+ "aria-disabled": true
276
+ };
277
+ var STATIC_ACTIVE_ATTRIBUTES = {
278
+ "data-status": "active",
279
+ "aria-current": "page"
280
+ };
281
+ var STATIC_TRANSITIONING_ATTRIBUTES = { "data-transitioning": "transitioning" };
282
+ /** Call a JSX.EventHandlerUnion with the event. */
283
+ function callHandler(event, handler) {
284
+ if (typeof handler === "function") handler(event);
285
+ else handler[0](handler[1], event);
286
+ return event.defaultPrevented;
287
+ }
288
+ function createComposedHandler(getHandler, fallback) {
289
+ return (event) => {
290
+ const handler = getHandler();
291
+ if (!handler || !callHandler(event, handler)) fallback(event);
292
+ };
270
293
  }
271
294
  function createLink(Comp) {
272
295
  return (props) => (0, solid_js_web.createComponent)(Link, (0, solid_js_web.mergeProps)(props, { _asChild: Comp }));
@@ -295,8 +318,14 @@ var Link = (props) => {
295
318
  return _el$;
296
319
  })();
297
320
  }
321
+ if (!local._asChild) return (() => {
322
+ var _el$3 = _tmpl$2();
323
+ (0, solid_js_web.spread)(_el$3, linkProps, false, true);
324
+ (0, solid_js_web.insert)(_el$3, children);
325
+ return _el$3;
326
+ })();
298
327
  return (0, solid_js_web.createComponent)(solid_js_web.Dynamic, (0, solid_js_web.mergeProps)({ get component() {
299
- return (0, solid_js_web.memo)(() => !!local._asChild)() ? local._asChild : "a";
328
+ return local._asChild;
300
329
  } }, linkProps, { get children() {
301
330
  return children();
302
331
  } }));
@@ -304,6 +333,12 @@ var Link = (props) => {
304
333
  function isCtrlEvent(e) {
305
334
  return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
306
335
  }
336
+ function isSafeInternal(to) {
337
+ if (typeof to !== "string") return false;
338
+ const zero = to.charCodeAt(0);
339
+ if (zero === 47) return to.charCodeAt(1) !== 47;
340
+ return zero === 46;
341
+ }
307
342
  var linkOptions = (options) => {
308
343
  return options;
309
344
  };
@@ -1 +1 @@
1
- {"version":3,"file":"link.cjs","names":["Solid","mergeRefs","deepEqual","exactPathTest","functionalUpdate","isDangerousProtocol","preloadWarning","removeTrailingSlash","isServer","Dynamic","useRouterState","useRouter","useIntersectionObserver","useHydrated","AnyRouter","Constrain","LinkOptions","RegisteredRouter","RoutePaths","ValidateLinkOptions","ValidateLinkOptionsArray","timeoutMap","WeakMap","EventTarget","ReturnType","setTimeout","useLinkProps","TRouter","TFrom","options","UseLinkPropsOptions","TTo","TMaskFrom","TMaskTo","ComponentProps","router","isTransitioning","setIsTransitioning","createSignal","shouldHydrateHash","ssr","hasHydrated","hasRenderFetched","local","rest","splitProps","mergeProps","activeProps","class","inactiveProps","_","propsSafeToSpread","currentLocation","select","s","location","buildLocationKey","leaf","matches","length","search","hash","path","pathname","from","_options","next","createMemo","buildLocation","hrefOption","disabled","undefined","maskedLocation","publicHref","external","href","history","createHref","externalLink","_href","protocolAllowlist","process","env","NODE_ENV","console","warn","to","isSafeInternal","charCodeAt","URL","preload","reloadDocument","defaultPreload","preloadDelay","defaultPreloadDelay","isActive","activeOptions","exact","testExact","basepath","currentPathSplit","split","nextPathSplit","pathIsFuzzyEqual","every","d","i","includeSearch","searchTest","partial","ignoreUndefined","explicitUndefined","includeHash","currentHash","doPreload","preloadRoute","catch","err","preloadViewportIoCallback","entry","IntersectionObserverEntry","isIntersecting","ref","setRef","Element","rootMargin","createEffect","handleClick","e","MouseEvent","elementTarget","currentTarget","HTMLAnchorElement","SVGAElement","getAttribute","effectiveTarget","target","isCtrlEvent","defaultPrevented","button","preventDefault","unsub","subscribe","navigate","replace","resetScroll","hashScrollIntoView","startTransition","viewTransition","ignoreBlocker","enqueueIntentPreload","FocusEvent","eventTarget","has","set","delete","handleTouchStart","TouchEvent","handleLeave","id","get","clearTimeout","callHandler","Event","event","TEvent","T","handler","JSX","EventHandlerUnion","composeEventHandlers","handlers","Array","resolvedActiveProps","Omit","style","CSSProperties","resolvedInactiveProps","resolvedClassName","filter","Boolean","join","resolvedStyle","onClick","onBlur","onFocus","onMouseEnter","onMouseOver","onMouseLeave","onMouseOut","onTouchStart","Object","keys","c","role","ActiveLinkOptions","ActiveLinkOptionProps","TComp","ActiveLinkProps","Partial","LinkComponentSolidProps","key","LinkProps","LinkPropsChildren","children","state","ValidComponent","CreateLinkProps","LinkComponentProps","LinkComponent","TDefaultFrom","props","LinkComponentRoute","defaultFrom","createLink","Comp","_$createComponent","Link","_$mergeProps","_asChild","linkProps","ch","svgLinkProps","_el$","_tmpl$","_el$2","firstChild","_$spread","_$insert","component","_$memo","metaKey","altKey","ctrlKey","shiftKey","LinkOptionsFnOptions","TOptions","ReadonlyArray","LinkOptionsFn","linkOptions"],"sources":["../../src/link.tsx"],"sourcesContent":["import * as Solid from 'solid-js'\n\nimport { mergeRefs } from '@solid-primitives/refs'\n\nimport {\n deepEqual,\n exactPathTest,\n functionalUpdate,\n isDangerousProtocol,\n preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\n\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { Dynamic } from 'solid-js/web'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\n\nimport { useIntersectionObserver } from './utils'\n\nimport { useHydrated } from './ClientOnly'\nimport type {\n AnyRouter,\n Constrain,\n LinkOptions,\n RegisteredRouter,\n RoutePaths,\n} from '@tanstack/router-core'\nimport type {\n ValidateLinkOptions,\n ValidateLinkOptionsArray,\n} from './typePrimitives'\n\nconst timeoutMap = new WeakMap<EventTarget, ReturnType<typeof setTimeout>>()\n\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n): Solid.ComponentProps<'a'> {\n const router = useRouter()\n const [isTransitioning, setIsTransitioning] = Solid.createSignal(false)\n const shouldHydrateHash = !isServer && !!router.options.ssr\n const hasHydrated = useHydrated()\n\n let hasRenderFetched = false\n\n const [local, rest] = Solid.splitProps(\n Solid.mergeProps(\n {\n activeProps: () => ({ class: 'active' }),\n inactiveProps: () => ({}),\n },\n options,\n ),\n [\n 'activeProps',\n 'inactiveProps',\n 'activeOptions',\n 'to',\n 'preload',\n 'preloadDelay',\n 'hashScrollIntoView',\n 'replace',\n 'startTransition',\n 'resetScroll',\n 'viewTransition',\n 'target',\n 'disabled',\n 'style',\n 'class',\n 'onClick',\n 'onBlur',\n 'onFocus',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseOver',\n 'onMouseOut',\n 'onTouchStart',\n 'ignoreBlocker',\n ],\n )\n\n // const {\n // // custom props\n // activeProps = () => ({ class: 'active' }),\n // inactiveProps = () => ({}),\n // activeOptions,\n // to,\n // preload: userPreload,\n // preloadDelay: userPreloadDelay,\n // hashScrollIntoView,\n // replace,\n // startTransition,\n // resetScroll,\n // viewTransition,\n // // element props\n // children,\n // target,\n // disabled,\n // style,\n // class,\n // onClick,\n // onFocus,\n // onMouseEnter,\n // onMouseLeave,\n // onTouchStart,\n // ignoreBlocker,\n // ...rest\n // } = options\n\n const [_, propsSafeToSpread] = Solid.splitProps(rest, [\n 'params',\n 'search',\n 'hash',\n 'state',\n 'mask',\n 'reloadDocument',\n 'unsafeRelative',\n ])\n\n const currentLocation = useRouterState({\n select: (s) => s.location,\n })\n\n const buildLocationKey = useRouterState({\n select: (s) => {\n const leaf = s.matches[s.matches.length - 1]\n return {\n search: leaf?.search,\n hash: s.location.hash,\n path: leaf?.pathname, // path + params\n }\n },\n })\n\n const from = options.from\n\n const _options = () => {\n return {\n ...options,\n from,\n }\n }\n\n const next = Solid.createMemo(() => {\n buildLocationKey()\n return router.buildLocation(_options() as any)\n })\n\n const hrefOption = Solid.createMemo(() => {\n if (_options().disabled) return undefined\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const location = next().maskedLocation ?? next()\n const publicHref = location.publicHref\n const external = location.external\n\n if (external) {\n return { href: publicHref, external: true }\n }\n\n return {\n href: router.history.createHref(publicHref) || '/',\n external: false,\n }\n })\n\n const externalLink = Solid.createMemo(() => {\n const _href = hrefOption()\n if (_href?.external) {\n // Block dangerous protocols for external links\n if (isDangerousProtocol(_href.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${_href.href}`)\n }\n return undefined\n }\n return _href.href\n }\n const to = _options().to\n const isSafeInternal =\n typeof to === 'string' &&\n to.charCodeAt(0) === 47 && // '/'\n to.charCodeAt(1) !== 47 // but not '//'\n if (isSafeInternal) return undefined\n try {\n new URL(to as any)\n // Block dangerous protocols like javascript:, blob:, data:\n if (isDangerousProtocol(to as string, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n return undefined\n })\n\n const preload = Solid.createMemo(() => {\n if (_options().reloadDocument || externalLink()) {\n return false\n }\n return local.preload ?? router.options.defaultPreload\n })\n const preloadDelay = () =>\n local.preloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = Solid.createMemo(() => {\n if (externalLink()) return false\n if (local.activeOptions?.exact) {\n const testExact = exactPathTest(\n currentLocation().pathname,\n next().pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPathSplit = removeTrailingSlash(\n currentLocation().pathname,\n router.basepath,\n ).split('/')\n const nextPathSplit = removeTrailingSlash(\n next()?.pathname,\n router.basepath,\n )?.split('/')\n\n const pathIsFuzzyEqual = nextPathSplit?.every(\n (d, i) => d === currentPathSplit[i],\n )\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (local.activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(currentLocation().search, next().search, {\n partial: !local.activeOptions?.exact,\n ignoreUndefined: !local.activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n\n if (local.activeOptions?.includeHash) {\n const currentHash =\n shouldHydrateHash && !hasHydrated() ? '' : currentLocation().hash\n return currentHash === next().hash\n }\n return true\n })\n\n const doPreload = () =>\n router.preloadRoute(_options() as any).catch((err: any) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n\n const preloadViewportIoCallback = (\n entry: IntersectionObserverEntry | undefined,\n ) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n }\n\n const [ref, setRef] = Solid.createSignal<Element | null>(null)\n\n useIntersectionObserver(\n ref,\n preloadViewportIoCallback,\n { rootMargin: '100px' },\n { disabled: !!local.disabled || !(preload() === 'viewport') },\n )\n\n Solid.createEffect(() => {\n if (hasRenderFetched) {\n return\n }\n if (!local.disabled && preload() === 'render') {\n doPreload()\n hasRenderFetched = true\n }\n })\n\n if (externalLink()) {\n return Solid.mergeProps(\n propsSafeToSpread,\n {\n ref: mergeRefs(setRef, _options().ref),\n href: externalLink(),\n },\n Solid.splitProps(local, [\n 'target',\n 'disabled',\n 'style',\n 'class',\n 'onClick',\n 'onBlur',\n 'onFocus',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseOut',\n 'onMouseOver',\n 'onTouchStart',\n ])[0],\n ) as any\n }\n\n // The click handler\n const handleClick = (e: MouseEvent) => {\n // Check actual element's target attribute as fallback\n const elementTarget = (\n e.currentTarget as HTMLAnchorElement | SVGAElement\n ).getAttribute('target')\n const effectiveTarget =\n local.target !== undefined ? local.target : elementTarget\n\n if (\n !local.disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!effectiveTarget || effectiveTarget === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n setIsTransitioning(true)\n\n const unsub = router.subscribe('onResolved', () => {\n unsub()\n setIsTransitioning(false)\n })\n\n // All is well? Navigate!\n // N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing\n router.navigate({\n ..._options(),\n replace: local.replace,\n resetScroll: local.resetScroll,\n hashScrollIntoView: local.hashScrollIntoView,\n startTransition: local.startTransition,\n viewTransition: local.viewTransition,\n ignoreBlocker: local.ignoreBlocker,\n })\n }\n }\n\n const enqueueIntentPreload = (e: MouseEvent | FocusEvent) => {\n if (local.disabled || preload() !== 'intent') return\n\n if (!preloadDelay()) {\n doPreload()\n return\n }\n\n const eventTarget = e.currentTarget || e.target\n\n if (!eventTarget || timeoutMap.has(eventTarget)) return\n\n timeoutMap.set(\n eventTarget,\n setTimeout(() => {\n timeoutMap.delete(eventTarget)\n doPreload()\n }, preloadDelay()),\n )\n }\n\n const handleTouchStart = (_: TouchEvent) => {\n if (local.disabled || preload() !== 'intent') return\n doPreload()\n }\n\n const handleLeave = (e: MouseEvent | FocusEvent) => {\n if (local.disabled) return\n const eventTarget = e.currentTarget || e.target\n\n if (eventTarget) {\n const id = timeoutMap.get(eventTarget)\n clearTimeout(id)\n timeoutMap.delete(eventTarget)\n }\n }\n\n /** Call a JSX.EventHandlerUnion with the event. */\n function callHandler<T, TEvent extends Event>(\n event: TEvent & { currentTarget: T; target: Element },\n handler: Solid.JSX.EventHandlerUnion<T, TEvent> | undefined,\n ) {\n if (handler) {\n if (typeof handler === 'function') {\n handler(event)\n } else {\n handler[0](handler[1], event)\n }\n }\n\n return event.defaultPrevented\n }\n\n function composeEventHandlers<T>(\n handlers: Array<Solid.JSX.EventHandlerUnion<T, any> | undefined>,\n ) {\n return (event: any) => {\n for (const handler of handlers) {\n callHandler(event, handler)\n }\n }\n }\n\n // Get the active props\n const resolvedActiveProps: () => Omit<Solid.ComponentProps<'a'>, 'style'> & {\n style?: Solid.JSX.CSSProperties\n } = () =>\n isActive() ? (functionalUpdate(local.activeProps as any, {}) ?? {}) : {}\n\n // Get the inactive props\n const resolvedInactiveProps: () => Omit<\n Solid.ComponentProps<'a'>,\n 'style'\n > & { style?: Solid.JSX.CSSProperties } = () =>\n isActive() ? {} : functionalUpdate(local.inactiveProps, {})\n\n const resolvedClassName = () =>\n [local.class, resolvedActiveProps().class, resolvedInactiveProps().class]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = () => ({\n ...local.style,\n ...resolvedActiveProps().style,\n ...resolvedInactiveProps().style,\n })\n\n return Solid.mergeProps(\n propsSafeToSpread,\n resolvedActiveProps,\n resolvedInactiveProps,\n () => {\n return {\n href: hrefOption()?.href,\n ref: mergeRefs(setRef, _options().ref),\n onClick: composeEventHandlers([local.onClick, handleClick]),\n onBlur: composeEventHandlers([local.onBlur, handleLeave]),\n onFocus: composeEventHandlers([local.onFocus, enqueueIntentPreload]),\n onMouseEnter: composeEventHandlers([\n local.onMouseEnter,\n enqueueIntentPreload,\n ]),\n onMouseOver: composeEventHandlers([\n local.onMouseOver,\n enqueueIntentPreload,\n ]),\n onMouseLeave: composeEventHandlers([local.onMouseLeave, handleLeave]),\n onMouseOut: composeEventHandlers([local.onMouseOut, handleLeave]),\n onTouchStart: composeEventHandlers([\n local.onTouchStart,\n handleTouchStart,\n ]),\n disabled: !!local.disabled,\n target: local.target,\n ...(() => {\n const s = resolvedStyle()\n return Object.keys(s).length ? { style: s } : {}\n })(),\n ...(() => {\n const c = resolvedClassName()\n return c ? { class: c } : {}\n })(),\n ...(local.disabled && {\n role: 'link',\n 'aria-disabled': true,\n }),\n ...(isActive() && { 'data-status': 'active', 'aria-current': 'page' }),\n ...(isTransitioning() && { 'data-transitioning': 'transitioning' }),\n }\n },\n ) as any\n}\n\nexport type UseLinkPropsOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<'a', TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n Omit<Solid.ComponentProps<'a'>, 'style'> & { style?: Solid.JSX.CSSProperties }\n\nexport type ActiveLinkOptions<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n ActiveLinkOptionProps<TComp>\n\ntype ActiveLinkProps<TComp> = Partial<\n LinkComponentSolidProps<TComp> & {\n [key: `data-${string}`]: unknown\n }\n>\n\nexport interface ActiveLinkOptionProps<TComp = 'a'> {\n /**\n * A function that returns additional props for the `active` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `class`'s are concatenated)\n */\n activeProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n /**\n * A function that returns additional props for the `inactive` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `class`'s are concatenated)\n */\n inactiveProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n}\n\nexport type LinkProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkPropsChildren\n\nexport interface LinkPropsChildren {\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 | Solid.JSX.Element\n | ((state: {\n isActive: boolean\n isTransitioning: boolean\n }) => Solid.JSX.Element)\n}\n\ntype LinkComponentSolidProps<TComp> = TComp extends Solid.ValidComponent\n ? Omit<Solid.ComponentProps<TComp>, keyof CreateLinkProps>\n : never\n\nexport type LinkComponentProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkComponentSolidProps<TComp> &\n LinkProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type CreateLinkProps = LinkProps<\n any,\n any,\n string,\n string,\n string,\n string\n>\n\nexport type LinkComponent<\n in out TComp,\n in out TDefaultFrom extends string = string,\n> = <\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = TDefaultFrom,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => Solid.JSX.Element\n\nexport interface LinkComponentRoute<\n in out TDefaultFrom extends string = string,\n> {\n defaultFrom: TDefaultFrom;\n <\n TRouter extends AnyRouter = RegisteredRouter,\n const TTo extends string | undefined = undefined,\n const TMaskTo extends string = '',\n >(\n props: LinkComponentProps<\n 'a',\n TRouter,\n this['defaultFrom'],\n TTo,\n this['defaultFrom'],\n TMaskTo\n >,\n ): Solid.JSX.Element\n}\n\nexport function createLink<const TComp>(\n Comp: Constrain<TComp, any, (props: CreateLinkProps) => Solid.JSX.Element>,\n): LinkComponent<TComp> {\n return (props) => <Link {...props} _asChild={Comp} />\n}\n\nexport const Link: LinkComponent<'a'> = (props) => {\n const [local, rest] = Solid.splitProps(\n props as typeof props & { _asChild: any },\n ['_asChild', 'children'],\n )\n\n const [_, linkProps] = Solid.splitProps(\n useLinkProps(rest as unknown as any),\n ['type'],\n )\n\n const children = Solid.createMemo(() => {\n const ch = local.children\n if (typeof ch === 'function') {\n return ch({\n get isActive() {\n return (linkProps as any)['data-status'] === 'active'\n },\n get isTransitioning() {\n return (linkProps as any)['data-transitioning'] === 'transitioning'\n },\n })\n }\n\n return ch satisfies Solid.JSX.Element\n })\n\n if (local._asChild === 'svg') {\n const [_, svgLinkProps] = Solid.splitProps(linkProps, ['class'])\n return (\n <svg>\n <a {...svgLinkProps}>{children()}</a>\n </svg>\n )\n }\n\n return (\n <Dynamic component={local._asChild ? local._asChild : 'a'} {...linkProps}>\n {children()}\n </Dynamic>\n )\n}\n\nfunction isCtrlEvent(e: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nexport type LinkOptionsFnOptions<\n TOptions,\n TComp,\n TRouter extends AnyRouter = RegisteredRouter,\n> =\n TOptions extends ReadonlyArray<any>\n ? ValidateLinkOptionsArray<TRouter, TOptions, string, TComp>\n : ValidateLinkOptions<TRouter, TOptions, string, TComp>\n\nexport type LinkOptionsFn<TComp> = <\n const TOptions,\n TRouter extends AnyRouter = RegisteredRouter,\n>(\n options: LinkOptionsFnOptions<TOptions, TComp, TRouter>,\n) => TOptions\n\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"link.cjs","names":["Solid","mergeRefs","deepEqual","exactPathTest","functionalUpdate","isDangerousProtocol","preloadWarning","removeTrailingSlash","isServer","Dynamic","useRouter","useIntersectionObserver","useHydrated","AnyRouter","Constrain","LinkOptions","RegisteredRouter","RoutePaths","ValidateLinkOptions","ValidateLinkOptionsArray","timeoutMap","WeakMap","EventTarget","ReturnType","setTimeout","useLinkProps","TRouter","TFrom","options","UseLinkPropsOptions","TTo","TMaskFrom","TMaskTo","ComponentProps","router","isTransitioning","setIsTransitioning","createSignal","shouldHydrateHash","ssr","hasHydrated","hasRenderFetched","local","rest","splitProps","mergeProps","activeProps","STATIC_ACTIVE_PROPS_GET","inactiveProps","STATIC_INACTIVE_PROPS_GET","_","propsSafeToSpread","currentLocation","createMemo","stores","location","state","undefined","equals","prev","next","href","_options","_fromLocation","untrack","buildLocation","hrefOption","disabled","maskedLocation","publicHref","external","history","createHref","externalLink","_href","protocolAllowlist","process","env","NODE_ENV","console","warn","to","safeInternal","isSafeInternal","indexOf","URL","preload","reloadDocument","defaultPreload","preloadDelay","defaultPreloadDelay","isActive","activeOptions","current","nextLocation","exact","testExact","pathname","basepath","currentPath","nextPath","pathIsFuzzyEqual","startsWith","length","includeSearch","searchTest","search","partial","ignoreUndefined","explicitUndefined","includeHash","currentHash","hash","doPreload","preloadRoute","_builtLocation","catch","err","preloadViewportIoCallback","entry","IntersectionObserverEntry","isIntersecting","ref","setRef","Element","rootMargin","createEffect","handleClick","e","MouseEvent","elementTarget","currentTarget","HTMLAnchorElement","SVGAElement","getAttribute","effectiveTarget","target","isCtrlEvent","defaultPrevented","button","preventDefault","unsub","subscribe","navigate","replace","resetScroll","hashScrollIntoView","startTransition","viewTransition","ignoreBlocker","enqueueIntentPreload","FocusEvent","eventTarget","has","set","delete","handleTouchStart","TouchEvent","handleLeave","id","get","clearTimeout","simpleStyling","class","style","onClick","createComposedHandler","onBlur","onFocus","onMouseEnter","onMouseOver","onMouseLeave","onMouseOut","onTouchStart","ResolvedLinkStateProps","Omit","JSX","CSSProperties","resolvedProps","active","base","STATIC_DISABLED_PROPS","STATIC_TRANSITIONING_ATTRIBUTES","STATIC_DEFAULT_ACTIVE_ATTRIBUTES","EMPTY_OBJECT","className","filter","Boolean","join","Object","keys","STATIC_ACTIVE_ATTRIBUTES","STATIC_ACTIVE_PROPS","role","callHandler","Event","event","TEvent","T","handler","EventHandlerUnion","getHandler","fallback","ActiveLinkOptions","ActiveLinkOptionProps","TComp","ActiveLinkProps","Partial","LinkComponentSolidProps","key","LinkProps","LinkPropsChildren","children","ValidComponent","CreateLinkProps","LinkComponentProps","LinkComponent","TDefaultFrom","props","LinkComponentRoute","defaultFrom","createLink","Comp","_$createComponent","Link","_$mergeProps","_asChild","linkProps","ch","svgLinkProps","_el$","_tmpl$","_el$2","firstChild","_$spread","_$insert","_el$3","_tmpl$2","component","metaKey","altKey","ctrlKey","shiftKey","zero","charCodeAt","LinkOptionsFnOptions","TOptions","ReadonlyArray","LinkOptionsFn","linkOptions"],"sources":["../../src/link.tsx"],"sourcesContent":["import * as Solid from 'solid-js'\n\nimport { mergeRefs } from '@solid-primitives/refs'\n\nimport {\n deepEqual,\n exactPathTest,\n functionalUpdate,\n isDangerousProtocol,\n preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\n\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { Dynamic } from 'solid-js/web'\nimport { useRouter } from './useRouter'\n\nimport { useIntersectionObserver } from './utils'\n\nimport { useHydrated } from './ClientOnly'\nimport type {\n AnyRouter,\n Constrain,\n LinkOptions,\n RegisteredRouter,\n RoutePaths,\n} from '@tanstack/router-core'\nimport type {\n ValidateLinkOptions,\n ValidateLinkOptionsArray,\n} from './typePrimitives'\n\nconst timeoutMap = new WeakMap<EventTarget, ReturnType<typeof setTimeout>>()\n\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n): Solid.ComponentProps<'a'> {\n const router = useRouter()\n const [isTransitioning, setIsTransitioning] = Solid.createSignal(false)\n const shouldHydrateHash = !isServer && !!router.options.ssr\n const hasHydrated = useHydrated()\n\n let hasRenderFetched = false\n\n const [local, rest] = Solid.splitProps(\n Solid.mergeProps(\n {\n activeProps: STATIC_ACTIVE_PROPS_GET,\n inactiveProps: STATIC_INACTIVE_PROPS_GET,\n },\n options,\n ),\n [\n 'activeProps',\n 'inactiveProps',\n 'activeOptions',\n 'to',\n 'preload',\n 'preloadDelay',\n 'hashScrollIntoView',\n 'replace',\n 'startTransition',\n 'resetScroll',\n 'viewTransition',\n 'target',\n 'disabled',\n 'style',\n 'class',\n 'onClick',\n 'onBlur',\n 'onFocus',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseOver',\n 'onMouseOut',\n 'onTouchStart',\n 'ignoreBlocker',\n ],\n )\n\n // const {\n // // custom props\n // activeProps = () => ({ class: 'active' }),\n // inactiveProps = () => ({}),\n // activeOptions,\n // to,\n // preload: userPreload,\n // preloadDelay: userPreloadDelay,\n // hashScrollIntoView,\n // replace,\n // startTransition,\n // resetScroll,\n // viewTransition,\n // // element props\n // children,\n // target,\n // disabled,\n // style,\n // class,\n // onClick,\n // onFocus,\n // onMouseEnter,\n // onMouseLeave,\n // onTouchStart,\n // ignoreBlocker,\n // ...rest\n // } = options\n\n const [_, propsSafeToSpread] = Solid.splitProps(rest, [\n 'params',\n 'search',\n 'hash',\n 'state',\n 'mask',\n 'reloadDocument',\n 'unsafeRelative',\n ])\n\n const currentLocation = Solid.createMemo(\n () => router.stores.location.state,\n undefined,\n { equals: (prev, next) => prev.href === next.href },\n )\n\n const _options = () => options\n\n const next = Solid.createMemo(() => {\n // Rebuild when inherited search/hash or the current route context changes.\n const _fromLocation = currentLocation()\n const options = { _fromLocation, ..._options() } as any\n // untrack because router-core will also access stores, which are signals in solid\n return Solid.untrack(() => router.buildLocation(options))\n })\n\n const hrefOption = Solid.createMemo(() => {\n if (_options().disabled) return undefined\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const location = next().maskedLocation ?? next()\n const publicHref = location.publicHref\n const external = location.external\n\n if (external) {\n return { href: publicHref, external: true }\n }\n\n return {\n href: router.history.createHref(publicHref) || '/',\n external: false,\n }\n })\n\n const externalLink = Solid.createMemo(() => {\n const _href = hrefOption()\n if (_href?.external) {\n // Block dangerous protocols for external links\n if (isDangerousProtocol(_href.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${_href.href}`)\n }\n return undefined\n }\n return _href.href\n }\n const to = _options().to\n const safeInternal = isSafeInternal(to)\n if (safeInternal) return undefined\n if (typeof to !== 'string' || to.indexOf(':') === -1) return undefined\n try {\n new URL(to as any)\n // Block dangerous protocols like javascript:, blob:, data:\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n return undefined\n })\n\n const preload = Solid.createMemo(() => {\n if (_options().reloadDocument || externalLink()) {\n return false\n }\n return local.preload ?? router.options.defaultPreload\n })\n const preloadDelay = () =>\n local.preloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = Solid.createMemo(() => {\n if (externalLink()) return false\n const activeOptions = local.activeOptions\n const current = currentLocation()\n const nextLocation = next()\n\n if (activeOptions?.exact) {\n const testExact = exactPathTest(\n current.pathname,\n nextLocation.pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPath = removeTrailingSlash(current.pathname, router.basepath)\n const nextPath = removeTrailingSlash(\n nextLocation.pathname,\n router.basepath,\n )\n\n const pathIsFuzzyEqual =\n currentPath.startsWith(nextPath) &&\n (currentPath.length === nextPath.length ||\n currentPath[nextPath.length] === '/')\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(current.search, nextLocation.search, {\n partial: !activeOptions?.exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n\n if (activeOptions?.includeHash) {\n const currentHash =\n shouldHydrateHash && !hasHydrated() ? '' : current.hash\n return currentHash === nextLocation.hash\n }\n return true\n })\n\n const doPreload = () =>\n router\n .preloadRoute({ ..._options(), _builtLocation: next() } as any)\n .catch((err: any) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n\n const preloadViewportIoCallback = (\n entry: IntersectionObserverEntry | undefined,\n ) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n }\n\n const [ref, setRef] = Solid.createSignal<Element | null>(null)\n\n useIntersectionObserver(\n ref,\n preloadViewportIoCallback,\n { rootMargin: '100px' },\n { disabled: !!local.disabled || !(preload() === 'viewport') },\n )\n\n Solid.createEffect(() => {\n if (hasRenderFetched) {\n return\n }\n if (!local.disabled && preload() === 'render') {\n doPreload()\n hasRenderFetched = true\n }\n })\n\n if (externalLink()) {\n return Solid.mergeProps(\n propsSafeToSpread,\n {\n ref: mergeRefs(setRef, _options().ref),\n href: externalLink(),\n },\n Solid.splitProps(local, [\n 'target',\n 'disabled',\n 'style',\n 'class',\n 'onClick',\n 'onBlur',\n 'onFocus',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseOut',\n 'onMouseOver',\n 'onTouchStart',\n ])[0],\n ) as any\n }\n\n // The click handler\n const handleClick = (e: MouseEvent) => {\n // Check actual element's target attribute as fallback\n const elementTarget = (\n e.currentTarget as HTMLAnchorElement | SVGAElement\n ).getAttribute('target')\n const effectiveTarget =\n local.target !== undefined ? local.target : elementTarget\n\n if (\n !local.disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!effectiveTarget || effectiveTarget === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n setIsTransitioning(true)\n\n const unsub = router.subscribe('onResolved', () => {\n unsub()\n setIsTransitioning(false)\n })\n\n // All is well? Navigate!\n // N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing\n router.navigate({\n ..._options(),\n replace: local.replace,\n resetScroll: local.resetScroll,\n hashScrollIntoView: local.hashScrollIntoView,\n startTransition: local.startTransition,\n viewTransition: local.viewTransition,\n ignoreBlocker: local.ignoreBlocker,\n })\n }\n }\n\n const enqueueIntentPreload = (e: MouseEvent | FocusEvent) => {\n if (local.disabled || preload() !== 'intent') return\n\n if (!preloadDelay()) {\n doPreload()\n return\n }\n\n const eventTarget = e.currentTarget || e.target\n\n if (!eventTarget || timeoutMap.has(eventTarget)) return\n\n timeoutMap.set(\n eventTarget,\n setTimeout(() => {\n timeoutMap.delete(eventTarget)\n doPreload()\n }, preloadDelay()),\n )\n }\n\n const handleTouchStart = (_: TouchEvent) => {\n if (local.disabled || preload() !== 'intent') return\n doPreload()\n }\n\n const handleLeave = (e: MouseEvent | FocusEvent) => {\n if (local.disabled) return\n const eventTarget = e.currentTarget || e.target\n\n if (eventTarget) {\n const id = timeoutMap.get(eventTarget)\n clearTimeout(id)\n timeoutMap.delete(eventTarget)\n }\n }\n\n const simpleStyling = Solid.createMemo(\n () =>\n local.activeProps === STATIC_ACTIVE_PROPS_GET &&\n local.inactiveProps === STATIC_INACTIVE_PROPS_GET &&\n local.class === undefined &&\n local.style === undefined,\n )\n\n const onClick = createComposedHandler(() => local.onClick, handleClick)\n const onBlur = createComposedHandler(() => local.onBlur, handleLeave)\n const onFocus = createComposedHandler(\n () => local.onFocus,\n enqueueIntentPreload,\n )\n const onMouseEnter = createComposedHandler(\n () => local.onMouseEnter,\n enqueueIntentPreload,\n )\n const onMouseOver = createComposedHandler(\n () => local.onMouseOver,\n enqueueIntentPreload,\n )\n const onMouseLeave = createComposedHandler(\n () => local.onMouseLeave,\n handleLeave,\n )\n const onMouseOut = createComposedHandler(() => local.onMouseOut, handleLeave)\n const onTouchStart = createComposedHandler(\n () => local.onTouchStart,\n handleTouchStart,\n )\n\n type ResolvedLinkStateProps = Omit<Solid.ComponentProps<'a'>, 'style'> & {\n style?: Solid.JSX.CSSProperties\n }\n\n const resolvedProps = Solid.createMemo(() => {\n const active = isActive()\n\n const base = {\n href: hrefOption()?.href,\n ref: mergeRefs(setRef, _options().ref),\n onClick,\n onBlur,\n onFocus,\n onMouseEnter,\n onMouseOver,\n onMouseLeave,\n onMouseOut,\n onTouchStart,\n disabled: !!local.disabled,\n target: local.target,\n ...(local.disabled && STATIC_DISABLED_PROPS),\n ...(isTransitioning() && STATIC_TRANSITIONING_ATTRIBUTES),\n }\n\n if (simpleStyling()) {\n return {\n ...base,\n ...(active && STATIC_DEFAULT_ACTIVE_ATTRIBUTES),\n }\n }\n\n const activeProps: ResolvedLinkStateProps = active\n ? (functionalUpdate(local.activeProps as any, {}) ?? EMPTY_OBJECT)\n : EMPTY_OBJECT\n const inactiveProps: ResolvedLinkStateProps = active\n ? EMPTY_OBJECT\n : functionalUpdate(local.inactiveProps, {})\n const style = {\n ...local.style,\n ...activeProps.style,\n ...inactiveProps.style,\n }\n const className = [local.class, activeProps.class, inactiveProps.class]\n .filter(Boolean)\n .join(' ')\n\n return {\n ...activeProps,\n ...inactiveProps,\n ...base,\n ...(Object.keys(style).length ? { style } : undefined),\n ...(className ? { class: className } : undefined),\n ...(active && STATIC_ACTIVE_ATTRIBUTES),\n } as ResolvedLinkStateProps\n })\n\n return Solid.mergeProps(propsSafeToSpread, resolvedProps) as any\n}\n\nconst STATIC_ACTIVE_PROPS = { class: 'active' }\nconst STATIC_ACTIVE_PROPS_GET = () => STATIC_ACTIVE_PROPS\nconst EMPTY_OBJECT = {}\nconst STATIC_INACTIVE_PROPS_GET = () => EMPTY_OBJECT\nconst STATIC_DEFAULT_ACTIVE_ATTRIBUTES = {\n class: 'active',\n 'data-status': 'active',\n 'aria-current': 'page',\n}\nconst STATIC_DISABLED_PROPS = {\n role: 'link',\n 'aria-disabled': true,\n}\nconst STATIC_ACTIVE_ATTRIBUTES = {\n 'data-status': 'active',\n 'aria-current': 'page',\n}\nconst STATIC_TRANSITIONING_ATTRIBUTES = {\n 'data-transitioning': 'transitioning',\n}\n\n/** Call a JSX.EventHandlerUnion with the event. */\nfunction callHandler<T, TEvent extends Event>(\n event: TEvent & { currentTarget: T; target: Element },\n handler: Solid.JSX.EventHandlerUnion<T, TEvent>,\n) {\n if (typeof handler === 'function') {\n handler(event)\n } else {\n handler[0](handler[1], event)\n }\n return event.defaultPrevented\n}\n\nfunction createComposedHandler<T, TEvent extends Event>(\n getHandler: () => Solid.JSX.EventHandlerUnion<T, TEvent> | undefined,\n fallback: (event: TEvent) => void,\n) {\n return (event: TEvent & { currentTarget: T; target: Element }) => {\n const handler = getHandler()\n if (!handler || !callHandler(event, handler)) fallback(event)\n }\n}\n\nexport type UseLinkPropsOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<'a', TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n Omit<Solid.ComponentProps<'a'>, 'style'> & { style?: Solid.JSX.CSSProperties }\n\nexport type ActiveLinkOptions<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n ActiveLinkOptionProps<TComp>\n\ntype ActiveLinkProps<TComp> = Partial<\n LinkComponentSolidProps<TComp> & {\n [key: `data-${string}`]: unknown\n }\n>\n\nexport interface ActiveLinkOptionProps<TComp = 'a'> {\n /**\n * A function that returns additional props for the `active` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `class`'s are concatenated)\n */\n activeProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n /**\n * A function that returns additional props for the `inactive` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `class`'s are concatenated)\n */\n inactiveProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n}\n\nexport type LinkProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkPropsChildren\n\nexport interface LinkPropsChildren {\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 | Solid.JSX.Element\n | ((state: {\n isActive: boolean\n isTransitioning: boolean\n }) => Solid.JSX.Element)\n}\n\ntype LinkComponentSolidProps<TComp> = TComp extends Solid.ValidComponent\n ? Omit<Solid.ComponentProps<TComp>, keyof CreateLinkProps>\n : never\n\nexport type LinkComponentProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkComponentSolidProps<TComp> &\n LinkProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type CreateLinkProps = LinkProps<\n any,\n any,\n string,\n string,\n string,\n string\n>\n\nexport type LinkComponent<\n in out TComp,\n in out TDefaultFrom extends string = string,\n> = <\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = TDefaultFrom,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => Solid.JSX.Element\n\nexport interface LinkComponentRoute<\n in out TDefaultFrom extends string = string,\n> {\n defaultFrom: TDefaultFrom;\n <\n TRouter extends AnyRouter = RegisteredRouter,\n const TTo extends string | undefined = undefined,\n const TMaskTo extends string = '',\n >(\n props: LinkComponentProps<\n 'a',\n TRouter,\n this['defaultFrom'],\n TTo,\n this['defaultFrom'],\n TMaskTo\n >,\n ): Solid.JSX.Element\n}\n\nexport function createLink<const TComp>(\n Comp: Constrain<TComp, any, (props: CreateLinkProps) => Solid.JSX.Element>,\n): LinkComponent<TComp> {\n return (props) => <Link {...props} _asChild={Comp} />\n}\n\nexport const Link: LinkComponent<'a'> = (props) => {\n const [local, rest] = Solid.splitProps(\n props as typeof props & { _asChild: any },\n ['_asChild', 'children'],\n )\n\n const [_, linkProps] = Solid.splitProps(\n useLinkProps(rest as unknown as any),\n ['type'],\n )\n\n const children = Solid.createMemo(() => {\n const ch = local.children\n if (typeof ch === 'function') {\n return ch({\n get isActive() {\n return (linkProps as any)['data-status'] === 'active'\n },\n get isTransitioning() {\n return (linkProps as any)['data-transitioning'] === 'transitioning'\n },\n })\n }\n\n return ch satisfies Solid.JSX.Element\n })\n\n if (local._asChild === 'svg') {\n const [_, svgLinkProps] = Solid.splitProps(linkProps, ['class'])\n return (\n <svg>\n <a {...svgLinkProps}>{children()}</a>\n </svg>\n )\n }\n\n if (!local._asChild) {\n return <a {...linkProps}>{children()}</a>\n }\n\n return (\n <Dynamic component={local._asChild as Solid.ValidComponent} {...linkProps}>\n {children()}\n </Dynamic>\n )\n}\n\nfunction isCtrlEvent(e: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nfunction isSafeInternal(to: unknown) {\n if (typeof to !== 'string') return false\n const zero = to.charCodeAt(0)\n if (zero === 47) return to.charCodeAt(1) !== 47 // '/' but not '//'\n return zero === 46 // '.', '..', './', '../'\n}\n\nexport type LinkOptionsFnOptions<\n TOptions,\n TComp,\n TRouter extends AnyRouter = RegisteredRouter,\n> =\n TOptions extends ReadonlyArray<any>\n ? ValidateLinkOptionsArray<TRouter, TOptions, string, TComp>\n : ValidateLinkOptions<TRouter, TOptions, string, TComp>\n\nexport type LinkOptionsFn<TComp> = <\n const TOptions,\n TRouter extends AnyRouter = RegisteredRouter,\n>(\n options: LinkOptionsFnOptions<TOptions, TComp, TRouter>,\n) => TOptions\n\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"mappings":"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"}