release: WRNexusJS 0.7.0
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import type { PageAst, ViewNode } from "@wrnexus/syntax";
|
||||
|
||||
export type RouteExecutionKind =
|
||||
| "static"
|
||||
| "static-interactive"
|
||||
| "request-ssr"
|
||||
| "authenticated-ssr"
|
||||
| "streaming-ssr"
|
||||
| "dynamic";
|
||||
|
||||
export interface RuntimeRequirements {
|
||||
kind: RouteExecutionKind;
|
||||
canPrerender: boolean;
|
||||
needsClientRuntime: boolean;
|
||||
needsServerRuntime: boolean;
|
||||
hydrationStrategy: string | null;
|
||||
reasons: string[];
|
||||
}
|
||||
|
||||
function hasEvent(nodes: ViewNode[]): boolean {
|
||||
for (const node of nodes) {
|
||||
if (node.type === "element") {
|
||||
if (node.attrs.some((attribute) => attribute.event)) return true;
|
||||
if (hasEvent(node.children)) return true;
|
||||
} else if (node.type === "each") {
|
||||
if (hasEvent(node.body) || hasEvent(node.empty)) return true;
|
||||
} else if (node.type === "if") {
|
||||
if (node.branches.some((branch) => hasEvent(branch.body))) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function analyzeRuntimeRequirements(ast: PageAst): RuntimeRequirements {
|
||||
const reasons: string[] = [];
|
||||
const clientFunctions = ast.runtimeFunctions.some((fn) => fn.runtime !== "server");
|
||||
const clientState = ast.states.some((state) => state.runtime !== "server");
|
||||
const interactive =
|
||||
clientFunctions ||
|
||||
clientState ||
|
||||
ast.effects.length > 0 ||
|
||||
ast.watches.length > 0 ||
|
||||
hasEvent(ast.view);
|
||||
if (interactive) reasons.push("client interactivity");
|
||||
|
||||
const requestData =
|
||||
ast.loads.length > 0 ||
|
||||
ast.actions.length > 0 ||
|
||||
ast.dataApis.length > 0 ||
|
||||
ast.apis.length > 0 ||
|
||||
ast.realtimes.length > 0 ||
|
||||
ast.runtimeFunctions.some((fn) => fn.runtime === "server") ||
|
||||
ast.states.some((state) => state.runtime === "server");
|
||||
if (requestData) reasons.push("server/request data");
|
||||
|
||||
const authenticated = /^(?:required|true)$/i.test(ast.security.auth ?? "");
|
||||
if (authenticated) reasons.push("authentication required");
|
||||
|
||||
const streaming = /^(?:true|required)$/i.test(ast.security.streaming ?? "");
|
||||
if (streaming) reasons.push("streaming enabled");
|
||||
|
||||
let kind: RouteExecutionKind;
|
||||
if (streaming) kind = "streaming-ssr";
|
||||
else if (authenticated) kind = "authenticated-ssr";
|
||||
else if (requestData && interactive) kind = "dynamic";
|
||||
else if (requestData) kind = "request-ssr";
|
||||
else if (interactive) kind = "static-interactive";
|
||||
else kind = "static";
|
||||
|
||||
return {
|
||||
kind,
|
||||
canPrerender: kind === "static" || kind === "static-interactive",
|
||||
needsClientRuntime: interactive && ast.hydrate !== "none" && ast.runtime !== "server",
|
||||
needsServerRuntime: requestData || authenticated || streaming || ast.runtime === "server",
|
||||
hydrationStrategy: interactive ? (ast.hydrate ?? "load") : null,
|
||||
reasons,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user