@tanstack/react-start-rsc 0.1.9 → 0.1.11

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.
@@ -16,33 +16,27 @@ setOnClientReference(({ deps, runtime }) => {
16
16
  if (cssCollector) for (const href of deps.css) cssCollector.add(href);
17
17
  const jsCollector = jsCollectorStorage.getStore();
18
18
  if (jsCollector) for (const href of deps.js) jsCollector.add(href);
19
- if (!ctx || runtime === "rsbuild") return;
20
- if (!ctx.requestAssets) ctx.requestAssets = [];
19
+ if (!ctx || runtime === "rsbuild" || !deps.js.length && !deps.css.length) return;
20
+ if (!ctx.requestAssets) ctx.requestAssets = {};
21
21
  const seenHrefs = /* @__PURE__ */ new Set();
22
- for (const asset of ctx.requestAssets) if (asset.tag === "link" && asset.attrs?.href) seenHrefs.add(asset.attrs.href);
22
+ for (const preload of ctx.requestAssets.preloads ?? []) seenHrefs.add(typeof preload === "string" ? preload : preload.href);
23
+ for (const stylesheet of ctx.requestAssets.css ?? []) seenHrefs.add(typeof stylesheet === "string" ? stylesheet : stylesheet.href);
24
+ let nextPreloads;
23
25
  for (const href of deps.js) {
24
26
  if (seenHrefs.has(href)) continue;
25
27
  seenHrefs.add(href);
26
- ctx.requestAssets.push({
27
- tag: "link",
28
- attrs: {
29
- rel: "modulepreload",
30
- href
31
- }
32
- });
28
+ if (!nextPreloads) nextPreloads = ctx.requestAssets.preloads ? ctx.requestAssets.preloads.slice() : [];
29
+ nextPreloads.push(href);
33
30
  }
31
+ if (nextPreloads) ctx.requestAssets.preloads = nextPreloads;
32
+ let nextCss;
34
33
  for (const href of deps.css) {
35
34
  if (seenHrefs.has(href)) continue;
36
35
  seenHrefs.add(href);
37
- ctx.requestAssets.push({
38
- tag: "link",
39
- attrs: {
40
- rel: "preload",
41
- href,
42
- as: "style"
43
- }
44
- });
36
+ if (!nextCss) nextCss = ctx.requestAssets.css ? ctx.requestAssets.css.slice() : [];
37
+ nextCss.push(href);
45
38
  }
39
+ if (nextCss) ctx.requestAssets.css = nextCss;
46
40
  });
