@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
package/README.md CHANGED
@@ -1,37 +1,38 @@
1
1
  # @zenithbuild/core ⚡
2
2
 
3
- The heart of the Zenith framework. High-performance reactive runtime, compiler, and build primitives.
3
+ The execution target and orchestrator for the Zenith framework. Contains the minimal reactive runtime and CLI tools.
4
4
 
5
5
  ## Overview
6
6
 
7
- Zenith is a modern reactive web framework designed for maximum performance and developer experience. The core package contains the essential building blocks:
8
- - **Compiler**: Transforms `.zen` files into optimized JavaScript.
9
- - **Runtime**: A lightweight, efficient reactive system for the browser.
10
- - **Router**: Lightweight client-side routing.
11
- - **Build Primitives**: Tools for dev servers and production builds.
7
+ Zenith is a modern reactive web framework designed for maximum performance and developer experience. The core package serves as the **Execution Target**:
8
+ - **Reactivity Engine**: Atomic signals and deep state with zero runtime abstraction.
9
+ - **Lifecycle System**: Efficient `onMount`/`onUnmount` management.
10
+ - **CLI Orchestrator**: Commands (`dev`, `build`, `preview`) that drive the native compiler.
12
11
 
13
12
  ## Key Components
14
13
 
15
- ### 1. Compiler (`/compiler`)
16
- The Zenith compiler handles parsing and transforming Single File Components (`.zen`). It leverages `parse5` for robust HTML parsing and generates highly optimized render functions.
14
+ ### 1. Reactivity (`/core/reactivity`)
15
+ The foundational reactive system. Pure, fast, and deterministic.
17
16
 
18
- ### 2. Runtime (`/runtime`)
19
- Our runtime is designed to be minimal. It manages the reactive cycle, efficient DOM updates, and lifecycle management (like `zenOnMount`).
17
+ ### 2. Lifecycle (`/core/lifecycle`)
18
+ Instance-based lifecycle management tied to the DOM.
20
19
 
21
- ### 3. Server (`/bin/zen-dev`, `/bin/zen-build`)
22
- Low-level binaries for orchestrating development and production environments.
20
+ ### 3. CLI (`/cli`)
21
+ The command-line interface that orchestrates the system build chain.
23
22
 
24
- ## Architecture
23
+ ## Coordinated Architecture
25
24
 
26
- Zenith follows a "Compiler-First" philosophy. We shift as much work as possible to build time, keeping the client-side bundle lean and fast.
25
+ Zenith follows a strict "Compiler-First" philosophy:
26
+ - **@zenithbuild/compiler**: Owns all structures, wiring, and build-time guarantees.
27
+ - **@zenithbuild/core**: Owns the minimal runtime execution needed to run compiled plans.
27
28
 
28
- ## Usage (Internal)
29
-
30
- This package is typically consumed by the Zenith CLI and other ecosystem tools.
29
+ ## Usage
31
30
 
32
31
  ```typescript
33
- import { compile } from '@zenithbuild/core/compiler';
34
- // ... compile logic
32
+ import { signal, effect, onMount } from '@zenithbuild/core';
33
+
34
+ const count = signal(0);
35
+ onMount(() => console.log('Ready'));
35
36
  ```
36
37
 
37
38
  ## License
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @zenith/cli - Add Command
2
+ * @zenithbuild/cli - Add Command
3
3
  *
4
4
  * Registers a plugin in the project
5
5
  */
@@ -32,6 +32,6 @@ export async function add(pluginName: string, options: AddOptions = {}): Promise
32
32
  if (success) {
33
33
  logger.info(`Plugin "${pluginName}" has been registered.`)
34
34
  logger.info('Note: You may need to install the package manually:')
35
- logger.log(` bun add @zenith/plugin-${pluginName}`)
35
+ logger.log(` bun add @zenithbuild/plugin-${pluginName}`)
36
36
  }
37
37
  }
@@ -1,13 +1,12 @@
1
1
  /**
2
- * @zenith/cli - Build Command
2
+ * @zenithbuild/cli - Build Command
3
3
  *
4
4
  * Builds the application for production using SSG.
5
5
  */
