@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.
- package/README.md +20 -19
- package/cli/commands/add.ts +2 -2
- package/cli/commands/build.ts +2 -3
- package/cli/commands/dev.ts +93 -73
- 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
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runtime Hydration Layer
|
|
3
|
-
*
|
|
4
|
-
* Phase 5: Browser-side runtime that hydrates static HTML with dynamic expressions
|
|
5
|
-
*
|
|
6
|
-
* This runtime:
|
|
7
|
-
* - Locates DOM placeholders (data-zen-text, data-zen-attr-*)
|
|
8
|
-
* - Evaluates precompiled expressions against state
|
|
9
|
-
* - Updates DOM textContent, attributes, and properties
|
|
10
|
-
* - Binds event handlers
|
|
11
|
-
* - Handles reactive state updates
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Expression registry - maps expression IDs to their evaluation functions
|
|
16
|
-
* Populated at runtime with compiled expressions
|
|
17
|
-
*/
|
|
18
|
-
declare global {
|
|
19
|
-
interface Window {
|
|
20
|
-
__ZENITH_EXPRESSIONS__?: Map<string, (state: any) => any>
|
|
21
|
-
__ZENITH_STATE__?: any
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Binding registry - tracks which DOM nodes are bound to which expressions
|
|
27
|
-
*/
|
|
28
|
-
interface Binding {
|
|
29
|
-
node: Node
|
|
30
|
-
type: 'text' | 'attribute'
|
|
31
|
-
attributeName?: string
|
|
32
|
-
expressionId: string
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const bindings: Binding[] = []
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Hydrate static HTML with dynamic expressions
|
|
39
|
-
*
|
|
40
|
-
* @param state - The state object to evaluate expressions against
|
|
41
|
-
* @param container - The container element to hydrate (defaults to document)
|
|
42
|
-
*/
|
|
43
|
-
export function hydrate(state: any, container: Document | Element = document): void {
|
|
44
|
-
if (!state) {
|
|
45
|
-
console.warn('[Zenith] hydrate called without state object')
|
|
46
|
-
return
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Store state globally for event handlers
|
|
50
|
-
if (typeof window !== 'undefined') {
|
|
51
|
-
window.__ZENITH_STATE__ = state
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Clear existing bindings
|
|
55
|
-
bindings.length = 0
|
|
56
|
-
|
|
57
|
-
// Find all text expression placeholders
|
|
58
|
-
const textPlaceholders = container.querySelectorAll('[data-zen-text]')
|
|
59
|
-
for (let i = 0; i < textPlaceholders.length; i++) {
|
|
60
|
-
const node = textPlaceholders[i]
|
|
61
|
-
if (!node) continue
|
|
62
|
-
const expressionId = node.getAttribute('data-zen-text')
|
|
63
|
-
if (!expressionId) continue
|
|
64
|
-
|
|
65
|
-
bindings.push({
|
|
66
|
-
node,
|
|
67
|
-
type: 'text',
|
|
68
|
-
expressionId
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
updateTextBinding(node, expressionId, state)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Find all attribute expression placeholders
|
|
75
|
-
const attrPlaceholders = container.querySelectorAll('[data-zen-attr-class], [data-zen-attr-style], [data-zen-attr-src], [data-zen-attr-href], [data-zen-attr-disabled], [data-zen-attr-checked]')
|
|
76
|
-
|
|
77
|
-
for (let i = 0; i < attrPlaceholders.length; i++) {
|
|
78
|
-
const node = attrPlaceholders[i]
|
|
79
|
-
if (!(node instanceof Element)) continue
|
|
80
|
-
|
|
81
|
-
// Check each possible attribute
|
|
82
|
-
const attrNames = ['class', 'style', 'src', 'href', 'disabled', 'checked']
|
|
83
|
-
for (const attrName of attrNames) {
|
|
84
|
-
const expressionId = node.getAttribute(`data-zen-attr-${attrName}`)
|
|
85
|
-
if (!expressionId) continue
|
|
86
|
-
|
|
87
|
-
bindings.push({
|
|
88
|
-
node,
|
|
89
|
-
type: 'attribute',
|
|
90
|
-
attributeName: attrName,
|
|
91
|
-
expressionId
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
updateAttributeBinding(node, attrName, expressionId, state)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Bind event handlers
|
|
99
|
-
bindEvents(container)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Update a text binding
|
|
104
|
-
*/
|
|
105
|
-
function updateTextBinding(node: Node, expressionId: string, state: any): void {
|
|
106
|
-
try {
|
|
107
|
-
const expression = window.__ZENITH_EXPRESSIONS__?.get(expressionId)
|
|
108
|
-
if (!expression) {
|
|
109
|
-
console.warn(`[Zenith] Expression ${expressionId} not found in registry`)
|
|
110
|
-
return
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const result = expression(state)
|
|
114
|
-
|
|
115
|
-
// Handle different result types
|
|
116
|
-
if (result === null || result === undefined || result === false) {
|
|
117
|
-
node.textContent = ''
|
|
118
|
-
} else if (typeof result === 'string' || typeof result === 'number') {
|
|
119
|
-
node.textContent = String(result)
|
|
120
|
-
} else if (result instanceof Node) {
|
|
121
|
-
// Replace node with result node
|
|
122
|
-
if (node.parentNode) {
|
|
123
|
-
node.parentNode.replaceChild(result, node)
|
|
124
|
-
}
|
|
125
|
-
} else if (Array.isArray(result)) {
|
|
126
|
-
// Handle array results (for map expressions)
|
|
127
|
-
if (node.parentNode) {
|
|
128
|
-
const fragment = document.createDocumentFragment()
|
|
129
|
-
for (const item of result) {
|
|
130
|
-
if (item instanceof Node) {
|
|
131
|
-
fragment.appendChild(item)
|
|
132
|
-
} else {
|
|
133
|
-
fragment.appendChild(document.createTextNode(String(item)))
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
node.parentNode.replaceChild(fragment, node)
|
|
137
|
-
}
|
|
138
|
-
} else {
|
|
139
|
-
node.textContent = String(result)
|
|
140
|
-
}
|
|
141
|
-
} catch (error: any) {
|
|
142
|
-
console.error(`[Zenith] Error evaluating expression ${expressionId}:`, error)
|
|
143
|
-
console.error('Expression ID:', expressionId, 'State:', state)
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Update an attribute binding
|
|
149
|
-
*/
|
|
150
|
-
function updateAttributeBinding(
|
|
151
|
-
element: Element,
|
|
152
|
-
attributeName: string,
|
|
153
|
-
expressionId: string,
|
|
154
|
-
state: any
|
|
155
|
-
): void {
|
|
156
|
-
try {
|
|
157
|
-
const expression = window.__ZENITH_EXPRESSIONS__?.get(expressionId)
|
|
158
|
-
if (!expression) {
|
|
159
|
-
console.warn(`[Zenith] Expression ${expressionId} not found in registry`)
|
|
160
|
-
return
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const result = expression(state)
|
|
164
|
-
|
|
165
|
-
// Handle different attribute types
|
|
166
|
-
if (attributeName === 'class' || attributeName === 'className') {
|
|
167
|
-
element.className = String(result ?? '')
|
|
168
|
-
} else if (attributeName === 'style') {
|
|
169
|
-
if (typeof result === 'string') {
|
|
170
|
-
element.setAttribute('style', result)
|
|
171
|
-
} else if (result && typeof result === 'object') {
|
|
172
|
-
// Handle style object
|
|
173
|
-
const styleStr = Object.entries(result)
|
|
174
|
-
.map(([key, value]) => `${key}: ${value}`)
|
|
175
|
-
.join('; ')
|
|
176
|
-
element.setAttribute('style', styleStr)
|
|
177
|
-
}
|
|
178
|
-
} else if (attributeName === 'disabled' || attributeName === 'checked' || attributeName === 'readonly') {
|
|
179
|
-
// Boolean attributes
|
|
180
|
-
if (result) {
|
|
181
|
-
element.setAttribute(attributeName, '')
|
|
182
|
-
} else {
|
|
183
|
-
element.removeAttribute(attributeName)
|
|
184
|
-
}
|
|
185
|
-
} else {
|
|
186
|
-
// Regular attributes
|
|
187
|
-
if (result === null || result === undefined || result === false) {
|
|
188
|
-
element.removeAttribute(attributeName)
|
|
189
|
-
} else {
|
|
190
|
-
element.setAttribute(attributeName, String(result))
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
} catch (error: any) {
|
|
194
|
-
console.error(`[Zenith] Error updating attribute ${attributeName} with expression ${expressionId}:`, error)
|
|
195
|
-
console.error('Expression ID:', expressionId, 'State:', state)
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Bind event handlers to DOM elements
|
|
201
|
-
*
|
|
202
|
-
* @param container - The container element to bind events in (defaults to document)
|
|
203
|
-
*/
|
|
204
|
-
export function bindEvents(container: Document | Element = document): void {
|
|
205
|
-
const eventTypes = ['click', 'change', 'input', 'submit', 'focus', 'blur', 'keyup', 'keydown']
|
|
206
|
-
|
|
207
|
-
for (const eventType of eventTypes) {
|
|
208
|
-
const elements = container.querySelectorAll(`[data-zen-${eventType}]`)
|
|
209
|
-
|
|
210
|
-
for (let i = 0; i < elements.length; i++) {
|
|
211
|
-
const element = elements[i]
|
|
212
|
-
if (!(element instanceof Element)) continue
|
|
213
|
-
|
|
214
|
-
const handlerName = element.getAttribute(`data-zen-${eventType}`)
|
|
215
|
-
if (!handlerName) continue
|
|
216
|
-
|
|
217
|
-
// Remove existing listener if any (to avoid duplicates)
|
|
218
|
-
const existingHandler = (element as any)[`__zen_${eventType}_handler`]
|
|
219
|
-
if (existingHandler) {
|
|
220
|
-
element.removeEventListener(eventType, existingHandler)
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Create new handler
|
|
224
|
-
const handler = (event: Event) => {
|
|
225
|
-
try {
|
|
226
|
-
// Get handler function from window (functions are registered on window)
|
|
227
|
-
const handlerFunc = (window as any)[handlerName]
|
|
228
|
-
if (typeof handlerFunc === 'function') {
|
|
229
|
-
handlerFunc(event, element)
|
|
230
|
-
} else {
|
|
231
|
-
console.warn(`[Zenith] Event handler "${handlerName}" not found for ${eventType} event`)
|
|
232
|
-
}
|
|
233
|
-
} catch (error: any) {
|
|
234
|
-
console.error(`[Zenith] Error executing event handler "${handlerName}":`, error)
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Store handler reference to allow cleanup
|
|
239
|
-
;(element as any)[`__zen_${eventType}_handler`] = handler
|
|
240
|
-
|
|
241
|
-
element.addEventListener(eventType, handler)
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Update all bindings when state changes
|
|
248
|
-
*
|
|
249
|
-
* @param state - The new state object
|
|
250
|
-
*/
|
|
251
|
-
export function update(state: any): void {
|
|
252
|
-
if (!state) {
|
|
253
|
-
console.warn('[Zenith] update called without state object')
|
|
254
|
-
return
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Update global state
|
|
258
|
-
if (typeof window !== 'undefined') {
|
|
259
|
-
window.__ZENITH_STATE__ = state
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Update all tracked bindings
|
|
263
|
-
for (const binding of bindings) {
|
|
264
|
-
if (binding.type === 'text') {
|
|
265
|
-
updateTextBinding(binding.node, binding.expressionId, state)
|
|
266
|
-
} else if (binding.type === 'attribute' && binding.attributeName) {
|
|
267
|
-
if (binding.node instanceof Element) {
|
|
268
|
-
updateAttributeBinding(binding.node, binding.attributeName, binding.expressionId, state)
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Initialize the expression registry
|
|
276
|
-
* Called once when the runtime loads
|
|
277
|
-
*
|
|
278
|
-
* @param expressions - Map of expression IDs to evaluation functions
|
|
279
|
-
*/
|
|
280
|
-
export function initExpressions(expressions: Map<string, (state: any) => any>): void {
|
|
281
|
-
if (typeof window !== 'undefined') {
|
|
282
|
-
window.__ZENITH_EXPRESSIONS__ = expressions
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Clear all bindings and event listeners
|
|
288
|
-
* Useful for cleanup when navigating away
|
|
289
|
-
*/
|
|
290
|
-
export function cleanup(container: Document | Element = document): void {
|
|
291
|
-
// Remove event listeners
|
|
292
|
-
const eventTypes = ['click', 'change', 'input', 'submit', 'focus', 'blur', 'keyup', 'keydown']
|
|
293
|
-
for (const eventType of eventTypes) {
|
|
294
|
-
const elements = container.querySelectorAll(`[data-zen-${eventType}]`)
|
|
295
|
-
for (let i = 0; i < elements.length; i++) {
|
|
296
|
-
const element = elements[i]
|
|
297
|
-
if (!(element instanceof Element)) continue
|
|
298
|
-
const handler = (element as any)[`__zen_${eventType}_handler`]
|
|
299
|
-
if (handler) {
|
|
300
|
-
element.removeEventListener(eventType, handler)
|
|
301
|
-
delete (element as any)[`__zen_${eventType}_handler`]
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Clear bindings
|
|
307
|
-
bindings.length = 0
|
|
308
|
-
}
|
|
309
|
-
|