@zenithbuild/core 1.2.2 → 1.2.3

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.
Files changed (83) hide show
  1. package/README.md +20 -19
  2. package/cli/commands/add.ts +2 -2
  3. package/cli/commands/build.ts +2 -3
  4. package/cli/commands/dev.ts +93 -73
  5. package/cli/commands/index.ts +1 -1
  6. package/cli/commands/preview.ts +1 -1
  7. package/cli/commands/remove.ts +2 -2
  8. package/cli/index.ts +1 -1
  9. package/cli/main.ts +1 -1
  10. package/cli/utils/logger.ts +1 -1
  11. package/cli/utils/plugin-manager.ts +1 -1
  12. package/cli/utils/project.ts +4 -4
  13. package/core/components/ErrorPage.zen +218 -0
  14. package/core/components/index.ts +15 -0
  15. package/core/config.ts +1 -0
  16. package/core/index.ts +29 -0
  17. package/dist/compiler-native-frej59m4.node +0 -0
  18. package/dist/core/compiler-native-frej59m4.node +0 -0
  19. package/dist/core/index.js +6293 -0
  20. package/dist/runtime/lifecycle/index.js +1 -0
  21. package/dist/runtime/reactivity/index.js +1 -0
  22. package/dist/zen-build.js +1 -20118
  23. package/dist/zen-dev.js +1 -20118
  24. package/dist/zen-preview.js +1 -20118
  25. package/dist/zenith.js +1 -20118
  26. package/package.json +11 -20
  27. package/compiler/README.md +0 -380
  28. package/compiler/build-analyzer.ts +0 -122
  29. package/compiler/css/index.ts +0 -317
  30. package/compiler/discovery/componentDiscovery.ts +0 -242
  31. package/compiler/discovery/layouts.ts +0 -70
  32. package/compiler/errors/compilerError.ts +0 -56
  33. package/compiler/finalize/finalizeOutput.ts +0 -192
  34. package/compiler/finalize/generateFinalBundle.ts +0 -82
  35. package/compiler/index.ts +0 -83
  36. package/compiler/ir/types.ts +0 -174
  37. package/compiler/output/types.ts +0 -48
  38. package/compiler/parse/detectMapExpressions.ts +0 -102
  39. package/compiler/parse/importTypes.ts +0 -78
  40. package/compiler/parse/parseImports.ts +0 -309
  41. package/compiler/parse/parseScript.ts +0 -46
  42. package/compiler/parse/parseTemplate.ts +0 -628
  43. package/compiler/parse/parseZenFile.ts +0 -66
  44. package/compiler/parse/scriptAnalysis.ts +0 -91
  45. package/compiler/parse/trackLoopContext.ts +0 -82
  46. package/compiler/runtime/dataExposure.ts +0 -332
  47. package/compiler/runtime/generateDOM.ts +0 -255
  48. package/compiler/runtime/generateHydrationBundle.ts +0 -407
  49. package/compiler/runtime/hydration.ts +0 -309
  50. package/compiler/runtime/navigation.ts +0 -432
  51. package/compiler/runtime/thinRuntime.ts +0 -160
  52. package/compiler/runtime/transformIR.ts +0 -406
  53. package/compiler/runtime/wrapExpression.ts +0 -114
  54. package/compiler/runtime/wrapExpressionWithLoop.ts +0 -97
  55. package/compiler/spa-build.ts +0 -917
  56. package/compiler/ssg-build.ts +0 -486
  57. package/compiler/test/component-stacking.test.ts +0 -365
  58. package/compiler/test/map-lowering.test.ts +0 -130
  59. package/compiler/test/validate-test.ts +0 -104
  60. package/compiler/transform/classifyExpression.ts +0 -444
  61. package/compiler/transform/componentResolver.ts +0 -350
  62. package/compiler/transform/componentScriptTransformer.ts +0 -303
  63. package/compiler/transform/expressionTransformer.ts +0 -385
  64. package/compiler/transform/fragmentLowering.ts +0 -819
  65. package/compiler/transform/generateBindings.ts +0 -68
  66. package/compiler/transform/generateHTML.ts +0 -28
  67. package/compiler/transform/layoutProcessor.ts +0 -132
  68. package/compiler/transform/slotResolver.ts +0 -292
  69. package/compiler/transform/transformNode.ts +0 -314
  70. package/compiler/transform/transformTemplate.ts +0 -38
  71. package/compiler/validate/invariants.ts +0 -292
  72. package/compiler/validate/validateExpressions.ts +0 -168
  73. package/core/config/index.ts +0 -18
  74. package/core/config/loader.ts +0 -69
  75. package/core/config/types.ts +0 -119
  76. package/core/plugins/bridge.ts +0 -193
  77. package/core/plugins/index.ts +0 -7
  78. package/core/plugins/registry.ts +0 -126
  79. package/dist/cli.js +0 -11675
  80. package/runtime/build.ts +0 -17
  81. package/runtime/bundle-generator.ts +0 -1266
  82. package/runtime/client-runtime.ts +0 -891
  83. package/runtime/serve.ts +0 -93
