UNPKG

vike

Version:

The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.

89 lines (88 loc) 4.4 kB
export { createGlobalContextShared }; export { getGlobalContextSyncErrMsg }; import { changeEnumerable, objectAssign, objectReplace, unique } from './utils.js'; import { parseVirtualFileExports } from './getPageFiles/parseVirtualFileExports.js'; import { resolveVikeConfigPublicGlobal, resolveVikeConfigPublicPageEager, } from './page-configs/resolveVikeConfigPublic.js'; import { execHookGlobal } from './hooks/execHook.js'; import { prepareGlobalContextForPublicUsage } from './prepareGlobalContextForPublicUsage.js'; import { getHookFromPageConfigGlobalCumulative } from './hooks/getHook.js'; const getGlobalContextSyncErrMsg = "The global context isn't set yet, call getGlobalContextSync() later or use getGlobalContext() instead."; async function createGlobalContextShared(virtualFileExports, globalObject, addGlobalContext) { const globalContext = createGlobalContextBase(virtualFileExports); const globalContextAddendum = await addGlobalContext?.(globalContext); objectAssign(globalContext, globalContextAddendum); const onCreateGlobalContextHooks = getHookFromPageConfigGlobalCumulative(globalContext._pageConfigGlobal, 'onCreateGlobalContext'); let hooksCalled = false; if (!hooksAreEqual(globalObject.onCreateGlobalContextHooks ?? [], onCreateGlobalContextHooks)) { globalObject.onCreateGlobalContextHooks = onCreateGlobalContextHooks; await execHookGlobal('onCreateGlobalContext', globalContext._pageConfigGlobal, null, globalContext, prepareGlobalContextForPublicUsage); hooksCalled = true; } if (!globalObject.globalContext) { globalObject.globalContext = globalContext; } else { // Singleton: ensure all `globalContext` user-land references are preserved & updated. if (hooksCalled) { objectReplace(globalObject.globalContext, globalContext); } else { // We don't use objectReplace() in order to keep user-land properties. objectAssign(globalObject.globalContext, globalContext, true); } } return globalObject.globalContext; } function createGlobalContextBase(virtualFileExports) { const { pageFilesAll, allPageIds, pageConfigs, pageConfigGlobal, vikeConfigPublicGlobal, vikeConfigPublicPagesEager, } = getConfigsAll(virtualFileExports); const globalContext = { /** * Useful for distinguishing `globalContext` from other objects and narrowing down TypeScript unions. * * https://vike.dev/globalContext#typescript */ isGlobalContext: true, _isOriginalObject: true, _virtualFileExports: virtualFileExports, _pageFilesAll: pageFilesAll, _pageConfigs: pageConfigs, _pageConfigGlobal: pageConfigGlobal, _allPageIds: allPageIds, _vikeConfigPublicGlobal: vikeConfigPublicGlobal, config: vikeConfigPublicGlobal.config, pages: vikeConfigPublicPagesEager, }; changeEnumerable(globalContext, '_isOriginalObject', false); return globalContext; } function getConfigsAll(virtualFileExports) { const { pageFilesAll, pageConfigs, pageConfigGlobal } = parseVirtualFileExports(virtualFileExports); const allPageIds = getAllPageIds(pageFilesAll, pageConfigs); const vikeConfigPublicGlobal = resolveVikeConfigPublicGlobal({ pageConfigGlobalValues: pageConfigGlobal.configValues, }); const vikeConfigPublicPagesEager = Object.fromEntries(pageConfigs.map((pageConfig) => { return resolveVikeConfigPublicPageEager(pageConfigGlobal.configValues, pageConfig, pageConfig.configValues); })); return { pageFilesAll, allPageIds, pageConfigs, pageConfigGlobal, vikeConfigPublicGlobal, vikeConfigPublicPagesEager, }; } function getAllPageIds(pageFilesAll, pageConfigs) { const fileIds = pageFilesAll.filter(({ isDefaultPageFile }) => !isDefaultPageFile).map(({ pageId }) => pageId); const allPageIds = unique(fileIds); const allPageIds2 = pageConfigs.map((p) => p.pageId); return [...allPageIds, ...allPageIds2]; } function hooksAreEqual(hooks1, hooks2) { const hooksFn1 = hooks1.map((hook) => hook.hookFn); const hooksFn2 = hooks2.map((hook) => hook.hookFn); return (hooksFn1.every((hook) => hooksFn2.includes(hook)) && // hooksFn2.every((hook) => hooksFn1.includes(hook))); }