@zenithbuild/core 0.1.0 → 0.3.1

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 (90) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +24 -40
  3. package/bin/zen-build.ts +2 -0
  4. package/bin/zen-dev.ts +2 -0
  5. package/bin/zen-preview.ts +2 -0
  6. package/bin/zenith.ts +2 -0
  7. package/cli/commands/add.ts +37 -0
  8. package/cli/commands/build.ts +37 -0
  9. package/cli/commands/create.ts +702 -0
  10. package/cli/commands/dev.ts +197 -0
  11. package/cli/commands/index.ts +112 -0
  12. package/cli/commands/preview.ts +62 -0
  13. package/cli/commands/remove.ts +33 -0
  14. package/cli/index.ts +10 -0
  15. package/cli/main.ts +101 -0
  16. package/cli/utils/branding.ts +153 -0
  17. package/cli/utils/logger.ts +40 -0
  18. package/cli/utils/plugin-manager.ts +114 -0
  19. package/cli/utils/project.ts +71 -0
  20. package/compiler/build-analyzer.ts +122 -0
  21. package/compiler/discovery/layouts.ts +61 -0
  22. package/compiler/index.ts +40 -24
  23. package/compiler/ir/types.ts +1 -0
  24. package/compiler/parse/parseScript.ts +29 -5
  25. package/compiler/parse/parseTemplate.ts +96 -58
  26. package/compiler/parse/scriptAnalysis.ts +77 -0
  27. package/compiler/runtime/dataExposure.ts +49 -31
  28. package/compiler/runtime/generateDOM.ts +18 -17
  29. package/compiler/runtime/generateHydrationBundle.ts +24 -5
  30. package/compiler/runtime/transformIR.ts +140 -49
  31. package/compiler/runtime/wrapExpressionWithLoop.ts +11 -11
  32. package/compiler/spa-build.ts +70 -153
  33. package/compiler/ssg-build.ts +412 -0
  34. package/compiler/transform/layoutProcessor.ts +132 -0
  35. package/compiler/transform/transformNode.ts +19 -19
  36. package/dist/cli.js +11648 -0
  37. package/dist/zen-build.js +11659 -0
  38. package/dist/zen-dev.js +11659 -0
  39. package/dist/zen-preview.js +11659 -0
  40. package/dist/zenith.js +11659 -0
  41. package/package.json +22 -2
  42. package/runtime/bundle-generator.ts +416 -0
  43. package/runtime/client-runtime.ts +532 -0
  44. package/.eslintignore +0 -15
  45. package/.gitattributes +0 -2
  46. package/.github/ISSUE_TEMPLATE/compiler-errors-for-invalid-state-declarations.md +0 -25
  47. package/.github/ISSUE_TEMPLATE/new_ticket.yaml +0 -34
  48. package/.github/pull_request_template.md +0 -15
  49. package/.github/workflows/discord-changelog.yml +0 -141
  50. package/.github/workflows/discord-notify.yml +0 -242
  51. package/.github/workflows/discord-version.yml +0 -195
  52. package/.prettierignore +0 -13
  53. package/.prettierrc +0 -21
  54. package/.zen.d.ts +0 -15
  55. package/app/components/Button.zen +0 -46
  56. package/app/components/Link.zen +0 -11
  57. package/app/favicon.ico +0 -0
  58. package/app/layouts/Main.zen +0 -59
  59. package/app/pages/about.zen +0 -23
  60. package/app/pages/blog/[id].zen +0 -53
  61. package/app/pages/blog/index.zen +0 -32
  62. package/app/pages/dynamic-dx.zen +0 -712
  63. package/app/pages/dynamic-primitives.zen +0 -453
  64. package/app/pages/index.zen +0 -154
  65. package/app/pages/navigation-demo.zen +0 -229
  66. package/app/pages/posts/[...slug].zen +0 -61
  67. package/app/pages/primitives-demo.zen +0 -273
  68. package/assets/logos/0E3B5DDD-605C-4839-BB2E-DFCA8ADC9604.PNG +0 -0
  69. package/assets/logos/760971E5-79A1-44F9-90B9-925DF30F4278.PNG +0 -0
  70. package/assets/logos/8A06ED80-9ED2-4689-BCBD-13B2E95EE8E4.JPG +0 -0
  71. package/assets/logos/C691FF58-ED13-4E8D-B6A3-02E835849340.PNG +0 -0
  72. package/assets/logos/C691FF58-ED13-4E8D-B6A3-02E835849340.svg +0 -601
  73. package/assets/logos/README.md +0 -54
  74. package/assets/logos/zen.icns +0 -0
  75. package/bun.lock +0 -39
  76. package/compiler/legacy/binding.ts +0 -254
  77. package/compiler/legacy/bindings.ts +0 -338
  78. package/compiler/legacy/component-process.ts +0 -1208
  79. package/compiler/legacy/component.ts +0 -301
  80. package/compiler/legacy/event.ts +0 -50
  81. package/compiler/legacy/expression.ts +0 -1149
  82. package/compiler/legacy/mutation.ts +0 -280
  83. package/compiler/legacy/parse.ts +0 -299
  84. package/compiler/legacy/split.ts +0 -608
  85. package/compiler/legacy/types.ts +0 -32
  86. package/docs/COMMENTS.md +0 -111
  87. package/docs/COMMITS.md +0 -36
  88. package/docs/CONTRIBUTING.md +0 -116
  89. package/docs/STYLEGUIDE.md +0 -62
  90. package/scripts/webhook-proxy.ts +0 -213
