@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,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
-