@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/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@zenithbuild/core",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "Core library for the Zenith framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
- "main": "./index.ts",
7
+ "main": "./core/index.ts",
8
8
  "bin": {
9
9
  "zenith": "./dist/zenith.js",
10
10
  "zenith-dev": "./dist/zen-dev.js",
@@ -15,7 +15,6 @@
15
15
  "files": [
16
16
  "bin",
17
17
  "cli",
18
- "compiler",
19
18
  "core",
20
19
  "router",
21
20
  "runtime",
@@ -24,12 +23,10 @@
24
23
  "tsconfig.json"
25
24
  ],
26
25
  "exports": {
27
- ".": "./index.ts",
28
- "./compiler": "./compiler/index.ts",
29
- "./config": "./core/config/index.ts",
30
- "./core": "./core/index.ts",
31
- "./router": "./router/index.ts",
32
- "./runtime": "./runtime/index.ts"
26
+ ".": "./core/index.ts",
27
+ "./config": "./core/config.ts",
28
+ "./plugins": "./core/index.ts",
29
+ "./runtime": "./core/index.ts"
33
30
  },
34
31
  "keywords": [
35
32
  "zenith",
@@ -39,13 +36,13 @@
39
36
  "author": "Zenith Team",
40
37
  "repository": {
41
38
  "type": "git",
42
- "url": "git@github.com:zenithbuild/zenith-core.git"
39
+ "url": "git+ssh://git@github.com/zenithbuild/zenith-core.git"
43
40
  },
44
41
  "scripts": {
45
- "dev": "bun dev",
46
- "build": "bun build",
42
+ "dev": "bun run build:cli && bin/zenith.ts dev",
43
+ "build": "bun run build:cli",
47
44
  "start": "bun run build && bun run dev",
48
- "build:cli": "bun build bin/zenith.ts bin/zen-dev.ts bin/zen-build.ts bin/zen-preview.ts --outdir dist --target bun --bundle && for f in dist/*.js; do echo '#!/usr/bin/env bun' | cat - \"$f\" > \"$f.tmp\" && mv \"$f.tmp\" \"$f\" && chmod +x \"$f\"; done",
45
+ "build:cli": "bun build bin/zenith.ts bin/zen-dev.ts bin/zen-build.ts bin/zen-preview.ts --outdir dist --target bun --bundle --external '*' && for f in dist/*.js; do echo '#!/usr/bin/env bun' | cat - \"$f\" > \"$f.tmp\" && mv \"$f.tmp\" \"$f\" && chmod +x \"$f\"; done",
49
46
  "format": "prettier --write \"**/*.ts\"",
50
47
  "format:check": "prettier --check \"**/*.ts\"",
51
48
  "release": "bun run scripts/release.ts",
@@ -67,14 +64,8 @@
67
64
  "typescript": "^5"
68
65
  },
69
66
  "dependencies": {
67
+ "@zenithbuild/compiler": "latest",
70
68
  "@zenithbuild/router": "latest",
71
- "@types/acorn": "^6.0.4",
72
- "@types/marked": "^6.0.0",
73
- "@types/parse5": "^7.0.0",
74
- "acorn": "^8.15.0",
75
- "es-module-lexer": "^2.0.0",
76
- "marked": "^17.0.1",
77
- "parse5": "^8.0.0",
78
69
  "picocolors": "^1.1.1"
79
70
  }
80
71
  }
@@ -1,380 +0,0 @@
1
- # Zenith Compiler - Phase 1: Parse & Extract
2
-
3
- ## Overview
4
-
5
- This is Phase 1 of the Zenith compiler implementation. This phase focuses on **parsing and extracting** structure from `.zen` files without any runtime execution or transformation.
6
-
7
- ## Directory Structure
8
-
9
- ```
10
- /compiler
11
- /parse
12
- parseZenFile.ts # Main file parser
13
- parseTemplate.ts # Template/HTML parser
14
- parseScript.ts # Script block extractor
15
- /ir
16
- types.ts # Intermediate Representation types
17
- /errors
18
- compilerError.ts # Compiler error handling
19
- index.ts # Public API entry point
20
- ```
21
-
22
- ## Usage
23
-
24
- ```typescript
25
- import { compileZen } from './compiler/index'
26
-
27
- const ir = compileZen('app/pages/example.zen')
28
- // Returns ZenIR structure with parsed template, script, styles, and extracted expressions
29
- ```
30
-
31
- ## What This Phase Does
32
-
33
- ✅ Parses `.zen` files into structured IR
34
- ✅ Extracts `<script>` and `<style>` blocks
35
- ✅ Parses HTML template structure
36
- ✅ Extracts `{expression}` patterns from text and attributes
37
- ✅ Records source locations for all nodes and expressions
38
- ✅ Throws compiler errors with location information
39
-
40
- ## What This Phase Does NOT Do
41
-
42
- ❌ Execute expressions
43
- ❌ Transform code
44
- ❌ Generate runtime code
45
- ❌ Handle reactivity
46
- ❌ Render to DOM
47
- ❌ Perform any runtime operations
48
-
49
- ## IR Structure
50
-
51
- The compiler produces a `ZenIR` object containing:
52
-
53
- - `filePath`: Path to the source file
54
- - `template`: TemplateIR with nodes and extracted expressions
55
- - `script`: ScriptIR with raw script content (or null)
56
- - `styles`: Array of StyleIR with raw style content
57
-
58
- ## Expression Extraction
59
-
60
- Expressions are extracted from:
61
- - Text content: `Hello {name}!`
62
- - Attribute values: `class={isActive ? "on" : "off"}`
63
-
64
- Each expression gets:
65
- - Unique ID (e.g., `expr_0`, `expr_1`)
66
- - Source code (the expression content)
67
- - Source location (line + column)
68
-
69
- ## Phase 2: Transform IR → Static HTML + Runtime Bindings
70
-
71
- Phase 2 transforms the IR into static HTML with explicit bindings:
72
-
73
- - ✅ All `{}` expressions removed from HTML
74
- - ✅ Expressions replaced with data attributes (`data-zen-text`, `data-zen-attr-*`)
75
- - ✅ Bindings array generated with expression source code
76
- - ✅ Scripts and styles pass through unchanged
77
- - ✅ No runtime execution - pure transformation
78
-
79
- ### Output Structure
80
-
81
- ```typescript
82
- {
83
- html: string, // Static HTML with no {}
84
- bindings: Binding[], // Array of expression bindings
85
- scripts: string, // Raw script content
86
- styles: string[] // Raw style content
87
- }
88
- ```
89
-
90
- ### Binding Format
91
-
92
- ```typescript
93
- {
94
- id: "exp_1",
95
- type: "text" | "attribute",
96
- target: "data-zen-text" | "class" | "style" | etc,
97
- expression: "user.name" // Original expression code
98
- }
99
- ```
100
-
101
- ## Phase 4: Runtime DOM & Reactivity
102
-
103
- Phase 4 transforms the IR into fully functional runtime JavaScript code:
104
-
105
- - ✅ Expression wrapping with state access
106
- - ✅ DOM creation code generation
107
- - ✅ Event handler binding
108
- - ✅ State initialization
109
- - ✅ Hydrate function for SPA hydration
110
- - ✅ Style injection
111
-
112
- ### Runtime Code Structure
113
-
114
- ```typescript
115
- {
116
- expressions: string, // Wrapped expression functions
117
- render: string, // renderDynamicPage(state) function
118
- hydrate: string, // hydrate(root, state) function
119
- styles: string, // Style injection code
120
- script: string, // Transformed script code
121
- stateInit: string // State initialization code
122
- }
123
- ```
124
-
125
- ### Usage
126
-
127
- ```typescript
128
- import { compileZen } from './compiler/index'
129
- import { transformIR } from './compiler/runtime/transformIR'
130
-
131
- const { ir } = compileZen('app/pages/example.zen')
132
- const runtime = transformIR(ir)
133
-
134
- // Runtime code is now ready to execute
135
- // - runtime.expressions: Expression wrapper functions
136
- // - runtime.render: DOM creation function
137
- // - runtime.hydrate: Hydration function
138
- ```
139
-
140
- ## Phase 5: Runtime Hydration
141
-
142
- Phase 5 provides the browser-side runtime that hydrates static HTML with dynamic expressions:
143
-
144
- - ✅ Expression evaluation via registry (`window.__ZENITH_EXPRESSIONS__`)
145
- - ✅ Text binding updates (`data-zen-text` attributes)
146
- - ✅ Attribute binding updates (`data-zen-attr-*` attributes)
147
- - ✅ Event handler binding (`data-zen-{eventType}` attributes)
148
- - ✅ Reactive state updates (`update(state)` function)
149
- - ✅ Cleanup and memory management
150
- - ✅ Error handling with expression IDs
151
-
152
- ### Runtime Functions
153
-
154
- ```typescript
155
- // Hydrate static HTML with dynamic expressions
156
- window.zenithHydrate(state, container?)
157
-
158
- // Update all bindings when state changes
159
- window.zenithUpdate(state)
160
-
161
- // Bind event handlers
162
- window.zenithBindEvents(container?)
163
-
164
- // Cleanup bindings and event listeners
165
- window.zenithCleanup(container?)
166
- ```
167
-
168
- ### Runtime Bundle
169
-
170
- The `transformIR` function now generates a complete runtime bundle:
171
-
172
- ```typescript
173
- const runtime = transformIR(ir)
174
- // runtime.bundle contains the complete JavaScript code ready for browser execution
175
- ```
176
-
177
- The bundle includes:
178
- - Expression wrapper functions
179
- - Expression registry initialization
180
- - Hydration runtime code
181
- - State initialization
182
- - Style injection
183
- - User script code
184
-
185
- ### Usage Example
186
-
187
- ```typescript
188
- // In browser
189
- const state = { user: { name: 'Alice' }, count: 5 }
190
- window.zenithHydrate(state, document.body)
191
-
192
- // On state change
193
- state.count = 10
194
- window.zenithUpdate(state)
195
- ```
196
-
197
- ## Phase 6: Explicit Data Exposure
198
-
199
- Phase 6 ensures all data references are explicit rather than relying on implicit globals:
200
-
201
- - ✅ Expression dependency analysis (loaderData, props, stores, state)
202
- - ✅ Explicit function signatures with data arguments
203
- - ✅ Updated hydration runtime to pass explicit data
204
- - ✅ Compile-time validation of data references
205
- - ✅ Backwards compatibility with legacy state-only expressions
206
-
207
- ### Data Sources
208
-
209
- Expressions can reference data from:
210
- 1. **Loader Data** - Route-level `loader()` function data (`loaderData.user.name`)
211
- 2. **Props** - Component/page props (`props.title`)
212
- 3. **Stores** - Global stores (`stores.cart.items`)
213
- 4. **State** - Reactive state (`state.count`)
214
-
215
- ### Expression Wrapper Signatures
216
-
217
- Phase 6 expressions now accept explicit arguments:
218
-
219
- ```typescript
220
- // Before (Phase 5)
221
- const expr_0 = (state) => { with (state) { return user.name } }
222
-
223
- // After (Phase 6)
224
- const expr_0 = (state, loaderData, props, stores) => {
225
- const __ctx = Object.assign({}, loaderData, props, stores, state);
226
- with (__ctx) { return user.name }
227
- }
228
- ```
229
-
230
- ### Runtime Hydration
231
-
232
- ```typescript
233
- // Phase 6 signature
234
- window.zenithHydrate(state, loaderData, props, stores, container?)
235
- window.zenithUpdate(state, loaderData, props, stores)
236
- ```
237
-
238
- The runtime maintains backwards compatibility - if called with only `state`, it uses legacy behavior.
239
-
240
- ### Data Dependency Analysis
241
-
242
- The compiler analyzes each expression to detect:
243
- - `loaderData.property` → loader data dependency
244
- - `props.name` → props dependency
245
- - `stores.name` → stores dependency
246
- - Simple identifiers → state dependency
247
-
248
- All dependencies are validated at compile time with clear error messages.
249
-
250
- ## Phase 7: Navigation, Prefetch & Bun Accelerator
251
-
252
- Phase 7 implements safe SPA navigation with prefetching and explicit data exposure:
253
-
254
- - ✅ Prefetch compiled output (HTML + JS) for routes
255
- - ✅ Route caching system
256
- - ✅ Safe SPA navigation with explicit data (loaderData, props, stores)
257
- - ✅ Browser history handling (back/forward)
258
- - ✅ ZenLink component with prefetch support
259
- - ✅ Navigation runtime integration
260
- - ✅ No raw .zen files in browser
261
-
262
- ### Navigation API
263
-
264
- ```typescript
265
- // Prefetch a route
266
- window.__zenith_prefetch('/dashboard')
267
-
268
- // Navigate with explicit data
269
- window.navigate('/dashboard', {
270
- loaderData: { user: { name: 'Alice' } },
271
- props: { title: 'Dashboard' },
272
- stores: { cart: { items: 3 } },
273
- replace: false // Use pushState instead of replaceState
274
- })
275
- ```
276
-
277
- ### ZenLink Component
278
-
279
- ```html
280
- <!-- With prefetch (on hover) -->
281
- <ZenLink href="/about" prefetch={true}>About</ZenLink>
282
-
283
- <!-- Without prefetch -->
284
- <ZenLink href="/blog">Blog</ZenLink>
285
- ```
286
-
287
- ### Key Principles
288
-
289
- 1. **Compiler owns all expressions** - Runtime never parses .zen files
290
- 2. **Prefetch compiled output** - HTML + JS bundles, not source
291
- 3. **Explicit data exposure** - All data passed explicitly (no implicit globals)
292
- 4. **Bun as accelerator** - Used for bundling/transpilation, not template parsing
293
- 5. **Safe navigation** - No stacked mutations, proper cleanup, history handling
294
-
295
- ### Route Cache
296
-
297
- Prefetched routes are cached with:
298
- - Compiled HTML
299
- - Compiled JS runtime
300
- - Styles
301
- - Route metadata
302
-
303
- ### Browser History
304
-
305
- The navigation system:
306
- - Handles `popstate` events for back/forward
307
- - Updates DOM safely without re-parsing
308
- - Maintains route state correctly
309
- - Avoids stacked history mutations
310
-
311
- ## Phase 8/9/10: Finalization & Build Guarantees
312
-
313
- Phase 8/9/10 ensures deterministic compilation and compile-time validation:
314
-
315
- - ✅ Compile-time expression validation
316
- - ✅ Build fails on invalid expressions with line/column info
317
- - ✅ No raw `{expression}` in HTML output
318
- - ✅ Thin declarative runtime (no eval, no template parsing)
319
- - ✅ Bun integration for bundling/transpilation (not template parsing)
320
- - ✅ Final HTML + JS output ready for browser
321
-
322
- ### Validation
323
-
324
- All expressions are validated at compile time:
325
- - Syntax validation
326
- - Brace/parentheses/bracket matching
327
- - Unsafe code detection (eval, Function, with)
328
- - Build fails immediately on errors
329
-
330
- ### Output Guarantees
331
-
332
- - **HTML**: Contains only hydration markers (`data-zen-text`, `data-zen-attr-*`)
333
- - **JS**: Pre-compiled expression functions, no template parsing
334
- - **Runtime**: Thin, declarative - only DOM updates and event binding
335
- - **No eval**: Runtime never uses `eval`, `new Function`, or `with(window)`
336
-
337
- ### Bun Integration
338
-
339
- Bun is used as an accelerator for:
340
- - ✅ JS/TS transpilation
341
- - ✅ Asset bundling
342
- - ✅ SSR runtime support
343
-
344
- Bun is **NOT** used for:
345
- - ❌ Template parsing
346
- - ❌ Expression analysis
347
- - ❌ AST transformations
348
-
349
- ### Build Guarantees
350
-
351
- - Build success = UI guaranteed to work
352
- - All failures are compile-time (never runtime)
353
- - Error messages include file, line, column
354
- - Invalid expressions fail the build immediately
355
-
356
- ## Next Phases
357
-
358
- Future enhancements:
359
- - Enhanced conditional/ternary handling in IR
360
- - Map iteration support in IR
361
- - Advanced reactivity with dependency tracking
362
- - SSR/SSG/ISR output generation
363
- - Type checking for loader/props/stores data
364
- - Route cache generation in build system
365
-
366
- ## Testing
367
-
368
- The compiler can be tested by importing and calling `compileZen()`:
369
-
370
- ```typescript
371
- import { compileZen } from './compiler/index'
372
-
373
- try {
374
- const ir = compileZen('app/pages/example.zen')
375
- console.log(JSON.stringify(ir, null, 2))
376
- } catch (error) {
377
- console.error('Compiler error:', error)
378
- }
379
- ```
380
-
@@ -1,122 +0,0 @@
1
- /**
2
- * Zenith Build Analyzer
3
- *
4
- * Analyzes .zen page source to determine build strategy:
5
- * - Static: Pure HTML+CSS, no JS needed
6
- * - Hydration: Has state/events/hooks, needs page-specific JS
7
- * - SSR: Uses useFetchServer, needs server rendering
8
- * - SPA: Uses ZenLink with passHref, needs client router
9
- */
10
-
11
- export interface PageAnalysis {
12
- /** Page has state declarations that need hydration */
13
- hasState: boolean
14
- /** Page has event handlers (onclick, etc.) */
15
- hasEventHandlers: boolean
16
- /** Page uses lifecycle hooks (zenOnMount, zenOnUnmount) */
17
- hasLifecycleHooks: boolean
18
- /** Page uses useFetchServer (requires SSR) */
19
- usesServerFetch: boolean
20
- /** Page uses useFetchClient (client-side data) */
21
- usesClientFetch: boolean
22
- /** Page uses ZenLink with passHref (SPA navigation) */
23
- usesZenLink: boolean
24
- /** Page uses reactive expressions in templates */
25
- hasReactiveExpressions: boolean
26
-
27
- /** Computed: page needs any JavaScript */
28
- needsHydration: boolean
29
- /** Computed: page is purely static (no JS) */
30
- isStatic: boolean
31
- /** Computed: page needs SSR */
32
- needsSSR: boolean
33
- }
34
-
35
- /**
36
- * Analyze a .zen page source to determine build requirements
37
- */
38
- export function analyzePageSource(source: string): PageAnalysis {
39
- // Extract script content for analysis
40
- const scriptMatch = source.match(/<script[^>]*>([\s\S]*?)<\/script>/i)
41
- const scriptContent = scriptMatch?.[1] || ''
42
-
43
- // Extract template content (everything outside script/style)
44
- const templateContent = source
45
- .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
46
- .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
47
-
48
- // Check for state declarations: "state varName = ..."
49
- const hasState = /\bstate\s+\w+\s*=/.test(scriptContent)
50
-
51
- // Check for event handlers in template
52
- const hasEventHandlers = /\bon(click|change|input|submit|focus|blur|keydown|keyup|keypress|mousedown|mouseup|mouseover|mouseout|mouseenter|mouseleave)\s*=\s*["'{]/.test(templateContent)
53
-
54
- // Check for lifecycle hooks
55
- const hasLifecycleHooks = /\bzen(OnMount|OnUnmount)\s*\(/.test(scriptContent)
56
-
57
- // Check for server fetch
58
- const usesServerFetch = /\buseFetchServer\s*\(/.test(scriptContent)
59
-
60
- // Check for client fetch
61
- const usesClientFetch = /\buseFetchClient\s*\(/.test(scriptContent)
62
-
63
- // Check for ZenLink with passHref
64
- const usesZenLink = /<ZenLink[^>]*passHref[^>]*>/.test(templateContent)
65
-
66
- // Check for reactive expressions in template: {expression}
67
- // Must be actual expressions, not just static text
68
- // Exclude attribute values like href="/path"
69
- const hasReactiveExpressions = /{[a-zA-Z_][a-zA-Z0-9_]*}/.test(templateContent)
70
-
71
- // Compute derived properties
72
- const needsHydration = hasState || hasEventHandlers || hasLifecycleHooks ||
73
- usesClientFetch || hasReactiveExpressions
74
- const isStatic = !needsHydration && !usesServerFetch
75
- const needsSSR = usesServerFetch
76
-
77
- return {
78
- hasState,
79
- hasEventHandlers,
80
- hasLifecycleHooks,
81
- usesServerFetch,
82
- usesClientFetch,
83
- usesZenLink,
84
- hasReactiveExpressions,
85
- needsHydration,
86
- isStatic,
87
- needsSSR
88
- }
89
- }
90
-
91
- /**
92
- * Get a human-readable summary of the page analysis
93
- */
94
- export function getAnalysisSummary(analysis: PageAnalysis): string {
95
- const flags: string[] = []
96
-
97
- if (analysis.isStatic) {
98
- flags.push('STATIC (no JS)')
99
- } else {
100
- if (analysis.hasState) flags.push('state')
101
- if (analysis.hasEventHandlers) flags.push('events')
102
- if (analysis.hasLifecycleHooks) flags.push('lifecycle')
103
- if (analysis.hasReactiveExpressions) flags.push('reactive')
104
- if (analysis.usesClientFetch) flags.push('clientFetch')
105
- }
106
-
107
- if (analysis.needsSSR) flags.push('SSR')
108
- if (analysis.usesZenLink) flags.push('SPA')
109
-
110
- return flags.length > 0 ? flags.join(', ') : 'minimal'
111
- }
112
-
113
- /**
114
- * Determine build output type for a page
115
- */
116
- export type BuildOutputType = 'static' | 'hydrated' | 'ssr'
117
-
118
- export function getBuildOutputType(analysis: PageAnalysis): BuildOutputType {
119
- if (analysis.needsSSR) return 'ssr'
120
- if (analysis.needsHydration) return 'hydrated'
121
- return 'static'
122
- }