vike 0.4.267-commit-b005535 → 0.4.267-commit-7884d91

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 (138) hide show
  1. package/dist/client/runtime-client-routing/createPageContextClient.d.ts +4 -0
  2. package/dist/client/runtime-client-routing/getGlobalContextClientInternal.d.ts +4 -0
  3. package/dist/client/runtime-client-routing/getPageContextFromHooks.d.ts +22 -2
  4. package/dist/client/runtime-client-routing/getPageContextFromHooks.js +4 -5
  5. package/dist/client/runtime-client-routing/renderPageClient.d.ts +472 -9
  6. package/dist/client/runtime-client-routing/renderPageClient.js +11 -5
  7. package/dist/client/runtime-client-routing/streamedValues.d.ts +5 -0
  8. package/dist/client/runtime-client-routing/streamedValues.js +23 -0
  9. package/dist/client/runtime-server-routing/createPageContextClient.d.ts +4 -0
  10. package/dist/client/runtime-server-routing/entry.js +1 -1
  11. package/dist/client/runtime-server-routing/getGlobalContextClientInternal.d.ts +4 -0
  12. package/dist/client/shared/getGlobalContextClientInternalShared.d.ts +4 -0
  13. package/dist/client/shared/getJsonSerializedInHtml.d.ts +2 -2
  14. package/dist/client/shared/getJsonSerializedInHtml.js +9 -6
  15. package/dist/client/shared/streamedValues/asyncIterable.d.ts +4 -0
  16. package/dist/client/shared/streamedValues/asyncIterable.js +26 -0
  17. package/dist/client/shared/streamedValues/lines.d.ts +11 -0
  18. package/dist/client/shared/streamedValues/lines.js +19 -0
  19. package/dist/client/shared/streamedValues/promise.d.ts +4 -0
  20. package/dist/client/shared/streamedValues/promise.js +19 -0
  21. package/dist/client/shared/streamedValues/readableStream.d.ts +4 -0
  22. package/dist/client/shared/streamedValues/readableStream.js +44 -0
  23. package/dist/client/shared/streamedValues/registry.d.ts +21 -0
  24. package/dist/client/shared/streamedValues/registry.js +40 -0
  25. package/dist/client/shared/streamedValues.d.ts +7 -0
  26. package/dist/client/shared/streamedValues.js +82 -0
  27. package/dist/node/api/resolveViteConfigUser.js +2 -2
  28. package/dist/node/prerender/runPrerender.d.ts +12 -4
  29. package/dist/node/prerender/runPrerender.js +60 -15
  30. package/dist/node/vite/assertEnvVite.js +1 -1
  31. package/dist/node/vite/index.js +2 -0
  32. package/dist/node/vite/plugins/build/handleAssetsManifest.js +6 -2
  33. package/dist/node/vite/plugins/build/pluginBuildApp.js +25 -26
  34. package/dist/node/vite/plugins/build/pluginBuildConfig.d.ts +2 -2
  35. package/dist/node/vite/plugins/build/pluginBuildConfig.js +24 -16
  36. package/dist/node/vite/plugins/build/pluginDistFileNames.js +70 -50
  37. package/dist/node/vite/plugins/build/pluginEnvironmentEntries.d.ts +6 -0
  38. package/dist/node/vite/plugins/build/pluginEnvironmentEntries.js +71 -0
  39. package/dist/node/vite/plugins/build/pluginSuppressRollupWarning.js +19 -17
  40. package/dist/node/vite/plugins/pluginCommon.js +9 -6
  41. package/dist/node/vite/plugins/pluginDev/optimizeDeps.js +1 -1
  42. package/dist/node/vite/plugins/pluginReplaceConstantsGlobalThis.js +6 -4
  43. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.d.ts +2 -1
  44. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.js +29 -12
  45. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntryWithOldDesign.js +3 -2
  46. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFilePageEntry.js +7 -7
  47. package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.d.ts +7 -5
  48. package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.js +4 -10
  49. package/dist/node/vite/plugins/pluginVirtualFiles.js +20 -0
  50. package/dist/node/vite/shared/addSsrMiddleware.js +13 -1
  51. package/dist/node/vite/shared/getAssetsDir.d.ts +3 -2
  52. package/dist/node/vite/shared/getAssetsDir.js +3 -3
  53. package/dist/node/vite/shared/isViteCli.d.ts +3 -3
  54. package/dist/node/vite/shared/isViteCli.js +80 -84
  55. package/dist/node/vite/shared/isViteServerSide.js +2 -7
  56. package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.d.ts +1 -1
  57. package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.js +8 -6
  58. package/dist/node/vite/shared/resolveVikeConfigInternal.d.ts +4 -1
  59. package/dist/node/vite/shared/resolveVikeConfigInternal.js +82 -11
  60. package/dist/server/runtime/globalContext.d.ts +20 -0
  61. package/dist/server/runtime/renderPageServer/analyzePage.js +3 -3
  62. package/dist/server/runtime/renderPageServer/createHttpResponse.d.ts +20 -7
  63. package/dist/server/runtime/renderPageServer/createHttpResponse.js +34 -15
  64. package/dist/server/runtime/renderPageServer/createPageContextServer.d.ts +4 -0
  65. package/dist/server/runtime/renderPageServer/execHookOnError.js +1 -1
  66. package/dist/server/runtime/renderPageServer/execHookOnRenderHtml.d.ts +9 -0
  67. package/dist/server/runtime/renderPageServer/execHookOnRenderHtml.js +17 -5
  68. package/dist/server/runtime/renderPageServer/getHttpResponseBody.d.ts +2 -2
  69. package/dist/server/runtime/renderPageServer/getHttpResponseBody.js +17 -2
  70. package/dist/server/runtime/renderPageServer/getPageContextJson.d.ts +8 -0
  71. package/dist/server/runtime/renderPageServer/getPageContextJson.js +47 -0
  72. package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.d.ts +2 -0
  73. package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.js +1 -1
  74. package/dist/server/runtime/renderPageServer/headersResponse.d.ts +11 -2
  75. package/dist/server/runtime/renderPageServer/headersResponse.js +20 -1
  76. package/dist/server/runtime/renderPageServer/html/injectAssets/getHtmlTags.js +5 -4
  77. package/dist/server/runtime/renderPageServer/html/injectAssets.d.ts +3 -2
  78. package/dist/server/runtime/renderPageServer/html/injectAssets.js +7 -1
  79. package/dist/server/runtime/renderPageServer/html/renderHtml.js +4 -2
  80. package/dist/server/runtime/renderPageServer/html/serializeContext.d.ts +5 -1
  81. package/dist/server/runtime/renderPageServer/html/serializeContext.js +12 -9
  82. package/dist/server/runtime/renderPageServer/html/stream.d.ts +13 -6
  83. package/dist/server/runtime/renderPageServer/html/stream.js +121 -31
  84. package/dist/server/runtime/renderPageServer/html/streamedValuesHtml.d.ts +30 -0
  85. package/dist/server/runtime/renderPageServer/html/streamedValuesHtml.js +92 -0
  86. package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.d.ts +4 -0
  87. package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.js +5 -1
  88. package/dist/server/runtime/renderPageServer/loadPageContextEnvironments.d.ts +15 -0
  89. package/dist/server/runtime/renderPageServer/loadPageContextEnvironments.js +61 -0
  90. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.d.ts +314 -1
  91. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.js +21 -12
  92. package/dist/server/runtime/renderPageServer/streamedValues/asyncIterable.d.ts +4 -0
  93. package/dist/server/runtime/renderPageServer/streamedValues/asyncIterable.js +12 -0
  94. package/dist/server/runtime/renderPageServer/streamedValues/lines.d.ts +10 -0
  95. package/dist/server/runtime/renderPageServer/streamedValues/lines.js +49 -0
  96. package/dist/server/runtime/renderPageServer/streamedValues/promise.d.ts +4 -0
  97. package/dist/server/runtime/renderPageServer/streamedValues/promise.js +14 -0
  98. package/dist/server/runtime/renderPageServer/streamedValues/pump.d.ts +10 -0
  99. package/dist/server/runtime/renderPageServer/streamedValues/pump.js +67 -0
  100. package/dist/server/runtime/renderPageServer/streamedValues/readableStream.d.ts +4 -0
  101. package/dist/server/runtime/renderPageServer/streamedValues/readableStream.js +12 -0
  102. package/dist/server/runtime/renderPageServer/streamedValues/registry.d.ts +28 -0
  103. package/dist/server/runtime/renderPageServer/streamedValues/registry.js +33 -0
  104. package/dist/server/runtime/renderPageServer.d.ts +4 -0
  105. package/dist/server/runtime/renderPageServer.js +17 -8
  106. package/dist/shared-server-client/createGlobalContextShared.d.ts +8 -0
  107. package/dist/shared-server-client/createGlobalContextShared.js +2 -1
  108. package/dist/shared-server-client/getPageContextPublicShared.js +0 -2
  109. package/dist/shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.d.ts +8 -0
  110. package/dist/shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.js +17 -7
  111. package/dist/shared-server-client/hooks/execHook.d.ts +1 -1
  112. package/dist/shared-server-client/hooks/execHook.js +2 -2
  113. package/dist/shared-server-client/route/abort.d.ts +1 -1
  114. package/dist/shared-server-client/route/abort.js +4 -2
  115. package/dist/shared-server-client/streamedValues.d.ts +22 -0
  116. package/dist/shared-server-client/streamedValues.js +24 -0
  117. package/dist/shared-server-node/vike-environments.d.ts +4 -0
  118. package/dist/shared-server-node/vike-environments.js +10 -0
  119. package/dist/shared-server-node/virtualFileId.d.ts +7 -5
  120. package/dist/shared-server-node/virtualFileId.js +42 -42
  121. package/dist/types/Config.d.ts +1 -1
  122. package/dist/types/PageConfig.d.ts +13 -5
  123. package/dist/types/PageContext.d.ts +18 -1
  124. package/dist/utils/PROJECT_VERSION.d.ts +1 -1
  125. package/dist/utils/PROJECT_VERSION.js +1 -1
  126. package/dist/utils/assertViteVersion.d.ts +1 -3
  127. package/dist/utils/assertViteVersion.js +6 -9
  128. package/dist/utils/deepEqual.d.ts +2 -1
  129. package/dist/utils/deepEqual.js +21 -6
  130. package/dist/utils/getContentTypeFromUrl.d.ts +2 -0
  131. package/dist/utils/getContentTypeFromUrl.js +39 -0
  132. package/dist/utils/injectRollupInputs.d.ts +2 -2
  133. package/dist/utils/injectRollupInputs.js +2 -2
  134. package/dist/utils/isDev.js +2 -7
  135. package/dist/utils/parseUrl-extras.js +4 -0
  136. package/package.json +6 -6
  137. package/dist/shared-server-client/addIs404ToPageProps.d.ts +0 -2
  138. package/dist/shared-server-client/addIs404ToPageProps.js +0 -17
