@hypen-space/web 0.3.12 → 0.4.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.
package/dist/index.js CHANGED
@@ -3510,315 +3510,9 @@ class DOMRenderer {
3510
3510
  }
3511
3511
  }
3512
3512
 
3513
- // src/hypen.ts
3514
- import {
3515
- BrowserEngine as Engine,
3516
- HypenModuleInstance,
3517
- HypenRouter,
3518
- HypenGlobalContext,
3519
- componentLoader,
3520
- Router,
3521
- Route,
3522
- Link,
3523
- frameworkLoggers as frameworkLoggers6,
3524
- setDebugMode
3525
- } from "@hypen-space/core";
3526
- var log6 = frameworkLoggers6.hypen;
3527
-
3528
- class Hypen {
3529
- engine = null;
3530
- renderer = null;
3531
- moduleInstance = null;
3532
- container = null;
3533
- config;
3534
- router;
3535
- globalContext;
3536
- moduleInstances = new Map;
3537
- constructor(config = {}) {
3538
- this.config = {
3539
- componentsDir: "./src/components",
3540
- debug: false,
3541
- ...config
3542
- };
3543
- if (this.config.debug) {
3544
- setDebugMode(true);
3545
- }
3546
- this.router = new HypenRouter;
3547
- this.globalContext = new HypenGlobalContext;
3548
- componentLoader.register("Router", Router, "");
3549
- componentLoader.register("Route", Route, "");
3550
- componentLoader.register("Link", Link, "");
3551
- this.globalContext.__router = this.router;
3552
- this.globalContext.__hypenEngine = this;
3553
- }
3554
- async init() {
3555
- log6.debug("Initializing...");
3556
- this.engine = new Engine;
3557
- await this.engine.init({
3558
- wasmUrl: this.config.wasmUrl,
3559
- jsUrl: this.config.jsUrl
3560
- });
3561
- log6.debug("Engine initialized");
3562
- }
3563
- async loadComponents(componentsDir) {
3564
- const dir = componentsDir || this.config.componentsDir;
3565
- log6.debug(`Loading components from ${dir}...`);
3566
- await componentLoader.loadFromComponentsDir(dir);
3567
- log6.debug(`Loaded ${componentLoader.getNames().length} components`);
3568
- }
3569
- async render(componentName, containerSelector) {
3570
- if (!this.engine) {
3571
- throw new Error("[Hypen] Engine not initialized. Call init() first.");
3572
- }
3573
- if (typeof containerSelector === "string") {
3574
- const element = document.querySelector(containerSelector);
3575
- if (!element) {
3576
- throw new Error(`[Hypen] Container not found: ${containerSelector}`);
3577
- }
3578
- this.container = element;
3579
- } else {
3580
- this.container = containerSelector;
3581
- }
3582
- const component = componentLoader.get(componentName);
3583
- if (!component) {
3584
- throw new Error(`[Hypen] Component "${componentName}" not found. Available: ${componentLoader.getNames().join(", ")}`);
3585
- }
3586
- log6.debug(`Rendering ${componentName} to`, this.container);
3587
- this.renderer = new DOMRenderer(this.container, this.engine, {
3588
- enabled: this.config.debugHeatmap || false,
3589
- showHeatmap: this.config.debugHeatmap || false,
3590
- heatmapIncrement: this.config.heatmapIncrement || 5,
3591
- fadeOutDuration: this.config.heatmapFadeOut || 2000,
3592
- maxOpacity: 0.8
3593
- });
3594
- this.engine.setRenderCallback((patches) => {
3595
- log6.debug(`Applying ${patches.length} patches`);
3596
- this.renderer.applyPatches(patches);
3597
- });
3598
- const routerContext = {
3599
- root: this.router,
3600
- current: this.router
3601
- };
3602
- this.renderer.setContext(routerContext, this.globalContext);
3603
- const moduleId = this.extractModuleId(componentName, component.template);
3604
- this.moduleInstance = new HypenModuleInstance(this.engine, component.module, routerContext, this.globalContext);
3605
- this.globalContext.registerModule(moduleId, this.moduleInstance);
3606
- this.moduleInstances.set(moduleId, this.moduleInstance);
3607
- this.moduleInstance.onStateChange(() => {
3608
- const mergedState = this.getMergedState();
3609
- log6.debug(`State changed, merged state:`, mergedState);
3610
- this.renderer.updateState(mergedState);
3611
- });
3612
- this.setupComponentResolver();
3613
- this.createNestedModuleInstances();
3614
- this.engine.renderSource(component.template);
3615
- this.renderer.updateState(this.getMergedState());
3616
- log6.debug(`${componentName} rendered successfully`);
3617
- }
3618
- async unmount() {
3619
- log6.debug("Unmounting...");
3620
- if (this.moduleInstance) {
3621
- await this.moduleInstance.destroy();
3622
- this.moduleInstance = null;
3623
- }
3624
- if (this.container) {
3625
- this.container.innerHTML = "";
3626
- this.container = null;
3627
- }
3628
- this.renderer = null;
3629
- log6.debug("Unmounted");
3630
- }
3631
- getModuleInstance() {
3632
- return this.moduleInstance;
3633
- }
3634
- getState() {
3635
- return this.moduleInstance?.getState() ?? null;
3636
- }
3637
- getRouter() {
3638
- return this.router;
3639
- }
3640
- getGlobalContext() {
3641
- return this.globalContext;
3642
- }
3643
- setDebugHeatmap(enabled) {
3644
- if (this.renderer) {
3645
- this.renderer.setDebugConfig({ enabled, showHeatmap: enabled });
3646
- log6.debug(`Debug heatmap ${enabled ? "enabled" : "disabled"}`);
3647
- }
3648
- }
3649
- resetDebugTracking() {
3650
- if (this.renderer) {
3651
- this.renderer.resetDebugTracking();
3652
- log6.debug("Debug tracking reset");
3653
- }
3654
- }
3655
- getDebugStats() {
3656
- return this.renderer?.getDebugStats() || null;
3657
- }
3658
- async renderLazyRoute(routePath, componentName, routeElement) {
3659
- if (!this.engine || !this.renderer) {
3660
- throw new Error("Engine not initialized");
3661
- }
3662
- const component = componentLoader.get(componentName);
3663
- if (!component) {
3664
- throw new Error(`Component ${componentName} not found`);
3665
- }
3666
- const template = component.template;
3667
- if (!template) {
3668
- throw new Error(`Component ${componentName} has no template`);
3669
- }
3670
- if (component.module && !this.moduleInstances.has(componentName)) {
3671
- const moduleId = this.extractModuleId(componentName, template);
3672
- const routerContext = {
3673
- root: this.router,
3674
- current: this.router
3675
- };
3676
- const moduleInstance = new HypenModuleInstance(this.engine, component.module, routerContext, this.globalContext);
3677
- this.globalContext.registerModule(moduleId, moduleInstance);
3678
- this.moduleInstances.set(componentName, moduleInstance);
3679
- moduleInstance.onStateChange(() => {
3680
- const mergedState2 = this.getMergedState();
3681
- log6.debug(`Lazy component ${componentName} state changed:`, mergedState2);
3682
- this.renderer.updateState(mergedState2);
3683
- });
3684
- }
3685
- await new Promise((resolve) => setTimeout(resolve, 50));
3686
- const routeNodeId = routeElement.dataset.hypenId;
3687
- if (!routeNodeId) {
3688
- throw new Error(`Route element is missing data-hypen-id attribute`);
3689
- }
3690
- const mergedState = this.getMergedState();
3691
- this.engine.renderInto(template, routeNodeId, mergedState);
3692
- this.renderer.updateState(mergedState);
3693
- }
3694
- extractModuleId(componentName, template) {
3695
- const idMatch = template.match(/\.id\(["']([^"']+)["']\)/);
3696
- const matchedId = idMatch?.[1];
3697
- if (matchedId) {
3698
- return matchedId;
3699
- }
3700
- return componentName;
3701
- }
3702
- createNestedModuleInstances() {
3703
- const routerContext = {
3704
- root: this.router,
3705
- current: this.router
3706
- };
3707
- if (Router && !this.moduleInstances.has("Router")) {
3708
- const routerInstance = new HypenModuleInstance(this.engine, Router, routerContext, this.globalContext);
3709
- this.globalContext.registerModule("Router", routerInstance);
3710
- this.moduleInstances.set("Router", routerInstance);
3711
- routerInstance.onStateChange(() => {
3712
- const mergedState = this.getMergedState();
3713
- log6.debug("Router state changed:", mergedState);
3714
- this.renderer.updateState(mergedState);
3715
- });
3716
- }
3717
- const componentNames = componentLoader.getNames();
3718
- for (const name of componentNames) {
3719
- if (this.moduleInstances.has(name)) {
3720
- continue;
3721
- }
3722
- const comp = componentLoader.get(name);
3723
- if (!comp || !comp.module) {
3724
- continue;
3725
- }
3726
- log6.debug(`Creating nested module instance for: ${name}`);
3727
- const moduleInstance = new HypenModuleInstance(this.engine, comp.module, routerContext, this.globalContext);
3728
- this.globalContext.registerModule(name, moduleInstance);
3729
- this.moduleInstances.set(name, moduleInstance);
3730
- moduleInstance.onStateChange(() => {
3731
- const mergedState = this.getMergedState();
3732
- log6.debug(`Nested component ${name} state changed:`, mergedState);
3733
- this.renderer.updateState(mergedState);
3734
- });
3735
- }
3736
- }
3737
- getMergedState() {
3738
- const merged = {};
3739
- if (this.moduleInstance) {
3740
- const mainState = this.moduleInstance.getState();
3741
- Object.assign(merged, mainState);
3742
- }
3743
- for (const [name, instance] of this.moduleInstances.entries()) {
3744
- const nestedState = instance.getState();
3745
- Object.assign(merged, nestedState);
3746
- }
3747
- return merged;
3748
- }
3749
- setupComponentResolver() {
3750
- if (!this.engine)
3751
- return;
3752
- const builtInElements = new Set([
3753
- "Column",
3754
- "Row",
3755
- "Text",
3756
- "Button",
3757
- "Image",
3758
- "Input",
3759
- "Container",
3760
- "Box",
3761
- "Center",
3762
- "List",
3763
- "Canvas",
3764
- "Spacer",
3765
- "Divider",
3766
- "ScrollView"
3767
- ]);
3768
- this.engine.setComponentResolver((componentName, contextPath) => {
3769
- if (builtInElements.has(componentName)) {
3770
- return null;
3771
- }
3772
- log6.debug(`Resolving component: ${componentName} (context: ${contextPath})`);
3773
- const componentDef = componentLoader.get(componentName);
3774
- if (!componentDef) {
3775
- log6.debug(`Component not found: ${componentName}`);
3776
- return null;
3777
- }
3778
- const isPassthrough = componentName === "Router";
3779
- const isLazy = componentName === "Route";
3780
- const resolved = {
3781
- source: componentDef.template,
3782
- path: componentDef.path || componentName,
3783
- passthrough: isPassthrough,
3784
- lazy: isLazy
3785
- };
3786
- const flags = [];
3787
- if (isPassthrough)
3788
- flags.push("passthrough");
3789
- if (isLazy)
3790
- flags.push("lazy");
3791
- const flagStr = flags.length > 0 ? ` (${flags.join(", ")})` : "";
3792
- log6.debug(`Resolved ${componentName} -> ${resolved.path}${flagStr}`);
3793
- return resolved;
3794
- });
3795
- }
3796
- }
3797
- async function render(componentName, containerSelector, config) {
3798
- const hypen = new Hypen(config);
3799
- await hypen.init();
3800
- await hypen.loadComponents();
3801
- await hypen.render(componentName, containerSelector);
3802
- return hypen;
3803
- }
3804
- async function renderWithComponents(components, componentName, containerSelector, config) {
3805
- const hypen = new Hypen(config);
3806
- await hypen.init();
3807
- for (const [name, { module, template }] of Object.entries(components)) {
3808
- let processedTemplate = template;
3809
- const moduleMatch = template.match(/^\s*module\s+\w+\s*\{([\s\S]*)\}\s*$/);
3810
- if (moduleMatch && moduleMatch[1]) {
3811
- processedTemplate = moduleMatch[1].trim();
3812
- }
3813
- componentLoader.register(name, module, processedTemplate);
3814
- }
3815
- await hypen.render(componentName, containerSelector);
3816
- return hypen;
3817
- }
3818
-
3819
3513
  // src/dom/events.ts
