@zenithbuild/core 0.4.6 → 0.5.0

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.
@@ -43,7 +43,7 @@ var __export = (target, all) => {
43
43
  };
44
44
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
45
45
 
46
- // ../../node_modules/picocolors/picocolors.js
46
+ // node_modules/picocolors/picocolors.js
47
47
  var require_picocolors = __commonJS((exports, module) => {
48
48
  var p = process || {};
49
49
  var argv = p.argv || [];
@@ -8441,7 +8441,12 @@ function generateExpressionId() {
8441
8441
  return `expr_${expressionIdCounter++}`;
8442
8442
  }
8443
8443
  function stripBlocks(html) {
8444
- let stripped = html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "");
8444
+ let stripped = html.replace(/<script([^>]*)>([\s\S]*?)<\/script>/gi, (match, attrs, content) => {
8445
+ if (attrs.includes("src=")) {
8446
+ return match;
8447
+ }
8448
+ return "";
8449
+ });
8445
8450
  stripped = stripped.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "");
8446
8451
  return stripped;
8447
8452
  }
@@ -8942,6 +8947,8 @@ function parseComponentFile(filePath) {
8942
8947
  slots,
8943
8948
  props,
8944
8949
  styles,
8950
+ script: ir.script?.raw || null,
8951
+ scriptAttributes: ir.script?.attributes || null,
8945
8952
  hasScript: ir.script !== null,
8946
8953
  hasStyles: ir.styles.length > 0
8947
8954
  };
@@ -9133,13 +9140,20 @@ function resolveComponentsInIR(ir, components) {
9133
9140
  usedComponents.clear();
9134
9141
  const resolvedNodes = resolveComponentsInNodes(ir.template.nodes, components);
9135
9142
  const componentStyles = Array.from(usedComponents).map((name) => components.get(name)).filter((meta) => meta !== undefined && meta.styles.length > 0).flatMap((meta) => meta.styles.map((raw) => ({ raw })));
9143
+ const componentScripts = Array.from(usedComponents).map((name) => components.get(name)).filter((meta) => meta !== undefined && meta.script !== null).map((meta) => ({
9144
+ name: meta.name,
9145
+ script: meta.script,
9146
+ props: meta.props,
9147
+ scriptAttributes: meta.scriptAttributes || {}
9148
+ }));
9136
9149
  return {
9137
9150
  ...ir,
9138
9151
  template: {
9139
9152
  ...ir.template,
9140
9153
  nodes: resolvedNodes
9141
9154
  },
9142
- styles: [...ir.styles, ...componentStyles]
9155
+ styles: [...ir.styles, ...componentStyles],
9156
+ componentScripts: [...ir.componentScripts || [], ...componentScripts]
9143
9157
  };
9144
9158
  }
9145
9159
  function resolveComponentsInNodes(nodes, components, depth = 0) {
@@ -9199,20 +9213,24 @@ function resolveComponent(componentNode, components, depth = 0) {
9199
9213
  }
9200
9214
  const templateNodes = JSON.parse(JSON.stringify(componentMeta.nodes));
9201
9215
  const resolvedTemplate = resolveSlots(templateNodes, resolvedSlots);
9202
- const forwardedTemplate = forwardAttributesToRoot(resolvedTemplate, componentNode.attributes, componentNode.loopContext);
9216
+ const forwardedTemplate = forwardAttributesToRoot(resolvedTemplate, componentNode.attributes, componentNode.loopContext, componentMeta.hasScript ? componentName : undefined);
9203
9217
  const fullyResolved = resolveComponentsInNodes(forwardedTemplate, components, depth + 1);
9204
9218
  return fullyResolved;
9205
9219
  }