6
6
 
7
- import path from 'path'
8
7
  import { requireProject } from '../utils/project'
9
8
  import * as logger from '../utils/logger'
10
- import { buildSSG } from '../../compiler/ssg-build'
9
+ import { buildSSG } from '@zenithbuild/compiler'
11
10
 
12
11
  export interface BuildOptions {
13
12
  outDir?: string
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @zenith/cli - Dev Command
2
+ * @zenithbuild/cli - Dev Command
3
3
  *
4
4
  * Development server with HMR support.
5
5
  *
@@ -24,22 +24,24 @@ import { serve, type ServerWebSocket } from 'bun'
24
24
  import { requireProject } from '../utils/project'
25
25
  import * as logger from '../utils/logger'
26
26
  import * as brand from '../utils/branding'
27
- import { compileZenSource } from '../../compiler/index'
28
- import { discoverLayouts } from '../../compiler/discovery/layouts'
29
- import { processLayout } from '../../compiler/transform/layoutProcessor'
30
- import { generateRouteDefinition } from '@zenithbuild/router'
31
- import { generateBundleJS } from '../../runtime/bundle-generator'
32
- import { loadZenithConfig } from '../../core/config/loader'
33
- import { PluginRegistry, createPluginContext, getPluginDataByNamespace } from '../../core/plugins/registry'
34
- import { compileCssAsync, resolveGlobalsCss } from '../../compiler/css'
35
27
  import {
28
+ compileZenSource,
29
+ discoverLayouts,
30
+ processLayout,
31
+ generateBundleJS,
32
+ loadZenithConfig,
33
+ PluginRegistry,
34
+ createPluginContext,
35
+ getPluginDataByNamespace,
36
+ compileCssAsync,
37
+ resolveGlobalsCss,
36
38
  createBridgeAPI,
37
39
  runPluginHooks,
38
40
  collectHookReturns,
39
41
  buildRuntimeEnvelope,
40
42
  clearHooks,
41
43
  type HookContext
42
- } from '../../core/plugins/bridge'
44
+ } from '@zenithbuild/compiler'
43
45
 
