@zenithbuild/compiler 1.3.2 → 1.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-analyzer.d.ts +44 -0
- package/dist/build-analyzer.js +87 -0
- package/dist/bundler.d.ts +31 -0
- package/dist/bundler.js +92 -0
- package/dist/core/config/index.d.ts +11 -0
- package/dist/core/config/index.js +10 -0
- package/dist/core/config/loader.d.ts +17 -0
- package/dist/core/config/loader.js +60 -0
- package/dist/core/config/types.d.ts +98 -0
- package/dist/core/config/types.js +32 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.js +6 -0
- package/dist/core/plugins/bridge.d.ts +116 -0
- package/dist/core/plugins/bridge.js +121 -0
- package/dist/core/plugins/index.d.ts +6 -0
- package/dist/core/plugins/index.js +6 -0
- package/dist/core/plugins/registry.d.ts +67 -0
- package/dist/core/plugins/registry.js +112 -0
- package/dist/css/index.d.ts +73 -0
- package/dist/css/index.js +246 -0
- package/dist/discovery/componentDiscovery.d.ts +41 -0
- package/dist/discovery/componentDiscovery.js +66 -0
- package/dist/discovery/layouts.d.ts +14 -0
- package/dist/discovery/layouts.js +36 -0
- package/dist/errors/compilerError.d.ts +31 -0
- package/dist/errors/compilerError.js +51 -0
- package/dist/finalize/generateFinalBundle.d.ts +24 -0
- package/dist/finalize/generateFinalBundle.js +68 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +44 -0
- package/dist/ir/types.d.ts +206 -0
- package/dist/ir/types.js +8 -0
- package/dist/output/types.d.ts +39 -0
- package/dist/output/types.js +6 -0
- package/dist/parseZenFile.d.ts +17 -0
- package/dist/parseZenFile.js +52 -0
- package/dist/runtime/build.d.ts +6 -0
- package/dist/runtime/build.js +13 -0
- package/dist/runtime/bundle-generator.d.ts +27 -0
- package/dist/runtime/bundle-generator.js +1438 -0
- package/dist/runtime/client-runtime.d.ts +41 -0
- package/dist/runtime/client-runtime.js +397 -0
- package/dist/runtime/hydration.d.ts +53 -0
- package/dist/runtime/hydration.js +271 -0
- package/dist/runtime/navigation.d.ts +58 -0
- package/dist/runtime/navigation.js +372 -0
- package/dist/runtime/serve.d.ts +13 -0
- package/dist/runtime/serve.js +76 -0
- package/dist/runtime/thinRuntime.d.ts +23 -0
- package/dist/runtime/thinRuntime.js +158 -0
- package/dist/spa-build.d.ts +26 -0
- package/dist/spa-build.js +849 -0
- package/dist/ssg-build.d.ts +31 -0
- package/dist/ssg-build.js +429 -0
- package/dist/test/bundler-contract.test.d.ts +1 -0
- package/dist/test/bundler-contract.test.js +137 -0
- package/dist/test/compiler-entry.test.d.ts +1 -0
- package/dist/test/compiler-entry.test.js +28 -0
- package/dist/test/error-native-bridge.test.d.ts +1 -0
- package/dist/test/error-native-bridge.test.js +31 -0
- package/dist/test/error-serialization.test.d.ts +1 -0
- package/dist/test/error-serialization.test.js +38 -0
- package/dist/test/phase5-boundary.test.d.ts +1 -0
- package/dist/test/phase5-boundary.test.js +51 -0
- package/dist/transform/layoutProcessor.d.ts +26 -0
- package/dist/transform/layoutProcessor.js +34 -0
- package/dist/validate/invariants.d.ts +23 -0
- package/dist/validate/invariants.js +55 -0
- package/native/compiler-native/compiler-native.node +0 -0
- package/native/compiler-native/index.d.ts +2 -46
- package/native/compiler-native/index.js +1 -16
- package/native/compiler-native/package.json +1 -1
- package/package.json +15 -5
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Discovery
|
|
3
|
+
*
|
|
4
|
+
* Discovers and catalogs components in a Zenith project using standard
|
|
5
|
+
* file system walking and the unified native "syscall" for metadata.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { parseZenFile } from '../parseZenFile';
|
|
10
|
+
/**
|
|
11
|
+
* Discover all components in a directory recursively
|
|
12
|
+
*/
|
|
13
|
+
export function discoverComponents(baseDir) {
|
|
14
|
+
const components = new Map();
|
|
15
|
+
if (!fs.existsSync(baseDir))
|
|
16
|
+
return components;
|
|
17
|
+
const walk = (dir) => {
|
|
18
|
+
const files = fs.readdirSync(dir);
|
|
19
|
+
for (const file of files) {
|
|
20
|
+
const fullPath = path.join(dir, file);
|
|
21
|
+
if (fs.statSync(fullPath).isDirectory()) {
|
|
22
|
+
walk(fullPath);
|
|
23
|
+
}
|
|
24
|
+
else if (file.endsWith('.zen')) {
|
|
25
|
+
const name = path.basename(file, '.zen');
|
|
26
|
+
try {
|
|
27
|
+
// Call the "One True Bridge" in metadata mode
|
|
28
|
+
const ir = parseZenFile(fullPath, undefined, { mode: 'metadata' });
|
|
29
|
+
// Map IR to ComponentMetadata format
|
|
30
|
+
components.set(name, {
|
|
31
|
+
name,
|
|
32
|
+
path: fullPath,
|
|
33
|
+
template: ir.template.raw,
|
|
34
|
+
nodes: ir.template.nodes,
|
|
35
|
+
expressions: ir.template.expressions,
|
|
36
|
+
slots: [], // Native bridge needs to return slot info in IR if used
|
|
37
|
+
props: ir.props || [],
|
|
38
|
+
states: ir.script?.states || {},
|
|
39
|
+
styles: ir.styles?.map((s) => s.raw) || [],
|
|
40
|
+
script: ir.script?.raw || null,
|
|
41
|
+
scriptAttributes: ir.script?.attributes || null,
|
|
42
|
+
hasScript: !!ir.script,
|
|
43
|
+
hasStyles: ir.styles?.length > 0
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
console.error(`[Zenith Discovery] Failed to parse component ${file}:`, e);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
walk(baseDir);
|
|
53
|
+
return components;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Universal Zenith Component Tag Rule: PascalCase
|
|
57
|
+
*/
|
|
58
|
+
export function isComponentTag(tagName) {
|
|
59
|
+
return tagName.length > 0 && tagName[0] === tagName[0]?.toUpperCase();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get component metadata by name
|
|
63
|
+
*/
|
|
64
|
+
export function getComponent(components, name) {
|
|
65
|
+
return components.get(name);
|
|
66
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface LayoutMetadata {
|
|
2
|
+
name: string;
|
|
3
|
+
filePath: string;
|
|
4
|
+
props: string[];
|
|
5
|
+
states: Map<string, any>;
|
|
6
|
+
html: string;
|
|
7
|
+
scripts: string[];
|
|
8
|
+
styles: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Discover layouts in a directory using standard file system walking
|
|
12
|
+
* and the unified native bridge for metadata.
|
|
13
|
+
*/
|
|
14
|
+
export declare function discoverLayouts(layoutsDir: string): Map<string, LayoutMetadata>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { parseZenFile } from '../parseZenFile';
|
|
4
|
+
/**
|
|
5
|
+
* Discover layouts in a directory using standard file system walking
|
|
6
|
+
* and the unified native bridge for metadata.
|
|
7
|
+
*/
|
|
8
|
+
export function discoverLayouts(layoutsDir) {
|
|
9
|
+
const layouts = new Map();
|
|
10
|
+
if (!fs.existsSync(layoutsDir))
|
|
11
|
+
return layouts;
|
|
12
|
+
const files = fs.readdirSync(layoutsDir);
|
|
13
|
+
for (const file of files) {
|
|
14
|
+
if (file.endsWith('.zen')) {
|
|
15
|
+
const fullPath = path.join(layoutsDir, file);
|
|
16
|
+
const name = path.basename(file, '.zen');
|
|
17
|
+
try {
|
|
18
|
+
// Call the "One True Bridge" in metadata mode
|
|
19
|
+
const ir = parseZenFile(fullPath, undefined, { mode: 'metadata' });
|
|
20
|
+
layouts.set(name, {
|
|
21
|
+
name,
|
|
22
|
+
filePath: fullPath,
|
|
23
|
+
props: ir.props || [],
|
|
24
|
+
states: new Map(),
|
|
25
|
+
html: ir.template.raw,
|
|
26
|
+
scripts: ir.script ? [ir.script.content] : [],
|
|
27
|
+
styles: ir.styles?.map((s) => s.raw) || []
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
console.error(`[Zenith Layout Discovery] Failed to parse layout ${file}:`, e);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return layouts;
|
|
36
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiler Error Handling
|
|
3
|
+
*
|
|
4
|
+
* Compiler errors with source location information
|
|
5
|
+
*/
|
|
6
|
+
export declare class CompilerError extends Error {
|
|
7
|
+
file: string;
|
|
8
|
+
line: number;
|
|
9
|
+
column: number;
|
|
10
|
+
errorType: string;
|
|
11
|
+
context?: string;
|
|
12
|
+
hints: string[];
|
|
13
|
+
code?: string;
|
|
14
|
+
constructor(message: string, file: string, line: number, column: number, errorType?: string, context?: string, hints?: string[], code?: string);
|
|
15
|
+
toString(): string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Invariant Error
|
|
19
|
+
*
|
|
20
|
+
* Thrown when a Zenith compiler invariant is violated.
|
|
21
|
+
* Invariants are non-negotiable rules that guarantee correct behavior.
|
|
22
|
+
*
|
|
23
|
+
* If an invariant fails, the compiler is at fault — not the user.
|
|
24
|
+
* The user receives a clear explanation of what is forbidden and why.
|
|
25
|
+
*/
|
|
26
|
+
export declare class InvariantError extends CompilerError {
|
|
27
|
+
invariantId: string;
|
|
28
|
+
guarantee: string;
|
|
29
|
+
constructor(invariantId: string, message: string, guarantee: string, file: string, line: number, column: number, context?: string, hints?: string[]);
|
|
30
|
+
toString(): string;
|
|
31
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiler Error Handling
|
|
3
|
+
*
|
|
4
|
+
* Compiler errors with source location information
|
|
5
|
+
*/
|
|
6
|
+
export class CompilerError extends Error {
|
|
7
|
+
file;
|
|
8
|
+
line;
|
|
9
|
+
column;
|
|
10
|
+
errorType;
|
|
11
|
+
context;
|
|
12
|
+
hints;
|
|
13
|
+
code;
|
|
14
|
+
constructor(message, file, line, column, errorType = 'COMPILER_ERROR', context, hints = [], code) {
|
|
15
|
+
super(`${file}:${line}:${column} ${message}`);
|
|
16
|
+
this.name = 'CompilerError';
|
|
17
|
+
this.file = file;
|
|
18
|
+
this.line = line;
|
|
19
|
+
this.column = column;
|
|
20
|
+
this.errorType = errorType;
|
|
21
|
+
this.context = context;
|
|
22
|
+
this.hints = hints;
|
|
23
|
+
this.code = code;
|
|
24
|
+
}
|
|
25
|
+
toString() {
|
|
26
|
+
return `${this.file}:${this.line}:${this.column} [${this.errorType}] ${this.message}`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Invariant Error
|
|
31
|
+
*
|
|
32
|
+
* Thrown when a Zenith compiler invariant is violated.
|
|
33
|
+
* Invariants are non-negotiable rules that guarantee correct behavior.
|
|
34
|
+
*
|
|
35
|
+
* If an invariant fails, the compiler is at fault — not the user.
|
|
36
|
+
* The user receives a clear explanation of what is forbidden and why.
|
|
37
|
+
*/
|
|
38
|
+
export class InvariantError extends CompilerError {
|
|
39
|
+
invariantId;
|
|
40
|
+
guarantee;
|
|
41
|
+
constructor(invariantId, message, guarantee, file, line, column, context, hints = []) {
|
|
42
|
+
super(`[${invariantId}] ${message}\n\n Zenith Guarantee: ${guarantee}`, file, line, column, 'COMPILER_INVARIANT_VIOLATION', context, hints, invariantId);
|
|
43
|
+
this.name = 'InvariantError';
|
|
44
|
+
this.invariantId = invariantId;
|
|
45
|
+
this.guarantee = guarantee;
|
|
46
|
+
this.code = invariantId;
|
|
47
|
+
}
|
|
48
|
+
toString() {
|
|
49
|
+
return `${this.file}:${this.line}:${this.column} [${this.invariantId}] ${this.message}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate Final Bundle
|
|
3
|
+
*
|
|
4
|
+
* Phase 8/9/10: Generate final browser-ready bundle
|
|
5
|
+
*
|
|
6
|
+
* Combines:
|
|
7
|
+
* - Compiled HTML
|
|
8
|
+
* - Runtime JS
|
|
9
|
+
* - Expression functions
|
|
10
|
+
* - Event bindings
|
|
11
|
+
* - Style injection
|
|
12
|
+
*/
|
|
13
|
+
import type { FinalizedOutput } from '../output/types';
|
|
14
|
+
/**
|
|
15
|
+
* Generate final bundle code
|
|
16
|
+
*
|
|
17
|
+
* This is the complete JavaScript bundle that will execute in the browser.
|
|
18
|
+
* All expressions are pre-compiled - no template parsing at runtime.
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateFinalBundle(finalized: FinalizedOutput): string;
|
|
21
|
+
/**
|
|
22
|
+
* Generate HTML with inline script
|
|
23
|
+
*/
|
|
24
|
+
export declare function generateHTMLWithScript(html: string, jsBundle: string, styles: string[]): string;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate Final Bundle
|
|
3
|
+
*
|
|
4
|
+
* Phase 8/9/10: Generate final browser-ready bundle
|
|
5
|
+
*
|
|
6
|
+
* Combines:
|
|
7
|
+
* - Compiled HTML
|
|
8
|
+
* - Runtime JS
|
|
9
|
+
* - Expression functions
|
|
10
|
+
* - Event bindings
|
|
11
|
+
* - Style injection
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Generate final bundle code
|
|
15
|
+
*
|
|
16
|
+
* This is the complete JavaScript bundle that will execute in the browser.
|
|
17
|
+
* All expressions are pre-compiled - no template parsing at runtime.
|
|
18
|
+
*/
|
|
19
|
+
export function generateFinalBundle(finalized) {
|
|
20
|
+
return `// Zenith Compiled Bundle (Phase 8/9/10)
|
|
21
|
+
// Generated at compile time - no .zen parsing in browser
|
|
22
|
+
// All expressions are pre-compiled - deterministic output
|
|
23
|
+
|
|
24
|
+
${finalized.js}
|
|
25
|
+
|
|
26
|
+
// Bundle complete - ready for browser execution
|
|
27
|
+
`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Generate HTML with inline script
|
|
31
|
+
*/
|
|
32
|
+
export function generateHTMLWithScript(html, jsBundle, styles) {
|
|
33
|
+
// Inject styles as <style> tags
|
|
34
|
+
const styleTags = styles.map(style => `<style>${escapeHTML(style)}</style>`).join('\n');
|
|
35
|
+
// Inject JS bundle as inline script
|
|
36
|
+
const scriptTag = `<script>${jsBundle}</script>`;
|
|
37
|
+
// Find </head> or <body> to inject styles
|
|
38
|
+
// Find </body> to inject script
|
|
39
|
+
let result = html;
|
|
40
|
+
if (styleTags) {
|
|
41
|
+
if (result.includes('</head>')) {
|
|
42
|
+
result = result.replace('</head>', `${styleTags}\n</head>`);
|
|
43
|
+
}
|
|
44
|
+
else if (result.includes('<body')) {
|
|
45
|
+
result = result.replace('<body', `${styleTags}\n<body`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (scriptTag) {
|
|
49
|
+
if (result.includes('</body>')) {
|
|
50
|
+
result = result.replace('</body>', `${scriptTag}\n</body>`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
result += scriptTag;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Escape HTML for safe embedding
|
|
60
|
+
*/
|
|
61
|
+
function escapeHTML(str) {
|
|
62
|
+
return str
|
|
63
|
+
.replace(/&/g, '&')
|
|
64
|
+
.replace(/</g, '<')
|
|
65
|
+
.replace(/>/g, '>')
|
|
66
|
+
.replace(/"/g, '"')
|
|
67
|
+
.replace(/'/g, ''');
|
|
68
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { parseZenFile } from './parseZenFile';
|
|
2
|
+
import type { ZenIR } from './ir/types';
|
|
3
|
+
import type { CompiledTemplate, FinalizedOutput } from './output/types';
|
|
4
|
+
export type ZenCompileOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* Map of component names to their definitions.
|
|
7
|
+
*/
|
|
8
|
+
components?: Map<string, any>;
|
|
9
|
+
/**
|
|
10
|
+
* Optional directory to discover components from
|
|
11
|
+
*/
|
|
12
|
+
componentsDir?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Optional layout to wrap the page in
|
|
15
|
+
*/
|
|
16
|
+
layout?: any;
|
|
17
|
+
/**
|
|
18
|
+
* Initial props for layout processing
|
|
19
|
+
*/
|
|
20
|
+
props?: Record<string, any>;
|
|
21
|
+
};
|
|
22
|
+
export type ZenCompileResult = {
|
|
23
|
+
ir: ZenIR;
|
|
24
|
+
compiled: CompiledTemplate;
|
|
25
|
+
finalized?: FinalizedOutput;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Compile Zenith source code using the unified "One True Bridge" (Native Syscall).
|
|
29
|
+
*/
|
|
30
|
+
export declare function compile(source: string, filePath: string, options?: ZenCompileOptions): Promise<ZenCompileResult>;
|
|
31
|
+
export { parseZenFile };
|
|
32
|
+
export type { FinalizedOutput, CompiledTemplate };
|
|
33
|
+
export type { BundlePlan, ExpressionIR, ZenIR, TemplateNode } from './ir/types';
|
|
34
|
+
export type { HookContext } from './core/plugins/bridge';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Core Imports (Internal)
|
|
2
|
+
import { parseZenFile } from './parseZenFile';
|
|
3
|
+
import { InvariantError } from './errors/compilerError';
|
|
4
|
+
import { discoverComponents } from './discovery/componentDiscovery';
|
|
5
|
+
/**
|
|
6
|
+
* Compile Zenith source code using the unified "One True Bridge" (Native Syscall).
|
|
7
|
+
*/
|
|
8
|
+
export async function compile(source, filePath, options) {
|
|
9
|
+
const opts = options || {};
|
|
10
|
+
// Discover components if directory provided
|
|
11
|
+
let components = opts.components || new Map();
|
|
12
|
+
if (opts.componentsDir) {
|
|
13
|
+
const discovered = discoverComponents(opts.componentsDir);
|
|
14
|
+
components = new Map([...components, ...discovered]);
|
|
15
|
+
}
|
|
16
|
+
const finalized = parseZenFile(filePath, source, {
|
|
17
|
+
mode: 'full',
|
|
18
|
+
components: components ? Object.fromEntries(components) : {},
|
|
19
|
+
layout: opts.layout,
|
|
20
|
+
props: opts.props,
|
|
21
|
+
useCache: true
|
|
22
|
+
});
|
|
23
|
+
// If the native side returned a compiler error (camelCase or snake_case fields)
|
|
24
|
+
if (finalized.code && (finalized.errorType || finalized.error_type)) {
|
|
25
|
+
throw new InvariantError(finalized.code, finalized.message, finalized.guarantee || "Zenith Invariant Violation", // Guarantee provided by native code checks
|
|
26
|
+
filePath, finalized.line || 1, finalized.column || 1, finalized.context, finalized.hints);
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
ir: finalized.ir,
|
|
30
|
+
compiled: {
|
|
31
|
+
html: finalized.html,
|
|
32
|
+
bindings: finalized.bindings || [],
|
|
33
|
+
scripts: finalized.js || null,
|
|
34
|
+
styles: finalized.styles || []
|
|
35
|
+
},
|
|
36
|
+
finalized: {
|
|
37
|
+
...finalized,
|
|
38
|
+
js: finalized.js,
|
|
39
|
+
npmImports: finalized.npmImports,
|
|
40
|
+
bundlePlan: finalized.bundlePlan
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export { parseZenFile };
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith Intermediate Representation (IR)
|
|
3
|
+
*
|
|
4
|
+
* Phase 1: Parse & Extract
|
|
5
|
+
* This IR represents the parsed structure of a .zen file
|
|
6
|
+
* without any runtime execution or transformation.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Structured ES module import metadata
|
|
10
|
+
* Parsed from component scripts, used for deterministic bundling
|
|
11
|
+
*/
|
|
12
|
+
export interface ScriptImport {
|
|
13
|
+
source: string;
|
|
14
|
+
specifiers: string;
|
|
15
|
+
typeOnly: boolean;
|
|
16
|
+
sideEffect: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Property extracted from interface/type definition
|
|
20
|
+
* Used by props<T>() constraint - shape-only parsing
|
|
21
|
+
*/
|
|
22
|
+
export interface PropTypeProperty {
|
|
23
|
+
name: string;
|
|
24
|
+
optional: boolean;
|
|
25
|
+
typeAnnotation: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* TypeScript type binding parsed from props<T>() constraint
|
|
29
|
+
* This is a CONSTRAINT, not a declaration - it restricts allowed props
|
|
30
|
+
*/
|
|
31
|
+
export interface PropsTypeBinding {
|
|
32
|
+
typeName: string;
|
|
33
|
+
sourceFile?: string;
|
|
34
|
+
properties: PropTypeProperty[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Component Script IR - represents a component's script block
|
|
38
|
+
* Used for collecting and bundling component scripts
|
|
39
|
+
*/
|
|
40
|
+
export type ComponentScriptIR = {
|
|
41
|
+
name: string;
|
|
42
|
+
script: string;
|
|
43
|
+
props: string[];
|
|
44
|
+
scriptAttributes: Record<string, string>;
|
|
45
|
+
imports: ScriptImport[];
|
|
46
|
+
instanceId?: string;
|
|
47
|
+
propValues?: Record<string, any>;
|
|
48
|
+
expressions?: ExpressionIR[];
|
|
49
|
+
propsTypeBinding?: PropsTypeBinding;
|
|
50
|
+
};
|
|
51
|
+
export type ZenIR = {
|
|
52
|
+
filePath: string;
|
|
53
|
+
template: TemplateIR;
|
|
54
|
+
script: ScriptIR | null;
|
|
55
|
+
styles: StyleIR[];
|
|
56
|
+
states?: Record<string, string>;
|
|
57
|
+
componentScripts?: ComponentScriptIR[];
|
|
58
|
+
pageBindings?: string[];
|
|
59
|
+
props?: string[];
|
|
60
|
+
mergedBindings?: string[];
|
|
61
|
+
};
|
|
62
|
+
export type TemplateIR = {
|
|
63
|
+
raw: string;
|
|
64
|
+
nodes: TemplateNode[];
|
|
65
|
+
expressions: ExpressionIR[];
|
|
66
|
+
};
|
|
67
|
+
export type TemplateNode = ElementNode | TextNode | ExpressionNode | ComponentNode | ConditionalFragmentNode | OptionalFragmentNode | LoopFragmentNode | DoctypeNode;
|
|
68
|
+
export type DoctypeNode = {
|
|
69
|
+
type: 'doctype';
|
|
70
|
+
name: string;
|
|
71
|
+
publicId: string;
|
|
72
|
+
systemId: string;
|
|
73
|
+
location: SourceLocation;
|
|
74
|
+
};
|
|
75
|
+
export type ElementNode = {
|
|
76
|
+
type: 'element';
|
|
77
|
+
tag: string;
|
|
78
|
+
attributes: AttributeIR[];
|
|
79
|
+
children: TemplateNode[];
|
|
80
|
+
location: SourceLocation;
|
|
81
|
+
loopContext?: LoopContext;
|
|
82
|
+
};
|
|
83
|
+
export type ComponentNode = {
|
|
84
|
+
type: 'component';
|
|
85
|
+
name: string;
|
|
86
|
+
attributes: AttributeIR[];
|
|
87
|
+
children: TemplateNode[];
|
|
88
|
+
location: SourceLocation;
|
|
89
|
+
loopContext?: LoopContext;
|
|
90
|
+
};
|
|
91
|
+
export type TextNode = {
|
|
92
|
+
type: 'text';
|
|
93
|
+
value: string;
|
|
94
|
+
location: SourceLocation;
|
|
95
|
+
};
|
|
96
|
+
export type ExpressionNode = {
|
|
97
|
+
type: 'expression';
|
|
98
|
+
expression: string;
|
|
99
|
+
location: SourceLocation;
|
|
100
|
+
loopContext?: LoopContext;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Conditional Fragment Node
|
|
104
|
+
*
|
|
105
|
+
* Represents ternary expressions with JSX branches: {cond ? <A /> : <B />}
|
|
106
|
+
*
|
|
107
|
+
* BOTH branches are compiled at compile time.
|
|
108
|
+
* Runtime toggles visibility — never creates DOM.
|
|
109
|
+
*/
|
|
110
|
+
export type ConditionalFragmentNode = {
|
|
111
|
+
type: 'conditional-fragment';
|
|
112
|
+
condition: string;
|
|
113
|
+
consequent: TemplateNode[];
|
|
114
|
+
alternate: TemplateNode[];
|
|
115
|
+
location: SourceLocation;
|
|
116
|
+
loopContext?: LoopContext;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Optional Fragment Node
|
|
120
|
+
*
|
|
121
|
+
* Represents logical AND expressions with JSX: {cond && <A />}
|
|
122
|
+
*
|
|
123
|
+
* Fragment is compiled at compile time.
|
|
124
|
+
* Runtime toggles mount/unmount based on condition.
|
|
125
|
+
*/
|
|
126
|
+
export type OptionalFragmentNode = {
|
|
127
|
+
type: 'optional-fragment';
|
|
128
|
+
condition: string;
|
|
129
|
+
fragment: TemplateNode[];
|
|
130
|
+
location: SourceLocation;
|
|
131
|
+
loopContext?: LoopContext;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Loop Fragment Node
|
|
135
|
+
*
|
|
136
|
+
* Represents .map() expressions with JSX body: {items.map(i => <li>...</li>)}
|
|
137
|
+
*
|
|
138
|
+
* Desugars to @for loop semantics at compile time.
|
|
139
|
+
* Body is compiled once, instantiated per item at runtime.
|
|
140
|
+
* Node identity is compiler-owned via stable keys.
|
|
141
|
+
*/
|
|
142
|
+
export type LoopFragmentNode = {
|
|
143
|
+
type: 'loop-fragment';
|
|
144
|
+
source: string;
|
|
145
|
+
itemVar: string;
|
|
146
|
+
indexVar?: string;
|
|
147
|
+
body: TemplateNode[];
|
|
148
|
+
location: SourceLocation;
|
|
149
|
+
loopContext: LoopContext;
|
|
150
|
+
};
|
|
151
|
+
export type AttributeIR = {
|
|
152
|
+
name: string;
|
|
153
|
+
value: string | ExpressionIR;
|
|
154
|
+
location: SourceLocation;
|
|
155
|
+
loopContext?: LoopContext;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Loop context for expressions inside map iterations
|
|
159
|
+
* Phase 7: Tracks loop variables (e.g., todo, index) for expressions inside .map() calls
|
|
160
|
+
*/
|
|
161
|
+
export type LoopContext = {
|
|
162
|
+
variables: string[];
|
|
163
|
+
mapSource?: string;
|
|
164
|
+
};
|
|
165
|
+
export type ExpressionIR = {
|
|
166
|
+
id: string;
|
|
167
|
+
code: string;
|
|
168
|
+
location: SourceLocation;
|
|
169
|
+
loopContext?: LoopContext;
|
|
170
|
+
};
|
|
171
|
+
export type ScriptIR = {
|
|
172
|
+
raw: string;
|
|
173
|
+
attributes: Record<string, string>;
|
|
174
|
+
props?: string[];
|
|
175
|
+
states?: Record<string, string>;
|
|
176
|
+
bindings?: string[];
|
|
177
|
+
};
|
|
178
|
+
export type StyleIR = {
|
|
179
|
+
raw: string;
|
|
180
|
+
};
|
|
181
|
+
export type SourceLocation = {
|
|
182
|
+
line: number;
|
|
183
|
+
column: number;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* BundlePlan - Compiler-emitted contract for bundler execution
|
|
187
|
+
*
|
|
188
|
+
* If a plan exists, bundling MUST occur.
|
|
189
|
+
* If no plan exists, bundling MUST NOT occur.
|
|
190
|
+
* The bundler performs ZERO inference—it executes exactly what the compiler specifies.
|
|
191
|
+
*/
|
|
192
|
+
export interface BundlePlan {
|
|
193
|
+
/** Entry point code (not a file path) */
|
|
194
|
+
entry: string;
|
|
195
|
+
/** Target platform */
|
|
196
|
+
platform: 'browser' | 'node';
|
|
197
|
+
/** Output format */
|
|
198
|
+
format: 'esm' | 'cjs';
|
|
199
|
+
/** Directories to resolve modules from */
|
|
200
|
+
resolveRoots: string[];
|
|
201
|
+
/** Virtual modules provided by the compiler */
|
|
202
|
+
virtualModules: Array<{
|
|
203
|
+
id: string;
|
|
204
|
+
code: string;
|
|
205
|
+
}>;
|
|
206
|
+
}
|
package/dist/ir/types.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiled Template Output Types
|
|
3
|
+
*
|
|
4
|
+
* Phase 2: Transform IR → Static HTML + Runtime Bindings
|
|
5
|
+
*/
|
|
6
|
+
export type CompiledTemplate = {
|
|
7
|
+
html: string;
|
|
8
|
+
bindings: Binding[];
|
|
9
|
+
scripts: string | null;
|
|
10
|
+
styles: string;
|
|
11
|
+
};
|
|
12
|
+
export type Binding = {
|
|
13
|
+
id: string;
|
|
14
|
+
type: 'text' | 'attribute' | 'conditional' | 'optional' | 'loop';
|
|
15
|
+
target: string;
|
|
16
|
+
expression: string;
|
|
17
|
+
location?: {
|
|
18
|
+
line: number;
|
|
19
|
+
column: number;
|
|
20
|
+
};
|
|
21
|
+
loopContext?: LoopContext;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Loop context for expressions inside map iterations
|
|
25
|
+
* Phase 7: Tracks loop variables for runtime setter generation
|
|
26
|
+
*/
|
|
27
|
+
export type LoopContext = {
|
|
28
|
+
variables: string[];
|
|
29
|
+
mapSource?: string;
|
|
30
|
+
};
|
|
31
|
+
export type FinalizedOutput = {
|
|
32
|
+
html: string;
|
|
33
|
+
js: string;
|
|
34
|
+
npmImports: string;
|
|
35
|
+
styles: string;
|
|
36
|
+
hasErrors: boolean;
|
|
37
|
+
errors: string[];
|
|
38
|
+
bundlePlan?: any;
|
|
39
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zenith File Parser (Native Bridge)
|
|
3
|
+
*
|
|
4
|
+
* Delegates all Zenith compilation to the Rust native "syscall" bridge.
|
|
5
|
+
* Zero fallbacks. Zero runtime abstraction.
|
|
6
|
+
*/
|
|
7
|
+
export interface ParseOptions {
|
|
8
|
+
mode?: 'metadata' | 'full';
|
|
9
|
+
components?: Record<string, any>;
|
|
10
|
+
layout?: any;
|
|
11
|
+
props?: Record<string, any>;
|
|
12
|
+
useCache?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Perform a Zenith "Syscall" to the native compiler
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseZenFile(filePath: string, sourceInput?: string, options?: ParseOptions): any;
|