Core Concepts
Compiler Pipeline
How NovaServe's 4-stage compiler transforms TypeScript AST into deterministic cloud deployments via Nova IR.
NovaServe treats cloud infrastructure as a compilation target rather than a set of imperatively invoked API scripts. The compiler transforms your TypeScript source code into deterministic cloud deployments through a 4-stage pipeline.
Stage 1: AST Parser & Static Analysis
- Input: TypeScript application source file (
App.ts) - Mechanism: The parser scans the Abstract Syntax Tree using TypeScript compiler APIs, extracting all static invocations of NovaServe primitives (
defineApp,api,storage,queue) - Output: Unlinked AST nodes representing application handlers and resource declarations
- Performance: ~0.04 seconds for typical projects
Stage 2: Dependency Graph Engine & IAM Inference
- Input: Parsed AST nodes
- Mechanism:
- Constructs a Directed Acyclic Graph (DAG) of resource dependencies
- Analyzes handler function bodies for method invocations (e.g.,
uploads.put()) - Synthesizes least-privilege IAM policies, mapping method calls to exact provider API actions without wildcards (
s3:PutObject)
- Output: Resource DAG + synthesized IAM policy JSON
Stage 3: Nova IR Generation
- Input: Validated resource DAG & IAM specs
- Mechanism: Serializes the graph into Nova Intermediate Representation (Nova IR) — a normalized, provider-neutral JSON format. Calculates a SHA-256 cryptographic checksum of the entire graph state.
- Output: Nova IR JSON payload + SHA-256 state lock file (
.nova/state.json)
Stage 4: Target Cloud Emitter
- Input: Nova IR payload + target provider selection
- Mechanism: Translates provider-neutral IR declarations into target-specific manifests (AWS Cloud Control API, Cloudflare API, or Docker build context)
- Output: Deterministically provisioned cloud resources + updated state lock
Compilation Example
Given this application code:
App.ts
import { defineApp, api, storage } from "novaserve";
export const app = defineApp({ name: "my-app" });
export const uploads = storage("user-uploads");
export const upload = api.post("/upload", async (req) => {
const data = await req.arrayBuffer();
await uploads.put("file.bin", data);
return { status: "uploaded" };
});The compiler infers this IAM policy automatically:
Synthesized IAM Policy
{
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": "arn:aws:s3:::user-uploads/*"
}Why a Compiler Approach Matters
- Eliminates duplicate config — resources are declared alongside handlers
- Zero-trust security by default — compiler-driven IAM ensures exact permissions
- Multi-cloud portability — Nova IR decouples logic from vendor APIs