@tanstack/start-server-core 1.168.0 → 1.168.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/createStartHandler.d.ts +2 -133
- package/dist/esm/createStartHandler.js +27 -154
- package/dist/esm/createStartHandler.js.map +1 -1
- package/dist/esm/early-hints.d.ts +12 -0
- package/dist/esm/early-hints.js +87 -1
- package/dist/esm/early-hints.js.map +1 -1
- package/dist/esm/finalManifest.d.ts +42 -0
- package/dist/esm/finalManifest.js +126 -0
- package/dist/esm/finalManifest.js.map +1 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/inlineCss.d.ts +10 -0
- package/dist/esm/inlineCss.js +14 -0
- package/dist/esm/inlineCss.js.map +1 -0
- package/dist/esm/request-handler.d.ts +11 -1
- package/dist/esm/transformAssetUrls.d.ts +25 -48
- package/dist/esm/transformAssetUrls.js +41 -34
- package/dist/esm/transformAssetUrls.js.map +1 -1
- package/package.json +4 -4
- package/skills/start-server-core/SKILL.md +1 -1
- package/src/createStartHandler.ts +43 -465
- package/src/early-hints.ts +159 -0
- package/src/finalManifest.ts +319 -0
- package/src/index.tsx +1 -5
- package/src/inlineCss.ts +31 -0
- package/src/request-handler.ts +12 -0
- package/src/transformAssetUrls.ts +118 -121
|
@@ -10,20 +10,32 @@ import type {
|
|
|
10
10
|
|
|
11
11
|
export type { AssetCrossOrigin }
|
|
12
12
|
|
|
13
|
-
export type
|
|
13
|
+
export type TransformAssetsContext =
|
|
14
|
+
| {
|
|
15
|
+
url: string
|
|
16
|
+
kind: 'modulepreload'
|
|
17
|
+
}
|
|
18
|
+
| {
|
|
19
|
+
url: string
|
|
20
|
+
kind: 'stylesheet'
|
|
21
|
+
}
|
|
22
|
+
| {
|
|
23
|
+
url: string
|
|
24
|
+
kind: 'clientEntry'
|
|
25
|
+
}
|
|
26
|
+
| {
|
|
27
|
+
url: string
|
|
28
|
+
kind: 'css-url'
|
|
29
|
+
stylesheetHref: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type TransformAssetKind = TransformAssetsContext['kind']
|
|
14
33
|
|
|
15
34
|
type TransformAssetsShorthandCrossOriginKind = Exclude<
|
|
16
35
|
TransformAssetKind,
|
|
17
|
-
'clientEntry'
|
|
36
|
+
'clientEntry' | 'css-url'
|
|
18
37
|
>
|
|
19
38
|
|
|
20
|
-
export type AssetUrlType = TransformAssetKind
|
|
21
|
-
|
|
22
|
-
export interface TransformAssetsContext {
|
|
23
|
-
url: string
|
|
24
|
-
kind: TransformAssetKind
|
|
25
|
-
}
|
|
26
|
-
|
|
27
39
|
export type TransformAssetResult =
|
|
28
40
|
| string
|
|
29
41
|
| {
|
|
@@ -35,16 +47,7 @@ export type TransformAssetsFn = (
|
|
|
35
47
|
context: TransformAssetsContext,
|
|
36
48
|
) => Awaitable<TransformAssetResult>
|
|
37
49
|
|
|
38
|
-
export
|
|
39
|
-
url: string
|
|
40
|
-
type: AssetUrlType
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export type TransformAssetUrlsFn = (
|
|
44
|
-
context: TransformAssetUrlsContext,
|
|
45
|
-
) => Awaitable<string>
|
|
46
|
-
|
|
47
|
-
export type CreateTransformAssetUrlsContext =
|
|
50
|
+
export type CreateTransformAssetsContext =
|
|
48
51
|
| {
|
|
49
52
|
/** True when the server is computing the cached manifest during startup warmup. */
|
|
50
53
|
warmup: true
|
|
@@ -60,19 +63,11 @@ export type CreateTransformAssetUrlsContext =
|
|
|
60
63
|
warmup: false
|
|
61
64
|
}
|
|
62
65
|
|
|
63
|
-
/**
|
|
64
|
-
* Async factory that runs once per manifest computation and returns the
|
|
65
|
-
* per-asset transform.
|
|
66
|
-
*/
|
|
67
|
-
export type CreateTransformAssetUrlsFn = (
|
|
68
|
-
ctx: CreateTransformAssetUrlsContext,
|
|
69
|
-
) => Awaitable<TransformAssetUrlsFn>
|
|
70
|
-
|
|
71
66
|
export type CreateTransformAssetsFn = (
|
|
72
|
-
ctx:
|
|
67
|
+
ctx: CreateTransformAssetsContext,
|
|
73
68
|
) => Awaitable<TransformAssetsFn>
|
|
74
69
|
|
|
75
|
-
type
|
|
70
|
+
type TransformAssetsOptionsBase = {
|
|
76
71
|
/**
|
|
77
72
|
* Whether to cache the transformed manifest after the first request.
|
|
78
73
|
*
|
|
@@ -98,45 +93,16 @@ type TransformAssetUrlsOptionsBase = {
|
|
|
98
93
|
warmup?: boolean
|
|
99
94
|
}
|
|
100
95
|
|
|
101
|
-
export type TransformAssetUrlsOptions =
|
|
102
|
-
| (TransformAssetUrlsOptionsBase & {
|
|
103
|
-
/**
|
|
104
|
-
* The transform to apply to asset URLs. Can be a string prefix or a callback.
|
|
105
|
-
*
|
|
106
|
-
* **String** — prepended to every asset URL.
|
|
107
|
-
* **Callback** — receives `{ url, type }` and returns a new URL.
|
|
108
|
-
*/
|
|
109
|
-
transform: string | TransformAssetUrlsFn
|
|
110
|
-
createTransform?: never
|
|
111
|
-
})
|
|
112
|
-
| (TransformAssetUrlsOptionsBase & {
|
|
113
|
-
/**
|
|
114
|
-
* Create a per-asset transform function.
|
|
115
|
-
*
|
|
116
|
-
* This factory runs once per manifest computation (per request when
|
|
117
|
-
* `cache: false`, or once per server when `cache: true`). It can do async
|
|
118
|
-
* setup work (fetch config, read from a KV, etc.) and return a fast
|
|
119
|
-
* per-asset transformer.
|
|
120
|
-
*/
|
|
121
|
-
createTransform: CreateTransformAssetUrlsFn
|
|
122
|
-
transform?: never
|
|
123
|
-
})
|
|
124
|
-
|
|
125
96
|
export type TransformAssetsOptions =
|
|
126
|
-
| (
|
|
97
|
+
| (TransformAssetsOptionsBase & {
|
|
127
98
|
transform: string | TransformAssetsFn
|
|
128
99
|
createTransform?: never
|
|
129
100
|
})
|
|
130
|
-
| (
|
|
101
|
+
| (TransformAssetsOptionsBase & {
|
|
131
102
|
createTransform: CreateTransformAssetsFn
|
|
132
103
|
transform?: never
|
|
133
104
|
})
|
|
134
105
|
|
|
135
|
-
export type TransformAssetUrls =
|
|
136
|
-
| string
|
|
137
|
-
| TransformAssetUrlsFn
|
|
138
|
-
| TransformAssetUrlsOptions
|
|
139
|
-
|
|
140
106
|
/**
|
|
141
107
|
* Per-kind crossOrigin configuration for the object shorthand.
|
|
142
108
|
*
|
|
@@ -195,21 +161,6 @@ export type ResolvedTransformAssetsConfig =
|
|
|
195
161
|
cache: boolean
|
|
196
162
|
}
|
|
197
163
|
|
|
198
|
-
let hasWarnedAboutDeprecatedTransformAssetUrls = false
|
|
199
|
-
|
|
200
|
-
export function warnDeprecatedTransformAssetUrls() {
|
|
201
|
-
if (
|
|
202
|
-
(process.env.NODE_ENV === 'development' ||
|
|
203
|
-
process.env.TSS_DEV_SERVER === 'true') &&
|
|
204
|
-
!hasWarnedAboutDeprecatedTransformAssetUrls
|
|
205
|
-
) {
|
|
206
|
-
hasWarnedAboutDeprecatedTransformAssetUrls = true
|
|
207
|
-
console.warn(
|
|
208
|
-
'[TanStack Start] `transformAssetUrls` is deprecated. Use `transformAssets` instead.',
|
|
209
|
-
)
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
164
|
function normalizeTransformAssetResult(
|
|
214
165
|
result: TransformAssetResult,
|
|
215
166
|
): Exclude<TransformAssetResult, string> {
|
|
@@ -220,6 +171,77 @@ function normalizeTransformAssetResult(
|
|
|
220
171
|
return result
|
|
221
172
|
}
|
|
222
173
|
|
|
174
|
+
function escapeCssString(value: string) {
|
|
175
|
+
return value
|
|
176
|
+
.replace(/\\/g, '\\\\')
|
|
177
|
+
.replace(/"/g, '\\"')
|
|
178
|
+
.replace(/\n/g, '\\a ')
|
|
179
|
+
.replace(/\r/g, '\\d ')
|
|
180
|
+
.replace(/\f/g, '\\c ')
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function transformInlineCssTemplate(options: {
|
|
184
|
+
stylesheetHref: string
|
|
185
|
+
template: { strings: Array<string>; urls: Array<string> }
|
|
186
|
+
transformFn: TransformAssetsFn
|
|
187
|
+
}) {
|
|
188
|
+
const { strings, urls } = options.template
|
|
189
|
+
|
|
190
|
+
if (strings.length !== urls.length + 1) {
|
|
191
|
+
throw new Error(
|
|
192
|
+
`TanStack Start inlineCss template for ${options.stylesheetHref} is invalid`,
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
let css = strings[0]!
|
|
197
|
+
|
|
198
|
+
for (let index = 0; index < urls.length; index++) {
|
|
199
|
+
const transformed = normalizeTransformAssetResult(
|
|
200
|
+
await options.transformFn({
|
|
201
|
+
kind: 'css-url',
|
|
202
|
+
url: urls[index]!,
|
|
203
|
+
stylesheetHref: options.stylesheetHref,
|
|
204
|
+
}),
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
css += escapeCssString(transformed.href) + strings[index + 1]!
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return css
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function transformInlineCssStyles(
|
|
214
|
+
inlineCss: NonNullable<Manifest['inlineCss']>,
|
|
215
|
+
transformFn: TransformAssetsFn,
|
|
216
|
+
) {
|
|
217
|
+
const transformedStyles: Record<string, string> = {}
|
|
218
|
+
|
|
219
|
+
const transformedEntries = await Promise.all(
|
|
220
|
+
Object.entries(inlineCss.styles).map(async ([stylesheetHref, css]) => {
|
|
221
|
+
const template = inlineCss.templates?.[stylesheetHref]
|
|
222
|
+
return [
|
|
223
|
+
stylesheetHref,
|
|
224
|
+
template
|
|
225
|
+
? await transformInlineCssTemplate({
|
|
226
|
+
stylesheetHref,
|
|
227
|
+
template,
|
|
228
|
+
transformFn,
|
|
229
|
+
})
|
|
230
|
+
: css,
|
|
231
|
+
] as const
|
|
232
|
+
}),
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
for (const [stylesheetHref, css] of transformedEntries) {
|
|
236
|
+
transformedStyles[stylesheetHref] = css
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
styles: transformedStyles,
|
|
241
|
+
...(inlineCss.templates ? { templates: inlineCss.templates } : {}),
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
223
245
|
function resolveTransformAssetsCrossOrigin(
|
|
224
246
|
config: TransformAssetsCrossOriginConfig | undefined,
|
|
225
247
|
kind: TransformAssetsShorthandCrossOriginKind,
|
|
@@ -265,7 +287,7 @@ export function resolveTransformAssetsConfig(
|
|
|
265
287
|
transformFn: ({ url, kind }) => {
|
|
266
288
|
const href = `${prefix}${url}`
|
|
267
289
|
|
|
268
|
-
if (kind === 'clientEntry') {
|
|
290
|
+
if (kind === 'clientEntry' || kind === 'css-url') {
|
|
269
291
|
return { href }
|
|
270
292
|
}
|
|
271
293
|
|
|
@@ -298,48 +320,6 @@ export function resolveTransformAssetsConfig(
|
|
|
298
320
|
}
|
|
299
321
|
}
|
|
300
322
|
|
|
301
|
-
export function adaptTransformAssetUrlsToTransformAssets(
|
|
302
|
-
transformFn: TransformAssetUrlsFn,
|
|
303
|
-
): TransformAssetsFn {
|
|
304
|
-
return async ({ url, kind }) => ({
|
|
305
|
-
href: await transformFn({ url, type: kind }),
|
|
306
|
-
})
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
export function adaptTransformAssetUrlsConfigToTransformAssets(
|
|
310
|
-
transform: TransformAssetUrls,
|
|
311
|
-
): TransformAssets {
|
|
312
|
-
warnDeprecatedTransformAssetUrls()
|
|
313
|
-
|
|
314
|
-
if (typeof transform === 'string') {
|
|
315
|
-
return transform
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (typeof transform === 'function') {
|
|
319
|
-
return adaptTransformAssetUrlsToTransformAssets(transform)
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if ('createTransform' in transform && transform.createTransform) {
|
|
323
|
-
return {
|
|
324
|
-
createTransform: async (ctx: CreateTransformAssetUrlsContext) =>
|
|
325
|
-
adaptTransformAssetUrlsToTransformAssets(
|
|
326
|
-
await transform.createTransform(ctx),
|
|
327
|
-
),
|
|
328
|
-
cache: transform.cache,
|
|
329
|
-
warmup: transform.warmup,
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return {
|
|
334
|
-
transform:
|
|
335
|
-
typeof transform.transform === 'string'
|
|
336
|
-
? transform.transform
|
|
337
|
-
: adaptTransformAssetUrlsToTransformAssets(transform.transform),
|
|
338
|
-
cache: transform.cache,
|
|
339
|
-
warmup: transform.warmup,
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
323
|
export interface StartManifestWithClientEntry {
|
|
344
324
|
manifest: Manifest
|
|
345
325
|
clientEntry: string
|
|
@@ -386,9 +366,20 @@ export async function transformManifestAssets(
|
|
|
386
366
|
transformFn: TransformAssetsFn,
|
|
387
367
|
_opts?: {
|
|
388
368
|
clone?: boolean
|
|
369
|
+
inlineCss?: boolean
|
|
389
370
|
},
|
|
390
371
|
): Promise<Manifest> {
|
|
391
372
|
const manifest = structuredClone(source.manifest)
|
|
373
|
+
const inlineCssEnabled = _opts?.inlineCss !== false
|
|
374
|
+
|
|
375
|
+
if (!inlineCssEnabled) {
|
|
376
|
+
delete manifest.inlineCss
|
|
377
|
+
} else if (manifest.inlineCss) {
|
|
378
|
+
manifest.inlineCss = await transformInlineCssStyles(
|
|
379
|
+
manifest.inlineCss,
|
|
380
|
+
transformFn,
|
|
381
|
+
)
|
|
382
|
+
}
|
|
392
383
|
|
|
393
384
|
for (const route of Object.values(manifest.routes)) {
|
|
394
385
|
if (route.preloads) {
|
|
@@ -410,7 +401,7 @@ export async function transformManifestAssets(
|
|
|
410
401
|
)
|
|
411
402
|
}
|
|
412
403
|
|
|
413
|
-
if (route.assets && !
|
|
404
|
+
if (route.assets && !manifest.inlineCss) {
|
|
414
405
|
for (const asset of route.assets) {
|
|
415
406
|
if (asset.tag === 'link' && asset.attrs?.href) {
|
|
416
407
|
const rel = asset.attrs.rel
|
|
@@ -460,12 +451,13 @@ export async function transformManifestAssets(
|
|
|
460
451
|
|
|
461
452
|
/**
|
|
462
453
|
* Builds a final Manifest from a StartManifestWithClientEntry without any
|
|
463
|
-
* URL transforms. Used when no
|
|
454
|
+
* URL transforms. Used when no transformAssets option is provided.
|
|
464
455
|
*
|
|
465
456
|
* Returns a new manifest object so the cached base manifest is never mutated.
|
|
466
457
|
*/
|
|
467
458
|
export function buildManifestWithClientEntry(
|
|
468
459
|
source: StartManifestWithClientEntry,
|
|
460
|
+
opts?: { inlineCss?: boolean },
|
|
469
461
|
): Manifest {
|
|
470
462
|
const scriptTag = buildClientEntryScriptTag(
|
|
471
463
|
source.clientEntry,
|
|
@@ -481,5 +473,10 @@ export function buildManifestWithClientEntry(
|
|
|
481
473
|
},
|
|
482
474
|
}
|
|
483
475
|
|
|
484
|
-
return {
|
|
476
|
+
return {
|
|
477
|
+
...(opts?.inlineCss === false
|
|
478
|
+
? {}
|
|
479
|
+
: { inlineCss: structuredClone(source.manifest.inlineCss) }),
|
|
480
|
+
routes,
|
|
481
|
+
}
|
|
485
482
|
}
|