@hypen-space/web 0.4.36 → 0.4.38

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 (149) hide show
  1. package/README.md +7 -6
  2. package/dist/canvas/accessibility.js +174 -174
  3. package/dist/canvas/accessibility.js.map +1 -10
  4. package/dist/canvas/events.js +264 -360
  5. package/dist/canvas/events.js.map +1 -11
  6. package/dist/canvas/index.js +11 -47
  7. package/dist/canvas/index.js.map +1 -9
  8. package/dist/canvas/input.js +178 -289
  9. package/dist/canvas/input.js.map +1 -11
  10. package/dist/canvas/layout.js +349 -547
  11. package/dist/canvas/layout.js.map +1 -12
  12. package/dist/canvas/paint.js +1122 -1146
  13. package/dist/canvas/paint.js.map +1 -12
  14. package/dist/canvas/renderer.js +352 -2259
  15. package/dist/canvas/renderer.js.map +1 -17
  16. package/dist/canvas/text.js +129 -264
  17. package/dist/canvas/text.js.map +1 -11
  18. package/dist/canvas/types.js +7 -2
  19. package/dist/canvas/types.js.map +1 -9
  20. package/dist/canvas/utils.js +158 -161
  21. package/dist/canvas/utils.js.map +1 -10
  22. package/dist/dom/applicators/advanced-layout.js +105 -138
  23. package/dist/dom/applicators/advanced-layout.js.map +1 -10
  24. package/dist/dom/applicators/background.js +36 -76
  25. package/dist/dom/applicators/background.js.map +1 -10
  26. package/dist/dom/applicators/border.js +82 -106
  27. package/dist/dom/applicators/border.js.map +1 -10
  28. package/dist/dom/applicators/color.js +17 -58
  29. package/dist/dom/applicators/color.js.map +1 -10
  30. package/dist/dom/applicators/display.js +39 -79
  31. package/dist/dom/applicators/display.js.map +1 -10
  32. package/dist/dom/applicators/effects.js +121 -147
  33. package/dist/dom/applicators/effects.js.map +1 -10
  34. package/dist/dom/applicators/events.js +413 -450
  35. package/dist/dom/applicators/events.js.map +1 -11
  36. package/dist/dom/applicators/font.js +119 -140
  37. package/dist/dom/applicators/font.js.map +1 -10
  38. package/dist/dom/applicators/index.js +386 -1770
  39. package/dist/dom/applicators/index.js.map +1 -26
  40. package/dist/dom/applicators/layout.js +143 -149
  41. package/dist/dom/applicators/layout.js.map +1 -10
  42. package/dist/dom/applicators/margin.js +64 -105
  43. package/dist/dom/applicators/margin.js.map +1 -10
  44. package/dist/dom/applicators/padding.js +64 -105
  45. package/dist/dom/applicators/padding.js.map +1 -10
  46. package/dist/dom/applicators/size.js +169 -172
  47. package/dist/dom/applicators/size.js.map +1 -10
  48. package/dist/dom/applicators/transform.js +73 -114
  49. package/dist/dom/applicators/transform.js.map +1 -10
  50. package/dist/dom/applicators/transition.js +47 -88
  51. package/dist/dom/applicators/transition.js.map +1 -10
  52. package/dist/dom/applicators/types.js +7 -2
  53. package/dist/dom/applicators/types.js.map +1 -9
  54. package/dist/dom/applicators/typography.js +68 -109
  55. package/dist/dom/applicators/typography.js.map +1 -10
  56. package/dist/dom/canvas/index.js +49 -83
  57. package/dist/dom/canvas/index.js.map +1 -10
  58. package/dist/dom/components/app.js +16 -63
  59. package/dist/dom/components/app.js.map +1 -10
  60. package/dist/dom/components/audio.js +31 -76
  61. package/dist/dom/components/audio.js.map +1 -10
  62. package/dist/dom/components/avatar.js +41 -87
  63. package/dist/dom/components/avatar.js.map +1 -10
  64. package/dist/dom/components/badge.js +35 -83
  65. package/dist/dom/components/badge.js.map +1 -10
  66. package/dist/dom/components/button.js +26 -69
  67. package/dist/dom/components/button.js.map +1 -10
  68. package/dist/dom/components/card.js +13 -63
  69. package/dist/dom/components/card.js.map +1 -10
  70. package/dist/dom/components/center.js +21 -65
  71. package/dist/dom/components/center.js.map +1 -10
  72. package/dist/dom/components/checkbox.js +37 -82
  73. package/dist/dom/components/checkbox.js.map +1 -10
  74. package/dist/dom/components/column.js +16 -62
  75. package/dist/dom/components/column.js.map +1 -10
  76. package/dist/dom/components/container.js +11 -59
  77. package/dist/dom/components/container.js.map +1 -10
  78. package/dist/dom/components/divider.js +27 -73
  79. package/dist/dom/components/divider.js.map +1 -10
  80. package/dist/dom/components/grid.js +41 -80
  81. package/dist/dom/components/grid.js.map +1 -10
  82. package/dist/dom/components/heading.js +28 -74
  83. package/dist/dom/components/heading.js.map +1 -10
  84. package/dist/dom/components/hypenapp.js +291 -288
  85. package/dist/dom/components/hypenapp.js.map +1 -10
  86. package/dist/dom/components/image.js +18 -67
  87. package/dist/dom/components/image.js.map +1 -10
  88. package/dist/dom/components/index.js +109 -1427
  89. package/dist/dom/components/index.js.map +1 -42
  90. package/dist/dom/components/input.js +19 -69
  91. package/dist/dom/components/input.js.map +1 -10
  92. package/dist/dom/components/link.js +23 -70
  93. package/dist/dom/components/link.js.map +1 -10
  94. package/dist/dom/components/list.js +26 -72
  95. package/dist/dom/components/list.js.map +1 -10
  96. package/dist/dom/components/paragraph.js +14 -63
  97. package/dist/dom/components/paragraph.js.map +1 -10
  98. package/dist/dom/components/progressbar.js +38 -85
  99. package/dist/dom/components/progressbar.js.map +1 -10
  100. package/dist/dom/components/route.js +27 -73
  101. package/dist/dom/components/route.js.map +1 -10
  102. package/dist/dom/components/router.js +15 -62
  103. package/dist/dom/components/router.js.map +1 -10
  104. package/dist/dom/components/row.js +25 -70
  105. package/dist/dom/components/row.js.map +1 -10
  106. package/dist/dom/components/select.js +42 -85
  107. package/dist/dom/components/select.js.map +1 -10
  108. package/dist/dom/components/slider.js +31 -76
  109. package/dist/dom/components/slider.js.map +1 -10
  110. package/dist/dom/components/spacer.js +10 -60
  111. package/dist/dom/components/spacer.js.map +1 -10
  112. package/dist/dom/components/spinner.js +41 -88
  113. package/dist/dom/components/spinner.js.map +1 -10
  114. package/dist/dom/components/stack.js +19 -67
  115. package/dist/dom/components/stack.js.map +1 -10
  116. package/dist/dom/components/switch.js +50 -93
  117. package/dist/dom/components/switch.js.map +1 -10
  118. package/dist/dom/components/text.js +24 -69
  119. package/dist/dom/components/text.js.map +1 -10
  120. package/dist/dom/components/textarea.js +35 -79
  121. package/dist/dom/components/textarea.js.map +1 -10
  122. package/dist/dom/components/video.js +35 -79
  123. package/dist/dom/components/video.js.map +1 -10
  124. package/dist/dom/debug.js +159 -160
  125. package/dist/dom/debug.js.map +1 -10
  126. package/dist/dom/element-data.js +181 -143
  127. package/dist/dom/element-data.js.map +1 -10
  128. package/dist/dom/events.js +133 -142
  129. package/dist/dom/events.js.map +1 -10
  130. package/dist/dom/index.js +11 -48
  131. package/dist/dom/index.js.map +1 -9
  132. package/dist/dom/renderer.js +311 -3596
  133. package/dist/dom/renderer.js.map +1 -62
  134. package/dist/index.d.ts +2 -2
  135. package/dist/index.js +36 -53
  136. package/dist/index.js.map +1 -9
  137. package/package.json +2 -16
  138. package/src/canvas/QUICKSTART.md +4 -3
  139. package/src/canvas/README.md +3 -2
  140. package/src/dom/README.md +4 -3
  141. package/src/index.ts +2 -2
  142. package/dist/client.d.ts +0 -19
  143. package/dist/client.js +0 -45
  144. package/dist/client.js.map +0 -9
  145. package/dist/hypen.d.ts +0 -140
  146. package/dist/hypen.js +0 -3909
  147. package/dist/hypen.js.map +0 -63
  148. package/src/client.ts +0 -20
  149. package/src/hypen.ts +0 -556
