@hypen-space/web 0.4.2 → 0.4.5

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 (114) hide show
  1. package/dist/canvas/accessibility.d.ts +47 -0
  2. package/dist/canvas/events.d.ts +87 -0
  3. package/dist/canvas/index.d.ts +11 -0
  4. package/dist/canvas/index.js +32 -14
  5. package/dist/canvas/index.js.map +7 -7
  6. package/dist/canvas/input.d.ts +63 -0
  7. package/dist/canvas/input.js +14 -2
  8. package/dist/canvas/input.js.map +3 -3
  9. package/dist/canvas/layout.d.ts +10 -0
  10. package/dist/canvas/layout.js +17 -12
  11. package/dist/canvas/layout.js.map +4 -4
  12. package/dist/canvas/paint.d.ts +14 -0
  13. package/dist/canvas/paint.js +3 -2
  14. package/dist/canvas/paint.js.map +4 -4
  15. package/dist/canvas/renderer.d.ts +99 -0
  16. package/dist/canvas/renderer.js +32 -14
  17. package/dist/canvas/renderer.js.map +7 -7
  18. package/dist/canvas/text.d.ts +22 -0
  19. package/dist/canvas/text.js +2 -2
  20. package/dist/canvas/text.js.map +2 -2
  21. package/dist/canvas/types.d.ts +96 -0
  22. package/dist/canvas/utils.d.ts +44 -0
  23. package/dist/client.d.ts +19 -0
  24. package/dist/client.js +106 -43
  25. package/dist/client.js.map +12 -11
  26. package/dist/dom/applicators/advanced-layout.d.ts +5 -0
  27. package/dist/dom/applicators/advanced-layout.js +1 -114
  28. package/dist/dom/applicators/advanced-layout.js.map +4 -5
  29. package/dist/dom/applicators/background.d.ts +5 -0
  30. package/dist/dom/applicators/border.d.ts +5 -0
  31. package/dist/dom/applicators/color.d.ts +5 -0
  32. package/dist/dom/applicators/display.d.ts +5 -0
  33. package/dist/dom/applicators/effects.d.ts +5 -0
  34. package/dist/dom/applicators/events.d.ts +8 -0
  35. package/dist/dom/applicators/events.js +55 -3
  36. package/dist/dom/applicators/events.js.map +3 -3
  37. package/dist/dom/applicators/font.d.ts +29 -0
  38. package/dist/dom/applicators/index.d.ts +76 -0
  39. package/dist/dom/applicators/index.js +55 -9
  40. package/dist/dom/applicators/index.js.map +4 -4
  41. package/dist/dom/applicators/layout.d.ts +10 -0
  42. package/dist/dom/applicators/margin.d.ts +11 -0
  43. package/dist/dom/applicators/padding.d.ts +11 -0
  44. package/dist/dom/applicators/size.d.ts +14 -0
  45. package/dist/dom/applicators/transform.d.ts +5 -0
  46. package/dist/dom/applicators/transition.d.ts +5 -0
  47. package/dist/dom/applicators/types.d.ts +6 -0
  48. package/dist/dom/applicators/typography.d.ts +5 -0
  49. package/dist/dom/canvas/index.d.ts +12 -0
  50. package/dist/dom/components/app.d.ts +8 -0
  51. package/dist/dom/components/app.js +55 -0
  52. package/dist/dom/components/app.js.map +10 -0
  53. package/dist/dom/components/audio.d.ts +5 -0
  54. package/dist/dom/components/avatar.d.ts +5 -0
  55. package/dist/dom/components/badge.d.ts +5 -0
  56. package/dist/dom/components/button.d.ts +9 -0
  57. package/dist/dom/components/card.d.ts +5 -0
  58. package/dist/dom/components/center.d.ts +9 -0
  59. package/dist/dom/components/checkbox.d.ts +5 -0
  60. package/dist/dom/components/column.d.ts +8 -0
  61. package/dist/dom/components/container.d.ts +5 -0
  62. package/dist/dom/components/divider.d.ts +5 -0
  63. package/dist/dom/components/grid.d.ts +7 -0
  64. package/dist/dom/components/heading.d.ts +5 -0
  65. package/dist/dom/components/hypenapp.d.ts +19 -0
  66. package/dist/dom/components/hypenapp.js +2 -4
  67. package/dist/dom/components/hypenapp.js.map +3 -3
  68. package/dist/dom/components/image.d.ts +5 -0
  69. package/dist/dom/components/index.d.ts +29 -0
  70. package/dist/dom/components/index.js +29 -5
  71. package/dist/dom/components/index.js.map +7 -6
  72. package/dist/dom/components/input.d.ts +5 -0
  73. package/dist/dom/components/link.d.ts +5 -0
  74. package/dist/dom/components/list.d.ts +5 -0
  75. package/dist/dom/components/paragraph.d.ts +5 -0
  76. package/dist/dom/components/progressbar.d.ts +5 -0
  77. package/dist/dom/components/route.d.ts +6 -0
  78. package/dist/dom/components/route.js +2 -2
  79. package/dist/dom/components/route.js.map +2 -2
  80. package/dist/dom/components/router.d.ts +5 -0
  81. package/dist/dom/components/row.d.ts +7 -0
  82. package/dist/dom/components/select.d.ts +5 -0
  83. package/dist/dom/components/slider.d.ts +5 -0
  84. package/dist/dom/components/spacer.d.ts +5 -0
  85. package/dist/dom/components/spinner.d.ts +5 -0
  86. package/dist/dom/components/stack.d.ts +5 -0
  87. package/dist/dom/components/switch.d.ts +5 -0
  88. package/dist/dom/components/text.d.ts +5 -0
  89. package/dist/dom/components/textarea.d.ts +5 -0
  90. package/dist/dom/components/video.d.ts +5 -0
  91. package/dist/dom/debug.d.ts +63 -0
  92. package/dist/dom/debug.js +2 -2
  93. package/dist/dom/debug.js.map +2 -2
  94. package/dist/dom/element-data.d.ts +94 -0
  95. package/dist/dom/events.d.ts +39 -0
  96. package/dist/dom/events.js +2 -2
  97. package/dist/dom/events.js.map +2 -2
  98. package/dist/dom/index.d.ts +10 -0
  99. package/dist/dom/index.js +101 -25
  100. package/dist/dom/index.js.map +12 -11
  101. package/dist/dom/renderer.d.ts +115 -0
  102. package/dist/dom/renderer.js +100 -24
  103. package/dist/dom/renderer.js.map +11 -10
  104. package/dist/hypen.d.ts +140 -0
  105. package/dist/hypen.js +106 -43
  106. package/dist/hypen.js.map +12 -11
  107. package/dist/index.d.ts +28 -0
  108. package/dist/index.js +132 -38
  109. package/dist/index.js.map +17 -16
  110. package/package.json +3 -2
  111. package/src/canvas/input.ts +23 -1
  112. package/src/dom/applicators/events.ts +71 -0
  113. package/src/dom/renderer.ts +4 -4
  114. package/src/hypen.ts +7 -24
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Type-Safe Element Data
3
+ *
4
+ * Provides strongly-typed access to Hypen-specific data attached to DOM elements.
5
+ * Eliminates `as any` casts throughout the codebase.
6
+ */
7
+ /**
8
+ * Engine interface for dispatching actions
9
+ */
10
+ export interface IEngine {
11
+ dispatchAction(name: string, payload?: unknown): void;
12
+ }
13
+ /**
14
+ * All Hypen-specific data attached to an element
15
+ */
16
+ export interface HypenElementData {
17
+ /** Engine reference for action dispatch */
18
+ engine?: IEngine;
19
+ /** Target key for keyboard events (e.g., "Enter", "Escape") */
20
+ keyTarget?: string;
21
+ /** Set of registered event type:action pairs */
22
+ registeredEvents?: Set<string>;
23
+ /** Custom element metadata */
24
+ meta?: Record<string, unknown>;
25
+ }
26
+ /**
27
+ * Get Hypen data for an element, creating if needed
28
+ */
29
+ export declare function getHypenData(element: HTMLElement): HypenElementData;
30
+ /**
31
+ * Check if element has Hypen data
32
+ */
33
+ export declare function hasHypenData(element: HTMLElement): boolean;
34
+ /**
35
+ * Clear Hypen data from an element
36
+ */
37
+ export declare function clearHypenData(element: HTMLElement): void;
38
+ /**
39
+ * Get the engine attached to an element
40
+ */
41
+ export declare function getEngine(element: HTMLElement): IEngine | undefined;
42
+ /**
43
+ * Set the engine on an element
44
+ */
45
+ export declare function setEngine(element: HTMLElement, engine: IEngine): void;
46
+ /**
47
+ * Find engine by walking up the DOM tree
48
+ */
49
+ export declare function findEngine(element: HTMLElement): IEngine | undefined;
50
+ /**
51
+ * Get registered events set for an element
52
+ */
53
+ export declare function getRegisteredEvents(element: HTMLElement): Set<string>;
54
+ /**
55
+ * Check if an event handler is registered
56
+ */
57
+ export declare function isEventRegistered(element: HTMLElement, eventKey: string): boolean;
58
+ /**
59
+ * Mark an event handler as registered
60
+ */
61
+ export declare function registerEvent(element: HTMLElement, eventKey: string): void;
62
+ /**
63
+ * Unregister an event handler
64
+ */
65
+ export declare function unregisterEvent(element: HTMLElement, eventKey: string): void;
66
+ /**
67
+ * Get the target key for keyboard events
68
+ */
69
+ export declare function getKeyTarget(element: HTMLElement): string | undefined;
70
+ /**
71
+ * Set the target key for keyboard events
72
+ */
73
+ export declare function setKeyTarget(element: HTMLElement, key: string): void;
74
+ /**
75
+ * Get custom metadata value
76
+ */
77
+ export declare function getMeta<T>(element: HTMLElement, key: string): T | undefined;
78
+ /**
79
+ * Set custom metadata value
80
+ */
81
+ export declare function setMeta<T>(element: HTMLElement, key: string, value: T): void;
82
+ /**
83
+ * Dispose all resources attached to an element and clear data
84
+ * Call this when removing an element from the DOM
85
+ */
86
+ export declare function disposeHypenElement(element: HTMLElement): void;
87
+ /**
88
+ * Legacy accessor for engine (backwards compatible with existing code)
89
+ */
90
+ export declare function getLegacyEngine(element: HTMLElement): IEngine | undefined;
91
+ /**
92
+ * Legacy setter for engine (backwards compatible)
93
+ */
94
+ export declare function setLegacyEngine(element: HTMLElement, engine: IEngine): void;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Event Management System
3
+ *
4
+ * Handles DOM event binding and action dispatching
5
+ */
6
+ interface IEngine {
7
+ dispatchAction(name: string, payload?: any): void;
8
+ }
9
+ export interface EventBinding {
10
+ elementId: string;
11
+ eventName: string;
12
+ actionName: string;
13
+ }
14
+ export declare class EventManager {
15
+ private engine;
16
+ private bindings;
17
+ constructor(engine: IEngine);
18
+ /**
19
+ * Attach an event listener to an element
20
+ */
21
+ attach(elementId: string, element: HTMLElement, eventName: string, actionName: string): void;
22
+ /**
23
+ * Detach an event listener from an element
24
+ */
25
+ detach(elementId: string, element: HTMLElement, eventName: string): void;
26
+ /**
27
+ * Extract relevant data from an event
28
+ */
29
+ private extractEventData;
30
+ /**
31
+ * Clear all event bindings for an element
32
+ */
33
+ clearElement(elementId: string, element: HTMLElement): void;
34
+ /**
35
+ * Clear all event bindings
36
+ */
37
+ clearAll(): void;
38
+ }
39
+ export {};
@@ -28,7 +28,7 @@ var __export = (target, all) => {
28
28
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
29
29
 
30
30
  // src/dom/events.ts
31
- import { frameworkLoggers } from "@hypen-space/core";
31
+ import { frameworkLoggers } from "@hypen-space/core/logger";
32
32
  var log = frameworkLoggers.events;
33
33
 
34
34
  class EventManager {
@@ -137,4 +137,4 @@ export {
137
137
  EventManager
138
138
  };
139
139
 
140
- //# debugId=CFF27E1FA4869F5864756E2164756E21
140
+ //# debugId=AB9487AE99F7A49464756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/dom/events.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Event Management System\n *\n * Handles DOM event binding and action dispatching\n */\n\nimport { frameworkLoggers } from \"@hypen-space/core\";\n\nconst log = frameworkLoggers.events;\n\n// Interface for the engine that EventManager needs\ninterface IEngine {\n dispatchAction(name: string, payload?: any): void;\n}\n\nexport interface EventBinding {\n elementId: string;\n eventName: string;\n actionName: string;\n}\n\nexport class EventManager {\n private engine: IEngine;\n private bindings: Map<string, Map<string, EventListener>> = new Map();\n\n constructor(engine: IEngine) {\n this.engine = engine;\n }\n\n /**\n * Attach an event listener to an element\n */\n attach(elementId: string, element: HTMLElement, eventName: string, actionName: string): void {\n // Convert onClick to click for DOM events\n const domEventName = eventName === \"onClick\" ? \"click\" : eventName;\n log.debug(`Attaching ${eventName} (DOM: ${domEventName}) to element ${elementId}, action: ${actionName}`);\n\n // Create event listener that dispatches action\n const listener = (event: Event) => {\n log.debug(`Event fired: ${eventName} on ${elementId}, dispatching action: ${actionName}`);\n log.debug(`Event object:`, event);\n log.debug(`Element:`, element);\n\n // Prevent default for certain events\n if (eventName === \"submit\" || (eventName === \"click\" && element.tagName === \"A\")) {\n event.preventDefault();\n }\n\n // Extract event data\n const payload = this.extractEventData(event, element);\n log.debug(`Event payload:`, payload);\n\n // Dispatch action to engine\n log.debug(`Calling engine.dispatchAction(${actionName})`);\n try {\n this.engine.dispatchAction(actionName, payload);\n log.debug(`dispatchAction succeeded`);\n } catch (error) {\n log.error(`dispatchAction failed:`, error);\n }\n };\n\n // Store listener reference\n let elementBindings = this.bindings.get(elementId);\n if (!elementBindings) {\n elementBindings = new Map();\n this.bindings.set(elementId, elementBindings);\n }\n elementBindings.set(eventName, listener);\n\n // Attach to DOM\n element.addEventListener(domEventName, listener);\n log.debug(`Listener attached to DOM for ${domEventName}`);\n log.debug(`Element details:`, {\n tagName: element.tagName,\n id: element.id,\n dataset: element.dataset,\n textContent: element.textContent?.substring(0, 50)\n });\n\n // Test: Add a simple click listener to verify DOM events work\n if (domEventName === \"click\") {\n element.addEventListener(\"click\", (e) => {\n log.debug(`Raw DOM click detected on ${element.tagName}`, e);\n });\n }\n }\n\n /**\n * Detach an event listener from an element\n */\n detach(elementId: string, element: HTMLElement, eventName: string): void {\n const elementBindings = this.bindings.get(elementId);\n if (!elementBindings) return;\n\n const listener = elementBindings.get(eventName);\n if (listener) {\n element.removeEventListener(eventName, listener);\n elementBindings.delete(eventName);\n }\n\n if (elementBindings.size === 0) {\n this.bindings.delete(elementId);\n }\n }\n\n /**\n * Extract relevant data from an event\n */\n private extractEventData(event: Event, element: HTMLElement): any {\n const data: any = {\n type: event.type,\n timestamp: Date.now(),\n };\n\n // Mouse events\n if (event instanceof MouseEvent) {\n data.clientX = event.clientX;\n data.clientY = event.clientY;\n data.button = event.button;\n }\n\n // Keyboard events\n if (event instanceof KeyboardEvent) {\n data.key = event.key;\n data.code = event.code;\n data.ctrlKey = event.ctrlKey;\n data.shiftKey = event.shiftKey;\n data.altKey = event.altKey;\n data.metaKey = event.metaKey;\n }\n\n // Input events (for form elements)\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n data.value = element.value;\n }\n\n // Select events\n if (element instanceof HTMLSelectElement) {\n data.value = element.value;\n data.selectedIndex = element.selectedIndex;\n }\n\n // Form events\n if (event.type === \"submit\" && element instanceof HTMLFormElement) {\n data.formData = new FormData(element);\n }\n\n return data;\n }\n\n /**\n * Clear all event bindings for an element\n */\n clearElement(elementId: string, element: HTMLElement): void {\n const elementBindings = this.bindings.get(elementId);\n if (!elementBindings) return;\n\n for (const [eventName, listener] of elementBindings) {\n element.removeEventListener(eventName, listener);\n }\n\n this.bindings.delete(elementId);\n }\n\n /**\n * Clear all event bindings\n */\n clearAll(): void {\n this.bindings.clear();\n }\n}\n"
5
+ "/**\n * Event Management System\n *\n * Handles DOM event binding and action dispatching\n */\n\nimport { frameworkLoggers } from \"@hypen-space/core/logger\";\n\nconst log = frameworkLoggers.events;\n\n// Interface for the engine that EventManager needs\ninterface IEngine {\n dispatchAction(name: string, payload?: any): void;\n}\n\nexport interface EventBinding {\n elementId: string;\n eventName: string;\n actionName: string;\n}\n\nexport class EventManager {\n private engine: IEngine;\n private bindings: Map<string, Map<string, EventListener>> = new Map();\n\n constructor(engine: IEngine) {\n this.engine = engine;\n }\n\n /**\n * Attach an event listener to an element\n */\n attach(elementId: string, element: HTMLElement, eventName: string, actionName: string): void {\n // Convert onClick to click for DOM events\n const domEventName = eventName === \"onClick\" ? \"click\" : eventName;\n log.debug(`Attaching ${eventName} (DOM: ${domEventName}) to element ${elementId}, action: ${actionName}`);\n\n // Create event listener that dispatches action\n const listener = (event: Event) => {\n log.debug(`Event fired: ${eventName} on ${elementId}, dispatching action: ${actionName}`);\n log.debug(`Event object:`, event);\n log.debug(`Element:`, element);\n\n // Prevent default for certain events\n if (eventName === \"submit\" || (eventName === \"click\" && element.tagName === \"A\")) {\n event.preventDefault();\n }\n\n // Extract event data\n const payload = this.extractEventData(event, element);\n log.debug(`Event payload:`, payload);\n\n // Dispatch action to engine\n log.debug(`Calling engine.dispatchAction(${actionName})`);\n try {\n this.engine.dispatchAction(actionName, payload);\n log.debug(`dispatchAction succeeded`);\n } catch (error) {\n log.error(`dispatchAction failed:`, error);\n }\n };\n\n // Store listener reference\n let elementBindings = this.bindings.get(elementId);\n if (!elementBindings) {\n elementBindings = new Map();\n this.bindings.set(elementId, elementBindings);\n }\n elementBindings.set(eventName, listener);\n\n // Attach to DOM\n element.addEventListener(domEventName, listener);\n log.debug(`Listener attached to DOM for ${domEventName}`);\n log.debug(`Element details:`, {\n tagName: element.tagName,\n id: element.id,\n dataset: element.dataset,\n textContent: element.textContent?.substring(0, 50)\n });\n\n // Test: Add a simple click listener to verify DOM events work\n if (domEventName === \"click\") {\n element.addEventListener(\"click\", (e) => {\n log.debug(`Raw DOM click detected on ${element.tagName}`, e);\n });\n }\n }\n\n /**\n * Detach an event listener from an element\n */\n detach(elementId: string, element: HTMLElement, eventName: string): void {\n const elementBindings = this.bindings.get(elementId);\n if (!elementBindings) return;\n\n const listener = elementBindings.get(eventName);\n if (listener) {\n element.removeEventListener(eventName, listener);\n elementBindings.delete(eventName);\n }\n\n if (elementBindings.size === 0) {\n this.bindings.delete(elementId);\n }\n }\n\n /**\n * Extract relevant data from an event\n */\n private extractEventData(event: Event, element: HTMLElement): any {\n const data: any = {\n type: event.type,\n timestamp: Date.now(),\n };\n\n // Mouse events\n if (event instanceof MouseEvent) {\n data.clientX = event.clientX;\n data.clientY = event.clientY;\n data.button = event.button;\n }\n\n // Keyboard events\n if (event instanceof KeyboardEvent) {\n data.key = event.key;\n data.code = event.code;\n data.ctrlKey = event.ctrlKey;\n data.shiftKey = event.shiftKey;\n data.altKey = event.altKey;\n data.metaKey = event.metaKey;\n }\n\n // Input events (for form elements)\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n data.value = element.value;\n }\n\n // Select events\n if (element instanceof HTMLSelectElement) {\n data.value = element.value;\n data.selectedIndex = element.selectedIndex;\n }\n\n // Form events\n if (event.type === \"submit\" && element instanceof HTMLFormElement) {\n data.formData = new FormData(element);\n }\n\n return data;\n }\n\n /**\n * Clear all event bindings for an element\n */\n clearElement(elementId: string, element: HTMLElement): void {\n const elementBindings = this.bindings.get(elementId);\n if (!elementBindings) return;\n\n for (const [eventName, listener] of elementBindings) {\n element.removeEventListener(eventName, listener);\n }\n\n this.bindings.delete(elementId);\n }\n\n /**\n * Clear all event bindings\n */\n clearAll(): void {\n this.bindings.clear();\n }\n}\n"
6
6
  ],
7
7
  "mappings": "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",
8
- "debugId": "CFF27E1FA4869F5864756E2164756E21",
8
+ "debugId": "AB9487AE99F7A49464756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * DOM Renderer for Hypen
3
+ *
4
+ * Browser-only module for rendering Hypen UI to the DOM
5
+ */
6
+ export { DOMRenderer } from "./renderer.js";
7
+ export { ComponentRegistry } from "./components/index.js";
8
+ export { ApplicatorRegistry } from "./applicators/index.js";
9
+ export { EventManager } from "./events.js";
10
+ export { RerenderTracker, type DebugConfig, defaultDebugConfig } from "./debug.js";
package/dist/dom/index.js CHANGED
@@ -1011,7 +1011,7 @@ var exports_route = {};
1011
1011
  __export(exports_route, {
1012
1012
  routeHandler: () => routeHandler
1013
1013
  });
1014
- import { frameworkLoggers } from "@hypen-space/core";
1014
+ import { frameworkLoggers } from "@hypen-space/core/logger";
1015
1015
  var log, routeHandler;
1016
1016
  var init_route = __esm(() => {
1017
1017
  log = frameworkLoggers.router;
@@ -1046,7 +1046,7 @@ __export(exports_hypenapp, {
1046
1046
  disconnectHypenApp: () => disconnectHypenApp
1047
1047
  });
1048
1048
  import { RemoteEngine } from "@hypen-space/core/remote/client";
1049
- import { frameworkLoggers as frameworkLoggers2 } from "@hypen-space/core";
1049
+ import { frameworkLoggers as frameworkLoggers2 } from "@hypen-space/core/logger";
1050
1050
  function applyPatches(container, nodes, patches, engine, onRoot) {
1051
1051
  for (const patch of patches) {
1052
1052
  switch (patch.type) {
@@ -1202,8 +1202,6 @@ function applyProp(el, name, value) {
1202
1202
  border: "border",
1203
1203
  gap: "gap",
1204
1204
  flex: "flex",
1205
- alignItems: "alignItems",
1206
- justifyContent: "justifyContent",
1207
1205
  opacity: "opacity",
1208
1206
  overflow: "overflow"
1209
1207
  };
@@ -1301,6 +1299,26 @@ var init_hypenapp = __esm(() => {
1301
1299
  };
1302
1300
  });
1303
1301
 
1302
+ // src/dom/components/app.ts
1303
+ var exports_app = {};
1304
+ __export(exports_app, {
1305
+ appHandler: () => appHandler
1306
+ });
1307
+ var appHandler;
1308
+ var init_app = __esm(() => {
1309
+ appHandler = {
1310
+ create() {
1311
+ const el = document.createElement("div");
1312
+ el.style.display = "flex";
1313
+ el.style.flexDirection = "column";
1314
+ el.style.minHeight = "100vh";
1315
+ el.style.width = "100%";
1316
+ el.dataset.hypenType = "app";
1317
+ return el;
1318
+ }
1319
+ };
1320
+ });
1321
+
1304
1322
  // src/dom/components/index.ts
1305
1323
  class ComponentRegistry {
1306
1324
  handlers = new Map;
@@ -1311,9 +1329,13 @@ class ComponentRegistry {
1311
1329
  this.handlers.set(type.toLowerCase(), handler);
1312
1330
  }
1313
1331
  get(type) {
1332
+ if (!type)
1333
+ return;
1314
1334
  return this.handlers.get(type.toLowerCase());
1315
1335
  }
1316
1336
  createElement(type, props = {}) {
1337
+ if (!type)
1338
+ return null;
1317
1339
  const handler = this.get(type);
1318
1340
  if (!handler)
1319
1341
  return null;
@@ -1355,6 +1377,8 @@ class ComponentRegistry {
1355
1377
  const { routerHandler: routerHandler2 } = (init_router(), __toCommonJS(exports_router));
1356
1378
  const { routeHandler: routeHandler2 } = (init_route(), __toCommonJS(exports_route));
1357
1379
  const { hypenAppHandler: hypenAppHandler2 } = (init_hypenapp(), __toCommonJS(exports_hypenapp));
1380
+ const { appHandler: appHandler2 } = (init_app(), __toCommonJS(exports_app));
1381
+ this.register("app", appHandler2);
1358
1382
  this.register("column", columnHandler2);
1359
1383
  this.register("row", rowHandler2);
1360
1384
  this.register("text", textHandler2);
@@ -2038,7 +2062,7 @@ import {
2038
2062
  disposableListener,
2039
2063
  disposableTimeout
2040
2064
  } from "@hypen-space/core/disposable";
2041
- import { frameworkLoggers as frameworkLoggers3 } from "@hypen-space/core";
2065
+ import { frameworkLoggers as frameworkLoggers3 } from "@hypen-space/core/logger";
2042
2066
  var log3 = frameworkLoggers3.events;
2043
2067
  function toPlainObject(value) {
2044
2068
  if (value instanceof Map) {
@@ -2323,10 +2347,62 @@ var eventHandlers = {
2323
2347
  extractPayload: scrollPayload
2324
2348
  }),
2325
2349
  onLongClick: createLongClickHandler(500),
2350
+ onLongPress: createLongClickHandler(500),
2326
2351
  onFocus: createEventHandler("focus", { extractPayload: focusPayload }),
2327
2352
  onBlur: createEventHandler("blur", { extractPayload: focusPayload }),
2328
2353
  onMouseEnter: createEventHandler("mouseenter", { extractPayload: mousePayload }),
2329
- onMouseLeave: createEventHandler("mouseleave", { extractPayload: mousePayload })
2354
+ onMouseLeave: createEventHandler("mouseleave", { extractPayload: mousePayload }),
2355
+ bind: (element, value) => {
2356
+ const bindPath = typeof value === "string" ? value : null;
2357
+ if (!bindPath)
2358
+ return;
2359
+ const disposables = getElementDisposables2(element);
2360
+ const eventKey = `bind:${bindPath}`;
2361
+ if (getRegisteredEvents(element).has(eventKey))
2362
+ return;
2363
+ registerEvent(element, eventKey);
2364
+ const hypenType = element.dataset?.hypenType;
2365
+ if (hypenType === "checkbox" || hypenType === "switch") {
2366
+ const input = element.querySelector('input[type="checkbox"]');
2367
+ if (!input)
2368
+ return;
2369
+ const listener = () => {
2370
+ const engine = getEngine(element);
2371
+ if (engine) {
2372
+ engine.dispatchAction("__hypen_bind", {
2373
+ path: bindPath,
2374
+ value: input.checked
2375
+ });
2376
+ }
2377
+ };
2378
+ disposables.add(disposableListener(input, "change", listener, { passive: true }));
2379
+ } else if (element instanceof HTMLSelectElement) {
2380
+ const listener = () => {
2381
+ const engine = getEngine(element);
2382
+ if (engine) {
2383
+ engine.dispatchAction("__hypen_bind", {
2384
+ path: bindPath,
2385
+ value: element.value
2386
+ });
2387
+ }
2388
+ };
2389
+ disposables.add(disposableListener(element, "change", listener, { passive: true }));
2390
+ } else if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
2391
+ const listener = () => {
2392
+ const engine = getEngine(element);
2393
+ if (engine) {
2394
+ engine.dispatchAction("__hypen_bind", {
2395
+ path: bindPath,
2396
+ value: element.value
2397
+ });
2398
+ }
2399
+ };
2400
+ disposables.add(disposableListener(element, "input", listener, { passive: true }));
2401
+ } else {
2402
+ return;
2403
+ }
2404
+ disposables.addCallback(() => unregisterEvent(element, eventKey));
2405
+ }
2330
2406
  };
2331
2407
 
2332
2408
  // src/dom/applicators/typography.ts
@@ -2584,12 +2660,6 @@ var advancedLayoutHandlers = {
2584
2660
  flexBasis: (el, value) => {
2585
2661
  el.style.flexBasis = typeof value === "number" ? `${value}px` : String(value);
2586
2662
  },
2587
- justifyContent: (el, value) => {
2588
- el.style.justifyContent = mapAlignmentValue(String(value));
2589
- },
2590
- alignItems: (el, value) => {
2591
- el.style.alignItems = mapAlignmentValue(String(value));
2592
- },
2593
2663
  alignContent: (el, value) => {
2594
2664
  el.style.alignContent = String(value);
2595
2665
  },
@@ -3127,7 +3197,7 @@ var canvasApplicators = {
3127
3197
  };
3128
3198
 
3129
3199
  // src/dom/debug.ts
3130
- import { frameworkLoggers as frameworkLoggers4 } from "@hypen-space/core";
3200
+ import { frameworkLoggers as frameworkLoggers4 } from "@hypen-space/core/logger";
3131
3201
  var log4 = frameworkLoggers4.debug;
3132
3202
  var defaultDebugConfig = {
3133
3203
  enabled: false,
@@ -3290,7 +3360,7 @@ class RerenderTracker {
3290
3360
  }
3291
3361
 
3292
3362
  // src/dom/renderer.ts
3293
- import { frameworkLoggers as frameworkLoggers5 } from "@hypen-space/core";
3363
+ import { frameworkLoggers as frameworkLoggers5 } from "@hypen-space/core/logger";
3294
3364
  var log5 = frameworkLoggers5.renderer;
3295
3365
 
3296
3366
  class DOMRenderer {
@@ -3301,7 +3371,7 @@ class DOMRenderer {
3301
3371
  applicators;
3302
3372
  engine;
3303
3373
  currentState = {};
3304
- routerContext = null;
3374
+ router = null;
3305
3375
  globalContext = null;
3306
3376
  componentInstances = new Map;
3307
3377
  debugTracker;
@@ -3316,8 +3386,8 @@ class DOMRenderer {
3316
3386
  this.applicators.register(name, handler);
3317
3387
  }
3318
3388
  }
3319
- setContext(routerContext, globalContext) {
3320
- this.routerContext = routerContext;
3389
+ setContext(router, globalContext) {
3390
+ this.router = router;
3321
3391
  this.globalContext = globalContext;
3322
3392
  }
3323
3393
  applyPatches(patches) {
@@ -3363,24 +3433,30 @@ class DOMRenderer {
3363
3433
  });
3364
3434
  }
3365
3435
  applyPatch(patch) {
3436
+ const p = patch;
3437
+ const id = patch.id ?? p.id;
3438
+ const elementType = patch.elementType ?? p.element_type;
3439
+ const parentId = patch.parentId ?? p.parent_id;
3440
+ const beforeId = patch.beforeId ?? p.before_id;
3441
+ const eventName = patch.eventName ?? p.event_name;
3366
3442
  switch (patch.type) {
3367
3443
  case "create":
3368
- this.onCreate(patch.id, patch.elementType, patch.props || {});
3444
+ this.onCreate(id, elementType ?? "container", patch.props || {});
3369
3445
  break;
3370
3446
  case "setProp":
3371
- this.onSetProp(patch.id, patch.name, patch.value);
3447
+ this.onSetProp(id, patch.name, patch.value);
3372
3448
  break;
3373
3449
  case "setText":
3374
- this.onSetText(patch.id, patch.text);
3450
+ this.onSetText(id, patch.text);
3375
3451
  break;
3376
3452
  case "insert":
3377
- this.onInsert(patch.parentId, patch.id, patch.beforeId);
3453
+ this.onInsert(parentId, id, beforeId);
3378
3454
  break;
3379
3455
  case "move":
3380
- this.onMove(patch.parentId, patch.id, patch.beforeId);
3456
+ this.onMove(parentId, id, beforeId);
3381
3457
  break;
3382
3458
  case "remove":
3383
- this.onRemove(patch.id);
3459
+ this.onRemove(id);
3384
3460
  break;
3385
3461
  }
3386
3462
  }
@@ -3511,7 +3587,7 @@ class DOMRenderer {
3511
3587
  }
3512
3588
 
3513
3589
  // src/dom/events.ts
3514
- import { frameworkLoggers as frameworkLoggers6 } from "@hypen-space/core";
3590
+ import { frameworkLoggers as frameworkLoggers6 } from "@hypen-space/core/logger";
3515
3591
  var log6 = frameworkLoggers6.events;
3516
3592
 
3517
3593
  class EventManager {
@@ -3625,4 +3701,4 @@ export {
3625
3701
  ApplicatorRegistry
3626
3702
  };
3627
3703
 
3628
- //# debugId=B4E923D0EBE0B01664756E2164756E21
3704
+ //# debugId=181A39A0B6D4721464756E2164756E21