release: WRNexusJS 0.7.0

This commit is contained in:
2026-08-01 10:04:42 +05:30
parent c54144f2e4
commit 87507edf59
207 changed files with 12607 additions and 679 deletions
+78
View File
@@ -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,
};
}