44
46
  export interface DevOptions {
45
47
  port?: number
@@ -56,53 +58,10 @@ interface CompiledPage {
56
58
  const pageCache = new Map<string, CompiledPage>()
57
59
 
58
60
  /**
59
- * Bundle page script using Bun's bundler to resolve npm imports at compile time.
60
- * This allows ES module imports like `import { gsap } from 'gsap'` to work.
61
+ * Bundle page script using Rolldown to resolve npm imports at compile time.
62
+ * Only called when compiler emits a BundlePlan - bundler performs no inference.
61
63
  */
62
- async function bundlePageScript(script: string, projectRoot: string): Promise<string> {
63
- // If no import statements, return as-is
64
- if (!script.includes('import ')) {
65
- return script
66
- }
67
-
68
- // Write temp file in PROJECT directory so Bun can find node_modules
69
- const tempDir = path.join(projectRoot, '.zenith-cache')
70
- if (!fs.existsSync(tempDir)) {
71
- fs.mkdirSync(tempDir, { recursive: true })
72
- }
73
- const tempFile = path.join(tempDir, `bundle-${Date.now()}.js`)
74
-
75
- try {
76
- // Write script to temp file
77
- fs.writeFileSync(tempFile, script, 'utf-8')
78
-
79
- // Use Bun.build to bundle with npm resolution from project's node_modules
80
- const result = await Bun.build({
81
- entrypoints: [tempFile],
82
- target: 'browser',
83
- format: 'esm',
84
- minify: false,
85
- external: [], // Bundle everything
86
- })
87
-
88
- if (!result.success || !result.outputs[0]) {
89
- console.error('[Zenith] Bundle errors:', result.logs)
90
- return script // Fall back to original
91
- }
92
-
93
- // Get the bundled output
94
- const bundledCode = await result.outputs[0].text()
95
- return bundledCode
96
- } catch (error: any) {
97
- console.error('[Zenith] Failed to bundle page script:', error.message)
98
- return script // Fall back to original
99
- } finally {
100
- // Clean up temp file
101
- try {
102
- fs.unlinkSync(tempFile)
103
- } catch { }
104
- }
105
- }
64
+ import { bundlePageScript, type BundlePlan, generateRouteDefinition } from '@zenithbuild/compiler'
106
65
 
107
66
  export async function dev(options: DevOptions = {}): Promise<void> {
108
67
  const project = requireProject()
@@ -208,8 +167,69 @@ export async function dev(options: DevOptions = {}): Promise<void> {
208
167
 
209
168
  const routeDef = generateRouteDefinition(pagePath, pagesDir)
210
169
 
211
- // Bundle the script to resolve npm imports at compile time
212
- const bundledScript = await bundlePageScript(result.finalized.js, rootDir)
170
+
171
+
172
+ // Safely strip imports from the top of the script
173
+ // This relies on the fact that duplicate imports (from Rust codegen)
174
+ // appear at the beginning of result.finalized.js
175
+ let jsLines = result.finalized.js.split('\n')
176
+
177
+ // Remove lines from top that are imports, whitespace, or comments
178
+ while (jsLines.length > 0 && jsLines[0] !== undefined) {
179
+ const line = jsLines[0].trim()
180
+ if (
181
+ line.startsWith('import ') ||
182
+ line === '' ||
183
+ line.startsWith('//') ||
184
+ line.startsWith('/*') ||
185
+ line.startsWith('*')
186
+ ) {
187
+ jsLines.shift()
188
+ } else {
189
+ break
190
+ }
191
+ }
192
+
193
+ let jsWithoutImports = jsLines.join('\n')
194
+
195
+ // PATCH: Fix unquoted keys with dashes (Rust codegen bug in jsx_lowerer)
196
+ // e.g. stroke-width: "1.5" -> "stroke-width": "1.5"
197
+ // We only apply this to the JS portions (Script and Expressions)
198
+ // to avoid corrupting the Styles section.
199
+ const stylesMarker = '// 6. Styles injection'
200
+ const parts = jsWithoutImports.split(stylesMarker)
201
+
202
+ if (parts.length > 1) {
203
+ // Apply patch only to the JS part
204
+ parts[0] = parts[0]!.replace(
205
+ /(^|[{,])\s*([a-zA-Z][a-zA-Z0-9-]*-[a-zA-Z0-9-]*)\s*:/gm,
206
+ '$1"$2":'
207
+ )
208
+ jsWithoutImports = parts.join(stylesMarker)
209
+ } else {
210
+ // Fallback if marker not found
211
+ jsWithoutImports = jsWithoutImports.replace(
212
+ /(^|[{,])\s*([a-zA-Z][a-zA-Z0-9-]*-[a-zA-Z0-9-]*)\s*:/gm,
213
+ '$1"$2":'
214
+ )
215
+ }
216
+
217
+ // Combine: structured imports first, then cleaned script body
218
+ const fullScript = (result.finalized.npmImports || '') + '\n\n' + jsWithoutImports
219
+
220
+ console.log('[Dev] Page Imports:', result.finalized.npmImports ? result.finalized.npmImports.split('\n').length : 0, 'lines')
221
+
222
+ // Bundle ONLY if compiler emitted a BundlePlan (no inference)
223
+ let bundledScript = fullScript
224
+ if (result.finalized.bundlePlan) {
225
+ // Compiler decided bundling is needed - pass plan with proper resolve roots
226
+ const plan: BundlePlan = {
227
+ ...result.finalized.bundlePlan,
228
+ entry: fullScript,
229
+ resolveRoots: [path.join(rootDir, 'node_modules'), 'node_modules']
230
+ }
231
+ bundledScript = await bundlePageScript(plan)
232
+ }
213
233
 
214
234
  return {
215
235
  html: result.finalized.html,
@@ -231,25 +251,21 @@ export async function dev(options: DevOptions = {}): Promise<void> {
231
251
  * It serializes blindly - never inspecting what's inside.
232
252
  */
233
253
  async function generateDevHTML(page: CompiledPage): Promise<string> {
234
- // Collect runtime payloads from ALL plugins
235
- // CLI doesn't know which plugins will respond - it just collects
236
- const payloads = await collectHookReturns('cli:runtime:collect', hookCtx)
237
-
238
- // Build envelope - CLI doesn't know what's inside
239
- const envelope = buildRuntimeEnvelope(payloads)
240
-
241
- // Escape </script> sequences in JSON to prevent breaking the script tag
242
- const envelopeJson = JSON.stringify(envelope).replace(/<\//g, '<\\/')
243
-
244
- // Single neutral injection point - NOT plugin-specific
254
+ // Single neutral injection point
245
255
  const runtimeTag = `<script src="/runtime.js"></script>`
246
- const pluginDataTag = `<script>window.__ZENITH_PLUGIN_DATA__ = ${envelopeJson};</script>`
247
256
  const scriptTag = `<script type="module">\n${page.script}\n</script>`
248
- const allScripts = `${runtimeTag}\n${pluginDataTag}\n${scriptTag}`
257
+ const allScripts = `${runtimeTag}\n${scriptTag}`
249
258
 
250
- return page.html.includes('</body>')
259
+ let html = page.html.includes('</body>')
251
260
  ? page.html.replace('</body>', `${allScripts}\n</body>`)
252
261
  : `${page.html}\n${allScripts}`
262
+
263
+ // Ensure DOCTYPE is present to prevent Quirks Mode (critical for SVG namespace)
264
+ if (!html.trimStart().toLowerCase().startsWith('<!doctype')) {
265
+ html = `<!DOCTYPE html>\n${html}`
266
+ }
267
+
268
+ return html
253
269
  }
254
270
 
255
271
  // ============================================
@@ -327,7 +343,11 @@ export async function dev(options: DevOptions = {}): Promise<void> {
327
343
 
328
344
  // Handle Zenith assets
329
345
  if (pathname === '/runtime.js') {
330
- const response = new Response(generateBundleJS(), {
346
+ // Collect runtime payloads from ALL plugins
347
+ const payloads = await collectHookReturns('cli:runtime:collect', hookCtx)
348
+ const envelope = buildRuntimeEnvelope(payloads)
349
+
350
+ const response = new Response(generateBundleJS(envelope), {
331
351
  headers: { 'Content-Type': 'application/javascript; charset=utf-8' }
332
352
  })
333
353
  logger.route('GET', pathname, 200, Math.round(performance.now() - startTime), 0, Math.round(performance.now() - startTime))
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @zenith/cli - Command Registry
2
+ * @zenithbuild/cli - Command Registry
3
3
  *
4
4
  * Central registry for all CLI commands
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @zenith/cli - Preview Command
2
+ * @zenithbuild/cli - Preview Command
3
3
  *
4
4
  * Serves the production build from the distribution directory.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @zenith/cli - Remove Command
2
+ * @zenithbuild/cli - Remove Command
3
3
  *
4
4
  * Removes a plugin from the project registry
5
5
  */
@@ -28,6 +28,6 @@ export async function remove(pluginName: string): Promise<void> {
28
28
  if (success) {
29
29
  logger.info(`Plugin "${pluginName}" has been unregistered.`)
30
30
  logger.info('Note: You may want to remove the package manually:')
31
- logger.log(` bun remove @zenith/plugin-${pluginName}`)
31
+ logger.log(` bun remove @zenithbuild/plugin-${pluginName}`)
32
32
  }
33
33
  }
package/cli/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @zenith/cli
2
+ * @zenithbuild/cli
3
3
  *
4
4
  * CLI for Zenith framework - dev server, build tools, and plugin management
5
5
  */
package/cli/main.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @zenith/cli - Shared CLI Execution Logic
2
+ * @zenithbuild/cli - Shared CLI Execution Logic
3
3
  */
4
4
 
5
5
  import process from 'node:process'
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @zenith/cli - Logger Utility
2
+ * @zenithbuild/cli - Logger Utility
3
3
  *
4
4
  * Colored console output for CLI feedback
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @zenith/cli - Plugin Manager
2
+ * @zenithbuild/cli - Plugin Manager
3
3
  *
4
4
  * Manages zenith.plugins.json for plugin registration
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @zenith/cli - Project Utility
2
+ * @zenithbuild/cli - Project Utility
3
3
  *
4
4
  * Detects Zenith project root and configuration
5
5
  */
@@ -28,8 +28,8 @@ export function findProjectRoot(startDir: string = process.cwd()): string | null
28
28
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
29
29
  const deps = { ...pkg.dependencies, ...pkg.devDependencies }
30
30
 
31
- // Check for any @zenith/* or @zenithbuild/* dependency
32
- const hasZenith = Object.keys(deps).some(d => d.startsWith('@zenith/') || d.startsWith('@zenithbuild/'))
31
+ // Check for any @zenithbuild/* or @zenithbuild/* dependency
32
+ const hasZenith = Object.keys(deps).some(d => d.startsWith('@zenithbuild/') || d.startsWith('@zenithbuild/'))
33
33
  if (hasZenith) {
34
34
  return current
35
35
  }
@@ -71,7 +71,7 @@ export function getProject(cwd: string = process.cwd()): ZenithProject | null {
71
71
  export function requireProject(cwd: string = process.cwd()): ZenithProject {
72
72
  const project = getProject(cwd)
73
73
  if (!project) {
74
- throw new Error('Not in a Zenith project. Run this command from a directory with @zenith/* dependencies.')
74
+ throw new Error('Not in a Zenith project. Run this command from a directory with @zenithbuild/* dependencies.')
75
75
  }
76
76
  return project
77
77
  }
@@ -0,0 +1,218 @@
1
+ <script setup="ts">
2
+ // ErrorPage.zen
3
+ // A high-fidelity, magazine-style error page for Zenith developers.
4
+
5
+ import { zenOnMount, zenSignal } from 'zenith:runtime';
6
+ import gsap from 'gsap';
7
+
8
+ interface ErrorProps {
9
+ file: string;
10
+ line: number;
11
+ column: number;
12
+ message: string;
13
+ errorType: string;
14
+ code: string;
15
+ guarantee?: string;
16
+ context?: string;
17
+ hints?: string[];
18
+ stack?: string;
19
+ isProd?: boolean;
20
+ }
21
+
22
+ const {
23
+ file,
24
+ line,
25
+ column,
26
+ message,
27
+ errorType,
28
+ code,
29
+ guarantee,
30
+ context,
31
+ hints = [],
32
+ stack,
33
+ isProd = false
34
+ } = zenProps<ErrorProps>();
35
+
36
+ const showAdvanced = zenSignal(false);
37
+ const errorRef = zenRef<HTMLElement>();
38
+
39
+ zenOnMount(() => {
40
+ const ctx = gsap.context(() => {
41
+ // Fade in main container
42
+ gsap.from('.error-hero', {
43
+ opacity: 0,
44
+ y: 30,
45
+ duration: 0.8,
46
+ ease: 'expo.out'
47
+ });
48
+
49
+ // Stagger in details
50
+ gsap.from(['.error-meta', '.error-message', '.error-hints > div'], {
51
+ opacity: 0,
52
+ x: -20,
53
+ stagger: 0.1,
54
+ duration: 0.6,
55
+ delay: 0.4,
56
+ ease: 'power2.out'
57
+ });
58
+
59
+ // Fade in code/context
60
+ gsap.from('.error-context', {
61
+ opacity: 0,
62
+ scale: 0.98,
63
+ duration: 1,
64
+ delay: 0.6,
65
+ ease: 'expo.out'
66
+ });
67
+ }, errorRef.current);
68
+
69
+ return () => ctx.revert();
70
+ });
71
+
72
+ const toggleAdvanced = () => showAdvanced(!showAdvanced());
73
+
74
+ </script>
75
+
76
+ <div class="error-page-container min-h-screen bg-background text-foreground font-body overflow-hidden selection:bg-red-500/30" ref={errorRef}>
77
+ <!-- Sticky Header -->
78
+ <header class="p-6 md:p-10 flex justify-between items-center border-b border-border/50">
79
+ <div class="flex items-center gap-3">
80
+ <div class="w-2 h-2 rounded-full bg-red-500 animate-pulse"></div>
81
+ <span class="text-[10px] font-bold uppercase tracking-[0.2em] text-muted-foreground">Zenith Developer Environment</span>
82
+ </div>
83
+ <a href="/documentation" class="text-[10px] font-bold uppercase tracking-widest hover:text-red-500 transition-colors">Documentation</a>
84
+ </header>
85
+
86
+ <main class="max-w-[1400px] mx-auto px-8 md:px-16 py-16 md:py-24 grid grid-cols-1 lg:grid-cols-[1.2fr_0.8fr] gap-16 md:gap-24">
87
+
88
+ <!-- Left Column: Primary Error Info -->
89
+ <section class="space-y-12">
90
+ <div class="error-hero space-y-6">
91
+ <div class="inline-block px-3 py-1 bg-red-500/10 border border-red-500/20 rounded-full">
92
+ <span class="text-[10px] font-black uppercase text-red-500 tracking-tighter">{code}</span>
93
+ </div>
94
+ <h1 class="text-5xl md:text-7xl font-black tracking-tight leading-[0.9] uppercase">
95
+ Something <br/> <span class="text-red-500">Went Wrong</span>
96
+ </h1>
97
+ </div>
98
+
99
+ <div class="error-meta flex flex-wrap gap-8 py-8 border-y border-border/30">
100
+ <div class="space-y-1">
101
+ <span class="text-[9px] uppercase font-bold text-muted-foreground tracking-widest">Location</span>
102
+ <p class="text-sm font-mono truncate max-w-[300px]">{file}:{line}:{column}</p>
103
+ </div>
104
+ <div class="space-y-1">
105
+ <span class="text-[9px] uppercase font-bold text-muted-foreground tracking-widest">Type</span>
106
+ <p class="text-sm font-mono">{errorType}</p>
107
+ </div>
108
+ </div>
109
+
110
+ <div class="error-message space-y-4">
111
+ <p class="text-2xl md:text-3xl font-medium leading-tight text-foreground/90">
112
+ {message}
113
+ </p>
114
+ {guarantee && (
115
+ <div class="p-6 bg-secondary/50 rounded-2xl border border-border/50">
116
+ <span class="text-[9px] uppercase font-black text-primary tracking-widest block mb-2">Zenith Guarantee</span>
117
+ <p class="text-sm italic opacity-80">{guarantee}</p>
118
+ </div>
119
+ )}
120
+ </div>
121
+
122
+ {hints.length > 0 && (
123
+ <div class="error-hints space-y-4 pt-10">
124
+ <h3 class="text-xs font-black uppercase tracking-[0.2em] text-muted-foreground mb-6">Suggestions</h3>
125
+ {hints.map(hint => (
126
+ <div key={hint} class="flex gap-4 items-start p-4 hover:bg-secondary/30 transition-colors rounded-xl border border-transparent hover:border-border/50">
127
+ <span class="text-red-500 mt-1">→</span>
128
+ <p class="text-sm">{hint}</p>
129
+ </div>
130
+ ))}
131
+ </div>
132
+ )}
133
+ </section>
134
+
135
+ <!-- Right Column: Context & Visuals -->
136
+ <section class="error-context space-y-8">
137
+ <div class="relative group">
138
+ <div class="absolute -inset-1 bg-gradient-to-tr from-red-500/20 to-transparent blur-2xl opacity-50"></div>
139
+ <div class="relative bg-zinc-950 rounded-3xl border border-white/10 overflow-hidden shadow-2xl">
140
+ <div class="flex items-center justify-between px-6 py-4 border-b border-white/5 bg-zinc-900/50">
141
+ <span class="text-[10px] font-bold uppercase tracking-widest text-zinc-500">Contextual Snippet</span>
142
+ <div class="flex gap-1.5">
143
+ <div class="w-2.5 h-2.5 rounded-full bg-white/10"></div>
144
+ <div class="w-2.5 h-2.5 rounded-full bg-white/10"></div>
145
+ <div class="w-2.5 h-2.5 rounded-full bg-white/10"></div>
146
+ </div>
147
+ </div>
148
+ <div class="p-8 font-mono text-sm leading-relaxed overflow-x-auto text-zinc-300">
149
+ {context ? (
150
+ <pre><code>{context}</code></pre>
151
+ ) : (
152
+ <div class="py-12 text-center opacity-30 select-none">
153
+ <p class="text-[10px] uppercase tracking-widest">No code snippet available</p>
154
+ </div>
155
+ )}
156
+ </div>
157
+ </div>
158
+ </div>
159
+
160
+ <!-- Advanced Section -->
161
+ {!isProd && (
162
+ <div class="pt-8">
163
+ <button
164
+ onClick={toggleAdvanced}
165
+ class="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-muted-foreground hover:text-foreground transition-colors group"
166
+ >
167
+ {showAdvanced() ? 'Collapse Details' : 'View Stack Trace'}
168
+ <span class={`transition-transform duration-300 ${showAdvanced() ? 'rotate-180' : ''}`}>↓</span>
169
+ </button>
170
+
171
+ {showAdvanced() && (
172
+ <div class="mt-8 space-y-6 animate-in fade-in slide-in-from-top-4 duration-500">
173
+ {stack && (
174
+ <div class="p-6 bg-zinc-950 rounded-2xl border border-white/5 overflow-x-auto">
175
+ <span class="text-[9px] uppercase font-bold text-zinc-500 tracking-widest block mb-4">Runtime Stack</span>
176
+ <pre class="text-[11px] font-mono text-zinc-500 leading-tight"><code>{stack}</code></pre>
177
+ </div>
178
+ )}
179
+ </div>
180
+ )}
181
+ </div>
182
+ )}
183
+ </section>
184
+ </main>
185
+
186
+ <!-- Footer Decoration -->
187
+ <div class="fixed bottom-0 left-0 w-full h-[30vh] pointer-events-none opacity-[0.03] select-none flex items-end justify-center overflow-hidden">
188
+ <span class="text-[25vw] font-black tracking-tighter leading-none translate-y-1/4 uppercase">ZENITH</span>
189
+ </div>
190
+ </div>
191
+
192
+ <style>
193
+ .error-page-container {
194
+ --primary: #ef4444; /* red-500 */
195
+ }
196
+
197
+ @keyframes pulse {
198
+ 0%, 100% { opacity: 1; }
199
+ 50% { opacity: 0.4; }
200
+ }
201
+
202
+ .animate-pulse {
203
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
204
+ }
205
+
206
+ /* Custom scrollbar for context box */
207
+ .error-context ::-webkit-scrollbar {
208
+ height: 4px;
209
+ width: 4px;
210
+ }
211
+ .error-context ::-webkit-scrollbar-track {
212
+ background: transparent;
213
+ }
214
+ .error-context ::-webkit-scrollbar-thumb {
215
+ background: rgba(255, 255, 255, 0.1);
216
+ border-radius: 10px;
217
+ }
218
+ </style>
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Core Components
3
+ *
4
+ * Reusable components provided by zenith-core.
5
+ */
6
+
7
+ // Export path constants for component resolution
8
+ export const CORE_COMPONENTS = {
9
+ ErrorPage: '@zenithbuild/core/components/ErrorPage.zen'
10
+ } as const;
11
+
12
+ // Component path resolver
13
+ export function getCoreComponentPath(componentName: keyof typeof CORE_COMPONENTS): string {
14
+ return CORE_COMPONENTS[componentName];
15
+ }
package/core/config.ts ADDED
@@ -0,0 +1 @@
1
+ export * from '@zenithbuild/compiler/config';