@tanstack/router-core 1.171.5 → 1.171.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/manifest.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  export type AssetCrossOrigin = 'anonymous' | 'use-credentials'
2
+ export type ScriptFormat = 'module' | 'iife'
3
+
4
+ export const DEV_STYLES_ATTR = 'data-tanstack-router-dev-styles'
2
5
 
3
6
  export type AssetCrossOriginConfig =
4
7
  | AssetCrossOrigin
5
- | Partial<Record<'modulepreload' | 'stylesheet', AssetCrossOrigin>>
8
+ | Partial<Record<'script' | 'stylesheet', AssetCrossOrigin>>
6
9
 
7
10
  export type ManifestAssetLink =
8
11
  | string
@@ -13,7 +16,7 @@ export type ManifestAssetLink =
13
16
 
14
17
  export function getAssetCrossOrigin(
15
18
  assetCrossOrigin: AssetCrossOriginConfig | undefined,
16
- kind: 'modulepreload' | 'stylesheet',
19
+ kind: 'script' | 'stylesheet',
17
20
  ): AssetCrossOrigin | undefined {
18
21
  if (!assetCrossOrigin) {
19
22
  return undefined
@@ -26,6 +29,35 @@ export function getAssetCrossOrigin(
26
29
  return assetCrossOrigin[kind]
27
30
  }
28
31
 
32
+ export function getManifestScriptFormat(
33
+ manifest: { scriptFormat?: ScriptFormat } | undefined,
34
+ ): ScriptFormat {
35
+ return manifest?.scriptFormat ?? 'module'
36
+ }
37
+
38
+ export function getScriptPreloadAttrs(
39
+ manifest: { scriptFormat?: ScriptFormat } | undefined,
40
+ link: ManifestAssetLink,
41
+ assetCrossOrigin?: AssetCrossOriginConfig,
42
+ ): {
43
+ rel: 'modulepreload' | 'preload'
44
+ as?: 'script'
45
+ href: string
46
+ crossOrigin?: AssetCrossOrigin
47
+ } {
48
+ const preloadLink = resolveManifestAssetLink(link)
49
+ const crossOrigin =
50
+ getAssetCrossOrigin(assetCrossOrigin, 'script') ?? preloadLink.crossOrigin
51
+
52
+ return {
53
+ ...(getManifestScriptFormat(manifest) === 'iife'
54
+ ? { rel: 'preload', as: 'script' }
55
+ : { rel: 'modulepreload' }),
56
+ href: preloadLink.href,
57
+ ...(crossOrigin ? { crossOrigin } : {}),
58
+ }
59
+ }
60
+
29
61
  export function resolveManifestAssetLink(link: ManifestAssetLink) {
30
62
  if (typeof link === 'string') {
31
63
  return { href: link, crossOrigin: undefined }
@@ -35,87 +67,147 @@ export function resolveManifestAssetLink(link: ManifestAssetLink) {
35
67
  }
36
68
 
37
69
  export type Manifest = {
38
- inlineCss?: {
39
- styles: Record<string, string>
40
- templates?: Record<
41
- string,
42
- {
43
- strings: Array<string>
44
- urls: Array<string>
45
- }
46
- >
47
- }
48
- routes: Record<
49
- string,
50
- {
51
- filePath?: string
52
- preloads?: Array<ManifestAssetLink>
53
- assets?: Array<RouterManagedTag>
54
- }
55
- >
70
+ scriptFormat?: ScriptFormat
71
+ inlineStyle?: ManifestInlineCss
72
+ routes: Record<string, ManifestRoute>
73
+ }
74
+
75
+ export type ServerManifest = {
76
+ scriptFormat?: ScriptFormat
77
+ inlineCss?: ServerManifestInlineCss
78
+ routes: Record<string, ServerManifestRoute>
79
+ }
80
+
81
+ export type ServerManifestInlineCss = {
82
+ styles: Record<string, string>
83
+ templates?: Record<string, InlineCssTemplate>
84
+ }
85
+
86
+ export type InlineCssTemplate = {
87
+ strings: Array<string>
88
+ urls: Array<string>
89
+ }
90
+
91
+ export type ManifestRoute = {
92
+ filePath?: string
93
+ preloads?: Array<ManifestAssetLink>
94
+ scripts?: Array<ManifestScript>
95
+ css?: Array<ManifestCssLink>
96
+ }
97
+
98
+ export type ServerManifestRoute = ManifestRoute
99
+
100
+ export type ManifestRouteAssets = Pick<
101
+ ManifestRoute,
102
+ 'preloads' | 'scripts' | 'css'
103
+ >
104
+
105
+ export type RouterManagedTitleTag = {
106
+ tag: 'title'
107
+ attrs?: Record<string, any>
108
+ children: string
109
+ }
110
+
111
+ export type RouterManagedMetaTag = {
112
+ tag: 'meta'
113
+ attrs?: Record<string, any>
114
+ children?: never
115
+ }
116
+
117
+ export type RouterManagedLinkTag = {
118
+ tag: 'link'
119
+ attrs?: Record<string, any>
120
+ children?: never
121
+ }
122
+
123
+ export type RouterManagedScriptTag = {
124
+ tag: 'script'
125
+ attrs?: Record<string, any>
126
+ children?: string
127
+ }
128
+
129
+ export type ManifestScript = Omit<RouterManagedScriptTag, 'tag'>
130
+
131
+ export type RouterManagedStyleTag = {
132
+ tag: 'style'
133
+ attrs?: Record<string, any>
134
+ children?: string
135
+ inlineCss?: true
56
136
  }
57
137
 
58
138
  export type RouterManagedTag =
59
- | {
60
- tag: 'title'
61
- attrs?: Record<string, any>
62
- children: string
63
- }
64
- | {
65
- tag: 'meta' | 'link'
66
- attrs?: Record<string, any>
67
- children?: never
68
- }
69
- | {
70
- tag: 'script'
71
- attrs?: Record<string, any>
72
- children?: string
139
+ | RouterManagedTitleTag
140
+ | RouterManagedMetaTag
141
+ | RouterManagedLinkTag
142
+ | RouterManagedScriptTag
143
+ | RouterManagedStyleTag
144
+
145
+ export function appendUniqueUserTags(
146
+ target: Array<RouterManagedTag>,
147
+ tags: Array<RouterManagedTag>,
148
+ ) {
149
+ if (tags.length === 0) {
150
+ return
151
+ }
152
+
153
+ if (tags.length === 1) {
154
+ target.push(tags[0]!)
155
+ return
156
+ }
157
+
158
+ const seen = new Set<string>()
159
+ for (const tag of tags) {
160
+ const key = JSON.stringify(tag)
161
+ if (seen.has(key)) {
162
+ continue
73
163
  }
164
+ seen.add(key)
165
+ target.push(tag)
166
+ }
167
+ }
168
+
169
+ export type ManifestCssLink =
170
+ | string
74
171
  | {
75
- tag: 'style'
76
- attrs?: Record<string, any>
77
- children?: string
78
- inlineCss?: true
172
+ href: string
173
+ crossOrigin?: AssetCrossOrigin
174
+ [DEV_STYLES_ATTR]?: true
79
175
  }
80
176
 
81
- export function getStylesheetHref(asset: RouterManagedTag) {
82
- if (asset.tag !== 'link') return undefined
83
-
84
- const rel = asset.attrs?.rel
85
- const href = asset.attrs?.href
86
- if (typeof href !== 'string') return undefined
177
+ export type ManifestInlineCss = {
178
+ attrs?: Record<string, any>
179
+ children?: string
180
+ }
87
181
 
88
- const relTokens = typeof rel === 'string' ? rel.split(/\s+/) : []
89
- if (!relTokens.includes('stylesheet')) return undefined
182
+ export type RouterManagedInlineCssTag = RouterManagedStyleTag & {
183
+ inlineCss: true
184
+ }
90
185
 
91
- return href
186
+ export function getStylesheetHref(asset: ManifestCssLink) {
187
+ return resolveManifestCssLink(asset).href
92
188
  }
93
189
 
94
- export function isInlinableStylesheet(
95
- manifest: Manifest | undefined,
96
- asset: RouterManagedTag,
97
- ) {
98
- const href = getStylesheetHref(asset)
99
- return !!href && manifest?.inlineCss?.styles[href] !== undefined
190
+ export function resolveManifestCssLink(link: ManifestCssLink) {
191
+ if (typeof link === 'string') {
192
+ return { href: link, crossOrigin: undefined }
193
+ }
194
+
195
+ return link
100
196
  }
101
197
 
102
- export function createInlineCssStyleAsset(css: string): RouterManagedTag {
198
+ export function createInlineCssStyleAsset(css: string): ManifestInlineCss {
103
199
  return {
104
- tag: 'style',
105
200
  attrs: {
106
201
  suppressHydrationWarning: true,
107
202
  },
108
- inlineCss: true,
109
203
  children: css,
110
204
  }
111
205
  }
112
206
 
113
- export function createInlineCssPlaceholderAsset(): RouterManagedTag {
207
+ export function createInlineCssPlaceholderAsset(): ManifestInlineCss {
114
208
  return {
115
- tag: 'style',
116
209
  attrs: {
117
210
  suppressHydrationWarning: true,
118
211
  },
119
- inlineCss: true,
120
212
  }
121
213
  }
package/src/router.ts CHANGED
@@ -98,7 +98,11 @@ import type {
98
98
  CommitLocationOptions,
99
99
  NavigateFn,
100
100
  } from './RouterProvider'
101
- import type { Manifest, RouterManagedTag } from './manifest'
101
+ import type {
102
+ Manifest,
103
+ ManifestRouteAssets,
104
+ RouterManagedTag,
105
+ } from './manifest'
102
106
  import type { AnySchema, AnyValidator } from './validators'
103
107
  import type { NavigateOptions, ResolveRelativePath, ToOptions } from './link'
104
108
  import type { NotFoundError } from './not-found'
@@ -803,9 +807,7 @@ export interface ServerSsr {
803
807
  setRenderFinished: () => void
804
808
  cleanup: () => void
805
809
  onSerializationFinished: (listener: () => void) => void
806
- dehydrate: (opts?: {
807
- requestAssets?: Array<RouterManagedTag>
808
- }) => Promise<void>
810
+ dehydrate: (opts?: { requestAssets?: ManifestRouteAssets }) => Promise<void>
809
811
  takeBufferedScripts: () => RouterManagedTag | undefined
810
812
  /**
811
813
  * Takes any buffered HTML that was injected.
@@ -8,7 +8,7 @@ import {
8
8
  import type { HandlerCallback } from './handlerCallback'
9
9
  import type { AnyHeaders } from './headers'
10
10
  import type { AnyRouter } from '../router'
11
- import type { Manifest } from '../manifest'
11
+ import type { ServerManifest } from '../manifest'
12
12
 
13
13
  export type RequestHandler<TRouter extends AnyRouter> = (
14
14
  cb: HandlerCallback<TRouter>,
@@ -21,7 +21,7 @@ export function createRequestHandler<TRouter extends AnyRouter>({
21
21
  }: {
22
22
  createRouter: () => TRouter
23
23
  request: Request
24
- getRouterManifest?: () => Manifest | Promise<Manifest>
24
+ getRouterManifest?: () => ServerManifest | Promise<ServerManifest>
25
25
  }): RequestHandler<TRouter> {
26
26
  return async (cb) => {
27
27
  const router = createRouter()
@@ -78,9 +78,10 @@ export function createRequestHandler<TRouter extends AnyRouter>({
78
78
  }
79
79
 
80
80
  function getRequestHeaders(opts: { router: AnyRouter }): Headers {
81
- const matchHeaders = opts.router.stores.matches
82
- .get()
83
- .map<AnyHeaders>((match) => match.headers)
81
+ const matchHeaders: Array<AnyHeaders> = []
82
+ for (const match of opts.router.stores.matches.get()) {
83
+ matchHeaders.push(match.headers)
84
+ }
84
85
 
85
86
  // Handle Redirects
86
87
  const redirect = opts.router.stores.redirect.get()