UNPKG

telefunc

Version:

Remote functions. Instead of API.

81 lines (80 loc) 4.24 kB
export { loadTelefuncFilesUsingVite }; import { importServerProductionEntry } from '@brillout/vite-plugin-server-entry/runtime'; import { assert, assertWarning, getNodeEnv, hasProp, isObject, isProduction, isTelefuncFilePath } from '../utils.js'; import { loadTelefuncFilesWithImportBuild } from './loadTelefuncFilesUsingVite/loadBuildEntry.js'; import { getViteDevServer } from '../globalContext.js'; import { VIRTUAL_FILE_ENTRY_ID } from '../../vite/plugins/pluginVirtualFileEntry/VIRTUAL_FILE_ENTRY_ID.js'; async function loadTelefuncFilesUsingVite(runContext, failOnFailure) { const res = await loadVirtualFile(failOnFailure); if (!res) return null; const { moduleExports, viteProvider } = res; assert(isObject(moduleExports), { moduleExports, viteProvider }); assert(hasProp(moduleExports, 'telefuncFilesGlob'), { moduleExports, viteProvider }); const telefuncFilesGlob = moduleExports.telefuncFilesGlob; const { telefuncFilesLoaded, telefuncFilesAll } = await loadViteGlobbedFiles(telefuncFilesGlob, runContext); assert(isObjectOfObjects(telefuncFilesLoaded)); return { telefuncFilesLoaded, viteProvider, telefuncFilesAll }; } async function loadVirtualFile(failOnFailure) { if (globalThis.__TELEFUNC__IS_NON_RUNNABLE_DEV) { // We don't directly use import() because: // - Avoid Cloudflare Workers (without @cloudflare/vite-plugin) to try to bundle `import('virtual:id')`. // - Using import() seems to lead to a Vite HMR bug: // ```js // assert(false) // // This line breaks the HMR of regular (runnable) apps, even though (as per the assert() above) it's never run. It seems to be a Vite bug: handleHotUpdate() receives an empty `modules` list. // import('virtual:vike:global-entry:server') // ``` const moduleExports = await __TELEFUNC__DYNAMIC_IMPORT('virtual:vite:telefunc:entry'); return { moduleExports, viteProvider: 'Vite with `import()`' }; } const viteDevServer = getViteDevServer(); if (viteDevServer) { const moduleExports = await viteDevServer.ssrLoadModule(VIRTUAL_FILE_ENTRY_ID, { fixStacktrace: true }); return { moduleExports, viteProvider: 'Vite with `ssrLoadModule()`' }; } else { let moduleExports; moduleExports = await loadTelefuncFilesWithImportBuild(); if (moduleExports === null) { const tolerateDoesNotExist = !failOnFailure; const success = await importServerProductionEntry({ tolerateDoesNotExist }); moduleExports = await loadTelefuncFilesWithImportBuild(); if (success === false) { assert(tolerateDoesNotExist); assert(!moduleExports); return null; } assert(moduleExports); } else { assert(moduleExports); } assertProd(); return { moduleExports, viteProvider: 'Vite with `@brillout/vite-plugin-server-entry`' }; } } function assertProd() { if (!isProduction()) { const env = getNodeEnv(); assert(env === undefined || env === 'development' || env === ''); assertWarning(false, `This seems to be a production environment yet process.env.NODE_ENV is ${JSON.stringify(env)}. Set it to a different value such as "production" or "staging".`, { onlyOnce: true }); } } function isObjectOfObjects(obj) { return isObject(obj) && Object.values(obj).every(isObject); } // Vite's import.meta.glob() returns promises async function loadViteGlobbedFiles(telefuncFilesGlob, runContext) { const telefuncFilesAll = Object.keys(telefuncFilesGlob); const telefuncFilesLoaded = Object.fromEntries(await Promise.all(Object.entries(telefuncFilesGlob) .filter(([telefuncFilePath]) => { assert(isTelefuncFilePath(telefuncFilePath)); assert(isTelefuncFilePath(runContext.telefuncFilePath)); return telefuncFilePath === runContext.telefuncFilePath; }) .map(async ([telefuncFilePath, loadModuleExports]) => [telefuncFilePath, await loadModuleExports()]))); assert(Object.keys(telefuncFilesLoaded).length <= 1); return { telefuncFilesAll, telefuncFilesLoaded }; }