one
Version:
One is a new React Framework that makes Vite serve both native and web.
632 lines • 24 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
value: true
}), mod);
var workerHandler_exports = {};
__export(workerHandler_exports, {
createWorkerHandler: () => createWorkerHandler
});
module.exports = __toCommonJS(workerHandler_exports);
var import_constants = require("../constants.cjs");
var import_createHandleRequest = require("../createHandleRequest.cjs");
var import_cleanUrl = require("../utils/cleanUrl.cjs");
var import_isResponse = require("../utils/isResponse.cjs");
var import_resolveResponse = require("../vite/resolveResponse.cjs");
var import_ssrLoaderData = require("./ssrLoaderData.cjs");
var import_staticHtmlFetcher = require("./staticHtmlFetcher.cjs");
function createWorkerHandler(options) {
const {
oneOptions
} = options;
let currentLazyRoutes = options.lazyRoutes;
let compiledManifest = (0, import_createHandleRequest.compileManifest)(options.buildInfo.manifest);
let routeToBuildInfo = options.buildInfo.routeToBuildInfo;
let routeMap = options.buildInfo.routeMap;
let currentPreloads = options.buildInfo.preloads;
let currentCssPreloads = options.buildInfo.cssPreloads;
const debugRouter = process.env.ONE_DEBUG_ROUTER;
const redirects = oneOptions.web?.redirects;
let compiledRedirects = null;
if (redirects?.length) {
compiledRedirects = redirects.map(r => {
const regexSource = r.source.replace(/:(\w+)/g, (_, name) => `(?<${name}>[^/]+)`);
return {
regex: new RegExp(`^${regexSource}$`),
destination: r.destination,
permanent: r.permanent || false
};
});
}
const useStreaming = !process.env.ONE_BUFFERED_SSR;
const htmlHeaders = {
"content-type": "text/html"
};
const ssrHtmlHeaders = {
"content-type": "text/html",
"cache-control": "no-cache"
};
const loaderCache = /* @__PURE__ */new Map();
const moduleImportCache = /* @__PURE__ */new Map();
const loaderCacheFnMap = /* @__PURE__ */new Map();
const pendingLoaderResults = /* @__PURE__ */new Map();
let render = null;
let renderStream = null;
let renderLoading = null;
let renderGeneration = 0;
function ensureRenderLoaded() {
if (render) return;
if (renderLoading) return renderLoading;
const gen = ++renderGeneration;
renderLoading = (async () => {
const entry = await currentLazyRoutes.serverEntry();
if (gen !== renderGeneration) return;
render = entry.default.render;
renderStream = entry.default.renderStream || null;
})();
return renderLoading;
}
function findNearestNotFoundPath(urlPath) {
let cur = urlPath;
while (cur) {
const parent = cur.lastIndexOf("/") > 0 ? cur.slice(0, cur.lastIndexOf("/")) : "";
if (routeMap[`${parent}/+not-found`]) return `${parent}/+not-found`;
if (!parent) break;
cur = parent;
}
return "/+not-found";
}
function make404LoaderJs(path, logReason) {
const nfPath = findNearestNotFoundPath(path);
if (logReason) console.error(`[one] 404 loader for ${path}: ${logReason}`);
return `export function loader(){return{__oneError:404,__oneErrorMessage:'Not Found',__oneNotFoundPath:${JSON.stringify(nfPath)}}}`;
}
async function readStaticHtml(htmlPath) {
const fetchStaticHtml = (0, import_staticHtmlFetcher.getFetchStaticHtml)();
if (fetchStaticHtml) return await fetchStaticHtml(htmlPath);
if (debugRouter) {
console.warn(`[one/worker] no fetchStaticHtml set, cannot read ${htmlPath}`);
}
return null;
}
function resolveLoaderSync(lazyKey) {
const cacheKey = lazyKey || "";
const cached = loaderCache.get(cacheKey);
if (cached !== void 0) return cached;
return (async () => {
let routeExported;
if (moduleImportCache.has(cacheKey)) {
routeExported = moduleImportCache.get(cacheKey);
} else if (lazyKey && currentLazyRoutes.pages[lazyKey]) {
routeExported = await currentLazyRoutes.pages[lazyKey]();
moduleImportCache.set(cacheKey, routeExported);
} else {
console.warn(`[one/worker] no lazy route for ${cacheKey}`);
loaderCache.set(cacheKey, null);
return null;
}
const loader = routeExported?.loader || null;
loaderCache.set(cacheKey, loader);
loaderCacheFnMap.set(cacheKey, routeExported?.loaderCache ?? null);
return loader;
})();
}
async function importAndRunLoader(routeId, lazyKey, loaderProps) {
if (!lazyKey) return {
loaderData: void 0,
routeId
};
const cacheMapKey = lazyKey;
const loaderCacheFn = loaderCacheFnMap.get(cacheMapKey);
let coalFullKey;
let coalTtl = 0;
if (loaderCacheFn) {
const cacheResult = loaderCacheFn(loaderProps?.params, loaderProps?.request);
const cacheKey = typeof cacheResult === "string" ? cacheResult : cacheResult?.key;
coalTtl = typeof cacheResult === "string" ? 0 : cacheResult?.ttl ?? 0;
if (cacheKey != null) {
coalFullKey = routeId + "\0" + cacheKey;
const existing = pendingLoaderResults.get(coalFullKey);
if (existing && (!existing.expires || Date.now() < existing.expires)) {
const loaderData = await existing.promise;
return {
loaderData,
routeId
};
}
}
}
try {
const loaderOrPromise = resolveLoaderSync(lazyKey);
const loader = loaderOrPromise instanceof Promise ? await loaderOrPromise : loaderOrPromise;
if (!loader) return {
loaderData: void 0,
routeId
};
if (coalFullKey) {
const promise = loader(loaderProps);
const entry = {
promise,
expires: 0
};
pendingLoaderResults.set(coalFullKey, entry);
promise.then(() => {
entry.expires = coalTtl > 0 ? Date.now() + coalTtl : 0;
if (coalTtl <= 0) Promise.resolve().then(() => pendingLoaderResults.delete(coalFullKey));
}, () => pendingLoaderResults.delete(coalFullKey));
const loaderData2 = await promise;
return {
loaderData: loaderData2,
routeId
};
}
const loaderData = await loader(loaderProps);
return {
loaderData,
routeId
};
} catch (err) {
if ((0, import_isResponse.isResponse)(err)) throw err;
if (err?.code === "ENOENT") return {
loaderData: void 0,
routeId,
isEnoent: true
};
console.error(`[one] Error running loader for ${routeId}:`, err);
return {
loaderData: void 0,
routeId
};
}
}
const requestHandlers = {
async handleStaticFile() {
return null;
},
async handleAPI({
route
}) {
if (currentLazyRoutes.api[route.page]) {
return await currentLazyRoutes.api[route.page]();
}
console.warn(`[one/worker] no lazy API route for ${route.page}`);
return null;
},
async loadMiddleware(route) {
if (currentLazyRoutes.middlewares[route.contextKey]) {
return await currentLazyRoutes.middlewares[route.contextKey]();
}
console.warn(`[one/worker] no lazy middleware for ${route.contextKey}`);
return null;
},
async handleLoader({
route,
loaderProps
}) {
const routeFile = route.routeFile || route.file;
let loader;
try {
const loaderResult = resolveLoaderSync(routeFile);
loader = loaderResult instanceof Promise ? await loaderResult : loaderResult;
} catch (err) {
if (err?.code === "ERR_MODULE_NOT_FOUND") return null;
throw err;
}
if (!loader) return null;
let json;
try {
json = await loader(loaderProps);
} catch (err) {
if (err?.code === "ENOENT") {
return make404LoaderJs(loaderProps?.path || "/", `ENOENT ${err?.path || err}`);
}
throw err;
}
if ((0, import_isResponse.isResponse)(json)) throw json;
return `export function loader() { return ${JSON.stringify(json)} }`;
},
async handlePage({
route,
url,
loaderProps
}) {
const routeBuildInfo = routeToBuildInfo[route.file];
if (route.type === "ssr") {
if (!routeBuildInfo) {
console.error(`Error in route`, route);
throw new Error(`No buildinfo found for ${url}, route: ${route.file}, in keys:
${Object.keys(routeToBuildInfo).join("\n ")}`);
}
try {
const layoutRoutes = route.layouts || [];
const layoutLoaderPromises = [];
const noLoaderResults = [];
for (const layout of layoutRoutes) {
const cacheKey = layout.contextKey || "";
const cachedLoader = loaderCache.get(cacheKey);
if (cachedLoader === null) {
noLoaderResults.push({
loaderData: void 0,
routeId: layout.contextKey
});
} else {
layoutLoaderPromises.push(importAndRunLoader(layout.contextKey, layout.contextKey, loaderProps));
}
}
const pageLoaderPromise = importAndRunLoader(route.file, route.file, loaderProps);
let layoutResults;
let pageResult;
try {
if (layoutLoaderPromises.length === 0) {
layoutResults = noLoaderResults;
pageResult = await pageLoaderPromise;
} else {
const [asyncLayoutResults, pr] = await Promise.all([Promise.all(layoutLoaderPromises), pageLoaderPromise]);
layoutResults = [...noLoaderResults, ...asyncLayoutResults];
pageResult = pr;
}
} catch (err) {
if ((0, import_isResponse.isResponse)(err)) return err;
throw err;
}
if (pageResult.isEnoent) {
const nfPath = findNearestNotFoundPath(loaderProps?.path || "/");
const nfHtml = routeMap[nfPath];
if (nfHtml) {
const html = await readStaticHtml(nfHtml);
if (html) {
return new Response(html, {
headers: {
"content-type": "text/html"
},
status: 404
});
}
}
return new Response("404 Not Found", {
status: 404
});
}
const matchPathname = loaderProps?.path || "/";
const matchParams = loaderProps?.params || {};
const matches = new Array(layoutResults.length + 1);
for (let i = 0; i < layoutResults.length; i++) {
const result = layoutResults[i];
matches[i] = {
routeId: result.routeId,
pathname: matchPathname,
params: matchParams,
loaderData: result.loaderData
};
}
matches[layoutResults.length] = {
routeId: pageResult.routeId,
pathname: matchPathname,
params: matchParams,
loaderData: pageResult.loaderData
};
const loaderData = pageResult.loaderData;
for (const layout of layoutRoutes) {
const key = layout.contextKey;
const loaderFn = loaderCache.get(key);
if (loaderFn) {
const result = layoutResults.find(r => r.routeId === key);
if (result) (0, import_ssrLoaderData.setSSRLoaderData)(loaderFn, result.loaderData);
}
}
const pageLoaderFn = loaderCache.get(route.file);
if (pageLoaderFn) (0, import_ssrLoaderData.setSSRLoaderData)(pageLoaderFn, pageResult.loaderData);
globalThis["__vxrnresetState"]?.();
const renderProps = {
mode: route.type,
loaderData,
loaderProps,
path: loaderProps?.path || "/",
preloads: routeBuildInfo.criticalPreloads || routeBuildInfo.preloads,
deferredPreloads: routeBuildInfo.deferredPreloads,
css: routeBuildInfo.css,
cssContents: routeBuildInfo.cssContents,
matches
};
const _rl = ensureRenderLoaded();
if (_rl) await _rl;
const status = route.isNotFound ? 404 : 200;
const responseHeaders = route.isNotFound ? htmlHeaders : ssrHtmlHeaders;
if (useStreaming) {
const stream = await renderStream(renderProps);
return new Response(stream, {
headers: responseHeaders,
status
});
}
const rendered = await render(renderProps);
return new Response(rendered, {
headers: responseHeaders,
status
});
} catch (err) {
if ((0, import_isResponse.isResponse)(err)) return err;
console.error(`[one] Error rendering SSR route ${route.file}
${err?.["stack"] ?? err}
url: ${url}`);
return null;
}
} else {
const layoutRoutes = route.layouts || [];
const needsSpaShell = route.type === "spa" && layoutRoutes.some(layout => layout.layoutRenderMode === "ssg" || layout.layoutRenderMode === "ssr");
if (needsSpaShell) {
try {
const layoutResults = await Promise.all(layoutRoutes.map(layout => importAndRunLoader(layout.contextKey, layout.contextKey, loaderProps)));
const matches = layoutResults.map(result => ({
routeId: result.routeId,
pathname: loaderProps?.path || "/",
params: loaderProps?.params || {},
loaderData: result.loaderData
}));
globalThis["__vxrnresetState"]?.();
const _rl = ensureRenderLoaded();
if (_rl) await _rl;
const spaRouteBuildInfo = routeToBuildInfo[route.file];
const rendered = await render({
mode: "spa-shell",
loaderData: void 0,
loaderProps,
path: loaderProps?.path || "/",
preloads: spaRouteBuildInfo?.criticalPreloads || spaRouteBuildInfo?.preloads,
deferredPreloads: spaRouteBuildInfo?.deferredPreloads,
css: spaRouteBuildInfo?.css,
cssContents: spaRouteBuildInfo?.cssContents,
matches
});
return new Response(rendered, {
headers: htmlHeaders,
status: route.isNotFound ? 404 : 200
});
} catch (err) {
if ((0, import_isResponse.isResponse)(err)) return err;
console.error(`[one] Error rendering spa-shell for ${route.file}
${err?.["stack"] ?? err}
url: ${url}`);
}
}
const isDynamicRoute = Object.keys(route.routeKeys).length > 0;
const routeCleanPath = route.urlCleanPath.replace(/\?/g, "");
const notFoundKey = route.isNotFound ? route.page.replace(/\[([^\]]+)\]/g, ":$1") : null;
const htmlPath = notFoundKey ? routeMap[notFoundKey] : isDynamicRoute ? routeMap[routeCleanPath] || routeMap[url.pathname] : routeMap[url.pathname] || routeMap[routeBuildInfo?.cleanPath];
if (htmlPath) {
const html = await readStaticHtml(htmlPath);
if (html) {
return new Response(html, {
headers: htmlHeaders,
status: route.isNotFound ? 404 : 200
});
}
}
if (isDynamicRoute) {
const notFoundRoute = findNearestNotFoundPath(url.pathname);
const notFoundHtmlPath = routeMap[notFoundRoute];
if (notFoundHtmlPath) {
const notFoundHtml = await readStaticHtml(notFoundHtmlPath);
if (notFoundHtml) {
const notFoundMarker = `<script>window.__one404=${JSON.stringify({
originalPath: url.pathname,
notFoundPath: notFoundRoute
})}</script>`;
const injectedHtml = notFoundHtml.includes("</head>") ? notFoundHtml.replace("</head>", `${notFoundMarker}</head>`) : notFoundHtml.replace("<body", `${notFoundMarker}<body`);
return new Response(injectedHtml, {
headers: htmlHeaders,
status: 404
});
}
}
return new Response("404 Not Found", {
status: 404
});
}
return null;
}
}
};
function setCacheHeaders(response, route, isAPI) {
if (!response.headers.has("cache-control") && !response.headers.has("Cache-Control")) {
try {
if (isAPI) {
response.headers.set("cache-control", "no-store");
} else if (route.type === "ssg" || route.type === "spa") {
response.headers.set("cache-control", "public, s-maxage=60, stale-while-revalidate=120");
} else {
response.headers.set("cache-control", "no-cache");
}
} catch {}
}
return response;
}
async function handleRequest(request) {
const url = (0, import_createHandleRequest.getURLfromRequestURL)(request);
const pathname = url.pathname;
const method = request.method;
if (compiledRedirects) {
for (const redirect of compiledRedirects) {
const match = redirect.regex.exec(pathname);
if (match) {
let destination = redirect.destination;
if (match.groups) {
for (const [name, value] of Object.entries(match.groups)) {
destination = destination.replace(`:${name}`, value);
}
}
if (debugRouter) console.info(`[one] \u21AA redirect ${pathname} \u2192 ${destination}`);
return new Response(null, {
status: redirect.permanent ? 301 : 302,
headers: {
location: new URL(destination, url.origin).toString()
}
});
}
}
}
if (pathname.endsWith(import_constants.PRELOAD_JS_POSTFIX)) {
if (!currentPreloads[pathname]) {
return new Response("", {
headers: {
"Content-Type": "text/javascript"
}
});
}
return null;
}
if (pathname.endsWith(import_constants.CSS_PRELOAD_JS_POSTFIX)) {
if (!currentCssPreloads?.[pathname]) {
return new Response("export default Promise.resolve()", {
headers: {
"Content-Type": "text/javascript"
}
});
}
return null;
}
if (pathname.endsWith(import_constants.LOADER_JS_POSTFIX_UNCACHED)) {
const originalUrl = (0, import_cleanUrl.getPathFromLoaderPath)(pathname);
for (const route of compiledManifest.pageRoutes) {
if (route.file === "") continue;
if (!route.compiledRegex.test(originalUrl)) continue;
if (route.type === "ssg" && Object.keys(route.routeKeys).length > 0 && !routeMap[originalUrl]) {
return new Response(make404LoaderJs(originalUrl, "ssg route not in routeMap"), {
headers: {
"Content-Type": "text/javascript"
}
});
}
if (route.hasLoader === false) {
return new Response("export function loader() { return undefined }", {
headers: {
"Content-Type": "text/javascript"
}
});
}
const loaderRoute = {
...route,
routeFile: route.file,
file: route.loaderServerPath || pathname
};
const finalUrl = new URL(originalUrl, url.origin);
finalUrl.search = url.search;
const cleanedRequest = new Request(finalUrl, request);
try {
return await (0, import_createHandleRequest.resolveLoaderRoute)(requestHandlers, cleanedRequest, finalUrl, loaderRoute);
} catch (err) {
if (err?.code === "ERR_MODULE_NOT_FOUND") {
return new Response("export function loader() { return undefined }", {
headers: {
"Content-Type": "text/javascript"
}
});
}
console.error(`Error running loader: ${err}`);
return null;
}
}
return null;
}
if (pathname.endsWith(".js") || pathname.endsWith(".css")) {
return null;
}
for (const route of compiledManifest.apiRoutes) {
if (route.compiledRegex.test(pathname)) {
if (debugRouter) console.info(`[one] \u26A1 ${pathname} \u2192 matched API route: ${route.page}`);
const response = await (0, import_createHandleRequest.resolveAPIRoute)(requestHandlers, request, url, route);
if (response && (0, import_isResponse.isResponse)(response)) {
return setCacheHeaders(response, route, true);
}
return null;
}
}
if (method === "GET") {
for (const route of compiledManifest.pageRoutes) {
if (!route.compiledRegex.test(pathname)) continue;
if (debugRouter) {
console.info(`[one] \u26A1 ${pathname} \u2192 matched page route: ${route.page} (${route.type})`);
}
if (route.type === "ssr" && !route.middlewares?.length) {
const params = {};
const match = route.compiledRegex.exec(pathname);
if (match?.groups) {
for (const [key, value] of Object.entries(match.groups)) {
params[route.routeKeys[key]] = value;
}
}
const loaderProps = {
path: pathname,
search: url.search,
subdomain: (0, import_createHandleRequest.getSubdomain)(url),
request,
params
};
const response = await (0, import_resolveResponse.resolveResponse)(async () => {
try {
return await requestHandlers.handlePage({
request,
route,
url,
loaderProps
});
} catch (err) {
if ((0, import_isResponse.isResponse)(err)) return err;
throw err;
}
});
if (response && (0, import_isResponse.isResponse)(response)) {
return setCacheHeaders(response, route, false);
}
return null;
}
try {
const response = await (0, import_createHandleRequest.resolvePageRoute)(requestHandlers, request, url, route);
if (response && (0, import_isResponse.isResponse)(response)) {
return setCacheHeaders(response, route, false);
}
} catch (err) {
console.error(` [one] Error handling request: ${err["stack"]}`);
}
return null;
}
}
return null;
}
function updateRoutes(newBuildInfo, newLazyRoutes) {
compiledManifest = (0, import_createHandleRequest.compileManifest)(newBuildInfo.manifest);
routeToBuildInfo = newBuildInfo.routeToBuildInfo;
routeMap = newBuildInfo.routeMap;
currentPreloads = newBuildInfo.preloads;
currentCssPreloads = newBuildInfo.cssPreloads;
if (newLazyRoutes) currentLazyRoutes = newLazyRoutes;
loaderCache.clear();
moduleImportCache.clear();
loaderCacheFnMap.clear();
pendingLoaderResults.clear();
render = null;
renderStream = null;
renderLoading = null;
}
return {
handleRequest,
updateRoutes
};
}