@@ -1,306 +1,309 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- function __accessProp(key) {
6
- return this[key];
7
- }
8
- var __toCommonJS = (from) => {
9
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
10
- if (entry)
11
- return entry;
12
- entry = __defProp({}, "__esModule", { value: true });
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (var key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(entry, key))
16
- __defProp(entry, key, {
17
- get: __accessProp.bind(from, key),
18
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
- });
20
- }
21
- __moduleCache.set(from, entry);
22
- return entry;
23
- };
24
- var __moduleCache;
25
- var __returnValue = (v) => v;
26
- function __exportSetter(name, newValue) {
27
- this[name] = __returnValue.bind(null, newValue);
28
- }
29
- var __export = (target, all) => {
30
- for (var name in all)
31
- __defProp(target, name, {
32
- get: all[name],
33
- enumerable: true,
34
- configurable: true,
35
- set: __exportSetter.bind(all, name)
36
- });
37
- };
38
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
39
-
40
- // src/dom/components/hypenapp.ts
41
- var exports_hypenapp = {};
42
- __export(exports_hypenapp, {
43
- hypenAppHandler: () => hypenAppHandler,
44
- disconnectHypenApp: () => disconnectHypenApp
45
- });
1
+ /**
2
+ * HypenApp Component
3
+ *
4
+ * Embeds a remote Hypen app via WebSocket
5
+ *
6
+ * Usage in Hypen DSL:
7
+ * ```hypen
8
+ * HypenApp("ws://localhost:3000")
9
+ *
10
+ * // Or with named prop:
11
+ * HypenApp(url: "ws://localhost:3000")
12
+ * ```
13
+ */
46
14
  import { RemoteEngine } from "@hypen-space/core/remote/client";
