@zenithbuild/core 1.2.2 → 1.2.4
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/README.md +20 -19
- package/cli/commands/add.ts +2 -2
- package/cli/commands/build.ts +2 -3
- package/cli/commands/dev.ts +94 -74
- package/cli/commands/index.ts +1 -1
- package/cli/commands/preview.ts +1 -1
- package/cli/commands/remove.ts +2 -2
- package/cli/index.ts +1 -1
- package/cli/main.ts +1 -1
- package/cli/utils/logger.ts +1 -1
- package/cli/utils/plugin-manager.ts +1 -1
- package/cli/utils/project.ts +4 -4
- package/core/components/ErrorPage.zen +218 -0
- package/core/components/index.ts +15 -0
- package/core/config.ts +1 -0
- package/core/index.ts +29 -0
- package/dist/compiler-native-frej59m4.node +0 -0
- package/dist/core/compiler-native-frej59m4.node +0 -0
- package/dist/core/index.js +6293 -0
- package/dist/runtime/lifecycle/index.js +1 -0
- package/dist/runtime/reactivity/index.js +1 -0
- package/dist/zen-build.js +1 -20118
- package/dist/zen-dev.js +1 -20118
- package/dist/zen-preview.js +1 -20118
- package/dist/zenith.js +1 -20118
- package/package.json +11 -20
- package/compiler/README.md +0 -380
- package/compiler/build-analyzer.ts +0 -122
- package/compiler/css/index.ts +0 -317
- package/compiler/discovery/componentDiscovery.ts +0 -242
- package/compiler/discovery/layouts.ts +0 -70
- package/compiler/errors/compilerError.ts +0 -56
- package/compiler/finalize/finalizeOutput.ts +0 -192
- package/compiler/finalize/generateFinalBundle.ts +0 -82
- package/compiler/index.ts +0 -83
- package/compiler/ir/types.ts +0 -174
- package/compiler/output/types.ts +0 -48
- package/compiler/parse/detectMapExpressions.ts +0 -102
- package/compiler/parse/importTypes.ts +0 -78
- package/compiler/parse/parseImports.ts +0 -309
- package/compiler/parse/parseScript.ts +0 -46
- package/compiler/parse/parseTemplate.ts +0 -628
- package/compiler/parse/parseZenFile.ts +0 -66
- package/compiler/parse/scriptAnalysis.ts +0 -91
- package/compiler/parse/trackLoopContext.ts +0 -82
- package/compiler/runtime/dataExposure.ts +0 -332
- package/compiler/runtime/generateDOM.ts +0 -255
- package/compiler/runtime/generateHydrationBundle.ts +0 -407
- package/compiler/runtime/hydration.ts +0 -309
- package/compiler/runtime/navigation.ts +0 -432
- package/compiler/runtime/thinRuntime.ts +0 -160
- package/compiler/runtime/transformIR.ts +0 -406
- package/compiler/runtime/wrapExpression.ts +0 -114
- package/compiler/runtime/wrapExpressionWithLoop.ts +0 -97
- package/compiler/spa-build.ts +0 -917
- package/compiler/ssg-build.ts +0 -486
- package/compiler/test/component-stacking.test.ts +0 -365
- package/compiler/test/map-lowering.test.ts +0 -130
- package/compiler/test/validate-test.ts +0 -104
- package/compiler/transform/classifyExpression.ts +0 -444
- package/compiler/transform/componentResolver.ts +0 -350
- package/compiler/transform/componentScriptTransformer.ts +0 -303
- package/compiler/transform/expressionTransformer.ts +0 -385
- package/compiler/transform/fragmentLowering.ts +0 -819
- package/compiler/transform/generateBindings.ts +0 -68
- package/compiler/transform/generateHTML.ts +0 -28
- package/compiler/transform/layoutProcessor.ts +0 -132
- package/compiler/transform/slotResolver.ts +0 -292
- package/compiler/transform/transformNode.ts +0 -314
- package/compiler/transform/transformTemplate.ts +0 -38
- package/compiler/validate/invariants.ts +0 -292
- package/compiler/validate/validateExpressions.ts +0 -168
- package/core/config/index.ts +0 -18
- package/core/config/loader.ts +0 -69
- package/core/config/types.ts +0 -119
- package/core/plugins/bridge.ts +0 -193
- package/core/plugins/index.ts +0 -7
- package/core/plugins/registry.ts +0 -126
- package/dist/cli.js +0 -11675
- package/runtime/build.ts +0 -17
- package/runtime/bundle-generator.ts +0 -1266
- package/runtime/client-runtime.ts +0 -891
- package/runtime/serve.ts +0 -93
package/README.md
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
# @zenithbuild/core ⚡
|
|
2
2
|
|
|
3
|
-
The
|
|
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
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
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.
|
|
16
|
-
The
|
|
14
|
+
### 1. Reactivity (`/core/reactivity`)
|
|
15
|
+
The foundational reactive system. Pure, fast, and deterministic.
|
|
17
16
|
|
|
18
|
-
### 2.
|
|
19
|
-
|
|
17
|
+
### 2. Lifecycle (`/core/lifecycle`)
|
|
18
|
+
Instance-based lifecycle management tied to the DOM.
|
|
20
19
|
|
|
21
|
-
### 3.
|
|
22
|
-
|
|
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
|
|
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
|
|
29
|
-
|
|
30
|
-
This package is typically consumed by the Zenith CLI and other ecosystem tools.
|
|
29
|
+
## Usage
|
|
31
30
|
|
|
32
31
|
```typescript
|
|
33
|
-
import {
|
|
34
|
-
|
|
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
|
package/cli/commands/add.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
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 @
|
|
35
|
+
logger.log(` bun add @zenithbuild/plugin-${pluginName}`)
|
|
36
36
|
}
|
|
37
37
|
}
|
package/cli/commands/build.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
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 '
|
|
9
|
+
import { buildSSG } from '@zenithbuild/compiler'
|
|
11
10
|
|
|
12
11
|
export interface BuildOptions {
|
|
13
12
|
outDir?: string
|
package/cli/commands/dev.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
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 '
|
|
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
|
|
60
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
212
|
-
|
|
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
|
-
//
|
|
235
|
-
|
|
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
|
|
245
|
-
const runtimeTag = `<script src="/runtime.js"></script>`
|
|
246
|
-
const pluginDataTag = `<script>window.__ZENITH_PLUGIN_DATA__ = ${envelopeJson};</script>`
|
|
254
|
+
// Single neutral injection point
|
|
255
|
+
const runtimeTag = `<script type="module" src="/runtime.js"></script>`
|
|
247
256
|
const scriptTag = `<script type="module">\n${page.script}\n</script>`
|
|
248
|
-
const allScripts = `${runtimeTag}\n${
|
|
257
|
+
const allScripts = `${runtimeTag}\n${scriptTag}`
|
|
249
258
|
|
|
250
|
-
|
|
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
|
-
|
|
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))
|
package/cli/commands/index.ts
CHANGED
package/cli/commands/preview.ts
CHANGED
package/cli/commands/remove.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
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 @
|
|
31
|
+
logger.log(` bun remove @zenithbuild/plugin-${pluginName}`)
|
|
32
32
|
}
|
|
33
33
|
}
|
package/cli/index.ts
CHANGED
package/cli/main.ts
CHANGED
package/cli/utils/logger.ts
CHANGED
package/cli/utils/project.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
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 @
|
|
32
|
-
const hasZenith = Object.keys(deps).some(d => d.startsWith('@
|
|
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 @
|
|
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';
|