@zenithbuild/compiler 1.0.2

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 (145) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -0
  3. package/dist/build-analyzer.d.ts +44 -0
  4. package/dist/build-analyzer.js +87 -0
  5. package/dist/bundler.d.ts +31 -0
  6. package/dist/bundler.js +86 -0
  7. package/dist/core/components/index.d.ts +9 -0
  8. package/dist/core/components/index.js +13 -0
  9. package/dist/core/config/index.d.ts +11 -0
  10. package/dist/core/config/index.js +10 -0
  11. package/dist/core/config/loader.d.ts +17 -0
  12. package/dist/core/config/loader.js +60 -0
  13. package/dist/core/config/types.d.ts +98 -0
  14. package/dist/core/config/types.js +32 -0
  15. package/dist/core/index.d.ts +7 -0
  16. package/dist/core/index.js +6 -0
  17. package/dist/core/lifecycle/index.d.ts +16 -0
  18. package/dist/core/lifecycle/index.js +19 -0
  19. package/dist/core/lifecycle/zen-mount.d.ts +66 -0
  20. package/dist/core/lifecycle/zen-mount.js +151 -0
  21. package/dist/core/lifecycle/zen-unmount.d.ts +54 -0
  22. package/dist/core/lifecycle/zen-unmount.js +76 -0
  23. package/dist/core/plugins/bridge.d.ts +116 -0
  24. package/dist/core/plugins/bridge.js +121 -0
  25. package/dist/core/plugins/index.d.ts +6 -0
  26. package/dist/core/plugins/index.js +6 -0
  27. package/dist/core/plugins/registry.d.ts +67 -0
  28. package/dist/core/plugins/registry.js +113 -0
  29. package/dist/core/reactivity/index.d.ts +30 -0
  30. package/dist/core/reactivity/index.js +33 -0
  31. package/dist/core/reactivity/tracking.d.ts +74 -0
  32. package/dist/core/reactivity/tracking.js +136 -0
  33. package/dist/core/reactivity/zen-batch.d.ts +45 -0
  34. package/dist/core/reactivity/zen-batch.js +54 -0
  35. package/dist/core/reactivity/zen-effect.d.ts +48 -0
  36. package/dist/core/reactivity/zen-effect.js +98 -0
  37. package/dist/core/reactivity/zen-memo.d.ts +43 -0
  38. package/dist/core/reactivity/zen-memo.js +100 -0
  39. package/dist/core/reactivity/zen-ref.d.ts +44 -0
  40. package/dist/core/reactivity/zen-ref.js +34 -0
  41. package/dist/core/reactivity/zen-signal.d.ts +48 -0
  42. package/dist/core/reactivity/zen-signal.js +84 -0
  43. package/dist/core/reactivity/zen-state.d.ts +35 -0
  44. package/dist/core/reactivity/zen-state.js +147 -0
  45. package/dist/core/reactivity/zen-untrack.d.ts +38 -0
  46. package/dist/core/reactivity/zen-untrack.js +41 -0
  47. package/dist/css/index.d.ts +73 -0
  48. package/dist/css/index.js +246 -0
  49. package/dist/discovery/componentDiscovery.d.ts +42 -0
  50. package/dist/discovery/componentDiscovery.js +56 -0
  51. package/dist/discovery/layouts.d.ts +13 -0
  52. package/dist/discovery/layouts.js +41 -0
  53. package/dist/errors/compilerError.d.ts +31 -0
  54. package/dist/errors/compilerError.js +51 -0
  55. package/dist/finalize/finalizeOutput.d.ts +32 -0
  56. package/dist/finalize/finalizeOutput.js +62 -0
  57. package/dist/finalize/generateFinalBundle.d.ts +24 -0
  58. package/dist/finalize/generateFinalBundle.js +68 -0
  59. package/dist/index.d.ts +36 -0
  60. package/dist/index.js +51 -0
  61. package/dist/ir/types.d.ts +181 -0
  62. package/dist/ir/types.js +8 -0
  63. package/dist/output/types.d.ts +30 -0
  64. package/dist/output/types.js +6 -0
  65. package/dist/parse/detectMapExpressions.d.ts +45 -0
  66. package/dist/parse/detectMapExpressions.js +77 -0
  67. package/dist/parse/parseScript.d.ts +8 -0
  68. package/dist/parse/parseScript.js +36 -0
  69. package/dist/parse/parseTemplate.d.ts +11 -0
  70. package/dist/parse/parseTemplate.js +487 -0
  71. package/dist/parse/parseZenFile.d.ts +11 -0
  72. package/dist/parse/parseZenFile.js +50 -0
  73. package/dist/parse/scriptAnalysis.d.ts +25 -0
  74. package/dist/parse/scriptAnalysis.js +60 -0
  75. package/dist/parse/trackLoopContext.d.ts +20 -0
  76. package/dist/parse/trackLoopContext.js +62 -0
  77. package/dist/parseZenFile.d.ts +10 -0
  78. package/dist/parseZenFile.js +55 -0
  79. package/dist/runtime/analyzeAndEmit.d.ts +20 -0
  80. package/dist/runtime/analyzeAndEmit.js +70 -0
  81. package/dist/runtime/build.d.ts +6 -0
  82. package/dist/runtime/build.js +13 -0
  83. package/dist/runtime/bundle-generator.d.ts +27 -0
  84. package/dist/runtime/bundle-generator.js +1263 -0
  85. package/dist/runtime/client-runtime.d.ts +41 -0
  86. package/dist/runtime/client-runtime.js +397 -0
  87. package/dist/runtime/dataExposure.d.ts +52 -0
  88. package/dist/runtime/dataExposure.js +227 -0
  89. package/dist/runtime/generateDOM.d.ts +21 -0
  90. package/dist/runtime/generateDOM.js +194 -0
  91. package/dist/runtime/generateHydrationBundle.d.ts +15 -0
  92. package/dist/runtime/generateHydrationBundle.js +399 -0
  93. package/dist/runtime/hydration.d.ts +53 -0
  94. package/dist/runtime/hydration.js +271 -0
  95. package/dist/runtime/navigation.d.ts +58 -0
  96. package/dist/runtime/navigation.js +372 -0
  97. package/dist/runtime/serve.d.ts +13 -0
  98. package/dist/runtime/serve.js +76 -0
  99. package/dist/runtime/thinRuntime.d.ts +23 -0
  100. package/dist/runtime/thinRuntime.js +158 -0
  101. package/dist/runtime/transformIR.d.ts +19 -0
  102. package/dist/runtime/transformIR.js +285 -0
  103. package/dist/runtime/wrapExpression.d.ts +24 -0
  104. package/dist/runtime/wrapExpression.js +76 -0
  105. package/dist/runtime/wrapExpressionWithLoop.d.ts +17 -0
  106. package/dist/runtime/wrapExpressionWithLoop.js +75 -0
  107. package/dist/spa-build.d.ts +26 -0
  108. package/dist/spa-build.js +866 -0
  109. package/dist/ssg-build.d.ts +32 -0
  110. package/dist/ssg-build.js +408 -0
  111. package/dist/test/analyze-emit.test.d.ts +1 -0
  112. package/dist/test/analyze-emit.test.js +88 -0
  113. package/dist/test/bundler-contract.test.d.ts +1 -0
  114. package/dist/test/bundler-contract.test.js +137 -0
  115. package/dist/test/compiler-authority.test.d.ts +1 -0
  116. package/dist/test/compiler-authority.test.js +90 -0
  117. package/dist/test/component-instance-test.d.ts +1 -0
  118. package/dist/test/component-instance-test.js +115 -0
  119. package/dist/test/error-native-bridge.test.d.ts +1 -0
  120. package/dist/test/error-native-bridge.test.js +51 -0
  121. package/dist/test/error-serialization.test.d.ts +1 -0
  122. package/dist/test/error-serialization.test.js +38 -0
  123. package/dist/test/macro-inlining.test.d.ts +1 -0
  124. package/dist/test/macro-inlining.test.js +178 -0
  125. package/dist/test/validate-test.d.ts +6 -0
  126. package/dist/test/validate-test.js +95 -0
  127. package/dist/transform/classifyExpression.d.ts +46 -0
  128. package/dist/transform/classifyExpression.js +354 -0
  129. package/dist/transform/componentResolver.d.ts +15 -0
  130. package/dist/transform/componentResolver.js +30 -0
  131. package/dist/transform/expressionTransformer.d.ts +19 -0
  132. package/dist/transform/expressionTransformer.js +333 -0
  133. package/dist/transform/fragmentLowering.d.ts +25 -0
  134. package/dist/transform/fragmentLowering.js +468 -0
  135. package/dist/transform/layoutProcessor.d.ts +5 -0
  136. package/dist/transform/layoutProcessor.js +34 -0
  137. package/dist/transform/transformTemplate.d.ts +11 -0
  138. package/dist/transform/transformTemplate.js +33 -0
  139. package/dist/validate/invariants.d.ts +23 -0
  140. package/dist/validate/invariants.js +55 -0
  141. package/native/compiler-native/compiler-native.node +0 -0
  142. package/native/compiler-native/index.d.ts +113 -0
  143. package/native/compiler-native/index.js +19 -0
  144. package/native/compiler-native/package.json +19 -0
  145. package/package.json +49 -0
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Zenith Client Runtime - Final Canonical Implementation
3
+ * Satisfies strict reactivity requirements:
4
+ * - Signals are functions (get/set)
5
+ * - State is a Proxy
6
+ * - Effects support cleanup/debounce
7
+ * - Memos are computed signals
8
+ * - Direct DOM updates via fine-grained reactivity
9
+ */
10
+ export declare function zenSignal<T>(initialValue: T): {
11
+ (newValue?: T): T;
12
+ _isSignal: boolean;
13
+ toString(): string;
14
+ valueOf(): T;
15
+ };
16
+ export declare function zenState<T extends object>(initialObj: T): T;
17
+ export declare function zenEffect(fn: () => void | (() => void), options?: {
18
+ debounce?: number;
19
+ defer?: boolean;
20
+ }): () => void;
21
+ export declare function zenMemo<T>(fn: () => T): {
22
+ (): T;
23
+ _isSignal: boolean;
24
+ };
25
+ export declare function zenRef<T>(initial?: T): {
26
+ current: NonNullable<T> | null;
27
+ };
28
+ export declare function zenBatch(fn: () => void): void;
29
+ export declare function zenUntrack<T>(fn: () => T): T;
30
+ export interface ComponentInstance {
31
+ mountHooks: Array<() => void | (() => void)>;
32
+ }
33
+ export declare function setActiveInstance(inst: ComponentInstance | null): void;
34
+ export declare function zenOnMount(cb: any): void;
35
+ export declare function zenOnUnmount(cb: any): void;
36
+ export declare function triggerMount(inst: ComponentInstance): void;
37
+ export declare function h(tag: string, props: any, ...children: any[]): Element;
38
+ export declare function fragment(children: any): DocumentFragment;
39
+ export declare function zenLoop(sourceFn: () => any[], itemFn: (item: any, idx: number) => Node): DocumentFragment;
40
+ export declare function zenithHydrate(state: any, container?: Element | Document): void;
41
+ export declare function setup(): void;
@@ -0,0 +1,397 @@
1
+ /**
2
+ * Zenith Client Runtime - Final Canonical Implementation
3
+ * Satisfies strict reactivity requirements:
4
+ * - Signals are functions (get/set)
5
+ * - State is a Proxy
6
+ * - Effects support cleanup/debounce
7
+ * - Memos are computed signals
8
+ * - Direct DOM updates via fine-grained reactivity
9
+ */
10
+ let currentEffect = null;
11
+ const contextStack = [];
12
+ let batchDepth = 0;
13
+ const pendingEffects = new Set();
14
+ function pushContext(effect) {
15
+ contextStack.push(currentEffect);
16
+ currentEffect = effect;
17
+ }
18
+ function popContext() {
19
+ currentEffect = contextStack.pop();
20
+ }
21
+ function trackDependency(subscribers) {
22
+ if (currentEffect) {
23
+ subscribers.add(currentEffect);
24
+ currentEffect.dependencies.add(subscribers);
25
+ }
26
+ }
27
+ function notifySubscribers(subscribers) {
28
+ const effects = Array.from(subscribers);
29
+ for (const effect of effects) {
30
+ if (batchDepth > 0) {
31
+ pendingEffects.add(effect);
32
+ }
33
+ else {
34
+ effect.run();
35
+ }
36
+ }
37
+ }
38
+ function cleanupEffect(effect) {
39
+ for (const dependency of effect.dependencies) {
40
+ dependency.delete(effect);
41
+ }
42
+ effect.dependencies.clear();
43
+ }
44
+ // === zenSignal ===
45
+ export function zenSignal(initialValue) {
46
+ let value = initialValue;
47
+ const subscribers = new Set();
48
+ function signal(newValue) {
49
+ if (arguments.length === 0) {
50
+ trackDependency(subscribers);
51
+ return value;
52
+ }
53
+ if (newValue !== value) {
54
+ value = newValue;
55
+ notifySubscribers(subscribers);
56
+ }
57
+ return value;
58
+ }
59
+ signal._isSignal = true;
60
+ signal.toString = () => String(value);
61
+ signal.valueOf = () => value;
62
+ // .value getter for convenience/compat
63
+ Object.defineProperty(signal, 'value', {
64
+ get: () => signal(),
65
+ set: (v) => signal(v)
66
+ });
67
+ return signal;
68
+ }
69
+ // === zenState ===
70
+ export function zenState(initialObj) {
71
+ const subscribers = new Map();
72
+ function getSubscribers(path) {
73
+ if (!subscribers.has(path)) {
74
+ subscribers.set(path, new Set());
75
+ }
76
+ return subscribers.get(path);
77
+ }
78
+ function createProxy(obj, parentPath = '') {
79
+ if (obj === null || typeof obj !== 'object' || obj._isSignal)
80
+ return obj;
81
+ return new Proxy(obj, {
82
+ get(target, prop) {
83
+ if (typeof prop === 'symbol')
84
+ return target[prop];
85
+ const path = parentPath ? `${parentPath}.${String(prop)}` : String(prop);
86
+ trackDependency(getSubscribers(path));
87
+ const value = target[prop];
88
+ if (value !== null && typeof value === 'object' && !value._isSignal) {
89
+ return createProxy(value, path);
90
+ }
91
+ return value;
92
+ },
93
+ set(target, prop, newValue) {
94
+ if (typeof prop === 'symbol') {
95
+ target[prop] = newValue;
96
+ return true;
97
+ }
98
+ const path = parentPath ? `${parentPath}.${String(prop)}` : String(prop);
99
+ const oldValue = target[prop];
100
+ if (oldValue && typeof oldValue === 'function' && oldValue._isSignal) {
101
+ oldValue(newValue);
102
+ }
103
+ else if (oldValue !== newValue) {
104
+ target[prop] = newValue;
105
+ notifySubscribers(getSubscribers(path));
106
+ // Bubble up
107
+ const parts = path.split('.');
108
+ for (let i = parts.length - 1; i >= 0; i--) {
109
+ const pp = parts.slice(0, i).join('.');
110
+ if (pp)
111
+ notifySubscribers(getSubscribers(pp));
112
+ }
113
+ }
114
+ return true;
115
+ }
116
+ });
117
+ }
118
+ return createProxy(initialObj);
119
+ }
120
+ // === zenEffect ===
121
+ export function zenEffect(fn, options = {}) {
122
+ let cleanup;
123
+ let timeout;
124
+ const effect = {
125
+ dependencies: new Set(),
126
+ run: () => {
127
+ if (options.debounce) {
128
+ if (timeout)
129
+ clearTimeout(timeout);
130
+ timeout = setTimeout(execute, options.debounce);
131
+ }
132
+ else {
133
+ execute();
134
+ }
135
+ }
136
+ };
137
+ function execute() {
138
+ cleanupEffect(effect);
139
+ pushContext(effect);
140
+ try {
141
+ if (cleanup)
142
+ cleanup();
143
+ cleanup = fn();
144
+ }
145
+ finally {
146
+ popContext();
147
+ }
148
+ }
149
+ if (!options.defer)
150
+ execute();
151
+ return () => {
152
+ cleanupEffect(effect);
153
+ if (cleanup)
154
+ cleanup();
155
+ };
156
+ }
157
+ // === zenMemo ===
158
+ export function zenMemo(fn) {
159
+ const signal = zenSignal(undefined);
160
+ zenEffect(() => { signal(fn()); });
161
+ const memo = () => signal();
162
+ memo._isSignal = true;
163
+ return memo;
164
+ }
165
+ // === zenRef ===
166
+ export function zenRef(initial) {
167
+ return { current: initial || null };
168
+ }
169
+ // === zenBatch ===
170
+ export function zenBatch(fn) {
171
+ batchDepth++;
172
+ try {
173
+ fn();
174
+ }
175
+ finally {
176
+ batchDepth--;
177
+ if (batchDepth === 0) {
178
+ const effects = Array.from(pendingEffects);
179
+ pendingEffects.clear();
180
+ effects.forEach(e => e.run());
181
+ }
182
+ }
183
+ }
184
+ export function zenUntrack(fn) {
185
+ pushContext(null);
186
+ try {
187
+ return fn();
188
+ }
189
+ finally {
190
+ popContext();
191
+ }
192
+ }
193
+ let activeInstance = null;
194
+ export function setActiveInstance(inst) { activeInstance = inst; }
195
+ export function zenOnMount(cb) {
196
+ if (activeInstance)
197
+ activeInstance.mountHooks.push(cb);
198
+ // Fallback: if no active instance (e.g. top level), run immediately?
199
+ // Better to strict scope it, but for safety in simple usages:
200
+ else if (typeof window !== 'undefined' && document.readyState === 'complete') {
201
+ // cb(); // Uncomment if lax behavior desired
202
+ }
203
+ }
204
+ export function zenOnUnmount(cb) {
205
+ // Placeholder: requires unmount hooks in instance
206
+ }
207
+ export function triggerMount(inst) {
208
+ if (inst && inst.mountHooks) {
209
+ inst.mountHooks.forEach(cb => {
210
+ const cleanup = cb();
211
+ // TODO: Store cleanup for unmount
212
+ });
213
+ }
214
+ }
215
+ // === Rendering & Hydration ===
216
+ const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
217
+ const SVG_TAGS = new Set([
218
+ 'svg', 'path', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'rect',
219
+ 'g', 'defs', 'use', 'symbol', 'clipPath', 'mask', 'pattern', 'marker',
220
+ 'linearGradient', 'radialGradient', 'stop', 'filter', 'feGaussianBlur',
221
+ 'feOffset', 'feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite',
222
+ 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feFlood',
223
+ 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feImage', 'feMerge', 'feMergeNode',
224
+ 'feMorphology', 'fePointLight', 'feSpotLight', 'feSpecularLighting', 'feTile',
225
+ 'feTurbulence', 'foreignObject', 'image', 'switch', 'text', 'tspan', 'textPath',
226
+ 'title', 'desc', 'metadata', 'a', 'view', 'animate', 'animateMotion',
227
+ 'animateTransform', 'set', 'mpath'
228
+ ]);
229
+ // Track current namespace context for nested elements
230
+ let currentNamespace = null;
231
+ export function h(tag, props, ...children) {
232
+ // Determine if this element should be in SVG namespace
233
+ const isSvgTag = SVG_TAGS.has(tag) || SVG_TAGS.has(tag.toLowerCase());
234
+ const useSvgNamespace = isSvgTag || currentNamespace === SVG_NAMESPACE;
235
+ // Create element with correct namespace
236
+ const el = useSvgNamespace
237
+ ? document.createElementNS(SVG_NAMESPACE, tag)
238
+ : document.createElement(tag);
239
+ // Track namespace context for children
240
+ const previousNamespace = currentNamespace;
241
+ if (tag === 'svg' || tag === 'SVG') {
242
+ currentNamespace = SVG_NAMESPACE;
243
+ }
244
+ if (props) {
245
+ for (const [key, val] of Object.entries(props)) {
246
+ if (key === 'ref') {
247
+ if (val && typeof val === 'object' && 'current' in val)
248
+ val.current = el;
249
+ else if (typeof val === 'string') {
250
+ const state = window.__ZENITH_STATE__;
251
+ if (state && state[val] && typeof state[val] === 'object' && 'current' in state[val])
252
+ state[val].current = el;
253
+ }
254
+ }
255
+ else if (key.startsWith('on') && typeof val === 'function') {
256
+ el.addEventListener(key.slice(2).toLowerCase(), (e) => {
257
+ // Check if val returns a function (expression wrapper) or is the handler
258
+ const res = val(e, el);
259
+ if (typeof res === 'function')
260
+ res(e, el);
261
+ });
262
+ }
263
+ else if (typeof val === 'function') {
264
+ zenEffect(() => { updateAttr(el, key, val()); });
265
+ }
266
+ else {
267
+ updateAttr(el, key, val);
268
+ }
269
+ }
270
+ }
271
+ const spread = (items) => items.reduce((acc, v) => acc.concat(Array.isArray(v) ? spread(v) : v), []);
272
+ spread(children).forEach(child => {
273
+ if (typeof child === 'function') {
274
+ // For reactive expressions, we need a placeholder that can be updated
275
+ // The placeholder is a comment node that marks where content should go
276
+ const placeholder = document.createComment('expr');
277
+ el.appendChild(placeholder);
278
+ let currentNodes = [];
279
+ zenEffect(() => {
280
+ const result = child();
281
+ // Remove old nodes
282
+ currentNodes.forEach(n => { if (n.parentNode)
283
+ n.parentNode.removeChild(n); });
284
+ currentNodes = [];
285
+ if (result == null) {
286
+ // null/undefined - render nothing
287
+ }
288
+ else if (result instanceof Node) {
289
+ // DOM node - insert it
290
+ placeholder.before(result);
291
+ currentNodes = [result];
292
+ }
293
+ else if (Array.isArray(result)) {
294
+ // Array of nodes/strings
295
+ result.forEach(item => {
296
+ const node = item instanceof Node ? item : document.createTextNode(String(item));
297
+ placeholder.before(node);
298
+ currentNodes.push(node);
299
+ });
300
+ }
301
+ else {
302
+ // Primitive (string, number) - create text node
303
+ const textNode = document.createTextNode(String(result));
304
+ placeholder.before(textNode);
305
+ currentNodes = [textNode];
306
+ }
307
+ });
308
+ }
309
+ else {
310
+ el.appendChild(child instanceof Node ? child : document.createTextNode(String(child)));
311
+ }
312
+ });
313
+ // Restore previous namespace context
314
+ currentNamespace = previousNamespace;
315
+ return el;
316
+ }
317
+ function updateAttr(el, key, val) {
318
+ if (key === 'class' || key === 'className') {
319
+ // SVG uses className.baseVal, HTML uses className directly
320
+ if ('className' in el && typeof el.className === 'object') {
321
+ el.className.baseVal = String(val || '');
322
+ }
323
+ else {
324
+ el.className = String(val || '');
325
+ }
326
+ }
327
+ else if (key === 'style' && typeof val === 'object')
328
+ Object.assign(el.style, val);
329
+ else if (val == null || val === false)
330
+ el.removeAttribute(key);
331
+ else
332
+ el.setAttribute(key, String(val));
333
+ }
334
+ export function fragment(children) {
335
+ const frag = document.createDocumentFragment();
336
+ const items = typeof children === 'function' ? children() : children;
337
+ const spread = (its) => its.reduce((acc, v) => acc.concat(Array.isArray(v) ? spread(v) : v), []);
338
+ spread(Array.isArray(items) ? items : [items]).forEach(item => {
339
+ frag.appendChild(item instanceof Node ? item : document.createTextNode(String(item)));
340
+ });
341
+ return frag;
342
+ }
343
+ export function zenLoop(sourceFn, itemFn) {
344
+ const start = document.createComment('loop:start');
345
+ const end = document.createComment('loop:end');
346
+ const frag = document.createDocumentFragment();
347
+ frag.append(start, end);
348
+ zenEffect(() => {
349
+ const items = sourceFn() || [];
350
+ let curr = start.nextSibling;
351
+ while (curr && curr !== end) {
352
+ const next = curr.nextSibling;
353
+ curr.remove();
354
+ curr = next;
355
+ }
356
+ items.forEach((item, i) => end.before(itemFn(item, i)));
357
+ });
358
+ return frag;
359
+ }
360
+ export function zenithHydrate(state, container = document) {
361
+ const ir = window.canonicalIR;
362
+ if (!ir)
363
+ return;
364
+ window.__ZENITH_STATE__ = state;
365
+ const nodes = ir(state);
366
+ const mount = container === document ? document.body : container;
367
+ mount.innerHTML = '';
368
+ const arr = Array.isArray(nodes) ? nodes : [nodes];
369
+ arr.forEach(n => {
370
+ if (n == null || n === false)
371
+ return;
372
+ // If it's a full <html> node, we might need to be more careful,
373
+ // but for now let's just avoid stringifying nulls.
374
+ mount.appendChild(n instanceof Node ? n : document.createTextNode(String(n)));
375
+ });
376
+ }
377
+ // === Global Setup ===
378
+ export function setup() {
379
+ if (typeof window === 'undefined')
380
+ return;
381
+ const w = window;
382
+ w.__zenith = { h, fragment, loop: zenLoop, state: zenState, signal: zenSignal, effect: zenEffect, memo: zenMemo, ref: zenRef, batch: zenBatch, onMount: zenOnMount, setActiveInstance, triggerMount, spread_children: (a) => a };
383
+ w.zenithHydrate = zenithHydrate;
384
+ // Expose globals for imported usage
385
+ w.zenSignal = zenSignal;
386
+ w.zenState = zenState;
387
+ w.zenEffect = zenEffect;
388
+ w.zenMemo = zenMemo;
389
+ w.zenRef = zenRef;
390
+ w.zenBatch = zenBatch;
391
+ w.zenUntrack = zenUntrack;
392
+ w.zenOnMount = zenOnMount;
393
+ // [ZENITH-NATIVE] zenOrder: Scheduling primitive
394
+ w.zenOrder = (fn) => { if (typeof fn === 'function')
395
+ fn(); };
396
+ }
397
+ setup();
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Explicit Data Exposure Analysis
3
+ *
4
+ * Phase 6: Analyzes expressions to detect data dependencies and ensure
5
+ * all data references are explicit (loader, props, stores) rather than implicit globals
6
+ */
7
+ import type { ExpressionIR } from '../ir/types';
8
+ /**
9
+ * Data dependency information for an expression
10
+ */
11
+ export interface ExpressionDataDependencies {
12
+ expressionId: string;
13
+ usesLoaderData: boolean;
14
+ usesProps: boolean;
15
+ usesStores: boolean;
16
+ usesState: boolean;
17
+ loaderProperties: string[];
18
+ propNames: string[];
19
+ storeNames: string[];
20
+ stateProperties: string[];
21
+ }
22
+ /**
23
+ * Analyze an expression to detect its data dependencies
24
+ *
25
+ * This is a simple heuristic-based analyzer that looks for patterns like:
26
+ * - user.name, user.email → loader data
27
+ * - props.title, props.showWelcome → props
28
+ * - stores.cart, stores.notifications → stores
29
+ * - count, isLoading → state (top-level properties)
30
+ */
31
+ export declare function analyzeExpressionDependencies(expr: ExpressionIR, declaredLoaderProps?: string[], declaredProps?: string[], declaredStores?: string[]): ExpressionDataDependencies;
32
+ /**
33
+ * Validate that all referenced data exists
34
+ */
35
+ export declare function validateDataDependencies(dependencies: ExpressionDataDependencies, filePath: string, declaredLoaderProps?: string[], declaredProps?: string[], declaredStores?: string[]): void;
36
+ /**
37
+ * Transform expression code to use explicit data arguments
38
+ *
39
+ * Converts patterns like:
40
+ * - user.name → loaderData.user.name
41
+ * - title → props.title (if declared as prop)
42
+ * - cart.items → stores.cart.items
43
+ */
44
+ export declare function transformExpressionCode(code: string, dependencies: ExpressionDataDependencies, declaredProps?: string[]): string;
45
+ /**
46
+ * Generate expression wrapper with explicit data arguments
47
+ */
48
+ export declare function generateExplicitExpressionWrapper(expr: ExpressionIR, dependencies: ExpressionDataDependencies): string;
49
+ /**
50
+ * Analyze all expressions in a template
51
+ */
52
+ export declare function analyzeAllExpressions(expressions: ExpressionIR[], filePath: string, declaredLoaderProps?: string[], declaredProps?: string[], declaredStores?: string[]): ExpressionDataDependencies[];