@@ -11,15 +11,13 @@
11
11
  import fs from "fs"
12
12
  import path from "path"
13
13
  // Import new compiler
14
- import { compileZen } from "./index"
15
- // Legacy imports (fallback for now)
16
- import { parseZen } from "./legacy/parse"
17
- import { splitZen } from "./legacy/split"
18
- import { processComponents } from "./legacy/component-process"
19
- import {
20
- discoverPages,
14
+ import { compileZen, compileZenSource } from "./index"
15
+ import { discoverLayouts } from "./discovery/layouts"
16
+ import { processLayout } from "./transform/layoutProcessor"
17
+ import {
18
+ discoverPages,
21
19
  generateRouteDefinition,
22
- routePathToRegex
20
+ routePathToRegex
23
21
  } from "../router/manifest"
24
22
 
25
23
  interface CompiledPage {
@@ -44,139 +42,58 @@ interface SPABuildOptions {
44
42
 
45
43
  /**
46
44
  * Compile a single page file
47
- * Uses new compiler by default, falls back to legacy if needed
48
45
  */
49
46
  function compilePage(
50
47
  pagePath: string,
51
48
  pagesDir: string,
52
- useNewCompiler: boolean = true // Feature flag: use new compiler
49
+ baseDir: string = process.cwd()
53
50
  ): CompiledPage {
54
- if (useNewCompiler) {
55
- try {
56
- // Use new compiler pipeline
57
- const result = compileZen(pagePath)
58
-
59
- if (!result.finalized) {
60
- throw new Error(`Compilation failed: No finalized output`)
61
- }
62
-
63
- // Extract compiled output
64
- const html = result.finalized.html
65
- const js = result.finalized.js
66
- const styles = result.finalized.styles
67
-
68
- // Convert JS bundle to scripts array (for compatibility)
69
- const scripts = js ? [js] : []
70
-
71
- // Generate route definition
72
- const routeDef = generateRouteDefinition(pagePath, pagesDir)
73
- const regex = routePathToRegex(routeDef.path)
74
-
75
- return {
76
- routePath: routeDef.path,
77
- filePath: pagePath,
78
- html,
79
- scripts,
80
- styles,
81
- score: routeDef.score,
82
- paramNames: routeDef.paramNames,
83
- regex
84
- }
85
- } catch (error: any) {
86
- console.warn(`[Zenith Build] New compiler failed for ${pagePath}, falling back to legacy:`, error.message)
87
- // Fall through to legacy compiler
88
- }
89
- }
90
-
91
- // Legacy compiler (fallback)
92
- // Parse the .zen file
93
- const zen = parseZen(pagePath)
94
-
95
- // Process components and layouts
96
- const processedZen = processComponents(zen, pagePath)
97
-
98
- // Split into html, scripts, styles
99
- const {
100
- html,
101
- styles,
102
- scripts,
103
- eventTypes,
104
- stateBindings,
105
- stateDeclarations,
106
- bindings,
107
- expressionBlocks,
108
- attrExprBindings
109
- } = splitZen(processedZen)
110
-
111
- // Import runtime generators
112
- const { generateEventBindingRuntime } = require("./legacy/event")
113
- const { generateBindingRuntime } = require("./legacy/binding")
114
- const { generateAttributeBindingRuntime } = require("./legacy/bindings")
115
- const { generateExpressionRuntime, generateExpressionRuntimeHelpers, generateAttributeExpressionRuntime } = require("./legacy/expression")
116
-
117
- // Generate runtime code
118
- const eventRuntime = generateEventBindingRuntime(eventTypes)
119
- const bindingRuntime = generateBindingRuntime(stateBindings, stateDeclarations)
120
- const attributeBindingRuntime = generateAttributeBindingRuntime(bindings)
121
-
122
- // Generate expression runtime
123
- // Always generate helpers if we have :class/:value bindings OR expression blocks
124
- // (bindings.ts uses window.__zen_eval_expr for :class expressions)
125
- const hasExpressions = expressionBlocks.length > 0 || attrExprBindings.length > 0 || bindings.length > 0
126
- const expressionRuntimeHelpers = hasExpressions ? generateExpressionRuntimeHelpers() : ''
127
- const expressionRuntimes = expressionBlocks.map((block: any) =>
128
- generateExpressionRuntime(block.expression, block.placeholderId)
129
- ).join('\n')
130
- const attrExprRuntime = generateAttributeExpressionRuntime(attrExprBindings)
131
-
132
- // Combine scripts with runtime
133
- // If scripts array is empty but we have runtimes to add, create a script entry
134
- const baseScripts = scripts.length > 0 ? scripts : ['']
135
-
136
- const scriptsWithRuntime = baseScripts.map((s, index) => {
137
- let result = ""
138
-
139
- // Add expression helpers first (only to first script)
140
- if (expressionRuntimeHelpers && index === 0) {
141
- result += expressionRuntimeHelpers + "\n\n"
142
- }
143
-
144
- if (bindingRuntime) {
145
- result += bindingRuntime + "\n\n"
146
- }
147
- if (attributeBindingRuntime) {
148
- result += attributeBindingRuntime + "\n\n"
51
+ try {
52
+ const layoutsDir = path.join(baseDir, 'app', 'layouts')
53
+ const layouts = discoverLayouts(layoutsDir)
54
+
55
+ const source = fs.readFileSync(pagePath, 'utf-8')
56
+
57
+ // Find suitable layout
58
+ let processedSource = source
59
+ let layoutToUse = layouts.get('DefaultLayout')
60
+
61
+ if (layoutToUse) {
62
+ processedSource = processLayout(source, layoutToUse)
149
63
  }
150
- result += s
151
-
152
- // Add expression and event runtimes to first script
153
- if (index === 0) {
154
- if (expressionRuntimes) {
155
- result += `\n\n${expressionRuntimes}`
156
- }
157
- if (attrExprRuntime) {
158
- result += `\n\n${attrExprRuntime}`
159
- }
160
- if (eventRuntime) {
161
- result += `\n\n${eventRuntime}`
162
- }
64
+
65
+ // Use new compiler pipeline on the processed source
66
+ const result = compileZenSource(processedSource, pagePath)
67
+
68
+ if (!result.finalized) {
69
+ throw new Error(`Compilation failed: No finalized output`)
163
70
  }
164
- return result
165
- })
166
-
167
- // Generate route definition
168
- const routeDef = generateRouteDefinition(pagePath, pagesDir)
169
- const regex = routePathToRegex(routeDef.path)
170
-
171
- return {
172
- routePath: routeDef.path,
173
- filePath: pagePath,
174
- html,
175
- scripts: scriptsWithRuntime,
176
- styles,
177
- score: routeDef.score,
178
- paramNames: routeDef.paramNames,
179
- regex
71
+
72
+ // Extract compiled output
73
+ const html = result.finalized.html
74
+ const js = result.finalized.js
75
+ const styles = result.finalized.styles
76
+
77
+ // Convert JS bundle to scripts array (for compatibility)
78
+ const scripts = js ? [js] : []
79
+
80
+ // Generate route definition
81
+ const routeDef = generateRouteDefinition(pagePath, pagesDir)
82
+ const regex = routePathToRegex(routeDef.path)
83
+
84
+ return {
85
+ routePath: routeDef.path,
86
+ filePath: pagePath,
87
+ html,
88
+ scripts,
89
+ styles,
90
+ score: routeDef.score,
91
+ paramNames: routeDef.paramNames,
92
+ regex
93
+ }
94
+ } catch (error: any) {
95
+ console.error(`[Zenith Build] Compilation failed for ${pagePath}:`, error.message)
96
+ throw error
180
97
  }
181
98
  }
182
99
 
@@ -839,7 +756,7 @@ function generateHTMLShell(
839
756
  ): string {
840
757
  // Collect all global styles (from layouts)
841
758
  const globalStyles = layoutStyles.join("\n")
842
-
759
+
843
760
  // Generate route manifest JavaScript
844
761
  const manifestJS = pages.map(page => ({
845
762
  path: page.routePath,
@@ -848,20 +765,20 @@ function generateHTMLShell(
848
765
  score: page.score,
849
766
  filePath: page.filePath
850
767
  }))
851
-
768
+
852
769
  // Generate page modules JavaScript
853
770
  const modulesJS = pages.map(page => {
854
771
  const escapedHtml = JSON.stringify(page.html)
855
772
  const escapedScripts = JSON.stringify(page.scripts)
856
773
  const escapedStyles = JSON.stringify(page.styles)
857
-
774
+
858
775
  return `${JSON.stringify(page.routePath)}: {
859
776
  html: ${escapedHtml},
860
777
  scripts: ${escapedScripts},
861
778
  styles: ${escapedStyles}
862
779
  }`
863
780
  }).join(",\n ")
864
-
781
+
865
782
  // Generate manifest with actual RegExp objects
866
783
  const manifestCode = `[
867
784
  ${pages.map(page => `{
@@ -871,7 +788,7 @@ function generateHTMLShell(
871
788
  score: ${page.score}
872
789
  }`).join(",\n ")}
873
790
  ]`
874
-
791
+
875
792
  return `<!DOCTYPE html>
876
793
  <html lang="en">
877
794
  <head>
@@ -928,30 +845,30 @@ function generateHTMLShell(
928
845
  */
929
846
  export function buildSPA(options: SPABuildOptions): void {
930
847
  const { pagesDir, outDir, baseDir } = options
931
-
848
+
932
849
  // Clean output directory
933
850
  if (fs.existsSync(outDir)) {
934
851
  fs.rmSync(outDir, { recursive: true, force: true })
935
852
  }
936
853
  fs.mkdirSync(outDir, { recursive: true })
937
-
854
+
938
855
  // Discover all pages
939
856
  const pageFiles = discoverPages(pagesDir)
940
-
857
+
941
858
  if (pageFiles.length === 0) {
942
859
  console.warn("[Zenith Build] No pages found in", pagesDir)
943
860
  return
944
861
  }
945
-
862
+
946
863
  console.log(`[Zenith Build] Found ${pageFiles.length} page(s)`)
947
-
864
+
948
865
  // Compile all pages
949
866
  const compiledPages: CompiledPage[] = []
950
867
  const layoutStyles: string[] = []
951
-
868
+
952
869
  for (const pageFile of pageFiles) {
953
870
  console.log(`[Zenith Build] Compiling: ${path.relative(pagesDir, pageFile)}`)
954
-
871
+
955
872
  try {
956
873
  const compiled = compilePage(pageFile, pagesDir)
957
874
  compiledPages.push(compiled)
@@ -960,29 +877,29 @@ export function buildSPA(options: SPABuildOptions): void {
960
877
  throw error
961
878
  }
962
879
  }
963
-
880
+
964
881
  // Sort pages by score (highest first)
965
882
  compiledPages.sort((a, b) => b.score - a.score)
966
-
883
+
967
884
  // Extract layout styles (they should be global)
968
885
  // For now, we'll include any styles from the first page that uses a layout
969
886
  // TODO: Better layout handling
970
-
887
+
971
888
  // Generate HTML shell
972
889
  const htmlShell = generateHTMLShell(compiledPages, layoutStyles)
973
-
890
+
974
891
  // Write index.html
975
892
  fs.writeFileSync(path.join(outDir, "index.html"), htmlShell)
976
-
893
+
977
894
  // Copy favicon if it exists
978
895
  const faviconPath = path.join(path.dirname(pagesDir), "favicon.ico")
979
896
  if (fs.existsSync(faviconPath)) {
980
897
  fs.copyFileSync(faviconPath, path.join(outDir, "favicon.ico"))
981
898
  }
982
-
899
+
983
900
  console.log(`[Zenith Build] Successfully built ${compiledPages.length} page(s)`)
984
901
  console.log(`[Zenith Build] Output: ${outDir}/index.html`)
985
-
902
+
986
903
  // Log route manifest
987
904
  console.log("\n[Zenith Build] Route Manifest:")
988
905
  for (const page of compiledPages) {