@@ -1,317 +0,0 @@
1
- /**
2
- * Zenith CSS Compiler Module
3
- *
4
- * Compiler-owned CSS processing that integrates Tailwind CSS v4 JIT
5
- * at compile time. This module ensures:
6
- *
7
- * 1. All CSS is processed at build time (no runtime generation)
8
- * 2. Tailwind sees all .zen templates for class scanning
9
- * 3. HMR support for instant CSS updates in dev mode
10
- * 4. Deterministic, cacheable output for production
11
- *
12
- * Per Zenith CSS Directive: The compiler owns styles.
13
- */
14
-
15
- import { spawn, spawnSync } from 'child_process'
16
- import path from 'path'
17
- import fs from 'fs'
18
-
19
- // ============================================
20
- // Types
21
- // ============================================
22
-
23
- export interface CSSCompileOptions {
24
- /** Input CSS file path (e.g., src/styles/globals.css) */
25
- input: string
26
- /** Output CSS file path, or ':memory:' for in-memory result */
27
- output: string
28
- /** Enable minification for production */
29
- minify?: boolean
30
- /** Watch mode for HMR */
31
- watch?: boolean
32
- }
33
-
34
- export interface CSSCompileResult {
35
- /** Compiled CSS content */
36
- css: string
37
- /** Compilation time in milliseconds */
38
- duration: number
39
- /** Whether compilation succeeded */
40
- success: boolean
41
- /** Error message if failed */
42
- error?: string
43
- }
44
-
45
- // ============================================
46
- // CSS Compilation
47
- // ============================================
48
-
49
- /**
50
- * Compile CSS using Tailwind CSS v4 CLI
51
- *
52
- * This function synchronously compiles CSS for use in:
53
- * - Dev server startup
54
- * - SSG build
55
- * - On-demand recompilation
56
- *
57
- * @param options Compilation options
58
- * @returns Compiled CSS result
59
- */
60
- export function compileCss(options: CSSCompileOptions): CSSCompileResult {
61
- const startTime = performance.now()
62
- const { input, output, minify = false } = options
63
-
64
- // Validate input exists
65
- if (!fs.existsSync(input)) {
66
- return {
67
- css: '',
68
- duration: 0,
69
- success: false,
70
- error: `CSS input file not found: ${input}`
71
- }
72
- }
73
-
74
- try {
75
- // Build Tailwind CLI arguments
76
- const args = [
77
- '@tailwindcss/cli',
78
- '-i', input
79
- ]
80
-
81
- // For in-memory compilation, use stdout
82
- const useStdout = output === ':memory:'
83
- if (!useStdout) {
84
- args.push('-o', output)
85
- }
86
-
87
- if (minify) {
88
- args.push('--minify')
89
- }
90
-
91
- // Execute Tailwind CLI synchronously
92
- const result = spawnSync('bunx', args, {
93
- cwd: path.dirname(input),
94
- encoding: 'utf-8',
95
- stdio: useStdout ? ['pipe', 'pipe', 'pipe'] : ['pipe', 'inherit', 'pipe'],
96
- env: { ...process.env }
97
- })
98
-
99
- const duration = Math.round(performance.now() - startTime)
100
-
101
- if (result.status !== 0) {
102
- const errorMsg = result.stderr?.toString() || 'Unknown compilation error'
103
- return {
104
- css: '',
105
- duration,
106
- success: false,
107
- error: `Tailwind compilation failed: ${errorMsg}`
108
- }
109
- }
110
-
111
- // Get CSS content
112
- let css = ''
113
- if (useStdout) {
114
- css = result.stdout?.toString() || ''
115
- } else if (fs.existsSync(output)) {
116
- css = fs.readFileSync(output, 'utf-8')
117
- }
118
-
119
- return {
120
- css,
121
- duration,
122
- success: true
123
- }
124
-
125
- } catch (error: any) {
126
- return {
127
- css: '',
128
- duration: Math.round(performance.now() - startTime),
129
- success: false,
130
- error: error.message
131
- }
132
- }
133
- }
134
-
135
- /**
136
- * Compile CSS asynchronously (non-blocking)
137
- *
138
- * Used for HMR updates where we don't want to block the main thread.
139
- */
140
- export async function compileCssAsync(options: CSSCompileOptions): Promise<CSSCompileResult> {
141
- return new Promise((resolve) => {
142
- const startTime = performance.now()
143
- const { input, output, minify = false } = options
144
-
145
- if (!fs.existsSync(input)) {
146
- resolve({
147
- css: '',
148
- duration: 0,
149
- success: false,
150
- error: `CSS input file not found: ${input}`
151
- })
152
- return
153
- }
154
-
155
- const args = ['@tailwindcss/cli', '-i', input]
156
- const useStdout = output === ':memory:'
157
-
158
- if (!useStdout) {
159
- args.push('-o', output)
160
- }
161
-
162
- if (minify) {
163
- args.push('--minify')
164
- }
165
-
166
- const child = spawn('bunx', args, {
167
- cwd: path.dirname(input),
168
- stdio: useStdout ? ['pipe', 'pipe', 'pipe'] : ['pipe', 'inherit', 'pipe'],
169
- env: { ...process.env }
170
- })
171
-
172
- let stdout = ''
173
- let stderr = ''
174
-
175
- if (useStdout && child.stdout) {
176
- child.stdout.on('data', (data) => { stdout += data.toString() })
177
- }
178
-
179
- if (child.stderr) {
180
- child.stderr.on('data', (data) => { stderr += data.toString() })
181
- }
182
-
183
- child.on('close', (code) => {
184
- const duration = Math.round(performance.now() - startTime)
185
-
186
- if (code !== 0) {
187
- resolve({
188
- css: '',
189
- duration,
190
- success: false,
191
- error: `Tailwind compilation failed: ${stderr}`
192
- })
193
- return
194
- }
195
-
196
- let css = ''
197
- if (useStdout) {
198
- css = stdout
199
- } else if (fs.existsSync(output)) {
200
- css = fs.readFileSync(output, 'utf-8')
201
- }
202
-
203
- resolve({
204
- css,
205
- duration,
206
- success: true
207
- })
208
- })
209
-
210
- child.on('error', (err) => {
211
- resolve({
212
- css: '',
213
- duration: Math.round(performance.now() - startTime),
214
- success: false,
215
- error: err.message
216
- })
217
- })
218
- })
219
- }
220
-
221
- // ============================================
222
- // CSS Watcher for HMR
223
- // ============================================
224
-
225
- export interface CSSWatchOptions extends CSSCompileOptions {
226
- /** Callback when CSS changes */
227
- onChange: (result: CSSCompileResult) => void
228
- /** Debounce delay in ms */
229
- debounce?: number
230
- }
231
-
232
- /**
233
- * Watch CSS and source files for changes, recompile on change
234
- *
235
- * This is used by the dev server for HMR support.
236
- * It watches both the CSS entry point AND all .zen files
237
- * that Tailwind scans for class names.
238
- */
239
- export function watchCss(options: CSSWatchOptions): () => void {
240
- const { input, output, minify, onChange, debounce = 100 } = options
241
-
242
- let timeout: NodeJS.Timeout | null = null
243
- let isCompiling = false
244
-
245
- const recompile = async () => {
246
- if (isCompiling) return
247
- isCompiling = true
248
-
249
- const result = await compileCssAsync({ input, output, minify })
250
- onChange(result)
251
-
252
- isCompiling = false
253
- }
254
-
255
- const debouncedRecompile = () => {
256
- if (timeout) clearTimeout(timeout)
257
- timeout = setTimeout(recompile, debounce)
258
- }
259
-
260
- // Watch the styles directory
261
- const stylesDir = path.dirname(input)
262
- const stylesWatcher = fs.watch(stylesDir, { recursive: true }, (event, filename) => {
263
- if (filename?.endsWith('.css')) {
264
- debouncedRecompile()
265
- }
266
- })
267
-
268
- // Watch source files that Tailwind scans (for class changes)
269
- // This assumes standard Zenith structure: src/pages, src/components, src/layouts
270
- const srcDir = path.resolve(stylesDir, '..')
271
- let srcWatcher: fs.FSWatcher | null = null
272
-
273
- if (fs.existsSync(srcDir)) {
274
- srcWatcher = fs.watch(srcDir, { recursive: true }, (event, filename) => {
275
- if (filename?.endsWith('.zen') || filename?.endsWith('.tsx') || filename?.endsWith('.jsx')) {
276
- debouncedRecompile()
277
- }
278
- })
279
- }
280
-
281
- // Return cleanup function
282
- return () => {
283
- if (timeout) clearTimeout(timeout)
284
- stylesWatcher.close()
285
- srcWatcher?.close()
286
- }
287
- }
288
-
289
- // ============================================
290
- // Path Utilities
291
- // ============================================
292
-
293
- /**
294
- * Resolve the canonical globals.css path for a Zenith project
295
- */
296
- export function resolveGlobalsCss(projectRoot: string): string | null {
297
- // Check for globals.css (canonical)
298
- const globalsPath = path.join(projectRoot, 'src', 'styles', 'globals.css')
299
- if (fs.existsSync(globalsPath)) return globalsPath
300
-
301
- // Check for global.css (legacy)
302
- const globalPath = path.join(projectRoot, 'src', 'styles', 'global.css')
303
- if (fs.existsSync(globalPath)) return globalPath
304
-
305
- return null
306
- }
307
-
308
- /**
309
- * Get the output path for compiled CSS
310
- */
311
- export function getCompiledCssPath(projectRoot: string, mode: 'dev' | 'build'): string {
312
- if (mode === 'build') {
313
- return path.join(projectRoot, 'dist', 'assets', 'styles.css')
314
- }
315
- // In dev mode, we use in-memory compilation
316
- return ':memory:'
317
- }
@@ -1,242 +0,0 @@
1
- /**
2
- * Component Discovery
3
- *
4
- * Discovers and catalogs components in a Zenith project.
5
- * Components are auto-imported based on filename:
6
- *
7
- * Auto-Import Rules:
8
- * - Component name = filename (without .zen extension)
9
- * - Subdirectories are for organization, not namespacing
10
- * - Name collisions produce compile-time errors with clear messages
11
- *
12
- * Examples:
13
- * components/Header.zen → <Header />
14
- * components/sections/HeroSection.zen → <HeroSection />
15
- * components/ui/buttons/Primary.zen → <Primary />
16
- *
17
- * If you have name collisions (same filename in different directories),
18
- * you must rename one of the components.
19
- *
20
- * Requirements:
21
- * - Auto-import resolution is deterministic and compile-time only
22
- * - Name collisions produce compile-time errors with clear messages
23
- * - No runtime component registration or global singleton registries
24
- */
25
-
26
- import * as fs from 'fs'
27
- import * as path from 'path'
28
- import { parseZenFile } from '../parse/parseZenFile'
29
- import { CompilerError } from '../errors/compilerError'
30
- import type { TemplateNode, ExpressionIR } from '../ir/types'
31
-
32
- export interface SlotDefinition {
33
- name: string | null // null = default slot, string = named slot
34
- location: {
35
- line: number
36
- column: number
37
- }
38
- }
39
-
40
- export interface ComponentMetadata {
41
- name: string // Component name (e.g., "Card", "HeroSection")
42
- path: string // Absolute path to .zen file
43
- relativePath: string // Relative path from components directory
44
- template: string // Raw template HTML
45
- nodes: TemplateNode[] // Parsed template nodes
46
- expressions: ExpressionIR[] // Expressions referenced by nodes
47
- slots: SlotDefinition[]
48
- props: string[] // Declared props
49
- styles: string[] // Raw CSS from <style> blocks
50
- script: string | null // Raw script content for bundling
51
- scriptAttributes: Record<string, string> | null // Script attributes (setup, lang)
52
- hasScript: boolean
53
- hasStyles: boolean
54
- }
55
-
56
- /**
57
- * Discover all components in a directory with auto-import naming
58
- *
59
- * Components are named by their filename (without .zen extension).
60
- * Subdirectories are for organization only and do not affect the component name.
61
- *
62
- * @param baseDir - Base directory to search (e.g., src/components)
63
- * @returns Map of component name to metadata
64
- * @throws CompilerError on name collisions
65
- */
66
- export function discoverComponents(baseDir: string): Map<string, ComponentMetadata> {
67
- const components = new Map<string, ComponentMetadata>()
68
- const collisions = new Map<string, string[]>() // name → [relative paths]
69
-
70
- // Check if components directory exists
71
- if (!fs.existsSync(baseDir)) {
72
- return components
73
- }
74
-
75
- // Recursively find all .zen files
76
- const zenFiles = findZenFiles(baseDir)
77
-
78
- for (const filePath of zenFiles) {
79
- try {
80
- const metadata = parseComponentFile(filePath, baseDir)
81
- if (metadata) {
82
- // Check for collision
83
- if (components.has(metadata.name)) {
84
- const existing = components.get(metadata.name)!
85
- if (!collisions.has(metadata.name)) {
86
- collisions.set(metadata.name, [existing.relativePath])
87
- }
88
- collisions.get(metadata.name)!.push(metadata.relativePath)
89
- } else {
90
- components.set(metadata.name, metadata)
91
- }
92
- }
93
- } catch (error: any) {
94
- console.warn(`[Zenith] Failed to parse component ${filePath}: ${error.message}`)
95
- }
96
- }
97
-
98
- // Report all collisions as a single error
99
- if (collisions.size > 0) {
100
- const collisionMessages = Array.from(collisions.entries())
101
- .map(([name, paths]) => {
102
- const pathList = paths.map(p => ` - ${p}`).join('\n')
103
- return `Component name "${name}" is used by multiple files:\n${pathList}`
104
- })
105
- .join('\n\n')
106
-
107
- throw new CompilerError(
108
- `Component name collision detected!\n\n${collisionMessages}\n\n` +
109
- `Each component must have a unique filename.\n` +
110
- `To fix: Rename one of the conflicting components to have a unique name.`,
111
- baseDir,
112
- 0,
113
- 0
114
- )
115
- }
116
-
117
- return components
118
- }
119
-
120
- /**
121
- * Recursively find all .zen files in a directory
122
- */
123
- function findZenFiles(dir: string): string[] {
124
- const files: string[] = []
125
-
126
- if (!fs.existsSync(dir)) {
127
- return files
128
- }
129
-
130
- const entries = fs.readdirSync(dir, { withFileTypes: true })
131
-
132
- for (const entry of entries) {
133
- const fullPath = path.join(dir, entry.name)
134
-
135
- if (entry.isDirectory()) {
136
- files.push(...findZenFiles(fullPath))
137
- } else if (entry.isFile() && entry.name.endsWith('.zen')) {
138
- files.push(fullPath)
139
- }
140
- }
141
-
142
- return files
143
- }
144
-
145
- /**
146
- * Parse a component file and extract metadata
147
- *
148
- * Component name is derived from the filename (without .zen extension).
149
- *
150
- * @param filePath - Absolute path to the component file
151
- * @param baseDir - Base directory for component discovery (used for relative path)
152
- */
153
- function parseComponentFile(filePath: string, baseDir: string): ComponentMetadata | null {
154
- const ir = parseZenFile(filePath)
155
-
156
- // Component name is just the filename (without .zen extension)
157
- const componentName = path.basename(filePath, '.zen')
158
-
159
- // Relative path for error messages and debugging
160
- const relativePath = path.relative(baseDir, filePath)
161
-
162
- // Extract slots from template
163
- const slots = extractSlots(ir.template.nodes)
164
-
165
- // Extract props from script attributes
166
- const props = ir.script?.attributes['props']?.split(',').map(p => p.trim()) || []
167
-
168
- // Extract raw CSS from styles
169
- const styles = ir.styles.map(s => s.raw)
170
-
171
- return {
172
- name: componentName,
173
- path: filePath,
174
- relativePath,
175
- template: ir.template.raw,
176
- nodes: ir.template.nodes,
177
- expressions: ir.template.expressions, // Store expressions for later merging
178
- slots,
179
- props,
180
- styles,
181
- script: ir.script?.raw || null, // Store raw script content
182
- scriptAttributes: ir.script?.attributes || null, // Store script attributes
183
- hasScript: ir.script !== null,
184
- hasStyles: ir.styles.length > 0
185
- }
186
- }
187
-
188
- /**
189
- * Extract slot definitions from template nodes
190
- */
191
- function extractSlots(nodes: TemplateNode[]): SlotDefinition[] {
192
- const slots: SlotDefinition[] = []
193
-
194
- function traverse(node: TemplateNode) {
195
- if (node.type === 'element') {
196
- // Check if this is a <slot> tag
197
- if (node.tag === 'slot') {
198
- // Extract slot name from attributes
199
- const nameAttr = node.attributes.find(attr => attr.name === 'name')
200
- const slotName = typeof nameAttr?.value === 'string' ? nameAttr.value : null
201
-
202
- slots.push({
203
- name: slotName,
204
- location: node.location
205
- })
206
- }
207
-
208
- // Traverse children
209
- for (const child of node.children) {
210
- traverse(child)
211
- }
212
- } else if (node.type === 'component') {
213
- // Also traverse component children
214
- for (const child of node.children) {
215
- traverse(child)
216
- }
217
- }
218
- }
219
-
220
- for (const node of nodes) {
221
- traverse(node)
222
- }
223
-
224
- return slots
225
- }
226
-
227
- /**
228
- * Check if a tag name represents a component (starts with uppercase)
229
- */
230
- export function isComponentTag(tagName: string): boolean {
231
- return tagName.length > 0 && tagName[0] !== undefined && tagName[0] === tagName[0].toUpperCase()
232
- }
233
-
234
- /**
235
- * Get component metadata by name
236
- */
237
- export function getComponent(
238
- components: Map<string, ComponentMetadata>,
239
- name: string
240
- ): ComponentMetadata | undefined {
241
- return components.get(name)
242
- }
@@ -1,70 +0,0 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import { parseTemplate } from '../parse/parseTemplate'
4
- import { parseScript } from '../parse/parseScript'
5
- import { extractProps, extractStateDeclarations } from '../parse/scriptAnalysis'
6
-
7
- export interface LayoutMetadata {
8
- name: string
9
- filePath: string
10
- props: string[]
11
- states: Map<string, string>
12
- html: string
13
- scripts: string[]
14
- styles: string[]
15
- }
16
-
17
- /**
18
- * Discover layouts in a directory
19
- */
20
- export function discoverLayouts(layoutsDir: string): Map<string, LayoutMetadata> {
21
- const layouts = new Map<string, LayoutMetadata>()
22
-
23
- if (!fs.existsSync(layoutsDir)) return layouts
24
-
25
- const files = fs.readdirSync(layoutsDir)
26
- for (const file of files) {
27
- if (file.endsWith('.zen')) {
28
- const filePath = path.join(layoutsDir, file)
29
- const name = path.basename(file, '.zen')
30
- const source = fs.readFileSync(filePath, 'utf-8')
31
-
32
- const script = parseScript(source)
33
- const props = script ? extractProps(script.raw) : []
34
- const states = script ? extractStateDeclarations(script.raw) : new Map()
35
-
36
- // Extract styles
37
- const styles: string[] = []
38
- const styleRegex = /<style[^>]*>([\s\S]*?)<\/style>/gi
39
- let match
40
- while ((match = styleRegex.exec(source)) !== null) {
41
- if (match[1]) styles.push(match[1].trim())
42
- }
43
-
44
- // Extract HTML (everything except inline scripts/style)
45
- // Preserve external script tags (<script src="...">) but remove inline <script setup> blocks
46
- // Use a function-based replace to check for src attribute
47
- let html = source.replace(/<script([^>]*)>([\s\S]*?)<\/script>/gi, (match, attrs, content) => {
48
- // Keep script tags with src attribute (external scripts)
49
- if (attrs.includes('src=')) {
50
- return match;
51
- }
52
- // Remove inline scripts (those without src)
53
- return '';
54
- })
55
- html = html.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '').trim()
56
-
57
- layouts.set(name, {
58
- name,
59
- filePath,
60
- props,
61
- states,
62
- html,
63
- scripts: script ? [script.raw] : [],
64
- styles
65
- })
66
- }
67
- }
68
-
69
- return layouts
70
- }
@@ -1,56 +0,0 @@
1
- /**
2
- * Compiler Error Handling
3
- *
4
- * Compiler errors with source location information
5
- */
6
-
7
- export class CompilerError extends Error {
8
- file: string
9
- line: number
10
- column: number
11
-
12
- constructor(message: string, file: string, line: number, column: number) {
13
- super(`${file}:${line}:${column} ${message}`)
14
- this.name = 'CompilerError'
15
- this.file = file
16
- this.line = line
17
- this.column = column
18
- }
19
-
20
- override toString(): string {
21
- return `${this.file}:${this.line}:${this.column} ${this.message}`
22
- }
23
- }
24
-
25
- /**
26
- * Invariant Error
27
- *
28
- * Thrown when a Zenith compiler invariant is violated.
29
- * Invariants are non-negotiable rules that guarantee correct behavior.
30
- *
31
- * If an invariant fails, the compiler is at fault — not the user.
32
- * The user receives a clear explanation of what is forbidden and why.
33
- */
34
- export class InvariantError extends CompilerError {
35
- invariantId: string
36
- guarantee: string
37
-
38
- constructor(
39
- invariantId: string,
40
- message: string,
41
- guarantee: string,
42
- file: string,
43
- line: number,
44
- column: number
45
- ) {
46
- super(`[${invariantId}] ${message}\n\n Zenith Guarantee: ${guarantee}`, file, line, column)
47
- this.name = 'InvariantError'
48
- this.invariantId = invariantId
49
- this.guarantee = guarantee
50
- }
51
-
52
- override toString(): string {
53
- return `${this.file}:${this.line}:${this.column} [${this.invariantId}] ${this.message}`
54
- }
55
- }
56
-