9206
- function forwardAttributesToRoot(nodes, attributes, loopContext) {
9207
- if (attributes.length === 0) {
9208
- return nodes;
9209
- }
9220
+ function forwardAttributesToRoot(nodes, attributes, loopContext, componentName) {
9210
9221
  const rootIndex = nodes.findIndex((n) => n.type === "element");
9211
9222
  if (rootIndex === -1) {
9212
9223
  return nodes;
9213
9224
  }
9214
9225
  const root = nodes[rootIndex];
9215
9226
  const mergedAttributes = [...root.attributes];
9227
+ if (componentName) {
9228
+ mergedAttributes.push({
9229
+ name: "data-zen-component",
9230
+ value: componentName,
9231
+ location: { line: 0, column: 0 }
9232
+ });
9233
+ }
9216
9234
  for (const attr of attributes) {
9217
9235
  const existingIndex = mergedAttributes.findIndex((a) => a.name === attr.name);
9218
9236
  const forwardedAttr = {
@@ -9267,6 +9285,7 @@ import process2 from "process";
9267
9285
  // cli/commands/dev.ts
9268
9286
  import path8 from "path";
9269
9287
  import fs8 from "fs";
9288
+ import os from "os";
9270
9289
  var {serve } = globalThis.Bun;
9271
9290
 
9272
9291
  // cli/utils/project.ts
@@ -10877,12 +10896,217 @@ function transformStateDeclarations(script) {
10877
10896
  transformed = transformed.replace(/export\s+let\s+props(?:\s*:\s*([^;]+))?\s*;?[ \t]*/g, "");
10878
10897
  transformed = transformed.replace(/(?:type|interface)\s+Props\s*=?\s*\{[^}]*(?:\{[^}]*\}[^}]*)*\}[ \t]*;?/gs, "");
10879
10898
  transformed = transformed.replace(/import\s+{[^}]+}\s+from\s+['"]zenith\/runtime['"]\s*;?[ \t]*/g, "");
10899
+ transformed = transformed.replace(/import\s+\w+\s+from\s+['"][^'"]*\.zen['"];?\s*/g, "");
10900
+ transformed = transformed.replace(/import\s+{[^}]*}\s+from\s+['"][^'"]+\.zen['"];?\s*/g, "");
10880
10901
  transformed = transformed.replace(/import\s*{\s*([^}]+)\s*}\s*from\s*['"]zenith:content['"]\s*;?/g, (_, imports) => `const { ${imports.trim()} } = window.__zenith;`);
10881
10902
  return transformed.trim();
10882
10903
  }
10883
10904
 
10905
+ // node_modules/es-module-lexer/dist/lexer.js
10906
+ var ImportType;
10907
+ (function(A) {
10908
+ A[A.Static = 1] = "Static", A[A.Dynamic = 2] = "Dynamic", A[A.ImportMeta = 3] = "ImportMeta", A[A.StaticSourcePhase = 4] = "StaticSourcePhase", A[A.DynamicSourcePhase = 5] = "DynamicSourcePhase", A[A.StaticDeferPhase = 6] = "StaticDeferPhase", A[A.DynamicDeferPhase = 7] = "DynamicDeferPhase";
10909
+ })(ImportType || (ImportType = {}));
10910
+ var A = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
10911
+ function parse2(E, g = "@") {
10912
+ if (!C)
10913
+ return init.then(() => parse2(E));
10914
+ const I = E.length + 1, o = (C.__heap_base.value || C.__heap_base) + 4 * I - C.memory.buffer.byteLength;
10915
+ o > 0 && C.memory.grow(Math.ceil(o / 65536));
10916
+ const D = C.sa(I - 1);
10917
+ if ((A ? B : Q)(E, new Uint16Array(C.memory.buffer, D, I)), !C.parse())
10918
+ throw Object.assign(new Error(`Parse error ${g}:${E.slice(0, C.e()).split(`
10919
+ `).length}:${C.e() - E.lastIndexOf(`
10920
+ `, C.e() - 1)}`), { idx: C.e() });
10921
+ const w = [], K = [];
10922
+ for (;C.ri(); ) {
10923
+ const A2 = C.is(), Q = C.ie(), B = C.it(), g2 = C.ai(), I2 = C.id(), o2 = C.ss(), D2 = C.se();
10924
+ let K2;
10925
+ C.ip() && (K2 = k(E.slice(I2 === -1 ? A2 - 1 : A2, I2 === -1 ? Q + 1 : Q)));
10926
+ const N = [];
10927
+ for (C.rsa();C.ra(); ) {
10928
+ const A3 = C.aks(), Q2 = C.ake(), B2 = C.avs(), g3 = C.ave();
10929
+ N.push([J(E.slice(A3, Q2)), J(E.slice(B2, g3))]);
10930
+ }
10931
+ w.push({ n: K2, t: B, s: A2, e: Q, ss: o2, se: D2, d: I2, a: g2, at: N.length > 0 ? N : null });
10932
+ }
10933
+ for (;C.re(); ) {
10934
+ const A2 = C.es(), Q = C.ee(), B = C.els(), g2 = C.ele(), I2 = J(E.slice(A2, Q)), o2 = B < 0 ? undefined : J(E.slice(B, g2));
10935
+ K.push({ s: A2, e: Q, ls: B, le: g2, n: I2, ln: o2 });
10936
+ }
10937
+ function k(A2) {
10938
+ try {
10939
+ return (0, eval)(A2);
10940
+ } catch (A3) {}
10941
+ }
10942
+ function J(A2) {
10943
+ if (!A2)
10944
+ return A2;
10945
+ const Q = A2[0];
10946
+ return (Q === '"' || Q === "'") && k(A2) || A2;
10947
+ }
10948
+ return [w, K, !!C.f(), !!C.ms()];
10949
+ }
10950
+ function Q(A2, Q2) {
10951
+ const B = A2.length;
10952
+ let C = 0;
10953
+ for (;C < B; ) {
10954
+ const B2 = A2.charCodeAt(C);
10955
+ Q2[C++] = (255 & B2) << 8 | B2 >>> 8;
10956
+ }
10957
+ }
10958
+ function B(A2, Q2) {
10959
+ const B2 = A2.length;
10960
+ let C = 0;
10961
+ for (;C < B2; )
10962
+ Q2[C] = A2.charCodeAt(C++);
10963
+ }
10964
+ var C;
10965
+ var E = () => {
10966
+ return A2 = "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", typeof Buffer != "undefined" ? Buffer.from(A2, "base64") : Uint8Array.from(atob(A2), (A3) => A3.charCodeAt(0));
10967
+ var A2;
10968
+ };
10969
+ var init = WebAssembly.compile(E()).then(WebAssembly.instantiate).then(({ exports: A2 }) => {
10970
+ C = A2;
10971
+ });
10972
+
10973
+ // compiler/transform/componentScriptTransformer.ts
10974
+ var lexerInitialized = false;
10975
+ async function ensureLexerInit() {
10976
+ if (!lexerInitialized) {
10977
+ await init;
10978
+ lexerInitialized = true;
10979
+ }
10980
+ }
10981
+ var NAMESPACE_BINDINGS = `const {
10982
+ signal, state, memo, effect, ref,
10983
+ batch, untrack, onMount, onUnmount
10984
+ } = __inst;`;
10985
+ var ZEN_PREFIX_MAPPINGS = {
10986
+ zenSignal: "signal",
10987
+ zenState: "state",
10988
+ zenMemo: "memo",
10989
+ zenEffect: "effect",
10990
+ zenRef: "ref",
10991
+ zenBatch: "batch",
10992
+ zenUntrack: "untrack",
10993
+ zenOnMount: "onMount",
10994
+ zenOnUnmount: "onUnmount"
10995
+ };
10996
+ async function parseAndExtractImports(scriptContent) {
10997
+ await ensureLexerInit();
10998
+ const imports = [];
10999
+ const [parsedImports] = parse2(scriptContent);
11000
+ const sortedImports = [...parsedImports].sort((a, b) => b.ss - a.ss);
11001
+ let strippedCode = scriptContent;
11002
+ for (const imp of sortedImports) {
11003
+ const source = imp.n || "";
11004
+ const importStatement = scriptContent.slice(imp.ss, imp.se);
11005
+ if (source.endsWith(".zen")) {
11006
+ strippedCode = strippedCode.slice(0, imp.ss) + strippedCode.slice(imp.se);
11007
+ continue;
11008
+ }
11009
+ if (source.startsWith("./") || source.startsWith("../")) {
11010
+ strippedCode = strippedCode.slice(0, imp.ss) + strippedCode.slice(imp.se);
11011
+ continue;
11012
+ }
11013
+ const isTypeOnly = importStatement.startsWith("import type");
11014
+ const isSideEffect = imp.ss === imp.se || !importStatement.includes(" from ");
11015
+ let specifiers = "";
11016
+ if (!isSideEffect) {
11017
+ const fromIndex = importStatement.indexOf(" from ");
11018
+ if (fromIndex !== -1) {
11019
+ const start = isTypeOnly ? "import type ".length : "import ".length;
11020
+ specifiers = importStatement.slice(start, fromIndex).trim();
11021
+ }
11022
+ }
11023
+ imports.push({
11024
+ source,
11025
+ specifiers,
11026
+ typeOnly: isTypeOnly,
11027
+ sideEffect: isSideEffect
11028
+ });
11029
+ strippedCode = strippedCode.slice(0, imp.ss) + strippedCode.slice(imp.se);
11030
+ }
11031
+ strippedCode = strippedCode.replace(/^\s*\n/gm, "");
11032
+ imports.reverse();
11033
+ return { imports, strippedCode };
11034
+ }
11035
+ async function transformComponentScript(componentName, scriptContent, props) {
11036
+ const { imports, strippedCode } = await parseAndExtractImports(scriptContent);
11037
+ let transformed = strippedCode;
11038
+ for (const [zenName, unprefixedName] of Object.entries(ZEN_PREFIX_MAPPINGS)) {
11039
+ const regex = new RegExp(`(?<!\\w)${zenName}\\s*\\(`, "g");
11040
+ transformed = transformed.replace(regex, `${unprefixedName}(`);
11041
+ }
11042
+ return {
11043
+ script: transformed.trim(),
11044
+ imports
11045
+ };
11046
+ }
11047
+ function generateComponentFactory(componentName, transformedScript, propNames) {
11048
+ const propsDestructure = propNames.length > 0 ? `const { ${propNames.join(", ")} } = props || {};` : "";
11049
+ return `
11050
+ // Component Factory: ${componentName}
11051
+ // Instantiation is driven by hydrator, not by bundle load
11052
+ __zenith.defineComponent('${componentName}', function(props, rootElement) {
11053
+ const __inst = __zenith.createInstance('${componentName}', rootElement);
11054
+
11055
+ // Namespace bindings (instance-scoped primitives)
11056
+ ${NAMESPACE_BINDINGS}
11057
+
11058
+ ${propsDestructure}
11059
+
11060
+ // Component script (instance-scoped)
11061
+ ${transformedScript}
11062
+
11063
+ // Execute mount lifecycle (rootElement is already in DOM)
11064
+ __inst.mount();
11065
+
11066
+ return __inst;
11067
+ });
11068
+ `;
11069
+ }
11070
+ function deduplicateImports(imports) {
11071
+ const seen = new Map;
11072
+ for (const imp of imports) {
11073
+ const key = `${imp.source}|${imp.specifiers}|${imp.typeOnly}`;
11074
+ if (!seen.has(key)) {
11075
+ seen.set(key, imp);
11076
+ }
11077
+ }
11078
+ return Array.from(seen.values()).sort((a, b) => a.source.localeCompare(b.source));
11079
+ }
11080
+ function emitImports(imports) {
11081
+ const deduplicated = deduplicateImports(imports);
11082
+ return deduplicated.map((imp) => {
11083
+ if (imp.sideEffect) {
11084
+ return `import '${imp.source}';`;
11085
+ }
11086
+ const typePrefix = imp.typeOnly ? "type " : "";
11087
+ return `import ${typePrefix}${imp.specifiers} from '${imp.source}';`;
11088
+ }).join(`
11089
+ `);
11090
+ }
11091
+ async function transformAllComponentScripts(componentScripts) {
11092
+ if (!componentScripts || componentScripts.length === 0) {
11093
+ return { code: "", imports: [] };
11094
+ }
11095
+ const allImports = [];
11096
+ const factories = await Promise.all(componentScripts.filter((comp) => comp.script && comp.script.trim().length > 0).map(async (comp) => {
11097
+ const result = await transformComponentScript(comp.name, comp.script, comp.props);
11098
+ allImports.push(...result.imports);
11099
+ return generateComponentFactory(comp.name, result.script, comp.props);
11100
+ }));
11101
+ return {
11102
+ code: factories.join(`
11103
+ `),
11104
+ imports: deduplicateImports(allImports)
11105
+ };
11106
+ }
11107
+
10884
11108
  // compiler/runtime/transformIR.ts
10885
- function transformIR(ir) {
11109
+ async function transformIR(ir) {
10886
11110
  const expressionDependencies = analyzeAllExpressions(ir.template.expressions, ir.filePath, [], ir.script?.attributes["props"] ? ir.script.attributes["props"].split(",") : [], []);
10887
11111
  const expressions = generateExpressionWrappers(ir.template.expressions, expressionDependencies);
10888
11112
  const renderFunction = generateDOMFunction(ir.template.nodes, ir.template.expressions, "renderDynamicPage");
@@ -10897,6 +11121,7 @@ function transformIR(ir) {
10897
11121
  const propDeclarations = extractProps(scriptContent);
10898
11122
  const stateInitCode = generateStateInitialization(stateDeclarations, [...propDeclarations, ...propKeys]);
10899
11123
  const scriptCode = transformStateDeclarations(scriptContent);
11124
+ const componentScriptResult = await transformAllComponentScripts(ir.componentScripts || []);
10900
11125
  const bundle = generateRuntimeBundle({
10901
11126
  expressions,
10902
11127
  expressionRegistry,
@@ -10904,7 +11129,9 @@ function transformIR(ir) {
10904
11129
  navigationRuntime,
10905
11130
  stylesCode,
10906
11131
  scriptCode,
10907
- stateInitCode
11132
+ stateInitCode,
11133
+ componentScriptCode: componentScriptResult.code,
11134
+ npmImports: componentScriptResult.imports
10908
11135
  });
10909
11136
  return {
10910
11137
  expressions,
@@ -10918,10 +11145,14 @@ function transformIR(ir) {
10918
11145
  }
10919
11146
  function generateRuntimeBundle(parts) {
10920
11147
  const functionRegistrations = extractFunctionRegistrations(parts.scriptCode);
11148
+ const npmImportsHeader = parts.npmImports.length > 0 ? `// NPM Imports (hoisted from component scripts)
11149
+ ${emitImports(parts.npmImports)}
11150
+
11151
+ ` : "";
10921
11152
  return `// Zenith Runtime Bundle (Phase 5)
10922
11153
  // Generated at compile time - no .zen parsing in browser
10923
11154
 
10924
- ${parts.expressions}
11155
+ ${npmImportsHeader}${parts.expressions}
10925
11156
 
10926
11157
  ${parts.expressionRegistry}
10927
11158
 
@@ -10940,6 +11171,9 @@ ${functionRegistrations}
10940
11171
  ${parts.stateInitCode ? `// State initialization
10941
11172
  ${parts.stateInitCode}` : ""}
10942
11173
 
11174
+ ${parts.componentScriptCode ? `// Component factories (instance-scoped)
11175
+ ${parts.componentScriptCode}` : ""}
11176
+
10943
11177
  // Export hydration functions
10944
11178
  if (typeof window !== 'undefined') {
10945
11179
  window.zenithHydrate = window.__zenith_hydrate || function(state, container) {
@@ -10998,10 +11232,21 @@ if (typeof window !== 'undefined') {
10998
11232
  // Get the router outlet or body
10999
11233
  const container = document.querySelector('#app') || document.body;
11000
11234
 
11001
- // Hydrate with state
11235
+ // Hydrate with state (expressions, bindings)
11002
11236
  if (window.__zenith_hydrate) {
11003
11237
  window.__zenith_hydrate(state, {}, {}, {}, container);
11004
11238
  }
11239
+
11240
+ // Hydrate components by discovering data-zen-component markers
11241
+ // This is the ONLY place component instantiation happens - driven by DOM markers
11242
+ if (window.__zenith && window.__zenith.hydrateComponents) {
11243
+ window.__zenith.hydrateComponents(container);
11244
+ }
11245
+
11246
+ // Trigger page-level mount lifecycle
11247
+ if (window.__zenith && window.__zenith.triggerMount) {
11248
+ window.__zenith.triggerMount();
11249
+ }
11005
11250
  }
11006
11251
 
11007
11252
  // Run on DOM ready
@@ -11178,7 +11423,7 @@ function validateExpressionsOrThrow(expressions, filePath) {
11178
11423
  }
11179
11424
 
11180
11425
  // compiler/finalize/finalizeOutput.ts
11181
- function finalizeOutput(ir, compiled) {
11426
+ async function finalizeOutput(ir, compiled) {
11182
11427
  const errors = [];
11183
11428
  try {
11184
11429
  validateExpressionsOrThrow(ir.template.expressions, ir.filePath);
@@ -11207,7 +11452,7 @@ function finalizeOutput(ir, compiled) {
11207
11452
  }
11208
11453
  let runtimeCode;
11209
11454
  try {
11210
- runtimeCode = transformIR(ir);
11455
+ runtimeCode = await transformIR(ir);
11211
11456
  } catch (error3) {
11212
11457
  errors.push(`Runtime generation failed: ${error3.message}`);
11213
11458
  return {
@@ -11263,8 +11508,8 @@ function verifyNoRawExpressions(html, filePath) {
11263
11508
  }
11264
11509
  return errors;
11265
11510
  }
11266
- function finalizeOutputOrThrow(ir, compiled) {
11267
- const output = finalizeOutput(ir, compiled);
11511
+ async function finalizeOutputOrThrow(ir, compiled) {
11512
+ const output = await finalizeOutput(ir, compiled);
11268
11513
  if (output.hasErrors) {
11269
11514
  const errorMessage = output.errors.join(`
11270
11515
 
@@ -11278,10 +11523,10 @@ ${errorMessage}`);
11278
11523
 
11279
11524
  // compiler/index.ts
11280
11525
  init_invariants();
11281
- function compileZenSource(source, filePath, options) {
11526
+ async function compileZenSource(source, filePath, options) {
11282
11527
  const template = parseTemplate(source, filePath);
11283
11528
  const script = parseScript(source);
11284
- const styleRegex = /\u003cstyle[^\u003e]*\u003e([\s\S]*?)\u003c\/style\u003e/gi;
11529
+ const styleRegex = /<style[^>]*>([\s\S]*?)<\/style>/gi;
11285
11530
  const styles = [];
11286
11531
  let match;
11287
11532
  while ((match = styleRegex.exec(source)) !== null) {
@@ -11303,7 +11548,7 @@ function compileZenSource(source, filePath, options) {
11303
11548
  validateInvariants(ir, filePath);
11304
11549
  const compiled = transformTemplate(ir);
11305
11550
  try {
11306
- const finalized = finalizeOutputOrThrow(ir, compiled);
11551
+ const finalized = await finalizeOutputOrThrow(ir, compiled);
11307
11552
  return { ir, compiled, finalized };
11308
11553
  } catch (error3) {
11309
11554
  throw new Error(`Failed to finalize output for ${filePath}:\\n${error3.message}`);
@@ -11333,7 +11578,12 @@ function discoverLayouts(layoutsDir) {
11333
11578
  if (match[1])
11334
11579
  styles.push(match[1].trim());
11335
11580
  }
11336
- let html = source.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "");
11581
+ let html = source.replace(/<script([^>]*)>([\s\S]*?)<\/script>/gi, (match2, attrs, content) => {
11582
+ if (attrs.includes("src=")) {
11583
+ return match2;
11584
+ }
11585
+ return "";
11586
+ });
11337
11587
  html = html.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "").trim();
11338
11588
  layouts.set(name, {
11339
11589
  name,
@@ -11835,6 +12085,144 @@ function generateBundleJS() {
11835
12085
  unmountCallbacks.length = 0;
11836
12086
  }
11837
12087
 
12088
+ // ============================================
12089
+ // Component Instance System
12090
+ // ============================================
12091
+ // Each component instance gets isolated state, effects, and lifecycles
12092
+ // Instances are tied to DOM elements via hydration markers
12093
+
12094
+ const componentRegistry = {};
12095
+
12096
+ function createComponentInstance(componentName, rootElement) {
12097
+ const instanceMountCallbacks = [];
12098
+ const instanceUnmountCallbacks = [];
12099
+ const instanceEffects = [];
12100
+ let instanceMounted = false;
12101
+
12102
+ return {
12103
+ // DOM reference
12104
+ root: rootElement,
12105
+
12106
+ // Lifecycle hooks (instance-scoped)
12107
+ onMount: function(fn) {
12108
+ if (instanceMounted) {
12109
+ const cleanup = fn();
12110
+ if (typeof cleanup === 'function') {
12111
+ instanceUnmountCallbacks.push(cleanup);
12112
+ }
12113
+ } else {
12114
+ instanceMountCallbacks.push(fn);
12115
+ }
12116
+ },
12117
+ onUnmount: function(fn) {
12118
+ instanceUnmountCallbacks.push(fn);
12119
+ },
12120
+
12121
+ // Reactivity (uses global primitives but tracks for cleanup)
12122
+ signal: function(initial) {
12123
+ return zenSignal(initial);
12124
+ },
12125
+ state: function(initial) {
12126
+ return zenState(initial);
12127
+ },
12128
+ ref: function(initial) {
12129
+ return zenRef(initial);
12130
+ },
12131
+ effect: function(fn) {
12132
+ const cleanup = zenEffect(fn);
12133
+ instanceEffects.push(cleanup);
12134
+ return cleanup;
12135
+ },
12136
+ memo: function(fn) {
12137
+ return zenMemo(fn);
12138
+ },
12139
+ batch: function(fn) {
12140
+ zenBatch(fn);
12141
+ },
12142
+ untrack: function(fn) {
12143
+ return zenUntrack(fn);
12144
+ },
12145
+
12146
+ // Lifecycle execution
12147
+ mount: function() {
12148
+ instanceMounted = true;
12149
+ for (let i = 0; i < instanceMountCallbacks.length; i++) {
12150
+ try {
12151
+ const cleanup = instanceMountCallbacks[i]();
12152
+ if (typeof cleanup === 'function') {
12153
+ instanceUnmountCallbacks.push(cleanup);
12154
+ }
12155
+ } catch(e) {
12156
+ console.error('[Zenith] Component mount error:', componentName, e);
12157
+ }
12158
+ }
12159
+ instanceMountCallbacks.length = 0;
12160
+ },
12161
+ unmount: function() {
12162
+ instanceMounted = false;
12163
+ // Cleanup effects
12164
+ for (let i = 0; i < instanceEffects.length; i++) {
12165
+ try {
12166
+ if (typeof instanceEffects[i] === 'function') instanceEffects[i]();
12167
+ } catch(e) {
12168
+ console.error('[Zenith] Effect cleanup error:', e);
12169
+ }
12170
+ }
12171
+ instanceEffects.length = 0;
12172
+ // Run unmount callbacks
12173
+ for (let i = 0; i < instanceUnmountCallbacks.length; i++) {
12174
+ try { instanceUnmountCallbacks[i](); } catch(e) { console.error('[Zenith] Unmount error:', e); }
12175
+ }
12176
+ instanceUnmountCallbacks.length = 0;
12177
+ }
12178
+ };
12179
+ }
12180
+
12181
+ function defineComponent(name, factory) {
12182
+ componentRegistry[name] = factory;
12183
+ }
12184
+
12185
+ function instantiateComponent(name, props, rootElement) {
12186
+ const factory = componentRegistry[name];
12187
+ if (!factory) {
12188
+ console.warn('[Zenith] Component not found:', name);
12189
+ return null;
12190
+ }
12191
+ return factory(props, rootElement);
12192
+ }
12193
+
12194
+ /**
12195
+ * Hydrate components by discovering data-zen-component markers
12196
+ * This is the ONLY place component instantiation should happen
12197
+ */
12198
+ function hydrateComponents(container) {
12199
+ const componentElements = container.querySelectorAll('[data-zen-component]');
12200
+
12201
+ for (let i = 0; i < componentElements.length; i++) {
12202
+ const el = componentElements[i];
12203
+ const componentName = el.getAttribute('data-zen-component');
12204
+
12205
+ // Skip if already hydrated
12206
+ if (el.__zenith_instance) continue;
12207
+
12208
+ // Parse props from data attribute if present
12209
+ const propsJson = el.getAttribute('data-zen-props') || '{}';
12210
+ let props = {};
12211
+ try {
12212
+ props = JSON.parse(propsJson);
12213
+ } catch(e) {
12214
+ console.warn('[Zenith] Invalid props JSON for', componentName);
12215
+ }
12216
+
12217
+ // Instantiate component and bind to DOM element
12218
+ const instance = instantiateComponent(componentName, props, el);
12219
+
12220
+ if (instance) {
12221
+ el.__zenith_instance = instance;
12222
+ }
12223
+ }
12224
+ }
12225
+
11838
12226
  // ============================================
11839
12227
  // Expression Registry & Hydration
11840
12228
  // ============================================
@@ -12254,8 +12642,13 @@ function generateBundleJS() {
12254
12642
  triggerUnmount: triggerUnmount,
12255
12643
  // Hydration
12256
12644
  hydrate: zenithHydrate,
12645
+ hydrateComponents: hydrateComponents, // Marker-driven component instantiation
12257
12646
  registerExpression: registerExpression,
12258
- getExpression: getExpression
12647
+ getExpression: getExpression,
12648
+ // Component instance system
12649
+ createInstance: createComponentInstance,
12650
+ defineComponent: defineComponent,
12651
+ instantiate: instantiateComponent
12259
12652
  };
12260
12653
 
12261
12654
  // Expose with zen* prefix for direct usage
@@ -12347,7 +12740,7 @@ var T = L();
12347
12740
  function Z(u) {
12348
12741
  T = u;
12349
12742
  }
12350
- var C = { exec: () => null };
12743
+ var C2 = { exec: () => null };
12351
12744
  function k(u, e = "") {
12352
12745
  let t = typeof u == "string" ? u : u.source, n = { replace: (r, i) => {
12353
12746
  let s = typeof i == "string" ? i : i.source;
@@ -12372,7 +12765,7 @@ var N = /(?:[*+-]|\d{1,9}[.)])/;
12372
12765
  var re = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
12373
12766
  var se = k(re).replace(/bull/g, N).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
12374
12767
  var Oe = k(re).replace(/bull/g, N).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
12375
- var Q = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
12768
+ var Q2 = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
12376
12769
  var we = /^[^\n]+/;
12377
12770
  var F = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/;
12378
12771
  var ye = k(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", F).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
@@ -12380,12 +12773,12 @@ var Pe = k(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, N).getRegex(
12380
12773
  var v = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
12381
12774
  var j = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
12382
12775
  var Se = k("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$))", "i").replace("comment", j).replace("tag", v).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
12383
- var ie = k(Q).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
12776
+ var ie = k(Q2).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
12384
12777
  var $e = k(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", ie).getRegex();
12385
- var U = { blockquote: $e, code: be, def: ye, fences: Re, heading: Te, hr: I, html: Se, lheading: se, list: Pe, newline: xe, paragraph: ie, table: C, text: we };
12778
+ var U = { blockquote: $e, code: be, def: ye, fences: Re, heading: Te, hr: I, html: Se, lheading: se, list: Pe, newline: xe, paragraph: ie, table: C2, text: we };
12386
12779
  var te = k("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3}\t)[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
12387
- var _e = { ...U, lheading: Oe, table: te, paragraph: k(Q).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", te).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex() };
12388
- var Le = { ...U, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", j).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: C, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: k(Q).replace("hr", I).replace("heading", ` *#{1,6} *[^
12780
+ var _e = { ...U, lheading: Oe, table: te, paragraph: k(Q2).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", te).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex() };
12781
+ var Le = { ...U, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", j).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: C2, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: k(Q2).replace("hr", I).replace("heading", ` *#{1,6} *[^
12389
12782
  ]`).replace("lheading", se).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
12390
12783
  var Me = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
12391
12784
  var ze = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
@@ -12416,11 +12809,11 @@ var ce = k(/^!?\[(label)\]\[(ref)\]/).replace("label", q).replace("ref", F).getR
12416
12809
  var he = k(/^!?\[(ref)\](?:\[\])?/).replace("ref", F).getRegex();
12417
12810
  var Ue = k("reflink|nolink(?!\\()", "g").replace("reflink", ce).replace("nolink", he).getRegex();
12418
12811
  var ne = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
12419
- var W = { _backpedal: C, anyPunctuation: Ge, autolink: Ne, blockSkip: Be, br: oe, code: ze, del: C, emStrongLDelim: qe, emStrongRDelimAst: De, emStrongRDelimUnd: Ze, escape: Me, link: je, nolink: he, punctuation: Ce, reflink: ce, reflinkSearch: Ue, tag: Fe, text: Ae, url: C };
12812
+ var W = { _backpedal: C2, anyPunctuation: Ge, autolink: Ne, blockSkip: Be, br: oe, code: ze, del: C2, emStrongLDelim: qe, emStrongRDelimAst: De, emStrongRDelimUnd: Ze, escape: Me, link: je, nolink: he, punctuation: Ce, reflink: ce, reflinkSearch: Ue, tag: Fe, text: Ae, url: C2 };
12420
12813
  var Ke = { ...W, link: k(/^!?\[(label)\]\((.*?)\)/).replace("label", q).getRegex(), reflink: k(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", q).getRegex() };
12421
12814
  var G = { ...W, emStrongRDelimAst: He, emStrongLDelim: ve, url: k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ne).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: k(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol", ne).getRegex() };
12422
12815
  var We = { ...G, br: k(oe).replace("{2,}", "*").getRegex(), text: k(G.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
12423
- var E = { normal: U, gfm: _e, pedantic: Le };
12816
+ var E2 = { normal: U, gfm: _e, pedantic: Le };
12424
12817
  var M = { normal: W, gfm: G, breaks: We, pedantic: Ke };
12425
12818
  var Xe = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
12426
12819
  var ke = (u) => Xe[u];
@@ -12616,12 +13009,12 @@ ${c}` : c;
12616
13009
  let O = this.rules.other.nextBulletRegex(f), V = this.rules.other.hrRegex(f), Y = this.rules.other.fencesBeginRegex(f), ee = this.rules.other.headingBeginRegex(f), fe = this.rules.other.htmlBeginRegex(f);
12617
13010
  for (;e; ) {
12618
13011
  let H = e.split(`
12619
- `, 1)[0], A;
12620
- if (h = H, this.options.pedantic ? (h = h.replace(this.rules.other.listReplaceNesting, " "), A = h) : A = h.replace(this.rules.other.tabCharGlobal, " "), Y.test(h) || ee.test(h) || fe.test(h) || O.test(h) || V.test(h))
13012
+ `, 1)[0], A2;
13013
+ if (h = H, this.options.pedantic ? (h = h.replace(this.rules.other.listReplaceNesting, " "), A2 = h) : A2 = h.replace(this.rules.other.tabCharGlobal, " "), Y.test(h) || ee.test(h) || fe.test(h) || O.test(h) || V.test(h))
12621
13014
  break;
12622
- if (A.search(this.rules.other.nonSpaceChar) >= f || !h.trim())
13015
+ if (A2.search(this.rules.other.nonSpaceChar) >= f || !h.trim())
12623
13016
  c += `
12624
- ` + A.slice(f);
13017
+ ` + A2.slice(f);
12625
13018
  else {
12626
13019
  if (R || g.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || Y.test(g) || ee.test(g) || V.test(g))
12627
13020
  break;
@@ -12629,7 +13022,7 @@ ${c}` : c;
12629
13022
  ` + h;
12630
13023
  }
12631
13024
  !R && !h.trim() && (R = true), p += H + `
12632
- `, e = e.substring(H.length + 1), g = A.slice(f);
13025
+ `, e = e.substring(H.length + 1), g = A2.slice(f);
12633
13026
  }
12634
13027
  }
12635
13028
  i.loose || (a ? i.loose = true : this.rules.other.doubleBlankLine.test(p) && (a = true)), i.items.push({ type: "list_item", raw: p, task: !!this.options.gfm && this.rules.other.listIsTask.test(c), loose: false, text: c, tokens: [] }), i.raw += p;
@@ -12850,11 +13243,11 @@ var x = class u {
12850
13243
  tokenizer;
12851
13244
  constructor(e) {
12852
13245
  this.tokens = [], this.tokens.links = Object.create(null), this.options = e || T, this.options.tokenizer = this.options.tokenizer || new y, this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true };
12853
- let t = { other: m, block: E.normal, inline: M.normal };
12854
- this.options.pedantic ? (t.block = E.pedantic, t.inline = M.pedantic) : this.options.gfm && (t.block = E.gfm, this.options.breaks ? t.inline = M.breaks : t.inline = M.gfm), this.tokenizer.rules = t;
13246
+ let t = { other: m, block: E2.normal, inline: M.normal };
13247
+ this.options.pedantic ? (t.block = E2.pedantic, t.inline = M.pedantic) : this.options.gfm && (t.block = E2.gfm, this.options.breaks ? t.inline = M.breaks : t.inline = M.gfm), this.tokenizer.rules = t;
12855
13248
  }
12856
13249
  static get rules() {
12857
- return { block: E, inline: M };
13250
+ return { block: E2, inline: M };
12858
13251
  }
12859
13252
  static lex(e, t) {
12860
13253
  return new u(t).lex(e);
@@ -13391,7 +13784,7 @@ var S = class {
13391
13784
  return this.block ? b.parse : b.parseInline;
13392
13785
  }
13393
13786
  };
13394
- var B = class {
13787
+ var B2 = class {
13395
13788
  defaults = L();
13396
13789
  options = this.setOptions;
13397
13790
  parse = this.parseMarkdown(true);
@@ -13571,7 +13964,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
13571
13964
  };
13572
13965
  }
13573
13966
  };
13574
- var _ = new B;
13967
+ var _ = new B2;
13575
13968
  function d(u3, e) {
13576
13969
  return _.parse(u3, e);
13577
13970
  }
@@ -13916,6 +14309,36 @@ function resolveGlobalsCss(projectRoot) {
13916
14309
 
13917
14310
  // cli/commands/dev.ts
13918
14311
  var pageCache = new Map;
14312
+ async function bundlePageScript(script, projectRoot) {
14313
+ if (!script.includes("import ")) {
14314
+ return script;
14315
+ }
14316
+ const tempDir = os.tmpdir();
14317
+ const tempFile = path8.join(tempDir, `zenith-bundle-${Date.now()}.js`);
14318
+ try {
14319
+ fs8.writeFileSync(tempFile, script, "utf-8");
14320
+ const result = await Bun.build({
14321
+ entrypoints: [tempFile],
14322
+ target: "browser",
14323
+ format: "esm",
14324
+ minify: false,
14325
+ external: []
14326
+ });
14327
+ if (!result.success || !result.outputs[0]) {
14328
+ console.error("[Zenith] Bundle errors:", result.logs);
14329
+ return script;
14330
+ }
14331
+ const bundledCode = await result.outputs[0].text();
14332
+ return bundledCode;
14333
+ } catch (error3) {
14334
+ console.error("[Zenith] Failed to bundle page script:", error3.message);
14335
+ return script;
14336
+ } finally {
14337
+ try {
14338
+ fs8.unlinkSync(tempFile);
14339
+ } catch {}
14340
+ }
14341
+ }
13919
14342
  async function dev(options = {}) {
13920
14343
  const project = requireProject();
13921
14344
  const port = options.port || parseInt(process.env.PORT || "3000", 10);
@@ -13979,7 +14402,7 @@ async function dev(options = {}) {
13979
14402
  ".json",
13980
14403
  ".map"
13981
14404
  ]);
13982
- function compilePageInMemory(pagePath) {
14405
+ async function compilePageInMemory(pagePath) {
13983
14406
  try {
13984
14407
  const layoutsDir = path8.join(pagesDir, "../layouts");
13985
14408
  const componentsDir = path8.join(pagesDir, "../components");
@@ -13989,15 +14412,16 @@ async function dev(options = {}) {
13989
14412
  let layoutToUse = layouts.get("DefaultLayout");
13990
14413
  if (layoutToUse)
13991
14414
  processedSource = processLayout(source, layoutToUse);
13992
- const result = compileZenSource(processedSource, pagePath, {
14415
+ const result = await compileZenSource(processedSource, pagePath, {
13993
14416
  componentsDir: fs8.existsSync(componentsDir) ? componentsDir : undefined
13994
14417
  });
13995
14418
  if (!result.finalized)
13996
14419
  throw new Error("Compilation failed");
13997
14420
  const routeDef = generateRouteDefinition(pagePath, pagesDir);
14421
+ const bundledScript = await bundlePageScript(result.finalized.js, rootDir);
13998
14422
  return {
13999
14423
  html: result.finalized.html,
14000
- script: result.finalized.js,
14424
+ script: bundledScript,
14001
14425
  styles: result.finalized.styles,
14002
14426
  route: routeDef.path,
14003
14427
  lastModified: Date.now()
@@ -14049,7 +14473,7 @@ async function dev(options = {}) {
14049
14473
  });
14050
14474
  const server = serve({
14051
14475
  port,
14052
- fetch(req, server2) {
14476
+ async fetch(req, server2) {
14053
14477
  const startTime = performance.now();
14054
14478
  const url = new URL(req.url);
14055
14479
  const pathname = url.pathname;
@@ -14094,7 +14518,7 @@ async function dev(options = {}) {
14094
14518
  let cached = pageCache.get(pagePath);
14095
14519
  const stat = fs8.statSync(pagePath);
14096
14520
  if (!cached || stat.mtimeMs > cached.lastModified) {
14097
- cached = compilePageInMemory(pagePath) || undefined;
14521
+ cached = await compilePageInMemory(pagePath) || undefined;
14098
14522
  if (cached)
14099
14523
  pageCache.set(pagePath, cached);
14100
14524
  }
@@ -14157,7 +14581,7 @@ function generateDevHTML(page, contentData = {}) {
14157
14581
  const runtimeTag = `<script src="/runtime.js"></script>`;
14158
14582
  const contentJson = JSON.stringify(contentData).replace(/<\//g, "<\\/");
14159
14583
  const contentTag = `<script>window.__ZENITH_CONTENT__ = ${contentJson};</script>`;
14160
- const scriptTag = `<script>
14584
+ const scriptTag = `<script type="module">
14161
14585
  ${page.script}
14162
14586
  </script>`;
14163
14587
  const allScripts = `${runtimeTag}
@@ -14286,7 +14710,7 @@ function getBuildOutputType(analysis) {
14286
14710
  }
14287
14711
 
14288
14712
  // compiler/ssg-build.ts
14289
- function compilePage(pagePath, pagesDir, baseDir = process.cwd()) {
14713
+ async function compilePage(pagePath, pagesDir, baseDir = process.cwd()) {
14290
14714
  const source = fs9.readFileSync(pagePath, "utf-8");
14291
14715
  const analysis = analyzePageSource(source);
14292
14716
  const layoutsDir = path10.join(baseDir, "layouts");
@@ -14296,7 +14720,7 @@ function compilePage(pagePath, pagesDir, baseDir = process.cwd()) {
14296
14720
  if (layoutToUse) {
14297
14721
  processedSource = processLayout(source, layoutToUse);
14298
14722
  }
14299
- const result = compileZenSource(processedSource, pagePath);
14723
+ const result = await compileZenSource(processedSource, pagePath);
14300
14724
  if (!result.finalized) {
14301
14725
  throw new Error(`Compilation failed for ${pagePath}: No finalized output`);
14302
14726
  }
@@ -14389,7 +14813,7 @@ ${page.pageScript}
14389
14813
  })();
14390
14814
  `;
14391
14815
  }
14392
- function buildSSG(options) {
14816
+ async function buildSSG(options) {
14393
14817
  const { pagesDir, outDir, baseDir = path10.dirname(pagesDir) } = options;
14394
14818
  const contentDir = path10.join(baseDir, "content");
14395
14819
  const contentData = loadContent(contentDir);
@@ -14414,7 +14838,7 @@ function buildSSG(options) {
14414
14838
  const relativePath = path10.relative(pagesDir, pageFile);
14415
14839
  console.log(` Compiling: ${relativePath}`);
14416
14840
  try {
14417
- const compiled = compilePage(pageFile, pagesDir, baseDir);
14841
+ const compiled = await compilePage(pageFile, pagesDir, baseDir);
14418
14842
  compiledPages.push(compiled);
14419
14843
  if (compiled.analysis.needsHydration) {
14420
14844
  hasHydratedPages = true;
@@ -14473,7 +14897,7 @@ function buildSSG(options) {
14473
14897
  const custom404Path = path10.join(pagesDir, candidate);
14474
14898
  if (fs9.existsSync(custom404Path)) {
14475
14899
  try {
14476
- const compiled = compilePage(custom404Path, pagesDir, baseDir);
14900
+ const compiled = await compilePage(custom404Path, pagesDir, baseDir);
14477
14901
  const html = generatePageHTML(compiled, globalStyles, contentData);
14478
14902
  fs9.writeFileSync(path10.join(outDir, "404.html"), html);
14479
14903
  console.log("\uD83D\uDCE6 Generated 404.html (custom)");