vike 0.4.235-commit-8f42b16 → 0.4.235-commit-d2ac38a
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/cjs/node/runtime/globalContext.js +21 -6
- package/dist/cjs/node/runtime/html/serializeContext.js +58 -13
- package/dist/cjs/node/runtime/renderPage/createHttpResponse/getCacheControl.js +7 -7
- package/dist/cjs/node/runtime/renderPage/createHttpResponse.js +8 -5
- package/dist/cjs/node/runtime/renderPage/loadPageConfigsLazyServerSide.js +28 -2
- package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +1 -0
- package/dist/cjs/node/runtime/renderPage.js +1 -0
- package/dist/cjs/node/vite/shared/resolveVikeConfigInternal/configDefinitionsBuiltIn.js +4 -0
- package/dist/cjs/node/vite/shared/resolveVikeConfigInternal/filesystemRouting.js +4 -6
- package/dist/cjs/shared/createGlobalContextShared.js +20 -7
- package/dist/cjs/shared/route/loadPageRoutes.js +7 -1
- package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
- package/dist/esm/client/runtime-client-routing/getPageContextFromHooks.d.ts +8 -0
- package/dist/esm/client/runtime-client-routing/renderPageClientSide.d.ts +2 -0
- package/dist/esm/client/shared/createGetGlobalContextClient.d.ts +2 -2
- package/dist/esm/node/prerender/runPrerender.d.ts +2 -1
- package/dist/esm/node/runtime/globalContext.d.ts +14 -12
- package/dist/esm/node/runtime/globalContext.js +23 -8
- package/dist/esm/node/runtime/html/serializeContext.d.ts +7 -1
- package/dist/esm/node/runtime/html/serializeContext.js +58 -13
- package/dist/esm/node/runtime/renderPage/createHttpResponse/getCacheControl.d.ts +3 -3
- package/dist/esm/node/runtime/renderPage/createHttpResponse/getCacheControl.js +7 -7
- package/dist/esm/node/runtime/renderPage/createHttpResponse.d.ts +1 -0
- package/dist/esm/node/runtime/renderPage/createHttpResponse.js +8 -5
- package/dist/esm/node/runtime/renderPage/loadPageConfigsLazyServerSide.d.ts +8 -4
- package/dist/esm/node/runtime/renderPage/loadPageConfigsLazyServerSide.js +29 -3
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +4 -2
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +1 -0
- package/dist/esm/node/runtime/renderPage.js +1 -0
- package/dist/esm/node/vite/shared/resolveVikeConfigInternal/configDefinitionsBuiltIn.js +4 -0
- package/dist/esm/node/vite/shared/resolveVikeConfigInternal/filesystemRouting.js +4 -6
- package/dist/esm/shared/createGlobalContextShared.d.ts +3 -3
- package/dist/esm/shared/createGlobalContextShared.js +20 -7
- package/dist/esm/shared/route/loadPageRoutes.d.ts +5 -0
- package/dist/esm/shared/route/loadPageRoutes.js +7 -1
- package/dist/esm/types/Config.d.ts +9 -1
- package/dist/esm/types/PageContext.d.ts +8 -2
- package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
- package/dist/esm/utils/PROJECT_VERSION.js +1 -1
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ export { setGlobalContext_viteDevServer };
|
|
|
13
13
|
export { setGlobalContext_viteConfig };
|
|
14
14
|
export { setGlobalContext_isPrerendering };
|
|
15
15
|
export { setGlobalContext_isProduction };
|
|
16
|
-
export { setGlobalContext_buildEntry };
|
|
16
|
+
export { setGlobalContext_buildEntry }; // production entry
|
|
17
17
|
export { clearGlobalContext };
|
|
18
18
|
export { assertBuildInfo };
|
|
19
19
|
export { updateUserFiles };
|
|
@@ -30,7 +30,7 @@ import { assert, onSetupRuntime, assertUsage, assertWarning, isPlainObject, obje
|
|
|
30
30
|
import { importServerProductionEntry } from '@brillout/vite-plugin-server-entry/runtime';
|
|
31
31
|
import { virtualFileIdEntryServer } from '../shared/virtualFiles/virtualFileEntry.js';
|
|
32
32
|
import pc from '@brillout/picocolors';
|
|
33
|
-
import { loadPageRoutes } from '../../shared/route/loadPageRoutes.js';
|
|
33
|
+
import { loadPageRoutes, loadPageRoutesSync } from '../../shared/route/loadPageRoutes.js';
|
|
34
34
|
import { assertV1Design } from '../shared/assertV1Design.js';
|
|
35
35
|
import { resolveBase } from '../shared/resolveBase.js';
|
|
36
36
|
import { createGlobalContextShared, getGlobalContextSyncErrMsg, } from '../../shared/createGlobalContextShared.js';
|
|
@@ -39,7 +39,7 @@ import { logRuntimeError, logRuntimeInfo } from './loggerRuntime.js';
|
|
|
39
39
|
import { getVikeConfigErrorBuild, setVikeConfigError } from '../shared/getVikeConfigError.js';
|
|
40
40
|
import { hasAlreadyLogged } from './renderPage/isNewError.js';
|
|
41
41
|
const debug = createDebugger('vike:globalContext');
|
|
42
|
-
const globalObject = getGlobalObject('runtime/globalContext.ts',
|
|
42
|
+
const globalObject = getGlobalObject('runtime/globalContext.ts', getInitialGlobalObject());
|
|
43
43
|
// Trick to break down TypeScript circular dependency
|
|
44
44
|
// https://chat.deepseek.com/a/chat/s/d7e9f90a-c7f3-4108-9cd5-4ad6caed3539
|
|
45
45
|
const globalObjectTyped = globalObject;
|
|
@@ -232,6 +232,7 @@ function assertViteManifest(manifest) {
|
|
|
232
232
|
async function loadBuildEntry(outDir) {
|
|
233
233
|
debug('loadBuildEntry()');
|
|
234
234
|
if (globalObject.globalContext) {
|
|
235
|
+
debug('loadBuildEntry() - already done');
|
|
235
236
|
return;
|
|
236
237
|
}
|
|
237
238
|
if (!globalObject.buildEntry) {
|
|
@@ -257,6 +258,8 @@ async function loadBuildEntry(outDir) {
|
|
|
257
258
|
globalObject.buildInfo = buildEntry.buildInfo;
|
|
258
259
|
await setGlobalContext(buildEntry.virtualFileExports);
|
|
259
260
|
}
|
|
261
|
+
// This is the production entry, see:
|
|
262
|
+
// https://github.com/vikejs/vike/blob/798e5465dc3e3e6723b38b601a50350c0a006fb8/packages/vike/node/vite/plugins/pluginBuild/pluginBuildEntry.ts#L47
|
|
260
263
|
async function setGlobalContext_buildEntry(buildEntry) {
|
|
261
264
|
debug('setGlobalContext_buildEntry()');
|
|
262
265
|
setIsProduction(true);
|
|
@@ -266,6 +269,7 @@ async function setGlobalContext_buildEntry(buildEntry) {
|
|
|
266
269
|
assert(globalObject.buildEntry); // ensure no infinite loop
|
|
267
270
|
await loadBuildEntry();
|
|
268
271
|
assertGlobalContextIsDefined();
|
|
272
|
+
debug('setGlobalContext_buildEntry() - done');
|
|
269
273
|
}
|
|
270
274
|
function assertBuildEntry(buildEntry) {
|
|
271
275
|
assert(isObject(buildEntry));
|
|
@@ -362,18 +366,29 @@ async function updateUserFiles() {
|
|
|
362
366
|
return onSuccess();
|
|
363
367
|
}
|
|
364
368
|
async function setGlobalContext(virtualFileExports) {
|
|
369
|
+
debug('setGlobalContext()');
|
|
365
370
|
assert(!getVikeConfigErrorBuild());
|
|
366
|
-
const globalContext = await createGlobalContextShared(virtualFileExports, globalObject,
|
|
371
|
+
const globalContext = await createGlobalContextShared(virtualFileExports, globalObject, addGlobalContextAsync, addGlobalContextSync);
|
|
367
372
|
assertV1Design(
|
|
368
373
|
// pageConfigs is PageConfigRuntime[] but assertV1Design() requires PageConfigBuildTime[]
|
|
369
374
|
globalContext._pageConfigs.length > 0, globalContext._pageFilesAll);
|
|
370
375
|
assertGlobalContextIsDefined();
|
|
371
376
|
onSetupRuntime();
|
|
377
|
+
debug('setGlobalContext() - done');
|
|
372
378
|
// Never actually used, only used for TypeScript `ReturnType<typeof setGlobalContext>`
|
|
373
379
|
return globalContext;
|
|
374
380
|
}
|
|
375
|
-
async function
|
|
381
|
+
async function addGlobalContextAsync(globalContext) {
|
|
382
|
+
debug('addGlobalContextAsync()');
|
|
376
383
|
const { pageRoutes, onBeforeRouteHook } = await loadPageRoutes(globalContext._pageFilesAll, globalContext._pageConfigs, globalContext._pageConfigGlobal, globalContext._allPageIds);
|
|
384
|
+
return addGlobalContextCommon(globalContext, pageRoutes, onBeforeRouteHook);
|
|
385
|
+
}
|
|
386
|
+
function addGlobalContextSync(globalContext) {
|
|
387
|
+
debug('addGlobalContextSync()');
|
|
388
|
+
const { pageRoutes, onBeforeRouteHook } = loadPageRoutesSync(globalContext._pageFilesAll, globalContext._pageConfigs, globalContext._pageConfigGlobal, globalContext._allPageIds);
|
|
389
|
+
return addGlobalContextCommon(globalContext, pageRoutes, onBeforeRouteHook);
|
|
390
|
+
}
|
|
391
|
+
function addGlobalContextCommon(globalContext, pageRoutes, onBeforeRouteHook) {
|
|
377
392
|
const globalContextBase = {
|
|
378
393
|
isClientSide: false,
|
|
379
394
|
_pageRoutes: pageRoutes,
|
|
@@ -432,10 +447,10 @@ async function addGlobalContext(globalContext) {
|
|
|
432
447
|
}
|
|
433
448
|
function clearGlobalContext() {
|
|
434
449
|
debug('clearGlobalContext()');
|
|
435
|
-
objectReplace(globalObject,
|
|
450
|
+
objectReplace(globalObject, getInitialGlobalObject(), ['buildEntryPrevious']);
|
|
436
451
|
}
|
|
437
|
-
function
|
|
438
|
-
debug('
|
|
452
|
+
function getInitialGlobalObject() {
|
|
453
|
+
debug('getInitialGlobalObject()');
|
|
439
454
|
const { promise: viteDevServerPromise, resolve: viteDevServerPromiseResolve } = genPromise();
|
|
440
455
|
return {
|
|
441
456
|
viteDevServerPromise,
|
|
@@ -2,19 +2,25 @@ export { getPageContextClientSerialized };
|
|
|
2
2
|
export { getPageContextClientSerializedAbort };
|
|
3
3
|
export { getGlobalContextClientSerialized };
|
|
4
4
|
export type { PageContextSerialization };
|
|
5
|
+
export type { PassToClient };
|
|
5
6
|
import type { UrlRedirect } from '../../../shared/route/abort.js';
|
|
6
7
|
import type { GlobalContextServerInternal } from '../globalContext.js';
|
|
7
8
|
type PageContextSerialization = {
|
|
8
9
|
pageId: string;
|
|
9
10
|
routeParams: Record<string, string>;
|
|
10
|
-
_passToClient:
|
|
11
|
+
_passToClient: PassToClient;
|
|
11
12
|
is404: null | boolean;
|
|
12
13
|
pageProps?: Record<string, unknown>;
|
|
13
14
|
_pageContextInit: Record<string, unknown>;
|
|
14
15
|
_globalContext: GlobalContextServerInternal;
|
|
16
|
+
isClientSideNavigation: boolean;
|
|
15
17
|
};
|
|
16
18
|
declare function getPageContextClientSerialized(pageContext: PageContextSerialization): string;
|
|
17
19
|
declare function getGlobalContextClientSerialized(pageContext: PageContextSerialization): string;
|
|
20
|
+
type PassToClient = (string | {
|
|
21
|
+
prop: string;
|
|
22
|
+
once?: boolean;
|
|
23
|
+
})[];
|
|
18
24
|
declare function getPageContextClientSerializedAbort(pageContext: Record<string, unknown> & ({
|
|
19
25
|
_urlRedirect: UrlRedirect;
|
|
20
26
|
} | {
|
|
@@ -27,20 +27,41 @@ const passToClientBuiltInPageContext = [
|
|
|
27
27
|
const pageToClientBuiltInPageContextError = ['pageProps', 'is404', isServerSideError];
|
|
28
28
|
function getPageContextClientSerialized(pageContext) {
|
|
29
29
|
const passToClientPageContext = getPassToClientPageContext(pageContext);
|
|
30
|
-
const
|
|
31
|
-
|
|
30
|
+
const getObj = (passToClientEntry) => {
|
|
31
|
+
if (passToClientEntry.once)
|
|
32
|
+
return undefined; // pass it to client-side globalContext
|
|
33
|
+
return { obj: pageContext, objName: 'pageContext' };
|
|
34
|
+
};
|
|
35
|
+
const res = applyPassToClient(passToClientPageContext, getObj);
|
|
36
|
+
const pageContextClient = res.objClient;
|
|
37
|
+
const pageContextClientProps = res.objClientProps;
|
|
38
|
+
if (pageContextClientProps.some((prop) => getPropVal(pageContext._pageContextInit, prop))) {
|
|
32
39
|
pageContextClient[pageContextInitIsPassedToClient] = true;
|
|
33
40
|
}
|
|
34
|
-
const pageContextClientSerialized = serializeObject(pageContextClient,
|
|
41
|
+
const pageContextClientSerialized = serializeObject(pageContextClient, passToClientPageContext, getObj);
|
|
35
42
|
return pageContextClientSerialized;
|
|
36
43
|
}
|
|
37
44
|
function getGlobalContextClientSerialized(pageContext) {
|
|
38
45
|
const passToClient = pageContext._passToClient;
|
|
39
|
-
const
|
|
40
|
-
const
|
|
46
|
+
const globalContext = pageContext._globalContext;
|
|
47
|
+
const getObj = ({ prop, once }) => {
|
|
48
|
+
if (once && getPropVal(pageContext, prop)) {
|
|
49
|
+
assert(typeof pageContext.isClientSideNavigation === 'boolean');
|
|
50
|
+
if (!pageContext.isClientSideNavigation) {
|
|
51
|
+
return { obj: pageContext, objName: 'pageContext' }; // pass it to client-side globalContext
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
return undefined; // already passed to client-side
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return { obj: globalContext, objName: 'globalContext' };
|
|
58
|
+
};
|
|
59
|
+
const res = applyPassToClient(passToClient, getObj);
|
|
60
|
+
const globalContextClient = res.objClient;
|
|
61
|
+
const globalContextClientSerialized = serializeObject(globalContextClient, passToClient, getObj);
|
|
41
62
|
return globalContextClientSerialized;
|
|
42
63
|
}
|
|
43
|
-
function serializeObject(obj,
|
|
64
|
+
function serializeObject(obj, passToClient, getObj) {
|
|
44
65
|
let serialized;
|
|
45
66
|
try {
|
|
46
67
|
serialized = serializeValue(obj);
|
|
@@ -49,11 +70,15 @@ function serializeObject(obj, objName, passToClient) {
|
|
|
49
70
|
const h = (s) => pc.cyan(s);
|
|
50
71
|
let hasWarned = false;
|
|
51
72
|
const propsNonSerializable = [];
|
|
52
|
-
passToClient.forEach((
|
|
73
|
+
passToClient.forEach((entry) => {
|
|
74
|
+
const entryNormalized = normalizePassToClientEntry(entry);
|
|
75
|
+
const { prop } = entryNormalized;
|
|
53
76
|
const res = getPropVal(obj, prop);
|
|
54
77
|
if (!res)
|
|
55
78
|
return;
|
|
56
79
|
const { value } = res;
|
|
80
|
+
const { objName } = getObj(entryNormalized) ?? {};
|
|
81
|
+
assert(objName);
|
|
57
82
|
const varName = `${objName}${getPropKeys(prop).map(getPropAccessNotation).join('')}`;
|
|
58
83
|
try {
|
|
59
84
|
serializeValue(value, varName);
|
|
@@ -163,16 +188,36 @@ function getPageContextClientSerializedAbort(pageContext) {
|
|
|
163
188
|
}
|
|
164
189
|
return serializeValue(pageContext);
|
|
165
190
|
}
|
|
166
|
-
function applyPassToClient(passToClient,
|
|
167
|
-
const
|
|
168
|
-
|
|
191
|
+
function applyPassToClient(passToClient, getObj) {
|
|
192
|
+
const objClient = {};
|
|
193
|
+
const objClientProps = [];
|
|
194
|
+
passToClient.forEach((entry) => {
|
|
195
|
+
const entryNormalized = normalizePassToClientEntry(entry);
|
|
196
|
+
const { prop } = entryNormalized;
|
|
197
|
+
const { obj } = getObj(entryNormalized) ?? {};
|
|
198
|
+
if (!obj)
|
|
199
|
+
return;
|
|
169
200
|
// Get value from pageContext
|
|
170
|
-
const res = getPropVal(
|
|
201
|
+
const res = getPropVal(obj, prop);
|
|
171
202
|
if (!res)
|
|
172
203
|
return;
|
|
173
204
|
const { value } = res;
|
|
174
205
|
// Set value to pageContextClient
|
|
175
|
-
setPropVal(
|
|
206
|
+
setPropVal(objClient, prop, value);
|
|
207
|
+
objClientProps.push(prop);
|
|
176
208
|
});
|
|
177
|
-
return
|
|
209
|
+
return { objClient, objClientProps };
|
|
210
|
+
}
|
|
211
|
+
function normalizePassToClientEntry(entry) {
|
|
212
|
+
let once;
|
|
213
|
+
let prop;
|
|
214
|
+
if (typeof entry === 'string') {
|
|
215
|
+
prop = entry;
|
|
216
|
+
once = false;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
prop = entry.prop;
|
|
220
|
+
once = entry.once ?? false;
|
|
221
|
+
}
|
|
222
|
+
return { prop, once };
|
|
178
223
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { getCacheControl };
|
|
2
|
+
export { cacheControlDisable };
|
|
2
3
|
import type { PageConfigRuntime } from '../../../../types/PageConfig.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
declare function getCacheControl(pageId: string | null, pageConfigs: PageConfigRuntime[], statusCode: StatusCode): string;
|
|
4
|
+
declare const cacheControlDisable = "no-store, max-age=0";
|
|
5
|
+
declare function getCacheControl(pageId: string | null, pageConfigs: PageConfigRuntime[]): string;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
// TODO/now: move
|
|
1
2
|
export { getCacheControl };
|
|
3
|
+
export { cacheControlDisable };
|
|
2
4
|
import { getPageConfig } from '../../../../shared/page-configs/helpers.js';
|
|
3
5
|
import { getConfigValueRuntime } from '../../../../shared/page-configs/getConfigValueRuntime.js';
|
|
4
|
-
const
|
|
5
|
-
function getCacheControl(pageId, pageConfigs
|
|
6
|
-
// TO-DO/next-major-release: remove
|
|
6
|
+
const cacheControlDisable = 'no-store, max-age=0';
|
|
7
|
+
function getCacheControl(pageId, pageConfigs) {
|
|
8
|
+
// TO-DO/next-major-release: remove this line
|
|
7
9
|
if (pageConfigs.length === 0)
|
|
8
|
-
return
|
|
9
|
-
if (statusCode > 499)
|
|
10
|
-
return defaultValue;
|
|
10
|
+
return cacheControlDisable;
|
|
11
11
|
if (pageId) {
|
|
12
12
|
const pageConfig = getPageConfig(pageId, pageConfigs);
|
|
13
13
|
const configValue = getConfigValueRuntime(pageConfig, 'cacheControl', 'string');
|
|
@@ -18,5 +18,5 @@ function getCacheControl(pageId, pageConfigs, statusCode) {
|
|
|
18
18
|
// - Disabling caching by default is the safest strategy, because caching is problematic with authentication as described in https://github.com/vikejs/vike/issues/1275#issuecomment-1824366875
|
|
19
19
|
// - Are there use cases when we don't need to disable caching?
|
|
20
20
|
// - When there isn't any <script id="vike_pageContext" type="application/json"> then we can safely have caching. (We don't implement this exception because we're lazy and it's quite a rare situation.)
|
|
21
|
-
return
|
|
21
|
+
return cacheControlDisable;
|
|
22
22
|
}
|
|
@@ -28,6 +28,7 @@ declare function createHttpResponsePage(htmlRender: HtmlRender, renderHook: null
|
|
|
28
28
|
__getPageAssets: GetPageAssets;
|
|
29
29
|
_globalContext: GlobalContextServerInternal;
|
|
30
30
|
abortStatusCode?: AbortStatusCode;
|
|
31
|
+
headersResponse?: Headers;
|
|
31
32
|
}): Promise<HttpResponse>;
|
|
32
33
|
declare function createHttpResponse404(errMsg404: string): HttpResponse;
|
|
33
34
|
declare function createHttpResponseBaseIsMissing(urlOriginal: string, baseServer: string): HttpResponse;
|
|
@@ -9,8 +9,8 @@ import { assert, assertWarning, escapeHtml } from '../utils.js';
|
|
|
9
9
|
import { getErrorPageId, isErrorPage } from '../../../shared/error-page.js';
|
|
10
10
|
import { getHttpResponseBody, getHttpResponseBodyStreamHandlers } from './getHttpResponseBody.js';
|
|
11
11
|
import { getEarlyHints } from './getEarlyHints.js';
|
|
12
|
-
import { getCacheControl } from './createHttpResponse/getCacheControl.js';
|
|
13
12
|
import { assertNoInfiniteHttpRedirect } from './createHttpResponse/assertNoInfiniteHttpRedirect.js';
|
|
13
|
+
import { cacheControlDisable } from './createHttpResponse/getCacheControl.js';
|
|
14
14
|
async function createHttpResponsePage(htmlRender, renderHook, pageContext) {
|
|
15
15
|
let statusCode = pageContext.abortStatusCode;
|
|
16
16
|
if (!statusCode) {
|
|
@@ -29,10 +29,13 @@ async function createHttpResponsePage(htmlRender, renderHook, pageContext) {
|
|
|
29
29
|
}
|
|
30
30
|
const earlyHints = getEarlyHints(await pageContext.__getPageAssets());
|
|
31
31
|
const headers = [];
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
headers.push([
|
|
35
|
-
}
|
|
32
|
+
const headersResponse = pageContext.headersResponse || new Headers();
|
|
33
|
+
headersResponse.forEach((value, key) => {
|
|
34
|
+
headers.push([key, value]);
|
|
35
|
+
});
|
|
36
|
+
// An 5xx error page shouldn't be cached (it should be temporary)
|
|
37
|
+
if (statusCode >= 500)
|
|
38
|
+
headersResponse.set('Cache-Control', cacheControlDisable);
|
|
36
39
|
return createHttpResponse(statusCode, 'text/html;charset=utf-8', headers, htmlRender, earlyHints, renderHook);
|
|
37
40
|
}
|
|
38
41
|
function createHttpResponse404(errMsg404) {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export { loadPageConfigsLazyServerSideAndExecHook };
|
|
2
2
|
export type { PageContext_loadPageConfigsLazyServerSide };
|
|
3
3
|
export type { PageConfigsLazy };
|
|
4
|
+
import { type VikeConfigPublicPageLazy } from '../../../shared/getPageFiles.js';
|
|
4
5
|
import { PromiseType } from '../utils.js';
|
|
5
6
|
import { PageContextGetPageAssets, type PageAsset } from './getPageAssets.js';
|
|
6
7
|
import { type PageContextDebugRouteMatches } from './debugPageFiles.js';
|
|
7
8
|
import type { GlobalContextServerInternal } from '../globalContext.js';
|
|
8
9
|
import { type PageContextExecHookServer } from './execHookServer.js';
|
|
10
|
+
import type { PassToClient } from '../html/serializeContext.js';
|
|
9
11
|
type PageContextExecuteHook = Omit<PageContextExecHookServer, keyof Awaited<ReturnType<typeof loadPageConfigsLazyServerSide>>>;
|
|
10
12
|
type PageContext_loadPageConfigsLazyServerSide = PageContextGetPageAssets & PageContextDebugRouteMatches & {
|
|
11
13
|
pageId: string;
|
|
@@ -13,19 +15,21 @@ type PageContext_loadPageConfigsLazyServerSide = PageContextGetPageAssets & Page
|
|
|
13
15
|
_globalContext: GlobalContextServerInternal;
|
|
14
16
|
};
|
|
15
17
|
type PageConfigsLazy = PromiseType<ReturnType<typeof loadPageConfigsLazyServerSide>>;
|
|
16
|
-
declare function loadPageConfigsLazyServerSideAndExecHook<PageContext extends PageContext_loadPageConfigsLazyServerSide & PageContextExecuteHook>(pageContext: PageContext): Promise<PageContext &
|
|
18
|
+
declare function loadPageConfigsLazyServerSideAndExecHook<PageContext extends PageContext_loadPageConfigsLazyServerSide & PageContextExecuteHook>(pageContext: PageContext): Promise<PageContext & VikeConfigPublicPageLazy & {
|
|
17
19
|
Page: unknown;
|
|
18
20
|
_isHtmlOnly: boolean;
|
|
19
|
-
_passToClient:
|
|
21
|
+
_passToClient: PassToClient;
|
|
20
22
|
_pageFilePathsLoaded: string[];
|
|
23
|
+
headersResponse: Headers;
|
|
21
24
|
} & {
|
|
22
25
|
__getPageAssets: () => Promise<PageAsset[]>;
|
|
23
26
|
}>;
|
|
24
|
-
declare function loadPageConfigsLazyServerSide(pageContext: PageContext_loadPageConfigsLazyServerSide): Promise<
|
|
27
|
+
declare function loadPageConfigsLazyServerSide(pageContext: PageContext_loadPageConfigsLazyServerSide): Promise<VikeConfigPublicPageLazy & {
|
|
25
28
|
Page: unknown;
|
|
26
29
|
_isHtmlOnly: boolean;
|
|
27
|
-
_passToClient:
|
|
30
|
+
_passToClient: PassToClient;
|
|
28
31
|
_pageFilePathsLoaded: string[];
|
|
32
|
+
headersResponse: Headers;
|
|
29
33
|
} & {
|
|
30
34
|
__getPageAssets: () => Promise<PageAsset[]>;
|
|
31
35
|
}>;
|
|
@@ -2,19 +2,22 @@ export { loadPageConfigsLazyServerSideAndExecHook };
|
|
|
2
2
|
import { getPageFilesServerSide } from '../../../shared/getPageFiles.js';
|
|
3
3
|
import { resolveVikeConfigPublicPageLazy } from '../../../shared/page-configs/resolveVikeConfigPublic.js';
|
|
4
4
|
import { analyzePageClientSideInit } from '../../../shared/getPageFiles/analyzePageClientSide.js';
|
|
5
|
-
import { assertUsage, assertWarning, hasProp, objectAssign
|
|
5
|
+
import { assertUsage, assertWarning, hasProp, objectAssign } from '../utils.js';
|
|
6
6
|
import { getPageAssets } from './getPageAssets.js';
|
|
7
7
|
import { debugPageFiles } from './debugPageFiles.js';
|
|
8
8
|
import { findPageConfig } from '../../../shared/page-configs/findPageConfig.js';
|
|
9
9
|
import { analyzePage } from './analyzePage.js';
|
|
10
10
|
import { loadConfigValues } from '../../../shared/page-configs/loadConfigValues.js';
|
|
11
11
|
import { execHookServer } from './execHookServer.js';
|
|
12
|
+
import { getCacheControl } from './createHttpResponse/getCacheControl.js';
|
|
13
|
+
// TODO/now: rename?
|
|
12
14
|
async function loadPageConfigsLazyServerSideAndExecHook(pageContext) {
|
|
13
15
|
const pageContextAddendum = await loadPageConfigsLazyServerSide(pageContext);
|
|
14
16
|
objectAssign(pageContext, pageContextAddendum);
|
|
15
17
|
await execHookServer('onCreatePageContext', pageContext);
|
|
16
18
|
return pageContext;
|
|
17
19
|
}
|
|
20
|
+
// TODO/now: rename?
|
|
18
21
|
async function loadPageConfigsLazyServerSide(pageContext) {
|
|
19
22
|
const pageConfig = findPageConfig(pageContext._globalContext._pageConfigs, pageContext.pageId); // Make pageConfig globally available as pageContext._pageConfig ?
|
|
20
23
|
const globalContext = pageContext._globalContext;
|
|
@@ -36,8 +39,9 @@ async function loadPageConfigsLazyServerSide(pageContext) {
|
|
|
36
39
|
}
|
|
37
40
|
else {
|
|
38
41
|
configPublicPageLazy.from.configsCumulative.passToClient?.values.forEach((v) => {
|
|
39
|
-
const { value
|
|
40
|
-
|
|
42
|
+
const { value } = v;
|
|
43
|
+
// const { definedAt } = v
|
|
44
|
+
// assertUsage(isArrayOfStrings(value), `+passToClient value defined at ${definedAt}${errMsg}`)
|
|
41
45
|
passToClient.push(...value);
|
|
42
46
|
});
|
|
43
47
|
}
|
|
@@ -48,6 +52,7 @@ async function loadPageConfigsLazyServerSide(pageContext) {
|
|
|
48
52
|
_isHtmlOnly: isHtmlOnly,
|
|
49
53
|
_passToClient: passToClient,
|
|
50
54
|
_pageFilePathsLoaded: pageFilesLoaded.map((p) => p.filePath),
|
|
55
|
+
headersResponse: resolveHeadersResponse(pageContext, pageContextAddendum),
|
|
51
56
|
});
|
|
52
57
|
objectAssign(pageContextAddendum, {
|
|
53
58
|
__getPageAssets: async () => {
|
|
@@ -100,6 +105,7 @@ async function loadPageConfigsLazyServerSide(pageContext) {
|
|
|
100
105
|
});
|
|
101
106
|
return pageContextAddendum;
|
|
102
107
|
}
|
|
108
|
+
// TODO/now: rename?
|
|
103
109
|
async function loadPageUserFiles(pageFilesAll, pageConfig, pageConfigGlobal, pageId, isDev) {
|
|
104
110
|
const pageFilesServerSide = getPageFilesServerSide(pageFilesAll, pageId);
|
|
105
111
|
const pageConfigLoaded = !pageConfig ? null : await loadConfigValues(pageConfig, isDev);
|
|
@@ -110,3 +116,23 @@ async function loadPageUserFiles(pageFilesAll, pageConfig, pageConfigGlobal, pag
|
|
|
110
116
|
pageFilesLoaded: pageFilesServerSide,
|
|
111
117
|
};
|
|
112
118
|
}
|
|
119
|
+
function resolveHeadersResponse(
|
|
120
|
+
// TODO/now: merge pageContextAddendum with pageContext
|
|
121
|
+
pageContext, pageContextAddendum) {
|
|
122
|
+
const headersResponse = mergeHeaders(pageContextAddendum.config.headersResponse);
|
|
123
|
+
if (!headersResponse.get('Cache-Control')) {
|
|
124
|
+
const cacheControl = getCacheControl(pageContext.pageId, pageContext._globalContext._pageConfigs);
|
|
125
|
+
if (cacheControl)
|
|
126
|
+
headersResponse.set('Cache-Control', cacheControl);
|
|
127
|
+
}
|
|
128
|
+
return headersResponse;
|
|
129
|
+
}
|
|
130
|
+
function mergeHeaders(headersList = []) {
|
|
131
|
+
const headersMerged = new Headers();
|
|
132
|
+
headersList.forEach((headers) => {
|
|
133
|
+
new Headers(headers).forEach((value, key) => {
|
|
134
|
+
headersMerged.append(key, value);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
return headersMerged;
|
|
138
|
+
}
|
|
@@ -143,8 +143,9 @@ declare function prerenderPage(pageContext: PageContextCreated & PageConfigsLazy
|
|
|
143
143
|
} & import("../../../shared/getPageFiles.js").VikeConfigPublicPageLazy & {
|
|
144
144
|
Page: unknown;
|
|
145
145
|
_isHtmlOnly: boolean;
|
|
146
|
-
_passToClient:
|
|
146
|
+
_passToClient: import("../html/serializeContext.js").PassToClient;
|
|
147
147
|
_pageFilePathsLoaded: string[];
|
|
148
|
+
headersResponse: Headers;
|
|
148
149
|
} & {
|
|
149
150
|
__getPageAssets: () => Promise<import("./getPageAssets.js").PageAsset[]>;
|
|
150
151
|
} & {
|
|
@@ -277,8 +278,9 @@ declare function prerenderPage(pageContext: PageContextCreated & PageConfigsLazy
|
|
|
277
278
|
} & import("../../../shared/getPageFiles.js").VikeConfigPublicPageLazy & {
|
|
278
279
|
Page: unknown;
|
|
279
280
|
_isHtmlOnly: boolean;
|
|
280
|
-
_passToClient:
|
|
281
|
+
_passToClient: import("../html/serializeContext.js").PassToClient;
|
|
281
282
|
_pageFilePathsLoaded: string[];
|
|
283
|
+
headersResponse: Headers;
|
|
282
284
|
} & {
|
|
283
285
|
__getPageAssets: () => Promise<import("./getPageAssets.js").PageAsset[]>;
|
|
284
286
|
} & {
|
|
@@ -14,6 +14,7 @@ import { preparePageContextForPublicUsageServer } from './preparePageContextForP
|
|
|
14
14
|
import { execHookGuard } from '../../../shared/route/execHookGuard.js';
|
|
15
15
|
import pc from '@brillout/picocolors';
|
|
16
16
|
import { isServerSideError } from '../../../shared/misc/isServerSideError.js';
|
|
17
|
+
// TODO/now: rename?
|
|
17
18
|
async function renderPageAlreadyRouted(pageContext) {
|
|
18
19
|
// pageContext.pageId can either be the:
|
|
19
20
|
// - ID of the page matching the routing, or the
|
|
@@ -170,6 +170,7 @@ async function renderPageOnError(errNominalPage, pageContextBegin, pageContextNo
|
|
|
170
170
|
return handleErrorWithoutErrorPage(pageContextErrorPageInit);
|
|
171
171
|
}
|
|
172
172
|
else {
|
|
173
|
+
// TODO/now: minor refactor
|
|
173
174
|
objectAssign(pageContextErrorPageInit, { pageId: errorPageId });
|
|
174
175
|
}
|
|
175
176
|
}
|
|
@@ -210,6 +210,10 @@ const configDefinitionsBuiltIn = {
|
|
|
210
210
|
env: { server: true },
|
|
211
211
|
global: true,
|
|
212
212
|
},
|
|
213
|
+
headersResponse: {
|
|
214
|
+
env: { server: true },
|
|
215
|
+
cumulative: true,
|
|
216
|
+
},
|
|
213
217
|
};
|
|
214
218
|
function getConfigEnv(configValueSources, configName) {
|
|
215
219
|
const configValueSource = getConfigValueSource(configValueSources, configName);
|
|
@@ -32,12 +32,10 @@ function getFilesystemRouteString(locationId) {
|
|
|
32
32
|
function getInheritanceRoot(locationId) {
|
|
33
33
|
return getLogicalPath(locationId, [
|
|
34
34
|
'renderer',
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
// - Not sure if it's a good idea? Could it make config inheritance confusing? Let's try for now and see how it goes.
|
|
40
|
-
// - TO-DO/eventually: update docs https://github.com/vikejs/vike/blob/5fcdc4d5094f1a4dcbefc0b481cdd30a205aef2d/docs/pages/filesystem-routing/%2BPage.mdx?plain=1#L98
|
|
35
|
+
// Enable hooks defined by vike-{react,vue,solid} such as +onBeforeRenderClient to be defined at the root directory. In other words, avoid following error:
|
|
36
|
+
// ```bash
|
|
37
|
+
// [11:09:43.072][/test-preview.test.ts][npm run preview][stderr] Error: [vike][Wrong Usage] /+onBeforeRenderClient.ts sets the value of the config onBeforeRenderClient which is a custom config that is defined with https://vike.dev/meta at a path that doesn't apply to / — see https://vike.dev/config#inheritance
|
|
38
|
+
// ```
|
|
41
39
|
'pages',
|
|
42
40
|
]);
|
|
43
41
|
}
|
|
@@ -9,10 +9,10 @@ import type { GlobalContextServerInternal } from '../node/runtime/globalContext.
|
|
|
9
9
|
import type { GlobalContextClientInternal } from '../client/runtime-client-routing/globalContext.js';
|
|
10
10
|
import { type Hook } from './hooks/getHook.js';
|
|
11
11
|
declare const getGlobalContextSyncErrMsg = "The global context isn't set yet, call getGlobalContextSync() later or use getGlobalContext() instead.";
|
|
12
|
-
declare function createGlobalContextShared<GlobalContextAddendum extends
|
|
12
|
+
declare function createGlobalContextShared<GlobalContextAddendum extends Record<string, any>>(virtualFileExports: unknown, globalObject: {
|
|
13
13
|
globalContext?: Record<string, unknown>;
|
|
14
14
|
onCreateGlobalContextHooks?: Hook[];
|
|
15
|
-
},
|
|
15
|
+
}, addGlobalContextAsync?: (globalContext: GlobalContextBase) => Promise<GlobalContextAddendum>, addGlobalContextSync?: (globalContext: GlobalContextBase) => GlobalContextAddendum): Promise<{
|
|
16
16
|
/**
|
|
17
17
|
* Useful for distinguishing `globalContext` from other objects and narrowing down TypeScript unions.
|
|
18
18
|
*
|
|
@@ -35,7 +35,7 @@ declare function createGlobalContextShared<GlobalContextAddendum extends object>
|
|
|
35
35
|
pages: {
|
|
36
36
|
[k: string]: import("./page-configs/resolveVikeConfigPublic.js").VikeConfigPublicPageEager;
|
|
37
37
|
};
|
|
38
|
-
} &
|
|
38
|
+
} & GlobalContextAddendum>;
|
|
39
39
|
type GlobalContextBasePublic = Pick<GlobalContextBase, 'config' | 'pages' | 'isGlobalContext'>;
|
|
40
40
|
type GlobalContextBase = ReturnType<typeof createGlobalContextBase>;
|
|
41
41
|
declare function createGlobalContextBase(virtualFileExports: unknown): {
|
|
@@ -7,10 +7,26 @@ import { execHookGlobal } from './hooks/execHook.js';
|
|
|
7
7
|
import { prepareGlobalContextForPublicUsage } from './prepareGlobalContextForPublicUsage.js';
|
|
8
8
|
import { getHookFromPageConfigGlobalCumulative } from './hooks/getHook.js';
|
|
9
9
|
const getGlobalContextSyncErrMsg = "The global context isn't set yet, call getGlobalContextSync() later or use getGlobalContext() instead.";
|
|
10
|
-
async function createGlobalContextShared(virtualFileExports, globalObject,
|
|
10
|
+
async function createGlobalContextShared(virtualFileExports, globalObject, addGlobalContextAsync, addGlobalContextSync) {
|
|
11
11
|
const globalContext = createGlobalContextBase(virtualFileExports);
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
let isNewGlobalContext;
|
|
13
|
+
if (!globalObject.globalContext) {
|
|
14
|
+
globalObject.globalContext = globalContext;
|
|
15
|
+
isNewGlobalContext = false;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
isNewGlobalContext = true;
|
|
19
|
+
}
|
|
20
|
+
if (addGlobalContextSync &&
|
|
21
|
+
// TODO/next-major-release: remove
|
|
22
|
+
globalContext._pageConfigs.length > 0) {
|
|
23
|
+
const globalContextAddendum = addGlobalContextSync?.(globalContext);
|
|
24
|
+
objectAssign(globalContext, globalContextAddendum);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const globalContextAddendum = await addGlobalContextAsync?.(globalContext);
|
|
28
|
+
objectAssign(globalContext, globalContextAddendum);
|
|
29
|
+
}
|
|
14
30
|
const onCreateGlobalContextHooks = getHookFromPageConfigGlobalCumulative(globalContext._pageConfigGlobal, 'onCreateGlobalContext');
|
|
15
31
|
let hooksCalled = false;
|
|
16
32
|
if (!hooksAreEqual(globalObject.onCreateGlobalContextHooks ?? [], onCreateGlobalContextHooks)) {
|
|
@@ -18,10 +34,7 @@ async function createGlobalContextShared(virtualFileExports, globalObject, addGl
|
|
|
18
34
|
await execHookGlobal('onCreateGlobalContext', globalContext._pageConfigGlobal, null, globalContext, prepareGlobalContextForPublicUsage);
|
|
19
35
|
hooksCalled = true;
|
|
20
36
|
}
|
|
21
|
-
if (
|
|
22
|
-
globalObject.globalContext = globalContext;
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
37
|
+
if (isNewGlobalContext) {
|
|
25
38
|
// Singleton: ensure all `globalContext` user-land references are preserved & updated.
|
|
26
39
|
if (hooksCalled) {
|
|
27
40
|
objectReplace(globalObject.globalContext, globalContext);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { loadPageRoutes };
|
|
2
|
+
export { loadPageRoutesSync };
|
|
2
3
|
export type { PageRoutes };
|
|
3
4
|
export type { RouteType };
|
|
4
5
|
import type { PageFile } from '../getPageFiles.js';
|
|
@@ -28,3 +29,7 @@ declare function loadPageRoutes(pageFilesAll: PageFile[], pageConfigs: PageConfi
|
|
|
28
29
|
pageRoutes: PageRoutes;
|
|
29
30
|
onBeforeRouteHook: null | Hook;
|
|
30
31
|
}>;
|
|
32
|
+
declare function loadPageRoutesSync(pageFilesAll: PageFile[], pageConfigs: PageConfigRuntime[], pageConfigGlobal: PageConfigGlobalRuntime, allPageIds: string[]): {
|
|
33
|
+
pageRoutes: PageRoutes;
|
|
34
|
+
onBeforeRouteHook: null | Hook;
|
|
35
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { loadPageRoutes };
|
|
2
|
+
export { loadPageRoutesSync };
|
|
2
3
|
import { isErrorPageId } from '../error-page.js';
|
|
3
4
|
import { assert, assertUsage, hasProp, slice } from './utils.js';
|
|
4
5
|
import { deduceRouteStringFromFilesystemPath } from './deduceRouteStringFromFilesystemPath.js';
|
|
@@ -10,8 +11,13 @@ import { getHookFromPageConfigGlobal, getHookTimeoutDefault } from '../hooks/get
|
|
|
10
11
|
async function loadPageRoutes(
|
|
11
12
|
// Remove all arguments and use GlobalContextServerInternal instead?
|
|
12
13
|
pageFilesAll, pageConfigs, pageConfigGlobal, allPageIds) {
|
|
13
|
-
// TO-DO/next-major-release: remove
|
|
14
|
+
// TO-DO/next-major-release: remove this line, remove this function, rename loadPageRoutesSync() to loadPageRoutes()
|
|
14
15
|
await Promise.all(pageFilesAll.filter((p) => p.fileType === '.page.route').map((p) => p.loadFile?.()));
|
|
16
|
+
return loadPageRoutesSync(pageFilesAll, pageConfigs, pageConfigGlobal, allPageIds);
|
|
17
|
+
}
|
|
18
|
+
function loadPageRoutesSync(
|
|
19
|
+
// Remove all arguments and use GlobalContextServerInternal instead?
|
|
20
|
+
pageFilesAll, pageConfigs, pageConfigGlobal, allPageIds) {
|
|
15
21
|
const { onBeforeRouteHook, filesystemRoots } = getGlobalHooks(pageFilesAll, pageConfigs, pageConfigGlobal);
|
|
16
22
|
const pageRoutes = getPageRoutes(filesystemRoots, pageFilesAll, pageConfigs, allPageIds);
|
|
17
23
|
return { pageRoutes, onBeforeRouteHook };
|
|
@@ -44,6 +44,7 @@ import type { Vike, VikePackages } from './VikeNamespace.js';
|
|
|
44
44
|
import type { HooksTimeoutProvidedByUser } from '../shared/hooks/getHook.js';
|
|
45
45
|
import type { GlobalContext, PageContextClient, PageContextServer } from './PageContext.js';
|
|
46
46
|
import type { InlineConfig } from 'vite';
|
|
47
|
+
import type { PassToClient } from '../node/runtime/html/serializeContext.js';
|
|
47
48
|
type HookNameOld = HookName | HookNameOldDesign;
|
|
48
49
|
type HookName = HookNamePage | HookNameGlobal;
|
|
49
50
|
type HookNamePage = 'onHydrationEnd' | 'onBeforePrerenderStart' | 'onBeforeRender' | 'onPageTransitionStart' | 'onPageTransitionEnd' | 'onRenderHtml' | 'onRenderClient' | 'guard' | 'data' | 'onData' | 'route';
|
|
@@ -362,7 +363,7 @@ type ConfigBuiltIn = {
|
|
|
362
363
|
*
|
|
363
364
|
* https://vike.dev/passToClient
|
|
364
365
|
*/
|
|
365
|
-
passToClient?:
|
|
366
|
+
passToClient?: PassToClient | ImportString;
|
|
366
367
|
/** Hook called when page is rendered on the client-side.
|
|
367
368
|
*
|
|
368
369
|
* https://vike.dev/onRenderClient
|
|
@@ -508,6 +509,12 @@ type ConfigBuiltIn = {
|
|
|
508
509
|
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
|
|
509
510
|
*/
|
|
510
511
|
cacheControl?: string;
|
|
512
|
+
/**
|
|
513
|
+
* Add HTTP headers to the HTTP response.
|
|
514
|
+
*
|
|
515
|
+
* https://vike.dev/headers#response
|
|
516
|
+
*/
|
|
517
|
+
headersResponse?: HeadersInit;
|
|
511
518
|
/**
|
|
512
519
|
* Make development/preview server available over LAN and public addresses.
|
|
513
520
|
*
|
|
@@ -561,6 +568,7 @@ type ConfigBuiltInResolved = {
|
|
|
561
568
|
redirects?: Record<string, string>[];
|
|
562
569
|
prerender?: Exclude<Config['prerender'], ImportString | undefined>[];
|
|
563
570
|
middleware?: Function[];
|
|
571
|
+
headersResponse?: HeadersInit[];
|
|
564
572
|
};
|
|
565
573
|
type ConfigMeta = Record<string, ConfigDefinition>;
|
|
566
574
|
type ImportString = `import:${string}`;
|