47
15
  import { frameworkLoggers } from "@hypen-space/core/logger";
48
- function applyPatches(container, nodes, patches, engine, onRoot) {
49
- for (const patch of patches) {
50
- switch (patch.type) {
51
- case "create": {
52
- const el = createElement(patch.elementType, patch.props || {});
53
- el.dataset.hypenId = patch.id;
54
- el.__hypenEngine = engine;
55
- nodes.set(patch.id, el);
56
- break;
57
- }
58
- case "setProp": {
59
- const el = nodes.get(patch.id);
60
- if (el) {
61
- applyProp(el, patch.name, patch.value);
16
+ const log = frameworkLoggers.remote;
17
+ // Store active HypenApp instances for cleanup
18
+ const activeInstances = new WeakMap();
19
+ export const hypenAppHandler = {
20
+ create() {
21
+ const el = document.createElement("div");
22
+ el.dataset.hypenType = "hypenapp";
23
+ el.style.display = "contents"; // Don't affect layout
24
+ return el;
25
+ },
26
+ applyProps(element, props) {
27
+ // Get URL from props (can be positional "0" or named "url")
28
+ const url = props["0"] || props.url;
29
+ if (!url || typeof url !== "string") {
30
+ log.error("HypenApp: URL is required");
31
+ element.innerHTML = '<div style="color: red;">HypenApp: URL required</div>';
32
+ return;
62
33
  }
63
- break;
64
- }
65
- case "setText": {
66
- const el = nodes.get(patch.id);
67
- if (el) {
68
- el.textContent = patch.text;
34
+ // Check if already connected
35
+ const existing = activeInstances.get(element);
36
+ if (existing) {
37
+ // Already connected, don't reconnect
38
+ return;
69
39
  }
70
- break;
71
- }
72
- case "insert": {
73
- const parentId = patch.parentId;
74
- const parent = parentId === "root" ? container : nodes.get(parentId);
75
- const child = nodes.get(patch.id);
76
- const beforeId = patch.beforeId;
77
- if (parent && child) {
78
- if (parentId === "root") {
79
- onRoot(patch.id);
80
- }
81
- if (beforeId) {
82
- const before = nodes.get(beforeId);
83
- if (before && before.parentNode === parent) {
84
- parent.insertBefore(child, before);
85
- } else if (!parent.contains(child)) {
86
- parent.appendChild(child);
40
+ // Create the remote engine
41
+ const engine = new RemoteEngine(url, {
42
+ autoReconnect: props.autoReconnect ?? true,
43
+ reconnectInterval: props.reconnectInterval ?? 3000,
44
+ maxReconnectAttempts: props.maxReconnectAttempts ?? 10,
45
+ });
46
+ // Map to track created nodes
47
+ const nodes = new Map();
48
+ let rootId = null;
49
+ // Store instance for cleanup
50
+ activeInstances.set(element, { engine, nodes });
51
+ // Set up patch handling
52
+ engine.onPatches((patches) => {
53
+ applyPatches(element, nodes, patches, engine, (id) => {
54
+ if (!rootId)
55
+ rootId = id;
56
+ });
57
+ });
58
+ // Show loading state
59
+ element.innerHTML = '<div class="hypen-app-loading">Connecting...</div>';
60
+ // Connect
61
+ engine
62
+ .connect()
63
+ .then(() => {
64
+ // Clear loading state - patches will populate content
65
+ element.innerHTML = "";
66
+ log.debug(`HypenApp connected to ${url}`);
67
+ })
68
+ .catch((error) => {
69
+ element.innerHTML = `<div style="color: red;">HypenApp: Connection failed - ${error.message}</div>`;
70
+ log.error("HypenApp connection failed:", error);
71
+ });
72
+ // Handle disconnection
73
+ engine.onDisconnect(() => {
74
+ log.debug("HypenApp disconnected");
75
+ });
76
+ engine.onError((error) => {
77
+ log.error("HypenApp error:", error);
78
+ });
79
+ // Cleanup on element removal
80
+ const observer = new MutationObserver((mutations) => {
81
+ for (const mutation of mutations) {
82
+ for (const removedNode of mutation.removedNodes) {
83
+ if (removedNode === element || removedNode.contains?.(element)) {
84
+ engine.disconnect();
85
+ activeInstances.delete(element);
86
+ observer.disconnect();
87
+ log.debug("HypenApp cleaned up");
88
+ return;
89
+ }
90
+ }
87
91
  }
88
- } else if (!parent.contains(child)) {
89
- parent.appendChild(child);
90
- }
92
+ });
93
+ // Observe parent for removal
94
+ if (element.parentNode) {
95
+ observer.observe(element.parentNode, { childList: true, subtree: true });
91
96
  }
92
- break;
93
- }
94
- case "move": {
95
- const parentId = patch.parentId;
96
- const parent = parentId === "root" ? container : nodes.get(parentId);
97
- const child = nodes.get(patch.id);
98
- const beforeId = patch.beforeId;
99
- if (parent && child) {
100
- if (beforeId) {
101
- const before = nodes.get(beforeId);
102
- if (before && before.parentNode === parent) {
103
- parent.insertBefore(child, before);
97
+ },
98
+ };
99
+ /**
100
+ * Minimal patch application for HypenApp container
101
+ */
102
+ function applyPatches(container, nodes, patches, engine, onRoot) {
103
+ for (const patch of patches) {
104
+ switch (patch.type) {
105
+ case "create": {
106
+ const el = createElement(patch.elementType, patch.props || {});
107
+ el.dataset.hypenId = patch.id;
108
+ el.__hypenEngine = engine;
109
+ nodes.set(patch.id, el);
110
+ break;
111
+ }
112
+ case "setProp": {
113
+ const el = nodes.get(patch.id);
114
+ if (el) {
115
+ applyProp(el, patch.name, patch.value);
116
+ }
117
+ break;
118
+ }
119
+ case "setText": {
120
+ const el = nodes.get(patch.id);
121
+ if (el) {
122
+ el.textContent = patch.text;
123
+ }
124
+ break;
125
+ }
126
+ case "insert": {
127
+ const parentId = patch.parentId;
128
+ const parent = parentId === "root" ? container : nodes.get(parentId);
129
+ const child = nodes.get(patch.id);
130
+ const beforeId = patch.beforeId;
131
+ if (parent && child) {
132
+ if (parentId === "root") {
133
+ onRoot(patch.id);
134
+ }
135
+ if (beforeId) {
136
+ const before = nodes.get(beforeId);
137
+ if (before && before.parentNode === parent) {
138
+ parent.insertBefore(child, before);
139
+ }
140
+ else if (!parent.contains(child)) {
141
+ parent.appendChild(child);
142
+ }
143
+ }
144
+ else if (!parent.contains(child)) {
145
+ parent.appendChild(child);
146
+ }
147
+ }
148
+ break;
149
+ }
150
+ case "move": {
151
+ const parentId = patch.parentId;
152
+ const parent = parentId === "root" ? container : nodes.get(parentId);
153
+ const child = nodes.get(patch.id);
154
+ const beforeId = patch.beforeId;
155
+ if (parent && child) {
156
+ if (beforeId) {
157
+ const before = nodes.get(beforeId);
158
+ if (before && before.parentNode === parent) {
159
+ parent.insertBefore(child, before);
160
+ }
161
+ }
162
+ else {
163
+ parent.appendChild(child);
164
+ }
165
+ }
166
+ break;
167
+ }
168
+ case "remove": {
169
+ const el = nodes.get(patch.id);
170
+ if (el && el.parentNode) {
171
+ el.parentNode.removeChild(el);
172
+ }
173
+ nodes.delete(patch.id);
174
+ break;
104
175
  }
105
- } else {
106
- parent.appendChild(child);
107
- }
108
- }
109
- break;
110
- }
111
- case "remove": {
112
- const el = nodes.get(patch.id);
113
- if (el && el.parentNode) {
114
- el.parentNode.removeChild(el);
115
176
  }
116
- nodes.delete(patch.id);
117
- break;
118
- }
119
177
  }
120
- }
121
178
  }
179
+ /**
180
+ * Create element by type
181
+ */
122
182
  function createElement(type, props) {
123
- const normalizedType = type.toLowerCase();
124
- const tagMap = {
125
- column: "div",
126
- row: "div",
127
- text: "span",
128
- button: "button",
129
- input: "input",
130
- image: "img",
131
- container: "div",
132
- box: "div",
133
- center: "div",
134
- list: "div",
135
- spacer: "div",
136
- stack: "div",
137
- divider: "hr",
138
- grid: "div",
139
- card: "div",
140
- heading: "h2",
141
- link: "a",
142
- textarea: "textarea",
143
- checkbox: "input",
144
- select: "select",
145
- slider: "input",
146
- switch: "input",
147
- spinner: "div",
148
- badge: "span",
149
- avatar: "img",
150
- progressbar: "div",
151
- video: "video",
152
- audio: "audio"
153
- };
154
- const tag = tagMap[normalizedType] || "div";
155
- const el = document.createElement(tag);
156
- el.dataset.hypenType = normalizedType;
157
- if (normalizedType === "column") {
158
- el.style.display = "flex";
159
- el.style.flexDirection = "column";
160
- } else if (normalizedType === "row") {
161
- el.style.display = "flex";
162
- el.style.flexDirection = "row";
163
- } else if (normalizedType === "center") {
164
- el.style.display = "flex";
165
- el.style.alignItems = "center";
166
- el.style.justifyContent = "center";
167
- } else if (normalizedType === "text") {
168
- if (props["0"]) {
169
- el.textContent = String(props["0"]);
183
+ const normalizedType = type.toLowerCase();
184
+ // Map Hypen types to HTML elements
185
+ const tagMap = {
186
+ column: "div",
187
+ row: "div",
188
+ text: "span",
189
+ button: "button",
190
+ input: "input",
191
+ image: "img",
192
+ container: "div",
193
+ box: "div",
194
+ center: "div",
195
+ list: "div",
196
+ spacer: "div",
197
+ stack: "div",
198
+ divider: "hr",
199
+ grid: "div",
200
+ card: "div",
201
+ heading: "h2",
202
+ link: "a",
203
+ textarea: "textarea",
204
+ checkbox: "input",
205
+ select: "select",
206
+ slider: "input",
207
+ switch: "input",
208
+ spinner: "div",
209
+ badge: "span",
210
+ avatar: "img",
211
+ progressbar: "div",
212
+ video: "video",
213
+ audio: "audio",
214
+ };
215
+ const tag = tagMap[normalizedType] || "div";
216
+ const el = document.createElement(tag);
217
+ el.dataset.hypenType = normalizedType;
218
+ // Apply basic styles
219
+ if (normalizedType === "column") {
220
+ el.style.display = "flex";
221
+ el.style.flexDirection = "column";
222
+ }
223
+ else if (normalizedType === "row") {
224
+ el.style.display = "flex";
225
+ el.style.flexDirection = "row";
226
+ }
227
+ else if (normalizedType === "center") {
228
+ el.style.display = "flex";
229
+ el.style.alignItems = "center";
230
+ el.style.justifyContent = "center";
231
+ }
232
+ else if (normalizedType === "text") {
233
+ // Text content from props
234
+ if (props["0"]) {
235
+ el.textContent = String(props["0"]);
236
+ }
237
+ }
238
+ else if (normalizedType === "button") {
239
+ el.style.cursor = "pointer";
170
240
  }
171
- } else if (normalizedType === "button") {
172
- el.style.cursor = "pointer";
173
- } else if (normalizedType === "checkbox" || normalizedType === "switch") {
174
- el.type = "checkbox";
175
- } else if (normalizedType === "slider") {
176
- el.type = "range";
177
- }
178
- return el;
241
+ else if (normalizedType === "checkbox" || normalizedType === "switch") {
242
+ el.type = "checkbox";
243
+ }
244
+ else if (normalizedType === "slider") {
245
+ el.type = "range";
246
+ }
247
+ return el;
179
248
  }
249
+ /**
250
+ * Apply a prop to an element
251
+ */
180
252
  function applyProp(el, name, value) {
181
- if (name === "0" || name === "text") {
182
- el.textContent = String(value);
183
- return;
184
- }
185
- const styleProps = {
186
- padding: "padding",
187
- margin: "margin",
188
- backgroundColor: "backgroundColor",
189
- background: "background",
190
- color: "color",
191
- fontSize: "fontSize",
192
- fontWeight: "fontWeight",
193
- width: "width",
194
- height: "height",
195
- minWidth: "minWidth",
196
- minHeight: "minHeight",
197
- maxWidth: "maxWidth",
198
- maxHeight: "maxHeight",
199
- borderRadius: "borderRadius",
200
- border: "border",
201
- gap: "gap",
202
- flex: "flex",
203
- opacity: "opacity",
204
- overflow: "overflow"
205
- };
206
- if (styleProps[name]) {
207
- const cssValue = typeof value === "number" ? `${value}px` : String(value);
208
- el.style[styleProps[name]] = cssValue;
209
- return;
210
- }
211
- if (name === "onClick" || name === "onclick") {
212
- el.onclick = () => {
213
- const engine = el.__hypenEngine;
214
- if (engine && typeof value === "string" && value.startsWith("@actions.")) {
215
- const action = value.replace("@actions.", "");
216
- engine.dispatchAction(action);
217
- }
218
- };
219
- return;
220
- }
221
- el.setAttribute(name, String(value));
222
- }
223
- function disconnectHypenApp(element) {
224
- const instance = activeInstances.get(element);
225
- if (instance) {
226
- instance.engine.disconnect();
227
- activeInstances.delete(element);
228
- }
229
- }
230
- var log, activeInstances, hypenAppHandler;
231
- var init_hypenapp = __esm(() => {
232
- log = frameworkLoggers.remote;
233
- activeInstances = new WeakMap;
234
- hypenAppHandler = {
235
- create() {
236
- const el = document.createElement("div");
237
- el.dataset.hypenType = "hypenapp";
238
- el.style.display = "contents";
239
- return el;
240
- },
241
- applyProps(element, props) {
242
- const url = props["0"] || props.url;
243
- if (!url || typeof url !== "string") {
244
- log.error("HypenApp: URL is required");
245
- element.innerHTML = '<div style="color: red;">HypenApp: URL required</div>';
253
+ // Text content
254
+ if (name === "0" || name === "text") {
255
+ el.textContent = String(value);
246
256
  return;
247
- }
248
- const existing = activeInstances.get(element);
249
- if (existing) {
257
+ }
258
+ // Style props
259
+ const styleProps = {
260
+ padding: "padding",
261
+ margin: "margin",
262
+ backgroundColor: "backgroundColor",
263
+ background: "background",
264
+ color: "color",
265
+ fontSize: "fontSize",
266
+ fontWeight: "fontWeight",
267
+ width: "width",
268
+ height: "height",
269
+ minWidth: "minWidth",
270
+ minHeight: "minHeight",
271
+ maxWidth: "maxWidth",
272
+ maxHeight: "maxHeight",
273
+ borderRadius: "borderRadius",
274
+ border: "border",
275
+ gap: "gap",
276
+ flex: "flex",
277
+ opacity: "opacity",
278
+ overflow: "overflow",
279
+ };
280
+ if (styleProps[name]) {
281
+ const cssValue = typeof value === "number" ? `${value}px` : String(value);
282
+ el.style[styleProps[name]] = cssValue;
250
283
  return;
251
- }
252
- const engine = new RemoteEngine(url, {
253
- autoReconnect: props.autoReconnect ?? true,
254
- reconnectInterval: props.reconnectInterval ?? 3000,
255
- maxReconnectAttempts: props.maxReconnectAttempts ?? 10
256
- });
257
- const nodes = new Map;
258
- let rootId = null;
259
- activeInstances.set(element, { engine, nodes });
260
- engine.onPatches((patches) => {
261
- applyPatches(element, nodes, patches, engine, (id) => {
262
- if (!rootId)
263
- rootId = id;
264
- });
265
- });
266
- element.innerHTML = '<div class="hypen-app-loading">Connecting...</div>';
267
- engine.connect().then(() => {
268
- element.innerHTML = "";
269
- log.debug(`HypenApp connected to ${url}`);
270
- }).catch((error) => {
271
- element.innerHTML = `<div style="color: red;">HypenApp: Connection failed - ${error.message}</div>`;
272
- log.error("HypenApp connection failed:", error);
273
- });
274
- engine.onDisconnect(() => {
275
- log.debug("HypenApp disconnected");
276
- });
277
- engine.onError((error) => {
278
- log.error("HypenApp error:", error);
279
- });
280
- const observer = new MutationObserver((mutations) => {
281
- for (const mutation of mutations) {
282
- for (const removedNode of mutation.removedNodes) {
283
- if (removedNode === element || removedNode.contains?.(element)) {
284
- engine.disconnect();
285
- activeInstances.delete(element);
286
- observer.disconnect();
287
- log.debug("HypenApp cleaned up");
288
- return;
284
+ }
285
+ // Event handlers
286
+ if (name === "onClick" || name === "onclick") {
287
+ el.onclick = () => {
288
+ const engine = el.__hypenEngine;
289
+ if (engine && typeof value === "string" && value.startsWith("@actions.")) {
290
+ const action = value.replace("@actions.", "");
291
+ engine.dispatchAction(action);
289
292
  }
290
- }
291
- }
292
- });
293
- if (element.parentNode) {
294
- observer.observe(element.parentNode, { childList: true, subtree: true });
295
- }
293
+ };
294
+ return;
296
295
  }
297
- };
298
- });
299
- init_hypenapp();
300
-
301
- export {
302
- hypenAppHandler,
303
- disconnectHypenApp
304
- };
305
-
306
- //# debugId=BE61E9DA4D780C4864756E2164756E21
296
+ // Other attributes
297
+ el.setAttribute(name, String(value));
298
+ }
299
+ /**
300
+ * Disconnect a HypenApp instance
301
+ */
302
+ export function disconnectHypenApp(element) {
303
+ const instance = activeInstances.get(element);
304
+ if (instance) {
305
+ instance.engine.disconnect();
306
+ activeInstances.delete(element);
307
+ }
308
+ }
309
+ //# sourceMappingURL=hypenapp.js.map