@zenithbuild/core 0.4.5 → 0.4.7
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.
- package/cli/commands/dev.ts +6 -5
- package/compiler/discovery/componentDiscovery.ts +4 -0
- package/compiler/discovery/layouts.ts +11 -2
- package/compiler/index.ts +1 -0
- package/compiler/ir/types.ts +12 -0
- package/compiler/parse/parseTemplate.ts +10 -2
- package/compiler/parse/scriptAnalysis.ts +8 -0
- package/compiler/runtime/transformIR.ts +22 -2
- package/compiler/transform/componentResolver.ts +36 -13
- package/compiler/transform/componentScriptTransformer.ts +147 -0
- package/dist/cli.js +8 -0
- package/dist/zen-build.js +7633 -3939
- package/dist/zen-dev.js +7633 -3939
- package/dist/zen-preview.js +7633 -3939
- package/dist/zenith.js +7633 -3939
- package/package.json +1 -1
- package/runtime/bundle-generator.ts +144 -1
package/package.json
CHANGED
|
@@ -282,6 +282,144 @@ export function generateBundleJS(): string {
|
|
|
282
282
|
unmountCallbacks.length = 0;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
// ============================================
|
|
286
|
+
// Component Instance System
|
|
287
|
+
// ============================================
|
|
288
|
+
// Each component instance gets isolated state, effects, and lifecycles
|
|
289
|
+
// Instances are tied to DOM elements via hydration markers
|
|
290
|
+
|
|
291
|
+
const componentRegistry = {};
|
|
292
|
+
|
|
293
|
+
function createComponentInstance(componentName, rootElement) {
|
|
294
|
+
const instanceMountCallbacks = [];
|
|
295
|
+
const instanceUnmountCallbacks = [];
|
|
296
|
+
const instanceEffects = [];
|
|
297
|
+
let instanceMounted = false;
|
|
298
|
+
|
|
299
|
+
return {
|
|
300
|
+
// DOM reference
|
|
301
|
+
root: rootElement,
|
|
302
|
+
|
|
303
|
+
// Lifecycle hooks (instance-scoped)
|
|
304
|
+
onMount: function(fn) {
|
|
305
|
+
if (instanceMounted) {
|
|
306
|
+
const cleanup = fn();
|
|
307
|
+
if (typeof cleanup === 'function') {
|
|
308
|
+
instanceUnmountCallbacks.push(cleanup);
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
instanceMountCallbacks.push(fn);
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
onUnmount: function(fn) {
|
|
315
|
+
instanceUnmountCallbacks.push(fn);
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
// Reactivity (uses global primitives but tracks for cleanup)
|
|
319
|
+
signal: function(initial) {
|
|
320
|
+
return zenSignal(initial);
|
|
321
|
+
},
|
|
322
|
+
state: function(initial) {
|
|
323
|
+
return zenState(initial);
|
|
324
|
+
},
|
|
325
|
+
ref: function(initial) {
|
|
326
|
+
return zenRef(initial);
|
|
327
|
+
},
|
|
328
|
+
effect: function(fn) {
|
|
329
|
+
const cleanup = zenEffect(fn);
|
|
330
|
+
instanceEffects.push(cleanup);
|
|
331
|
+
return cleanup;
|
|
332
|
+
},
|
|
333
|
+
memo: function(fn) {
|
|
334
|
+
return zenMemo(fn);
|
|
335
|
+
},
|
|
336
|
+
batch: function(fn) {
|
|
337
|
+
zenBatch(fn);
|
|
338
|
+
},
|
|
339
|
+
untrack: function(fn) {
|
|
340
|
+
return zenUntrack(fn);
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
// Lifecycle execution
|
|
344
|
+
mount: function() {
|
|
345
|
+
instanceMounted = true;
|
|
346
|
+
for (let i = 0; i < instanceMountCallbacks.length; i++) {
|
|
347
|
+
try {
|
|
348
|
+
const cleanup = instanceMountCallbacks[i]();
|
|
349
|
+
if (typeof cleanup === 'function') {
|
|
350
|
+
instanceUnmountCallbacks.push(cleanup);
|
|
351
|
+
}
|
|
352
|
+
} catch(e) {
|
|
353
|
+
console.error('[Zenith] Component mount error:', componentName, e);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
instanceMountCallbacks.length = 0;
|
|
357
|
+
},
|
|
358
|
+
unmount: function() {
|
|
359
|
+
instanceMounted = false;
|
|
360
|
+
// Cleanup effects
|
|
361
|
+
for (let i = 0; i < instanceEffects.length; i++) {
|
|
362
|
+
try {
|
|
363
|
+
if (typeof instanceEffects[i] === 'function') instanceEffects[i]();
|
|
364
|
+
} catch(e) {
|
|
365
|
+
console.error('[Zenith] Effect cleanup error:', e);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
instanceEffects.length = 0;
|
|
369
|
+
// Run unmount callbacks
|
|
370
|
+
for (let i = 0; i < instanceUnmountCallbacks.length; i++) {
|
|
371
|
+
try { instanceUnmountCallbacks[i](); } catch(e) { console.error('[Zenith] Unmount error:', e); }
|
|
372
|
+
}
|
|
373
|
+
instanceUnmountCallbacks.length = 0;
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function defineComponent(name, factory) {
|
|
379
|
+
componentRegistry[name] = factory;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function instantiateComponent(name, props, rootElement) {
|
|
383
|
+
const factory = componentRegistry[name];
|
|
384
|
+
if (!factory) {
|
|
385
|
+
console.warn('[Zenith] Component not found:', name);
|
|
386
|
+
return null;
|
|
387
|
+
}
|
|
388
|
+
return factory(props, rootElement);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Hydrate components by discovering data-zen-component markers
|
|
393
|
+
* This is the ONLY place component instantiation should happen
|
|
394
|
+
*/
|
|
395
|
+
function hydrateComponents(container) {
|
|
396
|
+
const componentElements = container.querySelectorAll('[data-zen-component]');
|
|
397
|
+
|
|
398
|
+
for (let i = 0; i < componentElements.length; i++) {
|
|
399
|
+
const el = componentElements[i];
|
|
400
|
+
const componentName = el.getAttribute('data-zen-component');
|
|
401
|
+
|
|
402
|
+
// Skip if already hydrated
|
|
403
|
+
if (el.__zenith_instance) continue;
|
|
404
|
+
|
|
405
|
+
// Parse props from data attribute if present
|
|
406
|
+
const propsJson = el.getAttribute('data-zen-props') || '{}';
|
|
407
|
+
let props = {};
|
|
408
|
+
try {
|
|
409
|
+
props = JSON.parse(propsJson);
|
|
410
|
+
} catch(e) {
|
|
411
|
+
console.warn('[Zenith] Invalid props JSON for', componentName);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Instantiate component and bind to DOM element
|
|
415
|
+
const instance = instantiateComponent(componentName, props, el);
|
|
416
|
+
|
|
417
|
+
if (instance) {
|
|
418
|
+
el.__zenith_instance = instance;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
285
423
|
// ============================================
|
|
286
424
|
// Expression Registry & Hydration
|
|
287
425
|
// ============================================
|
|
@@ -701,8 +839,13 @@ export function generateBundleJS(): string {
|
|
|
701
839
|
triggerUnmount: triggerUnmount,
|
|
702
840
|
// Hydration
|
|
703
841
|
hydrate: zenithHydrate,
|
|
842
|
+
hydrateComponents: hydrateComponents, // Marker-driven component instantiation
|
|
704
843
|
registerExpression: registerExpression,
|
|
705
|
-
getExpression: getExpression
|
|
844
|
+
getExpression: getExpression,
|
|
845
|
+
// Component instance system
|
|
846
|
+
createInstance: createComponentInstance,
|
|
847
|
+
defineComponent: defineComponent,
|
|
848
|
+
instantiate: instantiateComponent
|
|
706
849
|
};
|
|
707
850
|
|
|
708
851
|
// Expose with zen* prefix for direct usage
|