@@ -23,7 +23,7 @@ if (import.meta.env.DEV)
23
23
  hydrate();
24
24
  async function hydrate() {
25
25
  const pageContext = await createPageContextClient();
26
- objectAssign(pageContext, getPageContextSerializedInHtml());
26
+ objectAssign(pageContext, await getPageContextSerializedInHtml());
27
27
  // Sets pageContext.config using non-global configs — overrides the pageContext.config set using global configs at createPageContextClient()
28
28
  const pageContextAddendum = await loadPageConfigsLazyClientSide(pageContext.pageId, pageContext._pageFilesAll, pageContext._globalContext._pageConfigs, pageContext._globalContext._pageConfigGlobal);
29
29
  objectAssign(pageContext, pageContextAddendum);
@@ -25,6 +25,10 @@ declare function getGlobalContextClientInternal(): Promise<{
25
25
  _pageFilesAll: import("../../shared-server-client/getPageFiles.js").PageFile[];
26
26
  _pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
27
27
  _pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
28
+ _environmentEntries: Record<string, {
29
+ pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
30
+ pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
31
+ } | null>;
28
32
  _allPageIds: string[];
29
33
  } & {
30
34
  isClientSide: true;
@@ -29,6 +29,10 @@ declare function getGlobalContextClientInternalShared(): Promise<{
29
29
  _pageFilesAll: import("../../shared-server-client/getPageFiles.js").PageFile[];
30
30
  _pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
31
31
  _pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
32
+ _environmentEntries: Record<string, {
33
+ pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
34
+ pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
35
+ } | null>;
32
36
  _allPageIds: string[];
33
37
  } & {
34
38
  /**
@@ -1,8 +1,8 @@
1
1
  export { getPageContextSerializedInHtml };
2
2
  export { getGlobalContextSerializedInHtml };
3
3
  import '../assertEnvClient.js';
4
- declare function getPageContextSerializedInHtml(): {
4
+ declare function getPageContextSerializedInHtml(): Promise<{
5
5
  pageId: string;
6
6
  routeParams: Record<string, string>;
7
- };
7
+ }>;
8
8
  declare function getGlobalContextSerializedInHtml(): object;
@@ -9,23 +9,26 @@ import '../assertEnvClient.js';
9
9
  // 1. <script id="vike_pageContext" type="application/json"> appears before the <script> that loads Vike's client runtime (which includes this file)
10
10
  // 2. <script id="vike_pageContext" type="application/json"> is neither async nor defer
11
11
  // See https://github.com/vikejs/vike/pull/1271
12
- function getPageContextSerializedInHtml() {
13
- const pageContextSerializedInHtml = findAndParseJson(htmlElementId_pageContext);
12
+ async function getPageContextSerializedInHtml() {
13
+ const pageContextJson = findJson(htmlElementId_pageContext);
14
+ // A pageContext always serializes as `{…}`, so an array means streamed values https://vike.dev/passToClient#streaming
15
+ const pageContextSerializedInHtml = pageContextJson[0] === '['
16
+ ? (await import('./streamedValues.js')).parsePageContextHtml(pageContextJson)
17
+ : parse(pageContextJson);
14
18
  assert(hasProp(pageContextSerializedInHtml, 'pageId', 'string'));
15
19
  assert(hasProp(pageContextSerializedInHtml, 'routeParams', 'string{}'));
16
20
  return pageContextSerializedInHtml;
17
21
  }
18
22
  function getGlobalContextSerializedInHtml() {
19
- const globalContextSerializedInHtml = findAndParseJson(htmlElementId_globalContext);
23
+ const globalContextSerializedInHtml = parse(findJson(htmlElementId_globalContext));
20
24
  return globalContextSerializedInHtml;
21
25
  }
22
- function findAndParseJson(id) {
26
+ function findJson(id) {
23
27
  const elem = document.getElementById(id);
24
28
  assertUsage(elem,
25
29
  // It seems like it can be missing when HTML is malformed: https://github.com/vikejs/vike/issues/913
26
30
  `Couldn't find #${id} (which Vike automatically injects in the HTML): make sure it exists (i.e. don't remove it and make sure your HTML isn't malformed)`);
27
31
  const jsonStr = elem.textContent;
28
32
  assert(jsonStr);
29
- const json = parse(jsonStr);
30
- return json;
33
+ return jsonStr;
31
34
  }
@@ -0,0 +1,4 @@
1
+ export { asyncIterable };
2
+ import type { StreamedValueType } from './registry.js';
3
+ import '../../assertEnvClient.js';
4
+ declare const asyncIterable: StreamedValueType;
@@ -0,0 +1,26 @@
1
+ export { asyncIterable };
2
+ import { markers } from '../../../shared-server-client/streamedValues.js';
3
+ import { readableStream } from './readableStream.js';
4
+ import '../../assertEnvClient.js';
5
+ // A ReadableStream, consumed as an async iterable: `for await (const chunk of pageContext.someAsyncIterable)` (Safari's
6
+ // ReadableStream isn't async-iterable)
7
+ const asyncIterable = {
8
+ marker: markers.asyncIterable,
9
+ revive(parseValue) {
10
+ const streamedValue = readableStream.revive(parseValue);
11
+ return { ...streamedValue, value: toAsyncIterable(streamedValue.value) };
12
+ },
13
+ };
14
+ function toAsyncIterable(stream) {
15
+ const reader = stream.getReader();
16
+ const iterator = {
17
+ next: () => reader.read(),
18
+ // Called upon `break` in `for await`
19
+ async return(value) {
20
+ await reader.cancel();
21
+ return { done: true, value };
22
+ },
23
+ [Symbol.asyncIterator]: () => iterator,
24
+ };
25
+ return iterator;
26
+ }
@@ -0,0 +1,11 @@
1
+ export { decodeChunk };
2
+ export { getLineError };
3
+ import '../../assertEnvClient.js';
4
+ declare function decodeChunk(line: {
5
+ t: string;
6
+ } | {
7
+ b: string;
8
+ } | {
9
+ v: unknown;
10
+ }, parseValue: (value: unknown) => unknown): unknown;
11
+ declare function getLineError(): Error;
@@ -0,0 +1,19 @@
1
+ // The decoding of the lines (see shared-server-client/streamedValues.ts)
2
+ export { decodeChunk };
3
+ export { getLineError };
4
+ import '../../assertEnvClient.js';
5
+ const textEncoder = new TextEncoder();
6
+ function decodeChunk(line, parseValue) {
7
+ if ('t' in line)
8
+ return textEncoder.encode(line.t);
9
+ if ('b' in line)
10
+ return decodeBase64url(line.b);
11
+ return parseValue(line.v);
12
+ }
13
+ function getLineError() {
14
+ return new Error('A streamed pageContext value failed on the server-side (see the server logs)');
15
+ }
16
+ function decodeBase64url(str) {
17
+ const binary = atob(str.replaceAll('-', '+').replaceAll('_', '/'));
18
+ return Uint8Array.from(binary, (c) => c.charCodeAt(0));
19
+ }
@@ -0,0 +1,4 @@
1
+ export { promise };
2
+ import type { StreamedValueType } from './registry.js';
3
+ import '../../assertEnvClient.js';
4
+ declare const promise: StreamedValueType;
@@ -0,0 +1,19 @@
1
+ export { promise };
2
+ import { markers } from '../../../shared-server-client/streamedValues.js';
3
+ import { getLineError } from './lines.js';
4
+ import { genPromise } from '../../../utils/genPromise.js';
5
+ import '../../assertEnvClient.js';
6
+ // Settled by its `v` or `error` line
7
+ const promise = {
8
+ marker: markers.promise,
9
+ revive(parseValue) {
10
+ const { promise: value, resolve, reject } = genPromise({ timeout: null });
11
+ // Avoid an unhandled rejection if the user doesn't use the promise
12
+ value.catch(() => { });
13
+ return {
14
+ value,
15
+ push: (line) => ('v' in line ? resolve(parseValue(line.v)) : reject(getLineError())),
16
+ fail: reject,
17
+ };
18
+ },
19
+ };
@@ -0,0 +1,4 @@
1
+ export { readableStream };
2
+ import type { StreamedValueType } from './registry.js';
3
+ import '../../assertEnvClient.js';
4
+ declare const readableStream: StreamedValueType;
@@ -0,0 +1,44 @@
1
+ export { readableStream };
2
+ import { markers } from '../../../shared-server-client/streamedValues.js';
3
+ import { decodeChunk, getLineError } from './lines.js';
4
+ import '../../assertEnvClient.js';
5
+ // Fed by its chunk lines, until its `end` or `error` line
6
+ const readableStream = {
7
+ marker: markers.readableStream,
8
+ revive(parseValue) {
9
+ let controller;
10
+ let isClosed = false;
11
+ const value = new ReadableStream({
12
+ start(controller_) {
13
+ controller = controller_;
14
+ },
15
+ cancel() {
16
+ // Released by its consumer: the rest is ignored
17
+ isClosed = true;
18
+ },
19
+ });
20
+ const close = (err) => {
21
+ if (isClosed)
22
+ return;
23
+ isClosed = true;
24
+ if (err)
25
+ controller.error(err);
26
+ else
27
+ controller.close();
28
+ };
29
+ return {
30
+ value,
31
+ push(line) {
32
+ if (isClosed)
33
+ return;
34
+ if ('end' in line)
35
+ close();
36
+ else if ('error' in line)
37
+ close(getLineError());
38
+ else
39
+ controller.enqueue(decodeChunk(line, parseValue));
40
+ },
41
+ fail: close,
42
+ };
43
+ },
44
+ };
@@ -0,0 +1,21 @@
1
+ export { createReceiver };
2
+ export type { StreamedValueType };
3
+ import { type Reviver } from '@brillout/json-serializer/parse';
4
+ import type { Line } from '../../../shared-server-client/streamedValues.js';
5
+ import '../../assertEnvClient.js';
6
+ type StreamedValueType = {
7
+ marker: string;
8
+ /** `parseValue()` parses the value of a `v` line, which can contain further streamed values */
9
+ revive: (parseValue: (value: unknown) => unknown) => StreamedValue;
10
+ };
11
+ type StreamedValue = {
12
+ value: unknown;
13
+ push: (line: Line) => void;
14
+ fail: (err: unknown) => void;
15
+ };
16
+ declare function createReceiver(): {
17
+ reviver: Reviver;
18
+ onLine(lineStr: string): void;
19
+ /** The response failed, ended or was cancelled: the values that didn't end fail */
20
+ fail(err: unknown): void;
21
+ };
@@ -0,0 +1,40 @@
1
+ // The types of streamed pageContext values (see shared-server-client/streamedValues.ts), and the receiver: its reviver
2
+ // replaces the markers with values, which it then feeds with their lines.
3
+ export { createReceiver };
4
+ import { parseTransform } from '@brillout/json-serializer/parse';
5
+ import { assert } from '../../../utils/assert.js';
6
+ import { readableStream } from './readableStream.js';
7
+ import { promise } from './promise.js';
8
+ import { asyncIterable } from './asyncIterable.js';
9
+ import '../../assertEnvClient.js';
10
+ const types = [readableStream, promise, asyncIterable];
11
+ function createReceiver() {
12
+ const streamedValues = new Map();
13
+ const parseValue = (value) => parseTransform(value, { reviver });
14
+ const reviver = (_path, value) => {
15
+ const type = types.find((type) => value.startsWith(type.marker));
16
+ if (!type)
17
+ return undefined;
18
+ const id = value.slice(type.marker.length);
19
+ assert(/^\d+$/.test(id));
20
+ // The same value referenced twice
21
+ let streamedValue = streamedValues.get(Number(id));
22
+ if (!streamedValue) {
23
+ streamedValue = type.revive(parseValue);
24
+ streamedValues.set(Number(id), streamedValue);
25
+ }
26
+ return { replacement: streamedValue.value };
27
+ };
28
+ return {
29
+ reviver,
30
+ onLine(lineStr) {
31
+ const line = JSON.parse(lineStr);
32
+ // Unknown if contained in a chunk nobody read
33
+ streamedValues.get(line.s)?.push(line);
34
+ },
35
+ /** The response failed, ended or was cancelled: the values that didn't end fail */
36
+ fail(err) {
37
+ streamedValues.forEach((streamedValue) => streamedValue.fail(err));
38
+ },
39
+ };
40
+ }
@@ -0,0 +1,7 @@
1
+ export { parsePageContextHtml };
2
+ export { readPageContextJsonStreamed };
3
+ export { cancelStreamedValues };
4
+ import '../assertEnvClient.js';
5
+ declare function parsePageContextHtml(pageContextJson: string): unknown;
6
+ declare function readPageContextJsonStreamed(response: Response): Promise<Record<string, unknown>>;
7
+ declare function cancelStreamedValues(pageContext: object, isRendered: boolean): void;
@@ -0,0 +1,82 @@
1
+ // Streamed pageContext values, client-side (see shared-server-client/streamedValues.ts): the lines that follow the
2
+ // serialized pageContext feed the values of a receiver (see ./streamedValues/registry.ts).
3
+ //
4
+ // Loaded only if the pageContext has streamed values (see getJsonSerializedInHtml.ts and
5
+ // ../runtime-client-routing/streamedValues.ts).
6
+ export { parsePageContextHtml };
7
+ export { readPageContextJsonStreamed };
8
+ export { cancelStreamedValues };
9
+ import { parse } from '@brillout/json-serializer/parse';
10
+ import { assert } from '../../utils/assert.js';
11
+ import { isObject } from '../../utils/isObject.js';
12
+ import { createReceiver } from './streamedValues/registry.js';
13
+ import '../assertEnvClient.js';
14
+ // First render: the `<script>` tags that follow `<script id="vike_pageContext">` push the lines to `self.__vike_streamed`,
15
+ // before and after Vike's client runtime is loaded.
16
+ function parsePageContextHtml(pageContextJson) {
17
+ const receiver = createReceiver();
18
+ const [pageContext] = parse(pageContextJson, { reviver: receiver.reviver });
19
+ const g = self;
20
+ const linesQueued = Array.isArray(g.__vike_streamed) ? g.__vike_streamed : [];
21
+ g.__vike_streamed = { push: receiver.onLine };
22
+ linesQueued.forEach(receiver.onLine);
23
+ return pageContext;
24
+ }
25
+ // Client-side navigation: the `.pageContext.json` response (see server/runtime/renderPageServer/getPageContextJson.ts),
26
+ // `[pageContext` then one `,line` per line then `]`. The pageContext is returned as soon as its line arrives.
27
+ async function readPageContextJsonStreamed(response) {
28
+ const reader = response.body.getReader();
29
+ const lines = readLines(reader);
30
+ const { done, value: lineFirst } = await lines.next();
31
+ assert(!done && lineFirst[0] === '[');
32
+ const receiver = createReceiver();
33
+ const pageContextFromServer = parse(lineFirst.slice(1), { reviver: receiver.reviver });
34
+ assert(isObject(pageContextFromServer));
35
+ responsesStreaming.push(reader);
36
+ (async () => {
37
+ try {
38
+ for await (const line of lines) {
39
+ if (line !== ']')
40
+ receiver.onLine(line.slice(1));
41
+ }
42
+ receiver.fail(new Error('The pageContext.json response ended before the streamed pageContext values ended'));
43
+ }
44
+ catch (err) {
45
+ // E.g. the server aborted the response
46
+ receiver.fail(err);
47
+ }
48
+ })();
49
+ return { ...pageContextFromServer, _streamedValuesReader: reader };
50
+ }
51
+ async function* readLines(reader) {
52
+ const decoder = new TextDecoder();
53
+ // Joined once per line: joining upon each chunk would be quadratic
54
+ let parts = [];
55
+ while (true) {
56
+ const { done, value } = await reader.read();
57
+ if (done)
58
+ return;
59
+ const chunk = decoder.decode(value, { stream: true });
60
+ let lineStart = 0;
61
+ let lineEnd;
62
+ while ((lineEnd = chunk.indexOf('\n', lineStart)) !== -1) {
63
+ yield parts.join('') + chunk.slice(lineStart, lineEnd);
64
+ parts = [];
65
+ lineStart = lineEnd + 1;
66
+ }
67
+ parts.push(chunk.slice(lineStart));
68
+ }
69
+ }
70
+ // Once a page is rendered, the streamed values fetched before it are cancelled (the previous page's, and superseded
71
+ // navigations'): the previous page keeps its values while it's shown.
72
+ let responsesStreaming = [];
73
+ // Cancels the streamed values of `pageContext` (a superseded navigation), or, once `pageContext` is rendered, all the others
74
+ function cancelStreamedValues(pageContext, isRendered) {
75
+ const { _streamedValuesReader } = pageContext;
76
+ responsesStreaming = responsesStreaming.filter((reader) => {
77
+ if ((reader === _streamedValuesReader) === isRendered)
78
+ return true;
79
+ reader.cancel().catch(() => { });
80
+ return false;
81
+ });
82
+ }
@@ -15,7 +15,7 @@ import { toPosixPath } from '../../utils/path.js';
15
15
  import pc from '@brillout/picocolors';
16
16
  import { getEnvVarObject } from '../../utils/getEnvVarObject.js';
17
17
  import { getVikeApiOperation, isVikeCliOrApi } from '../../shared-server-node/api-context.js';
18
- import { getViteCliCommand, getViteCliArgs } from '../vite/shared/isViteCli.js';
18
+ import { getViteCliCommand, getViteCliArgsMinimal } from '../vite/shared/isViteCli.js';
19
19
  import './assertEnvApiDevAndProd.js';
20
20
  const globalObject = getGlobalObject('resolveViteConfigUser.ts', {});
21
21
  const debug = createDebug('vike:vite-config-user');
@@ -83,7 +83,7 @@ async function resolve(viteContext) {
83
83
  // Vite CLI args (when invoked via Vite's CLI rather than Vike's API).
84
84
  // - Without this, Vike loads vite.config.js blind to `vite [root]` / `-c <file>` and ends up with the wrong root when those Vite CLI args are used.
85
85
  {
86
- const viteConfigFromViteCli = getViteCliArgs();
86
+ const viteConfigFromViteCli = getViteCliArgsMinimal();
87
87
  addConfig(viteConfigFromViteCli);
88
88
  if (debug.isActivated)
89
89
  debug('viteConfigFromViteCli', viteConfigFromViteCli);
@@ -32,13 +32,17 @@ type PrerenderContext = {
32
32
  _userRootDir: string;
33
33
  _outDirClient: string;
34
34
  };
35
- type Output<PageContext = PageContextPrerendered> = {
35
+ type Output<PageContext = PageContextPrerendered> = ({
36
36
  filePath: string;
37
- fileType: FileType;
37
+ fileType: 'HTML' | 'JSON';
38
38
  fileContent: string;
39
39
  pageContext: PageContext;
40
- }[];
41
- type FileType = 'HTML' | 'JSON';
40
+ } | {
41
+ filePath: string;
42
+ fileType: 'CONTENT';
43
+ fileContent: string | Uint8Array;
44
+ pageContext: PageContext;
45
+ })[];
42
46
  type PageContext = Awaited<ReturnType<typeof createPageContextPrerendering>> & {
43
47
  _urlOriginalBeforeHook?: string;
44
48
  };
@@ -101,6 +105,10 @@ declare function createPageContextPrerendering(urlOriginal: string, prerenderCon
101
105
  _pageFilesAll: PageFile[];
102
106
  _pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
103
107
  _pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
108
+ _environmentEntries: Record<string, {
109
+ pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
110
+ pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
111
+ } | null>;
104
112
  _allPageIds: string[];
105
113
  } & (({
106
114
  isClientSide: false;
@@ -21,6 +21,7 @@ import { preservePropertyGetters } from '../../utils/preservePropertyGetters.js'
21
21
  import { assertPosixPath } from '../../utils/path.js';
22
22
  import { urlToFile } from '../../utils/urlToFile.js';
23
23
  import { prependBase } from '../../utils/parseUrl-extras.js';
24
+ import { parseUrl } from '../../utils/parseUrl.js';
24
25
  import { prerenderPage } from '../../server/runtime/renderPageServer/renderPageServerAfterRoute.js';
25
26
  import { createPageContextServer } from '../../server/runtime/renderPageServer/createPageContextServer.js';
26
27
  import pc from '@brillout/picocolors';
@@ -43,6 +44,8 @@ import { resolvePrerenderConfigGlobal, resolvePrerenderConfigLocal, isDistServer
43
44
  import { getOutDirsAllFromRootNormalized } from '../vite/shared/getOutDirs.js';
44
45
  import fs from 'node:fs';
45
46
  import { getPublicProxy } from '../../shared-server-client/getPublicProxy.js';
47
+ import { getPageContextPublicServer } from '../../server/runtime/renderPageServer/getPageContextPublicServer.js';
48
+ import { isObject } from '../../utils/isObject.js';
46
49
  import { getStaticRedirectsForPrerender } from '../../server/runtime/renderPageServer/resolveRedirects.js';
47
50
  import { updateType } from '../../utils/updateType.js';
48
51
  const docLink = 'https://vike.dev/i18n#pre-rendering';
@@ -482,6 +485,7 @@ async function callOnPrerenderStartHook(prerenderContext, globalContext, concurr
482
485
  });
483
486
  const prerenderContextPublic = getPrerenderContextPublic(prerenderContext);
484
487
  let result = await execHookSingleWithoutPageContext(onPrerenderStartHook, globalContext, () => hookFn(prerenderContextPublic));
488
+ prerenderContext.pageContexts = prerenderContext.pageContexts.map(getPageContextOriginal);
485
489
  // Before applying result
486
490
  prerenderContext.pageContexts.forEach((pageContext) => {
487
491
  ;
@@ -507,7 +511,7 @@ async function callOnPrerenderStartHook(prerenderContext, globalContext, concurr
507
511
  assertUsage(isObjectWithKeys(result, ['prerenderContext']) &&
508
512
  hasProp(result, 'prerenderContext', 'object') &&
509
513
  hasProp(result.prerenderContext, 'pageContexts', 'array'), rightUsage);
510
- prerenderContext.pageContexts = result.prerenderContext.pageContexts;
514
+ prerenderContext.pageContexts = result.prerenderContext.pageContexts.map(getPageContextOriginal);
511
515
  prerenderContext.pageContexts.forEach((pageContext) => {
512
516
  // TO-DO/next-major-release: remove
513
517
  if (pageContext.url && !isPropertyGetter(pageContext, 'url')) {
@@ -546,11 +550,12 @@ async function prerenderPages(prerenderContext, concurrencyLimit, onComplete) {
546
550
  assertIsNotAbort(err, pc.cyan(pageContextBeforeRender.urlOriginal));
547
551
  throw err;
548
552
  }
549
- const { documentHtml, pageContext } = res;
553
+ const { documentHtml, content, pageContext } = res;
550
554
  const pageContextSerialized = pageContext.is404 ? null : res.pageContextSerialized;
551
555
  await onComplete({
552
556
  pageContext,
553
557
  htmlString: documentHtml,
558
+ content,
554
559
  pageContextSerialized,
555
560
  });
556
561
  })));
@@ -579,7 +584,13 @@ async function warnMissingPages(prerenderedPageContexts, globalContext, doNotPre
579
584
  assertWarning(partial, `Cannot pre-render page ${pageAt} because it has a non-static route, while there isn't any ${hookName}() hook returning an URL matching the page's route. You must use a ${hookName}() hook (https://vike.dev/${hookName}) for providing the list of URLs to be pre-rendered for that page. If you want to skip pre-rendering that page, you can remove this warning by setting +prerender to false at ${pageAt} (https://vike.dev/pre-rendering#partial) or by setting +prerender.partial to true (https://vike.dev/prerender#partial).`, { onlyOnce: true });
580
585
  });
581
586
  }
582
- async function writeFiles({ pageContext, htmlString, pageContextSerialized }, prerenderContext, onPagePrerender, logLevel) {
587
+ async function writeFiles({ pageContext, htmlString, content, pageContextSerialized }, prerenderContext, onPagePrerender, logLevel) {
588
+ if (content !== null) {
589
+ assert(htmlString === null && pageContextSerialized === null);
590
+ await write(pageContext, 'CONTENT', content, onPagePrerender, prerenderContext, logLevel);
591
+ return;
592
+ }
593
+ assert(htmlString !== null);
583
594
  const writeJobs = [write(pageContext, 'HTML', htmlString, onPagePrerender, prerenderContext, logLevel)];
584
595
  if (pageContextSerialized !== null) {
585
596
  writeJobs.push(write(pageContext, 'JSON', pageContextSerialized, onPagePrerender, prerenderContext, logLevel));
@@ -594,10 +605,13 @@ async function write(pageContext, fileType, fileContent, onPagePrerender, preren
594
605
  const doNotCreateExtraDirectory = prerenderContext._noExtraDir ?? pageContext.is404;
595
606
  fileUrl = urlToFile(urlOriginal, '.html', doNotCreateExtraDirectory);
596
607
  }
597
- else {
598
- assert(fileType === 'JSON');
608
+ else if (fileType === 'JSON') {
599
609
  fileUrl = getPageContextRequestUrl(urlOriginal);
600
610
  }
611
+ else {
612
+ assert(fileType === 'CONTENT');
613
+ fileUrl = getContentFileUrl(pageContext);
614
+ }
601
615
  assertPosixPath(fileUrl);
602
616
  assert(fileUrl.startsWith('/'));
603
617
  const filePathRelative = fileUrl.slice(1);
@@ -614,14 +628,15 @@ async function write(pageContext, fileType, fileContent, onPagePrerender, preren
614
628
  fileContent,
615
629
  },
616
630
  });
617
- prerenderContext.output.push({
618
- filePath,
619
- fileType,
620
- fileContent,
621
- pageContext,
622
- });
631
+ if (fileType === 'CONTENT') {
632
+ prerenderContext.output.push({ filePath, fileType, fileContent, pageContext });
633
+ }
634
+ else {
635
+ assert(typeof fileContent === 'string');
636
+ prerenderContext.output.push({ filePath, fileType, fileContent, pageContext });
637
+ }
623
638
  if (onPagePrerender) {
624
- await onPagePrerender(pageContext);
639
+ await onPagePrerender(getPageContextPublicPrerendered(pageContext));
625
640
  }
626
641
  else {
627
642
  const { promises } = await import('node:fs');
@@ -640,6 +655,18 @@ async function write(pageContext, fileType, fileContent, onPagePrerender, preren
640
655
  }
641
656
  }
642
657
  }
658
+ // With `pageContext.content` the URL is the file path: `/feed.atom` => `dist/client/feed.atom`
659
+ function getContentFileUrl(pageContext) {
660
+ const { urlOriginal } = pageContext;
661
+ // The query string and the hash are ignored: a static host serves the file at the pathname
662
+ const { pathnameOriginal } = parseUrl(urlOriginal, '/');
663
+ const errPrefix = `Cannot pre-render ${pc.cyan(urlOriginal)} with ${pc.code('pageContext.content')}`;
664
+ const errSuffix = "pre-rendering writes the content to the file at the URL's pathname (e.g. /feed.atom => dist/client/feed.atom)";
665
+ assertUsage(!pageContext.is404, `${errPrefix} because it's the 404 page`);
666
+ const segments = pathnameOriginal.split('/').slice(1);
667
+ assertUsage(segments.every((s) => s !== '' && s !== '.' && s !== '..'), `${errPrefix} because the URL's pathname isn't a file path: ${errSuffix}`);
668
+ return pathnameOriginal;
669
+ }
643
670
  function normalizeOnPrerenderHookResult(prerenderResult, prerenderHookFile, hookName) {
644
671
  if (isArray(prerenderResult)) {
645
672
  return prerenderResult.map(normalize);
@@ -730,14 +757,31 @@ function getPrerenderContextPublic(prerenderContext) {
730
757
  configurable: true,
731
758
  });
732
759
  }
733
- // Required because of https://vike.dev/i18n#pre-rendering
734
- // - Thus, we have to let users access the original pageContext object => we cannot use ES proxies and we cannot use getPageContextPublicShared()
735
- prerenderContext.pageContexts.forEach((pageContext) => {
760
+ prerenderContext.pageContexts = prerenderContext.pageContexts.map((pageContext) => {
761
+ // Required because of https://vike.dev/i18n#pre-rendering
762
+ // - Users copy pageContext, e.g. `{ ...pageContext, locale }`, and Vike renders the copies => the copies need to be original objects
736
763
  changeEnumerable(pageContext, '_isOriginalObject', true);
764
+ return getPageContextPublicServer(pageContext);
765
+ });
766
+ prerenderContext.output.forEach((file) => {
767
+ file.pageContext = getPageContextPublicPrerendered(file.pageContext);
737
768
  });
738
769
  const prerenderContextPublic = getPublicProxy(prerenderContext, 'prerenderContext');
739
770
  return prerenderContextPublic;
740
771
  }
772
+ // The user may return the public pageContext objects passed to +onPrerenderStart
773
+ function getPageContextOriginal(pageContext) {
774
+ const obj = pageContext;
775
+ if (isObject(obj) && obj._isProxyObject)
776
+ return obj._originalObject;
777
+ return pageContext;
778
+ }
779
+ function getPageContextPublicPrerendered(pageContext) {
780
+ // Pre-rendered redirects don't have any real pageContext object, but only a plain object `{ urlOriginal, pageId: null, is404: false, isRedirect: true }` which we cannot pass to getPageContextPublicServer() as it only accepts real pageContext objects (it asserts pageContext._isOriginalObject)
781
+ if (pageContext.isRedirect)
782
+ return pageContext;
783
+ return getPageContextPublicServer(pageContext);
784
+ }
741
785
  async function prerenderRedirects(globalContext, onComplete, showWarningUponDynamicRedirects) {
742
786
  const redirects = globalContext.config.redirects ?? [];
743
787
  const redirectsStatic = getStaticRedirectsForPrerender(redirects, showWarningUponDynamicRedirects);
@@ -748,6 +792,7 @@ async function prerenderRedirects(globalContext, onComplete, showWarningUponDyna
748
792
  await onComplete({
749
793
  pageContext: { urlOriginal, pageId: null, is404: false, isRedirect: true },
750
794
  htmlString,
795
+ content: null,
751
796
  pageContextSerialized: null,
752
797
  });
753
798
  }
@@ -11,7 +11,7 @@ function assertEnvVite() {
11
11
  markSetup_vikeVitePlugin();
12
12
  assertIsNotBrowser();
13
13
  assertNodeVersion();
14
- assertViteVersion(viteVersion);
14
+ assertViteVersion(viteVersion); // Early check — more reliable check using `this.meta.viteVersion` later
15
15
  assertIsNotProductionRuntime(); // Don't bloat server with heavy dependencies like Vite
16
16
  }
17
17
  function onLoad() {
@@ -32,6 +32,7 @@ import { pluginSuppressRollupWarning } from './plugins/build/pluginSuppressRollu
32
32
  import { pluginDistFileNames } from './plugins/build/pluginDistFileNames.js';
33
33
  import { pluginProdBuildEntry } from './plugins/build/pluginProdBuildEntry.js';
34
34
  import { pluginBuildConfig } from './plugins/build/pluginBuildConfig.js';
35
+ import { pluginEnvironmentEntries } from './plugins/build/pluginEnvironmentEntries.js';
35
36
  import { pluginModuleBanner } from './plugins/build/pluginModuleBanner.js';
36
37
  import { pluginReplaceConstantsNonRunnableDev } from './plugins/non-runnable-dev/pluginReplaceConstantsNonRunnableDev.js';
37
38
  import { isVikeCliOrApi } from '../../shared-server-node/api-context.js';
@@ -83,6 +84,7 @@ function plugin(vikeVitePluginOptions = {}) {
83
84
  function pluginBuild() {
84
85
  return [
85
86
  ...pluginBuildConfig(),
87
+ ...pluginEnvironmentEntries(),
86
88
  ...pluginBuildApp(),
87
89
  ...pluginProdBuildEntry(),
88
90
  ...pluginDistPackageJsonFile(),
@@ -45,7 +45,7 @@ async function fixServerAssets(config) {
45
45
  }
46
46
  async function copyAssets(filesToMove, filesToRemove, config) {
47
47
  const { outDirClient, outDirServer } = getOutDirs(config, undefined);
48
- const assetsDir = getAssetsDir(config);
48
+ const assetsDir = getAssetsDir(config.environments.ssr.build);
49
49
  const assetsDirServer = path.posix.join(outDirServer, assetsDir);
50
50
  if (!filesToMove.length && !filesToRemove.length && !existsSync(assetsDirServer))
51
51
  return;
@@ -180,7 +180,11 @@ function getPageId(key) {
180
180
  // to:
181
181
  // virtual:vike:page-entry:client:/pages/index
182
182
  // (This seems to be needed only for vitest tests that use Vite's build() API with an inline config.)
183
- key = key.substring(key.indexOf('virtual:vike'));
183
+ const prefix = key.split('virtual:vike')[0];
184
+ // Skip virtual modules wrapping a Vike virtual module, e.g. virtual:vite-rsc/client-references/group/facade:virtual:vike:page-entry:client:/pages/index
185
+ if (prefix && !prefix.endsWith('/'))
186
+ return null;
187
+ key = key.substring(prefix.length);
184
188
  const result = parseVirtualFileId(key);
185
189
  return result && result.type === 'page-entry' ? result.pageId : null;
186
190
  }