3820
- import { frameworkLoggers as frameworkLoggers7 } from "@hypen-space/core";
3821
- var log7 = frameworkLoggers7.events;
3514
+ import { frameworkLoggers as frameworkLoggers6 } from "@hypen-space/core";
3515
+ var log6 = frameworkLoggers6.events;
3822
3516
 
3823
3517
  class EventManager {
3824
3518
  engine;
@@ -3828,22 +3522,22 @@ class EventManager {
3828
3522
  }
3829
3523
  attach(elementId, element, eventName, actionName) {
3830
3524
  const domEventName = eventName === "onClick" ? "click" : eventName;
3831
- log7.debug(`Attaching ${eventName} (DOM: ${domEventName}) to element ${elementId}, action: ${actionName}`);
3525
+ log6.debug(`Attaching ${eventName} (DOM: ${domEventName}) to element ${elementId}, action: ${actionName}`);
3832
3526
  const listener = (event) => {
3833
- log7.debug(`Event fired: ${eventName} on ${elementId}, dispatching action: ${actionName}`);
3834
- log7.debug(`Event object:`, event);
3835
- log7.debug(`Element:`, element);
3527
+ log6.debug(`Event fired: ${eventName} on ${elementId}, dispatching action: ${actionName}`);
3528
+ log6.debug(`Event object:`, event);
3529
+ log6.debug(`Element:`, element);
3836
3530
  if (eventName === "submit" || eventName === "click" && element.tagName === "A") {
3837
3531
  event.preventDefault();
3838
3532
  }
3839
3533
  const payload = this.extractEventData(event, element);
3840
- log7.debug(`Event payload:`, payload);
3841
- log7.debug(`Calling engine.dispatchAction(${actionName})`);
3534
+ log6.debug(`Event payload:`, payload);
3535
+ log6.debug(`Calling engine.dispatchAction(${actionName})`);
3842
3536
  try {
3843
3537
  this.engine.dispatchAction(actionName, payload);
3844
- log7.debug(`dispatchAction succeeded`);
3538
+ log6.debug(`dispatchAction succeeded`);
3845
3539
  } catch (error) {
3846
- log7.error(`dispatchAction failed:`, error);
3540
+ log6.error(`dispatchAction failed:`, error);
3847
3541
  }
3848
3542
  };
3849
3543
  let elementBindings = this.bindings.get(elementId);
@@ -3853,8 +3547,8 @@ class EventManager {
3853
3547
  }
3854
3548
  elementBindings.set(eventName, listener);
3855
3549
  element.addEventListener(domEventName, listener);
3856
- log7.debug(`Listener attached to DOM for ${domEventName}`);
3857
- log7.debug(`Element details:`, {
3550
+ log6.debug(`Listener attached to DOM for ${domEventName}`);
3551
+ log6.debug(`Element details:`, {
3858
3552
  tagName: element.tagName,
3859
3553
  id: element.id,
3860
3554
  dataset: element.dataset,
@@ -3862,7 +3556,7 @@ class EventManager {
3862
3556
  });
3863
3557
  if (domEventName === "click") {
3864
3558
  element.addEventListener("click", (e) => {
3865
- log7.debug(`Raw DOM click detected on ${element.tagName}`, e);
3559
+ log6.debug(`Raw DOM click detected on ${element.tagName}`, e);
3866
3560
  });
3867
3561
  }
3868
3562
  }
@@ -4047,8 +3741,8 @@ function getAbsoluteBounds(node) {
4047
3741
  }
4048
3742
 
4049
3743
  // src/canvas/text.ts
4050
- import { frameworkLoggers as frameworkLoggers8 } from "@hypen-space/core";
4051
- var log8 = frameworkLoggers8.canvas;
3744
+ import { frameworkLoggers as frameworkLoggers7 } from "@hypen-space/core";
3745
+ var log7 = frameworkLoggers7.canvas;
4052
3746
  var textMetricsCache = new Map;
4053
3747
  function getCacheKey(text, fontStyle, maxWidth) {
4054
3748
  return `${text}|${fontStyle.fontSize}|${fontStyle.fontWeight}|${fontStyle.fontFamily}|${maxWidth || "auto"}`;
@@ -4148,7 +3842,7 @@ async function loadFont(fontFamily, fontWeight = "normal") {
4148
3842
  try {
4149
3843
  await document.fonts.load(font);
4150
3844
  } catch (error) {
4151
- log8.warn(`Failed to load font: ${font}`, error);
3845
+ log7.warn(`Failed to load font: ${font}`, error);
4152
3846
  }
4153
3847
  }
4154
3848
 
@@ -5763,8 +5457,8 @@ class AccessibilityLayer {
5763
5457
  }
5764
5458
 
5765
5459
  // src/canvas/renderer.ts
5766
- import { frameworkLoggers as frameworkLoggers9 } from "@hypen-space/core";
5767
- var log9 = frameworkLoggers9.canvas;
5460
+ import { frameworkLoggers as frameworkLoggers8 } from "@hypen-space/core";
5461
+ var log8 = frameworkLoggers8.canvas;
5768
5462
  var DEFAULT_OPTIONS = {
5769
5463
  devicePixelRatio: typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1,
5770
5464
  backgroundColor: "#ffffff",
@@ -5972,7 +5666,7 @@ class CanvasRenderer {
5972
5666
  const elapsed = performance.now() - startTime;
5973
5667
  this.frameCount++;
5974
5668
  if (performance.now() - this.lastFrameTime > 1000) {
5975
- log9.debug(`Canvas FPS: ${this.frameCount}, Last frame: ${elapsed.toFixed(2)}ms`);
5669
+ log8.debug(`Canvas FPS: ${this.frameCount}, Last frame: ${elapsed.toFixed(2)}ms`);
5976
5670
  this.frameCount = 0;
5977
5671
  this.lastFrameTime = performance.now();
5978
5672
  }
@@ -6017,15 +5711,12 @@ class CanvasRenderer {
6017
5711
  // src/index.ts
6018
5712
  init_hypenapp();
6019
5713
  export {
6020
- renderWithComponents,
6021
- render,
6022
5714
  hypenAppHandler,
6023
5715
  disconnectHypenApp,
6024
5716
  defaultDebugConfig,
6025
5717
  canvasHandler,
6026
5718
  canvasApplicators,
6027
5719
  RerenderTracker,
6028
- Hypen,
6029
5720
  EventManager,
6030
5721
  DOMRenderer,
6031
5722
  ComponentRegistry,
@@ -6033,4 +5724,4 @@ export {
6033
5724
  ApplicatorRegistry
6034
5725
  };
6035
5726
 
6036
- //# debugId=4FAEC1A16542965464756E2164756E21
5727
+ //# debugId=12C217F7874690EA64756E2164756E21