47
41
  var ssrHandler = {
48
42
  async decode(stream) {
@@ -1 +1 @@
1
- {"version":3,"file":"serialization.server.js","names":[],"sources":["../../src/serialization.server.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport { createSerializationAdapter } from '@tanstack/react-router'\nimport { RawStream } from '@tanstack/router-core'\nimport { getStartContext } from '@tanstack/start-storage-context'\nimport {\n setOnClientReference,\n createFromReadableStream as ssrDecode,\n} from 'virtual:tanstack-rsc-ssr-decode'\nimport {\n RENDERABLE_RSC,\n RSC_SLOT_USAGES_STREAM,\n SERVER_COMPONENT_STREAM,\n isServerComponent,\n} from './ServerComponentTypes'\nimport { createRscProxy } from './createRscProxy'\nimport { awaitLazyElements } from './awaitLazyElements'\nimport { unwrapRscCssEnvelope } from './rscCssEnvelope'\nimport type {\n AnyCompositeComponent,\n ServerComponentStream,\n} from './ServerComponentTypes'\nimport type { RscDecodeResult, RscSsrHandler } from './rscSsrHandler'\n\n// ===== SSR Handler Registration =====\n// This handler is registered on globalThis for the RSC environment to access.\n// The RSC env calls these functions during loader execution to pre-decode streams\n// and create renderable proxies.\n//\n// This MUST happen in a module without 'use client' directive.\n// Modules with 'use client' may be transformed to client references in the\n// SSR environment when RSC is enabled, preventing the side effect from running.\n\n// AsyncLocalStorage for decode-scoped CSS collector.\n// Each decode() runs in its own async context with its own collector.\n// The onClientReference callback reads from this to write CSS hrefs.\nconst decodeCollectorStorage = new AsyncLocalStorage<Set<string>>()\nconst jsCollectorStorage = new AsyncLocalStorage<Set<string>>()\n\nsetOnClientReference(\n ({\n deps,\n runtime,\n }: {\n deps: { js: Array<string>; css: Array<string> }\n runtime?: 'rsbuild'\n }) => {\n const ctx = getStartContext({ throwIfNotFound: false })\n\n const cssCollector = decodeCollectorStorage.getStore()\n if (cssCollector) {\n for (const href of deps.css) {\n cssCollector.add(href)\n }\n }\n\n const jsCollector = jsCollectorStorage.getStore()\n if (jsCollector) {\n for (const href of deps.js) {\n jsCollector.add(href)\n }\n }\n\n if (!ctx || runtime === 'rsbuild') return\n\n if (!ctx.requestAssets) ctx.requestAssets = []\n const seenHrefs = new Set<string>()\n for (const asset of ctx.requestAssets) {\n if (asset.tag === 'link' && asset.attrs?.href) {\n seenHrefs.add(asset.attrs.href as string)\n }\n }\n\n for (const href of deps.js) {\n if (seenHrefs.has(href)) continue\n seenHrefs.add(href)\n ctx.requestAssets.push({\n tag: 'link',\n attrs: { rel: 'modulepreload', href },\n })\n }\n\n for (const href of deps.css) {\n if (seenHrefs.has(href)) continue\n seenHrefs.add(href)\n ctx.requestAssets.push({\n tag: 'link',\n attrs: { rel: 'preload', href, as: 'style' },\n })\n }\n },\n)\n\nconst ssrHandler: RscSsrHandler = {\n async decode(stream: ServerComponentStream): Promise<RscDecodeResult> {\n const readableStream = stream.createReplayStream()\n\n // Create a collector for this decode operation.\n // Run the decode in an AsyncLocalStorage context so the onClientReference\n // callback can write to this specific collector even with parallel decodes.\n const cssCollector = new Set<string>()\n const jsCollector = new Set<string>()\n\n return decodeCollectorStorage.run(cssCollector, async () => {\n return jsCollectorStorage.run(jsCollector, async () => {\n const decodedTree = await ssrDecode(readableStream)\n await awaitLazyElements(decodedTree, (href) => {\n cssCollector.add(href)\n })\n\n return {\n tree: unwrapRscCssEnvelope(decodedTree),\n cssHrefs: cssCollector.size > 0 ? cssCollector : undefined,\n jsPreloads: jsCollector.size > 0 ? jsCollector : undefined,\n }\n })\n })\n },\n\n createRenderableProxy(stream, decoded): any {\n return createRscProxy(() => decoded.tree, {\n stream,\n cssHrefs: decoded.cssHrefs,\n jsPreloads: decoded.jsPreloads,\n renderable: true,\n })\n },\n\n createCompositeProxy(\n stream,\n decoded,\n slotUsagesStream,\n ): AnyCompositeComponent {\n const proxy = createRscProxy(() => decoded.tree, {\n stream,\n cssHrefs: decoded.cssHrefs,\n jsPreloads: decoded.jsPreloads,\n renderable: false,\n slotUsagesStream,\n })\n return proxy\n },\n}\n\n// Register SSR handler on globalThis for RSC environment to access.\nglobalThis.__RSC_SSR__ = ssrHandler\n\n// ===== End SSR Handler Registration =====\n\n/**\n * Helper to check if a value is a renderable RSC (from renderServerComponent).\n * The value can be either an object (proxy target) or a function (stub for server functions).\n */\nfunction isRenderableRsc(value: unknown): boolean {\n if (value === null || value === undefined) return false\n if (typeof value !== 'object' && typeof value !== 'function') return false\n return RENDERABLE_RSC in value && (value as any)[RENDERABLE_RSC] === true\n}\n\n/**\n * Server-side serialization adapter for RSC (renderable + composite).\n */\nconst adapter = createSerializationAdapter({\n key: '$RSC',\n test: (value: unknown): value is AnyCompositeComponent => {\n return isServerComponent(value)\n },\n toSerializable: (component: AnyCompositeComponent) => {\n const stream = component[SERVER_COMPONENT_STREAM]!.createReplayStream()\n\n const kind = isRenderableRsc(component) ? 'renderable' : 'composite'\n\n const slotUsagesStream =\n kind === 'composite' &&\n process.env.NODE_ENV === 'development' &&\n RSC_SLOT_USAGES_STREAM in component\n ? ((component as any)[RSC_SLOT_USAGES_STREAM] as unknown as\n | ReadableStream<any>\n | undefined)\n : undefined\n\n return {\n kind,\n stream: new RawStream(stream, { hint: 'text' }),\n slotUsagesStream,\n }\n },\n fromSerializable: (): never => {\n throw new Error('Server should never deserialize RSC data')\n },\n})\n\n/**\n * Factory function for server-side RSC serialization adapter.\n */\nexport const rscSerializationAdapter = () => [adapter]\n"],"mappings":"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"}
1
+ {"version":3,"file":"serialization.server.js","names":[],"sources":["../../src/serialization.server.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport { createSerializationAdapter } from '@tanstack/react-router'\nimport { RawStream } from '@tanstack/router-core'\nimport { getStartContext } from '@tanstack/start-storage-context'\nimport {\n setOnClientReference,\n createFromReadableStream as ssrDecode,\n} from 'virtual:tanstack-rsc-ssr-decode'\nimport {\n RENDERABLE_RSC,\n RSC_SLOT_USAGES_STREAM,\n SERVER_COMPONENT_STREAM,\n isServerComponent,\n} from './ServerComponentTypes'\nimport { createRscProxy } from './createRscProxy'\nimport { awaitLazyElements } from './awaitLazyElements'\nimport { unwrapRscCssEnvelope } from './rscCssEnvelope'\nimport type {\n AnyCompositeComponent,\n ServerComponentStream,\n} from './ServerComponentTypes'\nimport type { RscDecodeResult, RscSsrHandler } from './rscSsrHandler'\n\n// ===== SSR Handler Registration =====\n// This handler is registered on globalThis for the RSC environment to access.\n// The RSC env calls these functions during loader execution to pre-decode streams\n// and create renderable proxies.\n//\n// This MUST happen in a module without 'use client' directive.\n// Modules with 'use client' may be transformed to client references in the\n// SSR environment when RSC is enabled, preventing the side effect from running.\n\n// AsyncLocalStorage for decode-scoped CSS collector.\n// Each decode() runs in its own async context with its own collector.\n// The onClientReference callback reads from this to write CSS hrefs.\nconst decodeCollectorStorage = new AsyncLocalStorage<Set<string>>()\nconst jsCollectorStorage = new AsyncLocalStorage<Set<string>>()\n\nsetOnClientReference(\n ({\n deps,\n runtime,\n }: {\n deps: { js: Array<string>; css: Array<string> }\n runtime?: 'rsbuild'\n }) => {\n const ctx = getStartContext({ throwIfNotFound: false })\n\n const cssCollector = decodeCollectorStorage.getStore()\n if (cssCollector) {\n for (const href of deps.css) {\n cssCollector.add(href)\n }\n }\n\n const jsCollector = jsCollectorStorage.getStore()\n if (jsCollector) {\n for (const href of deps.js) {\n jsCollector.add(href)\n }\n }\n\n if (\n !ctx ||\n runtime === 'rsbuild' ||\n (!deps.js.length && !deps.css.length)\n ) {\n return\n }\n\n if (!ctx.requestAssets) ctx.requestAssets = {}\n const seenHrefs = new Set<string>()\n for (const preload of ctx.requestAssets.preloads ?? []) {\n seenHrefs.add(typeof preload === 'string' ? preload : preload.href)\n }\n for (const stylesheet of ctx.requestAssets.css ?? []) {\n seenHrefs.add(\n typeof stylesheet === 'string' ? stylesheet : stylesheet.href,\n )\n }\n\n let nextPreloads: typeof ctx.requestAssets.preloads | undefined\n for (const href of deps.js) {\n if (seenHrefs.has(href)) continue\n seenHrefs.add(href)\n if (!nextPreloads) {\n nextPreloads = ctx.requestAssets.preloads\n ? ctx.requestAssets.preloads.slice()\n : []\n }\n nextPreloads.push(href)\n }\n if (nextPreloads) {\n ctx.requestAssets.preloads = nextPreloads\n }\n\n let nextCss: typeof ctx.requestAssets.css | undefined\n for (const href of deps.css) {\n if (seenHrefs.has(href)) continue\n seenHrefs.add(href)\n if (!nextCss) {\n nextCss = ctx.requestAssets.css ? ctx.requestAssets.css.slice() : []\n }\n nextCss.push(href)\n }\n if (nextCss) {\n ctx.requestAssets.css = nextCss\n }\n },\n)\n\nconst ssrHandler: RscSsrHandler = {\n async decode(stream: ServerComponentStream): Promise<RscDecodeResult> {\n const readableStream = stream.createReplayStream()\n\n // Create a collector for this decode operation.\n // Run the decode in an AsyncLocalStorage context so the onClientReference\n // callback can write to this specific collector even with parallel decodes.\n const cssCollector = new Set<string>()\n const jsCollector = new Set<string>()\n\n return decodeCollectorStorage.run(cssCollector, async () => {\n return jsCollectorStorage.run(jsCollector, async () => {\n const decodedTree = await ssrDecode(readableStream)\n await awaitLazyElements(decodedTree, (href) => {\n cssCollector.add(href)\n })\n\n return {\n tree: unwrapRscCssEnvelope(decodedTree),\n cssHrefs: cssCollector.size > 0 ? cssCollector : undefined,\n jsPreloads: jsCollector.size > 0 ? jsCollector : undefined,\n }\n })\n })\n },\n\n createRenderableProxy(stream, decoded): any {\n return createRscProxy(() => decoded.tree, {\n stream,\n cssHrefs: decoded.cssHrefs,\n jsPreloads: decoded.jsPreloads,\n renderable: true,\n })\n },\n\n createCompositeProxy(\n stream,\n decoded,\n slotUsagesStream,\n ): AnyCompositeComponent {\n const proxy = createRscProxy(() => decoded.tree, {\n stream,\n cssHrefs: decoded.cssHrefs,\n jsPreloads: decoded.jsPreloads,\n renderable: false,\n slotUsagesStream,\n })\n return proxy\n },\n}\n\n// Register SSR handler on globalThis for RSC environment to access.\nglobalThis.__RSC_SSR__ = ssrHandler\n\n// ===== End SSR Handler Registration =====\n\n/**\n * Helper to check if a value is a renderable RSC (from renderServerComponent).\n * The value can be either an object (proxy target) or a function (stub for server functions).\n */\nfunction isRenderableRsc(value: unknown): boolean {\n if (value === null || value === undefined) return false\n if (typeof value !== 'object' && typeof value !== 'function') return false\n return RENDERABLE_RSC in value && (value as any)[RENDERABLE_RSC] === true\n}\n\n/**\n * Server-side serialization adapter for RSC (renderable + composite).\n */\nconst adapter = createSerializationAdapter({\n key: '$RSC',\n test: (value: unknown): value is AnyCompositeComponent => {\n return isServerComponent(value)\n },\n toSerializable: (component: AnyCompositeComponent) => {\n const stream = component[SERVER_COMPONENT_STREAM]!.createReplayStream()\n\n const kind = isRenderableRsc(component) ? 'renderable' : 'composite'\n\n const slotUsagesStream =\n kind === 'composite' &&\n process.env.NODE_ENV === 'development' &&\n RSC_SLOT_USAGES_STREAM in component\n ? ((component as any)[RSC_SLOT_USAGES_STREAM] as unknown as\n | ReadableStream<any>\n | undefined)\n : undefined\n\n return {\n kind,\n stream: new RawStream(stream, { hint: 'text' }),\n slotUsagesStream,\n }\n },\n fromSerializable: (): never => {\n throw new Error('Server should never deserialize RSC data')\n },\n})\n\n/**\n * Factory function for server-side RSC serialization adapter.\n */\nexport const rscSerializationAdapter = () => [adapter]\n"],"mappings":";;;;;;;;;;AAmCA,IAAM,yBAAyB,IAAI,mBAAgC;AACnE,IAAM,qBAAqB,IAAI,mBAAgC;AAE/D,sBACG,EACC,MACA,cAII;CACJ,MAAM,MAAM,gBAAgB,EAAE,iBAAiB,OAAO,CAAC;CAEvD,MAAM,eAAe,uBAAuB,UAAU;AACtD,KAAI,aACF,MAAK,MAAM,QAAQ,KAAK,IACtB,cAAa,IAAI,KAAK;CAI1B,MAAM,cAAc,mBAAmB,UAAU;AACjD,KAAI,YACF,MAAK,MAAM,QAAQ,KAAK,GACtB,aAAY,IAAI,KAAK;AAIzB,KACE,CAAC,OACD,YAAY,aACX,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,IAAI,OAE9B;AAGF,KAAI,CAAC,IAAI,cAAe,KAAI,gBAAgB,EAAE;CAC9C,MAAM,4BAAY,IAAI,KAAa;AACnC,MAAK,MAAM,WAAW,IAAI,cAAc,YAAY,EAAE,CACpD,WAAU,IAAI,OAAO,YAAY,WAAW,UAAU,QAAQ,KAAK;AAErE,MAAK,MAAM,cAAc,IAAI,cAAc,OAAO,EAAE,CAClD,WAAU,IACR,OAAO,eAAe,WAAW,aAAa,WAAW,KAC1D;CAGH,IAAI;AACJ,MAAK,MAAM,QAAQ,KAAK,IAAI;AAC1B,MAAI,UAAU,IAAI,KAAK,CAAE;AACzB,YAAU,IAAI,KAAK;AACnB,MAAI,CAAC,aACH,gBAAe,IAAI,cAAc,WAC7B,IAAI,cAAc,SAAS,OAAO,GAClC,EAAE;AAER,eAAa,KAAK,KAAK;;AAEzB,KAAI,aACF,KAAI,cAAc,WAAW;CAG/B,IAAI;AACJ,MAAK,MAAM,QAAQ,KAAK,KAAK;AAC3B,MAAI,UAAU,IAAI,KAAK,CAAE;AACzB,YAAU,IAAI,KAAK;AACnB,MAAI,CAAC,QACH,WAAU,IAAI,cAAc,MAAM,IAAI,cAAc,IAAI,OAAO,GAAG,EAAE;AAEtE,UAAQ,KAAK,KAAK;;AAEpB,KAAI,QACF,KAAI,cAAc,MAAM;EAG7B;AAED,IAAM,aAA4B;CAChC,MAAM,OAAO,QAAyD;EACpE,MAAM,iBAAiB,OAAO,oBAAoB;EAKlD,MAAM,+BAAe,IAAI,KAAa;EACtC,MAAM,8BAAc,IAAI,KAAa;AAErC,SAAO,uBAAuB,IAAI,cAAc,YAAY;AAC1D,UAAO,mBAAmB,IAAI,aAAa,YAAY;IACrD,MAAM,cAAc,MAAM,yBAAU,eAAe;AACnD,UAAM,kBAAkB,cAAc,SAAS;AAC7C,kBAAa,IAAI,KAAK;MACtB;AAEF,WAAO;KACL,MAAM,qBAAqB,YAAY;KACvC,UAAU,aAAa,OAAO,IAAI,eAAe,KAAA;KACjD,YAAY,YAAY,OAAO,IAAI,cAAc,KAAA;KAClD;KACD;IACF;;CAGJ,sBAAsB,QAAQ,SAAc;AAC1C,SAAO,qBAAqB,QAAQ,MAAM;GACxC;GACA,UAAU,QAAQ;GAClB,YAAY,QAAQ;GACpB,YAAY;GACb,CAAC;;CAGJ,qBACE,QACA,SACA,kBACuB;AAQvB,SAPc,qBAAqB,QAAQ,MAAM;GAC/C;GACA,UAAU,QAAQ;GAClB,YAAY,QAAQ;GACpB,YAAY;GACZ;GACD,CAAC;;CAGL;AAGD,WAAW,cAAc;;;;;AAQzB,SAAS,gBAAgB,OAAyB;AAChD,KAAI,UAAU,QAAQ,UAAU,KAAA,EAAW,QAAO;AAClD,KAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAAY,QAAO;AACrE,QAAO,kBAAkB,SAAU,MAAc,oBAAoB;;;;;AAMvE,IAAM,UAAU,2BAA2B;CACzC,KAAK;CACL,OAAO,UAAmD;AACxD,SAAO,kBAAkB,MAAM;;CAEjC,iBAAiB,cAAqC;EACpD,MAAM,SAAS,UAAU,yBAA0B,oBAAoB;EAEvE,MAAM,OAAO,gBAAgB,UAAU,GAAG,eAAe;EAEzD,MAAM,mBACJ,SAAS,eAAA,QAAA,IAAA,aACgB,iBACzB,0BAA0B,YACpB,UAAkB,0BAGpB,KAAA;AAEN,SAAO;GACL;GACA,QAAQ,IAAI,UAAU,QAAQ,EAAE,MAAM,QAAQ,CAAC;GAC/C;GACD;;CAEH,wBAA+B;AAC7B,QAAM,IAAI,MAAM,2CAA2C;;CAE9D,CAAC;;;;AAKF,IAAa,gCAAgC,CAAC,QAAQ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-start-rsc",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "React Server Components support for TanStack Start",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -82,15 +82,15 @@
82
82
  },
83
83
  "dependencies": {
84
84
  "pathe": "^2.0.3",
85
- "@tanstack/react-router": "1.170.6",
86
- "@tanstack/react-start-server": "1.167.6",
87
- "@tanstack/router-core": "1.171.4",
85
+ "@tanstack/react-router": "1.170.8",
86
+ "@tanstack/react-start-server": "1.167.8",
87
+ "@tanstack/router-core": "1.171.6",
88
88
  "@tanstack/router-utils": "1.162.1",
89
- "@tanstack/start-client-core": "1.170.1",
89
+ "@tanstack/start-client-core": "1.170.3",
90
90
  "@tanstack/start-fn-stubs": "1.162.0",
91
- "@tanstack/start-plugin-core": "1.171.2",
92
- "@tanstack/start-server-core": "1.169.1",
93
- "@tanstack/start-storage-context": "1.167.6"
91
+ "@tanstack/start-plugin-core": "1.171.4",
92
+ "@tanstack/start-server-core": "1.169.3",
93
+ "@tanstack/start-storage-context": "1.167.8"
94
94
  },
95
95
  "devDependencies": {
96
96
  "@rspack/core": "2.0.0",
@@ -60,32 +60,51 @@ setOnClientReference(
60
60
  }
61
61
  }
62
62
 
63
- if (!ctx || runtime === 'rsbuild') return
63
+ if (
64
+ !ctx ||
65
+ runtime === 'rsbuild' ||
66
+ (!deps.js.length && !deps.css.length)
67
+ ) {
68
+ return
69
+ }
64
70
 
65
- if (!ctx.requestAssets) ctx.requestAssets = []
71
+ if (!ctx.requestAssets) ctx.requestAssets = {}
66
72
  const seenHrefs = new Set<string>()
67
- for (const asset of ctx.requestAssets) {
68
- if (asset.tag === 'link' && asset.attrs?.href) {
69
- seenHrefs.add(asset.attrs.href as string)
70
- }
73
+ for (const preload of ctx.requestAssets.preloads ?? []) {
74
+ seenHrefs.add(typeof preload === 'string' ? preload : preload.href)
75
+ }
76
+ for (const stylesheet of ctx.requestAssets.css ?? []) {
77
+ seenHrefs.add(
78
+ typeof stylesheet === 'string' ? stylesheet : stylesheet.href,
79
+ )
71
80
  }
72
81
 
82
+ let nextPreloads: typeof ctx.requestAssets.preloads | undefined
73
83
  for (const href of deps.js) {
74
84
  if (seenHrefs.has(href)) continue
75
85
  seenHrefs.add(href)
76
- ctx.requestAssets.push({
77
- tag: 'link',
78
- attrs: { rel: 'modulepreload', href },
79
- })
86
+ if (!nextPreloads) {
87
+ nextPreloads = ctx.requestAssets.preloads
88
+ ? ctx.requestAssets.preloads.slice()
89
+ : []
90
+ }
91
+ nextPreloads.push(href)
92
+ }
93
+ if (nextPreloads) {
94
+ ctx.requestAssets.preloads = nextPreloads
80
95
  }
81
96
 
97
+ let nextCss: typeof ctx.requestAssets.css | undefined
82
98
  for (const href of deps.css) {
83
99
  if (seenHrefs.has(href)) continue
84
100
  seenHrefs.add(href)
85
- ctx.requestAssets.push({
86
- tag: 'link',
87
- attrs: { rel: 'preload', href, as: 'style' },
88
- })
101
+ if (!nextCss) {
102
+ nextCss = ctx.requestAssets.css ? ctx.requestAssets.css.slice() : []
103
+ }
104
+ nextCss.push(href)
105
+ }
106
+ if (nextCss) {
107
+ ctx.requestAssets.css = nextCss
89
108
  }
90
109
  },
91
110
  )