@hypen-space/web 0.4.35 → 0.4.37
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/canvas/accessibility.js +174 -174
- package/dist/canvas/accessibility.js.map +1 -10
- package/dist/canvas/events.js +264 -360
- package/dist/canvas/events.js.map +1 -11
- package/dist/canvas/index.js +11 -47
- package/dist/canvas/index.js.map +1 -9
- package/dist/canvas/input.js +178 -289
- package/dist/canvas/input.js.map +1 -11
- package/dist/canvas/layout.js +349 -547
- package/dist/canvas/layout.js.map +1 -12
- package/dist/canvas/paint.js +1122 -1146
- package/dist/canvas/paint.js.map +1 -12
- package/dist/canvas/renderer.js +352 -2259
- package/dist/canvas/renderer.js.map +1 -17
- package/dist/canvas/text.js +129 -264
- package/dist/canvas/text.js.map +1 -11
- package/dist/canvas/types.js +7 -2
- package/dist/canvas/types.js.map +1 -9
- package/dist/canvas/utils.js +158 -161
- package/dist/canvas/utils.js.map +1 -10
- package/dist/client.js +19 -45
- package/dist/client.js.map +1 -9
- package/dist/dom/applicators/advanced-layout.js +105 -138
- package/dist/dom/applicators/advanced-layout.js.map +1 -10
- package/dist/dom/applicators/background.js +36 -76
- package/dist/dom/applicators/background.js.map +1 -10
- package/dist/dom/applicators/border.js +82 -106
- package/dist/dom/applicators/border.js.map +1 -10
- package/dist/dom/applicators/color.js +17 -58
- package/dist/dom/applicators/color.js.map +1 -10
- package/dist/dom/applicators/display.js +39 -79
- package/dist/dom/applicators/display.js.map +1 -10
- package/dist/dom/applicators/effects.js +121 -147
- package/dist/dom/applicators/effects.js.map +1 -10
- package/dist/dom/applicators/events.js +413 -450
- package/dist/dom/applicators/events.js.map +1 -11
- package/dist/dom/applicators/font.js +119 -140
- package/dist/dom/applicators/font.js.map +1 -10
- package/dist/dom/applicators/index.js +386 -1770
- package/dist/dom/applicators/index.js.map +1 -26
- package/dist/dom/applicators/layout.js +143 -149
- package/dist/dom/applicators/layout.js.map +1 -10
- package/dist/dom/applicators/margin.js +64 -105
- package/dist/dom/applicators/margin.js.map +1 -10
- package/dist/dom/applicators/padding.js +64 -105
- package/dist/dom/applicators/padding.js.map +1 -10
- package/dist/dom/applicators/size.js +169 -172
- package/dist/dom/applicators/size.js.map +1 -10
- package/dist/dom/applicators/transform.js +73 -114
- package/dist/dom/applicators/transform.js.map +1 -10
- package/dist/dom/applicators/transition.js +47 -88
- package/dist/dom/applicators/transition.js.map +1 -10
- package/dist/dom/applicators/types.js +7 -2
- package/dist/dom/applicators/types.js.map +1 -9
- package/dist/dom/applicators/typography.js +68 -109
- package/dist/dom/applicators/typography.js.map +1 -10
- package/dist/dom/canvas/index.js +49 -83
- package/dist/dom/canvas/index.js.map +1 -10
- package/dist/dom/components/app.js +16 -63
- package/dist/dom/components/app.js.map +1 -10
- package/dist/dom/components/audio.js +31 -76
- package/dist/dom/components/audio.js.map +1 -10
- package/dist/dom/components/avatar.js +41 -87
- package/dist/dom/components/avatar.js.map +1 -10
- package/dist/dom/components/badge.js +35 -83
- package/dist/dom/components/badge.js.map +1 -10
- package/dist/dom/components/button.js +26 -69
- package/dist/dom/components/button.js.map +1 -10
- package/dist/dom/components/card.js +13 -63
- package/dist/dom/components/card.js.map +1 -10
- package/dist/dom/components/center.js +21 -65
- package/dist/dom/components/center.js.map +1 -10
- package/dist/dom/components/checkbox.js +37 -82
- package/dist/dom/components/checkbox.js.map +1 -10
- package/dist/dom/components/column.js +16 -62
- package/dist/dom/components/column.js.map +1 -10
- package/dist/dom/components/container.js +11 -59
- package/dist/dom/components/container.js.map +1 -10
- package/dist/dom/components/divider.js +27 -73
- package/dist/dom/components/divider.js.map +1 -10
- package/dist/dom/components/grid.js +41 -80
- package/dist/dom/components/grid.js.map +1 -10
- package/dist/dom/components/heading.js +28 -74
- package/dist/dom/components/heading.js.map +1 -10
- package/dist/dom/components/hypenapp.js +291 -288
- package/dist/dom/components/hypenapp.js.map +1 -10
- package/dist/dom/components/image.js +18 -67
- package/dist/dom/components/image.js.map +1 -10
- package/dist/dom/components/index.js +109 -1427
- package/dist/dom/components/index.js.map +1 -42
- package/dist/dom/components/input.js +19 -69
- package/dist/dom/components/input.js.map +1 -10
- package/dist/dom/components/link.js +23 -70
- package/dist/dom/components/link.js.map +1 -10
- package/dist/dom/components/list.js +26 -72
- package/dist/dom/components/list.js.map +1 -10
- package/dist/dom/components/paragraph.js +14 -63
- package/dist/dom/components/paragraph.js.map +1 -10
- package/dist/dom/components/progressbar.js +38 -85
- package/dist/dom/components/progressbar.js.map +1 -10
- package/dist/dom/components/route.js +27 -73
- package/dist/dom/components/route.js.map +1 -10
- package/dist/dom/components/router.js +15 -62
- package/dist/dom/components/router.js.map +1 -10
- package/dist/dom/components/row.js +25 -70
- package/dist/dom/components/row.js.map +1 -10
- package/dist/dom/components/select.js +42 -85
- package/dist/dom/components/select.js.map +1 -10
- package/dist/dom/components/slider.js +31 -76
- package/dist/dom/components/slider.js.map +1 -10
- package/dist/dom/components/spacer.js +10 -60
- package/dist/dom/components/spacer.js.map +1 -10
- package/dist/dom/components/spinner.js +41 -88
- package/dist/dom/components/spinner.js.map +1 -10
- package/dist/dom/components/stack.js +19 -67
- package/dist/dom/components/stack.js.map +1 -10
- package/dist/dom/components/switch.js +50 -93
- package/dist/dom/components/switch.js.map +1 -10
- package/dist/dom/components/text.js +24 -69
- package/dist/dom/components/text.js.map +1 -10
- package/dist/dom/components/textarea.js +35 -79
- package/dist/dom/components/textarea.js.map +1 -10
- package/dist/dom/components/video.js +35 -79
- package/dist/dom/components/video.js.map +1 -10
- package/dist/dom/debug.js +159 -160
- package/dist/dom/debug.js.map +1 -10
- package/dist/dom/element-data.js +181 -143
- package/dist/dom/element-data.js.map +1 -10
- package/dist/dom/events.js +133 -142
- package/dist/dom/events.js.map +1 -10
- package/dist/dom/index.js +11 -48
- package/dist/dom/index.js.map +1 -9
- package/dist/dom/renderer.js +311 -3596
- package/dist/dom/renderer.js.map +1 -62
- package/dist/hypen.js +385 -3880
- package/dist/hypen.js.map +1 -63
- package/dist/index.js +36 -53
- package/dist/index.js.map +1 -9
- package/package.json +2 -2
|
@@ -1,306 +1,309 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
el
|
|
54
|
-
el.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
});
|
|
93
|
+
// Observe parent for removal
|
|
94
|
+
if (element.parentNode) {
|
|
95
|
+
observer.observe(element.parentNode, { childList: true, subtree: true });
|
|
91
96
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
|
|
249
|
-
|
|
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
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
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
|