@hypen-space/web 0.4.980 → 0.5.3
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/README.md +20 -13
- package/dist/canvas/accessibility.d.ts +118 -11
- package/dist/canvas/accessibility.js +470 -108
- package/dist/canvas/accessibility.js.map +1 -1
- package/dist/canvas/dispatch.d.ts +24 -0
- package/dist/canvas/dispatch.js +62 -0
- package/dist/canvas/dispatch.js.map +1 -0
- package/dist/canvas/editing.d.ts +178 -0
- package/dist/canvas/editing.js +590 -0
- package/dist/canvas/editing.js.map +1 -0
- package/dist/canvas/events.d.ts +28 -23
- package/dist/canvas/events.js +90 -103
- package/dist/canvas/events.js.map +1 -1
- package/dist/canvas/focus.d.ts +78 -0
- package/dist/canvas/focus.js +182 -0
- package/dist/canvas/focus.js.map +1 -0
- package/dist/canvas/index.d.ts +3 -2
- package/dist/canvas/index.js +3 -2
- package/dist/canvas/index.js.map +1 -1
- package/dist/canvas/layout.js +68 -98
- package/dist/canvas/layout.js.map +1 -1
- package/dist/canvas/paint.d.ts +16 -3
- package/dist/canvas/paint.js +449 -110
- package/dist/canvas/paint.js.map +1 -1
- package/dist/canvas/renderer.d.ts +28 -4
- package/dist/canvas/renderer.js +201 -81
- package/dist/canvas/renderer.js.map +1 -1
- package/dist/canvas/selection.js +31 -177
- package/dist/canvas/selection.js.map +1 -1
- package/dist/canvas/text-geometry.d.ts +72 -0
- package/dist/canvas/text-geometry.js +244 -0
- package/dist/canvas/text-geometry.js.map +1 -0
- package/dist/canvas/text.js +44 -18
- package/dist/canvas/text.js.map +1 -1
- package/dist/canvas/types.d.ts +10 -1
- package/dist/canvas/utils.d.ts +0 -23
- package/dist/canvas/utils.js +3 -67
- package/dist/canvas/utils.js.map +1 -1
- package/dist/canvas/variants.d.ts +52 -0
- package/dist/canvas/variants.js +156 -0
- package/dist/canvas/variants.js.map +1 -0
- package/dist/dom/a11y-styles.d.ts +20 -0
- package/dist/dom/a11y-styles.js +61 -0
- package/dist/dom/a11y-styles.js.map +1 -0
- package/dist/dom/applicators/aria.d.ts +19 -0
- package/dist/dom/applicators/aria.js +36 -0
- package/dist/dom/applicators/aria.js.map +1 -0
- package/dist/dom/applicators/events.d.ts +7 -0
- package/dist/dom/applicators/events.js +36 -8
- package/dist/dom/applicators/events.js.map +1 -1
- package/dist/dom/applicators/font.d.ts +11 -6
- package/dist/dom/applicators/font.js +16 -27
- package/dist/dom/applicators/font.js.map +1 -1
- package/dist/dom/applicators/index.js +51 -45
- package/dist/dom/applicators/index.js.map +1 -1
- package/dist/dom/canvas/index.js +2 -2
- package/dist/dom/canvas/index.js.map +1 -1
- package/dist/dom/components/app.js +2 -2
- package/dist/dom/components/app.js.map +1 -1
- package/dist/dom/components/audio.js +2 -2
- package/dist/dom/components/audio.js.map +1 -1
- package/dist/dom/components/avatar.js +3 -4
- package/dist/dom/components/avatar.js.map +1 -1
- package/dist/dom/components/badge.js +3 -4
- package/dist/dom/components/badge.js.map +1 -1
- package/dist/dom/components/button.js +2 -2
- package/dist/dom/components/button.js.map +1 -1
- package/dist/dom/components/card.js +2 -2
- package/dist/dom/components/card.js.map +1 -1
- package/dist/dom/components/center.js +2 -2
- package/dist/dom/components/center.js.map +1 -1
- package/dist/dom/components/checkbox.js +4 -5
- package/dist/dom/components/checkbox.js.map +1 -1
- package/dist/dom/components/column.js +2 -2
- package/dist/dom/components/column.js.map +1 -1
- package/dist/dom/components/container.js +2 -2
- package/dist/dom/components/container.js.map +1 -1
- package/dist/dom/components/divider.js +2 -2
- package/dist/dom/components/divider.js.map +1 -1
- package/dist/dom/components/grid.js +10 -10
- package/dist/dom/components/grid.js.map +1 -1
- package/dist/dom/components/heading.js +4 -6
- package/dist/dom/components/heading.js.map +1 -1
- package/dist/dom/components/hypenapp.d.ts +25 -1
- package/dist/dom/components/hypenapp.js +215 -247
- package/dist/dom/components/hypenapp.js.map +1 -1
- package/dist/dom/components/icon.js +4 -5
- package/dist/dom/components/icon.js.map +1 -1
- package/dist/dom/components/image.js +2 -2
- package/dist/dom/components/image.js.map +1 -1
- package/dist/dom/components/index.d.ts +2 -2
- package/dist/dom/components/index.js +9 -2
- package/dist/dom/components/index.js.map +1 -1
- package/dist/dom/components/input.js +2 -2
- package/dist/dom/components/input.js.map +1 -1
- package/dist/dom/components/link.js +2 -2
- package/dist/dom/components/link.js.map +1 -1
- package/dist/dom/components/list.js +2 -2
- package/dist/dom/components/list.js.map +1 -1
- package/dist/dom/components/paragraph.js +3 -4
- package/dist/dom/components/paragraph.js.map +1 -1
- package/dist/dom/components/progressbar.js +3 -3
- package/dist/dom/components/progressbar.js.map +1 -1
- package/dist/dom/components/route.js +2 -2
- package/dist/dom/components/route.js.map +1 -1
- package/dist/dom/components/router.js +2 -2
- package/dist/dom/components/router.js.map +1 -1
- package/dist/dom/components/row.js +10 -10
- package/dist/dom/components/row.js.map +1 -1
- package/dist/dom/components/select.js +3 -4
- package/dist/dom/components/select.js.map +1 -1
- package/dist/dom/components/slider.js +2 -2
- package/dist/dom/components/slider.js.map +1 -1
- package/dist/dom/components/spacer.js +2 -2
- package/dist/dom/components/spacer.js.map +1 -1
- package/dist/dom/components/spinner.js +27 -13
- package/dist/dom/components/spinner.js.map +1 -1
- package/dist/dom/components/stack.js +10 -10
- package/dist/dom/components/stack.js.map +1 -1
- package/dist/dom/components/switch.js +5 -6
- package/dist/dom/components/switch.js.map +1 -1
- package/dist/dom/components/tabs.d.ts +27 -0
- package/dist/dom/components/tabs.js +69 -0
- package/dist/dom/components/tabs.js.map +1 -0
- package/dist/dom/components/text.js +4 -7
- package/dist/dom/components/text.js.map +1 -1
- package/dist/dom/components/textarea.js +2 -2
- package/dist/dom/components/textarea.js.map +1 -1
- package/dist/dom/components/video.js +2 -2
- package/dist/dom/components/video.js.map +1 -1
- package/dist/dom/components/visuallyhidden.d.ts +9 -0
- package/dist/dom/components/visuallyhidden.js +26 -0
- package/dist/dom/components/visuallyhidden.js.map +1 -0
- package/dist/dom/debug.js +6 -8
- package/dist/dom/debug.js.map +1 -1
- package/dist/dom/index.d.ts +0 -1
- package/dist/dom/index.js +0 -1
- package/dist/dom/index.js.map +1 -1
- package/dist/dom/operability.d.ts +100 -0
- package/dist/dom/operability.js +298 -0
- package/dist/dom/operability.js.map +1 -0
- package/dist/dom/renderer.d.ts +98 -5
- package/dist/dom/renderer.js +400 -66
- package/dist/dom/renderer.js.map +1 -1
- package/dist/dom/route-focus.d.ts +42 -0
- package/dist/dom/route-focus.js +88 -0
- package/dist/dom/route-focus.js.map +1 -0
- package/dist/dom/semantics.d.ts +35 -0
- package/dist/dom/semantics.js +184 -0
- package/dist/dom/semantics.js.map +1 -0
- package/dist/variants.d.ts +90 -0
- package/dist/variants.js +206 -0
- package/dist/variants.js.map +1 -0
- package/package.json +2 -2
- package/src/canvas/QUICKSTART.md +16 -11
- package/src/canvas/README.md +63 -34
- package/src/canvas/accessibility.ts +507 -115
- package/src/canvas/dispatch.ts +78 -0
- package/src/canvas/editing.ts +697 -0
- package/src/canvas/events.ts +104 -115
- package/src/canvas/focus.ts +216 -0
- package/src/canvas/index.ts +8 -9
- package/src/canvas/layout.ts +68 -103
- package/src/canvas/paint.ts +509 -109
- package/src/canvas/renderer.ts +239 -99
- package/src/canvas/selection.ts +52 -210
- package/src/canvas/text-geometry.ts +311 -0
- package/src/canvas/text.ts +45 -18
- package/src/canvas/types.ts +28 -1
- package/src/canvas/utils.ts +3 -69
- package/src/canvas/variants.ts +172 -0
- package/src/dom/README.md +8 -7
- package/src/dom/a11y-styles.ts +65 -0
- package/src/dom/applicators/aria.ts +41 -0
- package/src/dom/applicators/events.ts +39 -7
- package/src/dom/applicators/font.ts +16 -29
- package/src/dom/applicators/index.ts +61 -46
- package/src/dom/canvas/index.ts +2 -2
- package/src/dom/components/app.ts +2 -2
- package/src/dom/components/audio.ts +2 -2
- package/src/dom/components/avatar.ts +3 -4
- package/src/dom/components/badge.ts +3 -4
- package/src/dom/components/button.ts +2 -2
- package/src/dom/components/card.ts +2 -2
- package/src/dom/components/center.ts +2 -2
- package/src/dom/components/checkbox.ts +4 -5
- package/src/dom/components/column.ts +2 -2
- package/src/dom/components/container.ts +2 -2
- package/src/dom/components/divider.ts +2 -2
- package/src/dom/components/grid.ts +10 -10
- package/src/dom/components/heading.ts +4 -6
- package/src/dom/components/hypenapp.ts +246 -274
- package/src/dom/components/icon.ts +4 -5
- package/src/dom/components/image.ts +2 -2
- package/src/dom/components/index.ts +10 -3
- package/src/dom/components/input.ts +2 -2
- package/src/dom/components/link.ts +2 -2
- package/src/dom/components/list.ts +2 -2
- package/src/dom/components/paragraph.ts +3 -4
- package/src/dom/components/progressbar.ts +3 -3
- package/src/dom/components/route.ts +2 -2
- package/src/dom/components/router.ts +2 -2
- package/src/dom/components/row.ts +10 -10
- package/src/dom/components/select.ts +3 -4
- package/src/dom/components/slider.ts +2 -2
- package/src/dom/components/spacer.ts +2 -2
- package/src/dom/components/spinner.ts +34 -16
- package/src/dom/components/stack.ts +10 -10
- package/src/dom/components/switch.ts +5 -6
- package/src/dom/components/tabs.ts +76 -0
- package/src/dom/components/text.ts +4 -7
- package/src/dom/components/textarea.ts +2 -2
- package/src/dom/components/video.ts +2 -2
- package/src/dom/components/visuallyhidden.ts +30 -0
- package/src/dom/debug.ts +6 -8
- package/src/dom/index.ts +0 -8
- package/src/dom/operability.ts +312 -0
- package/src/dom/renderer.ts +457 -66
- package/src/dom/route-focus.ts +98 -0
- package/src/dom/semantics.ts +199 -0
- package/src/variants.ts +249 -0
- package/dist/canvas/input.d.ts +0 -76
- package/dist/canvas/input.js +0 -207
- package/dist/canvas/input.js.map +0 -1
- package/dist/client.d.ts +0 -36
- package/dist/client.js +0 -47
- package/dist/client.js.map +0 -1
- package/src/canvas/input.ts +0 -251
- package/src/client.ts +0 -88
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HypenApp Component
|
|
3
3
|
*
|
|
4
|
-
* Embeds a remote Hypen app via WebSocket
|
|
4
|
+
* Embeds a remote Hypen app via WebSocket.
|
|
5
5
|
*
|
|
6
6
|
* Usage in Hypen DSL:
|
|
7
7
|
* ```hypen
|
|
@@ -9,16 +9,159 @@
|
|
|
9
9
|
*
|
|
10
10
|
* // Or with named prop:
|
|
11
11
|
* HypenApp(url: "ws://localhost:3000")
|
|
12
|
+
*
|
|
13
|
+
* // With custom loading / error UI via slot children:
|
|
14
|
+
* HypenApp("ws://localhost:3000") {
|
|
15
|
+
* Column { Spinner() Text("Connecting to app...") }.slot("loading")
|
|
16
|
+
* Column { Text("Couldn't reach the app") }.slot("error")
|
|
17
|
+
* }
|
|
12
18
|
* ```
|
|
19
|
+
*
|
|
20
|
+
* Slot children are rendered by the *host* app (they're ordinary host
|
|
21
|
+
* nodes with full access to host state and actions); the handler only
|
|
22
|
+
* toggles their visibility as the connection moves through
|
|
23
|
+
* loading → connected / error. Children without a recognized slot render
|
|
24
|
+
* unconditionally. When a slot isn't provided, a built-in fallback is
|
|
25
|
+
* used ("Connecting..." text / red error message).
|
|
26
|
+
*
|
|
27
|
+
* The embedded app is rendered by a full `DOMRenderer` driven by its own
|
|
28
|
+
* `RemoteEngine` — the exact pairing the generic client uses at top level —
|
|
29
|
+
* so embedded apps get identical styling, event dispatch, router patch
|
|
30
|
+
* handling, and a11y behavior to a standalone page. (Route-change focus is
|
|
31
|
+
* disabled: the *host* app owns focus management; an embedded frame stealing
|
|
32
|
+
* focus on its internal navigations would fight it.) It renders into a
|
|
33
|
+
* dedicated content wrapper so slot toggling and error handling never
|
|
34
|
+
* touch host-owned slot children, and vice versa.
|
|
13
35
|
*/
|
|
14
36
|
import { RemoteEngine } from "@hypen-space/core/remote/client";
|
|
37
|
+
import { getElementDisposables } from "@hypen-space/core/disposable";
|
|
15
38
|
import { frameworkLoggers } from "@hypen-space/core/logger";
|
|
16
39
|
const log = frameworkLoggers.remote;
|
|
40
|
+
export const LOADING_SLOT = "loading";
|
|
41
|
+
export const ERROR_SLOT = "error";
|
|
17
42
|
// Store active HypenApp instances for cleanup
|
|
18
43
|
const activeInstances = new WeakMap();
|
|
44
|
+
/** Direct children of the container tagged with `.slot(name)`. */
|
|
45
|
+
function slotChildren(element, name) {
|
|
46
|
+
const out = [];
|
|
47
|
+
for (const child of Array.from(element.children)) {
|
|
48
|
+
if (child.dataset?.hypenSlot === name) {
|
|
49
|
+
out.push(child);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Hide/show an element while preserving its inline display value —
|
|
56
|
+
* applicators set `display: flex` etc. inline, so a plain `display = ""`
|
|
57
|
+
* on re-show would lose the element's layout.
|
|
58
|
+
*/
|
|
59
|
+
function setVisible(el, visible) {
|
|
60
|
+
const hidden = el.dataset.hypenSlotHidden === "true";
|
|
61
|
+
if (visible && hidden) {
|
|
62
|
+
el.style.display = el.dataset.hypenPrevDisplay ?? "";
|
|
63
|
+
delete el.dataset.hypenPrevDisplay;
|
|
64
|
+
delete el.dataset.hypenSlotHidden;
|
|
65
|
+
}
|
|
66
|
+
else if (!visible && !hidden) {
|
|
67
|
+
el.dataset.hypenPrevDisplay = el.style.display;
|
|
68
|
+
el.dataset.hypenSlotHidden = "true";
|
|
69
|
+
el.style.display = "none";
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Connection-state → visibility controller for one HypenApp container.
|
|
74
|
+
*
|
|
75
|
+
* Slot children arrive via Insert patches *after* the container's Create
|
|
76
|
+
* (and can arrive/leave any time under ForEach/When), so visibility is
|
|
77
|
+
* re-applied from a MutationObserver rather than computed once.
|
|
78
|
+
*/
|
|
79
|
+
class SlotVisibilityController {
|
|
80
|
+
element;
|
|
81
|
+
contentHost;
|
|
82
|
+
status = "loading";
|
|
83
|
+
errorMessage = "";
|
|
84
|
+
defaultLoading = null;
|
|
85
|
+
defaultError = null;
|
|
86
|
+
observer = null;
|
|
87
|
+
constructor(element, contentHost) {
|
|
88
|
+
this.element = element;
|
|
89
|
+
this.contentHost = contentHost;
|
|
90
|
+
// Slot children arrive via Insert patches *after* this controller is
|
|
91
|
+
// constructed, so re-apply visibility whenever the container's child
|
|
92
|
+
// list changes (falls back to status-change-only updates where
|
|
93
|
+
// MutationObserver is unavailable, e.g. non-DOM test envs).
|
|
94
|
+
if (typeof MutationObserver !== "undefined") {
|
|
95
|
+
this.observer = new MutationObserver(() => this.update());
|
|
96
|
+
this.observer.observe(element, { childList: true });
|
|
97
|
+
}
|
|
98
|
+
this.update();
|
|
99
|
+
}
|
|
100
|
+
setStatus(status, errorMessage) {
|
|
101
|
+
this.status = status;
|
|
102
|
+
if (errorMessage !== undefined)
|
|
103
|
+
this.errorMessage = errorMessage;
|
|
104
|
+
this.element.dataset.hypenAppStatus = status;
|
|
105
|
+
this.update();
|
|
106
|
+
}
|
|
107
|
+
update() {
|
|
108
|
+
const showLoading = this.status === "loading";
|
|
109
|
+
const showError = this.status === "error";
|
|
110
|
+
const loadingSlots = slotChildren(this.element, LOADING_SLOT);
|
|
111
|
+
const errorSlots = slotChildren(this.element, ERROR_SLOT);
|
|
112
|
+
for (const el of loadingSlots)
|
|
113
|
+
setVisible(el, showLoading);
|
|
114
|
+
for (const el of errorSlots)
|
|
115
|
+
setVisible(el, showError);
|
|
116
|
+
// Built-in fallbacks only cover states the host didn't style.
|
|
117
|
+
this.toggleDefaultLoading(showLoading && loadingSlots.length === 0);
|
|
118
|
+
this.toggleDefaultError(showError && errorSlots.length === 0);
|
|
119
|
+
// A failed connection may leave a partial embedded tree behind;
|
|
120
|
+
// don't show it alongside the error UI.
|
|
121
|
+
setVisible(this.contentHost, !showError);
|
|
122
|
+
}
|
|
123
|
+
toggleDefaultLoading(show) {
|
|
124
|
+
if (show && !this.defaultLoading) {
|
|
125
|
+
const el = document.createElement("div");
|
|
126
|
+
el.className = "hypen-app-loading";
|
|
127
|
+
el.textContent = "Connecting...";
|
|
128
|
+
this.defaultLoading = el;
|
|
129
|
+
this.element.appendChild(el);
|
|
130
|
+
}
|
|
131
|
+
else if (!show && this.defaultLoading) {
|
|
132
|
+
this.defaultLoading.remove();
|
|
133
|
+
this.defaultLoading = null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
toggleDefaultError(show) {
|
|
137
|
+
if (show && !this.defaultError) {
|
|
138
|
+
const el = document.createElement("div");
|
|
139
|
+
el.className = "hypen-app-error";
|
|
140
|
+
el.style.color = "red";
|
|
141
|
+
this.defaultError = el;
|
|
142
|
+
this.element.appendChild(el);
|
|
143
|
+
}
|
|
144
|
+
if (this.defaultError) {
|
|
145
|
+
if (show) {
|
|
146
|
+
this.defaultError.textContent = this.errorMessage || "HypenApp: Connection failed";
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
this.defaultError.remove();
|
|
150
|
+
this.defaultError = null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
dispose() {
|
|
155
|
+
this.observer?.disconnect();
|
|
156
|
+
this.defaultLoading?.remove();
|
|
157
|
+
this.defaultError?.remove();
|
|
158
|
+
this.defaultLoading = null;
|
|
159
|
+
this.defaultError = null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
19
162
|
export const hypenAppHandler = {
|
|
20
|
-
create(
|
|
21
|
-
const el =
|
|
163
|
+
create() {
|
|
164
|
+
const el = document.createElement("div");
|
|
22
165
|
el.dataset.hypenType = "hypenapp";
|
|
23
166
|
el.style.display = "contents"; // Don't affect layout
|
|
24
167
|
return el;
|
|
@@ -26,283 +169,108 @@ export const hypenAppHandler = {
|
|
|
26
169
|
applyProps(element, props) {
|
|
27
170
|
// Get URL from props (can be positional "0" or named "url")
|
|
28
171
|
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;
|
|
33
|
-
}
|
|
34
|
-
// Check if already connected
|
|
35
172
|
const existing = activeInstances.get(element);
|
|
36
173
|
if (existing) {
|
|
37
|
-
|
|
174
|
+
if (existing.url === url)
|
|
175
|
+
return; // Already connected to this app
|
|
176
|
+
// URL changed (or became invalid) — tear down and reconnect below.
|
|
177
|
+
existing.dispose();
|
|
178
|
+
activeInstances.delete(element);
|
|
179
|
+
}
|
|
180
|
+
// The nested renderer owns this wrapper; host-owned slot children are
|
|
181
|
+
// siblings of it, so neither side's cleanup can clobber the other.
|
|
182
|
+
const contentHost = document.createElement("div");
|
|
183
|
+
contentHost.className = "hypen-app-content";
|
|
184
|
+
contentHost.style.display = "contents";
|
|
185
|
+
element.appendChild(contentHost);
|
|
186
|
+
const visibility = new SlotVisibilityController(element, contentHost);
|
|
187
|
+
if (!url || typeof url !== "string") {
|
|
188
|
+
log.error("HypenApp: URL is required");
|
|
189
|
+
visibility.setStatus("error", "HypenApp: URL required");
|
|
190
|
+
activeInstances.set(element, {
|
|
191
|
+
engine: null,
|
|
192
|
+
renderer: null,
|
|
193
|
+
url: null,
|
|
194
|
+
dispose() {
|
|
195
|
+
visibility.dispose();
|
|
196
|
+
contentHost.remove();
|
|
197
|
+
},
|
|
198
|
+
});
|
|
38
199
|
return;
|
|
39
200
|
}
|
|
40
|
-
//
|
|
201
|
+
// Lazy-required to break the static cycle:
|
|
202
|
+
// renderer.ts → components/index.ts → hypenapp.ts → renderer.ts
|
|
203
|
+
const { DOMRenderer: Renderer } = require("../renderer.js");
|
|
41
204
|
const engine = new RemoteEngine(url, {
|
|
42
205
|
autoReconnect: props.autoReconnect ?? true,
|
|
43
206
|
reconnectInterval: props.reconnectInterval ?? 3000,
|
|
44
207
|
maxReconnectAttempts: props.maxReconnectAttempts ?? 10,
|
|
45
208
|
});
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
209
|
+
const renderer = new Renderer(contentHost, engine, undefined, { routeFocus: "off" });
|
|
210
|
+
const instance = {
|
|
211
|
+
engine,
|
|
212
|
+
renderer,
|
|
213
|
+
url,
|
|
214
|
+
dispose() {
|
|
215
|
+
engine.disconnect();
|
|
216
|
+
visibility.dispose();
|
|
217
|
+
contentHost.remove();
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
activeInstances.set(element, instance);
|
|
221
|
+
// Same replacement-root handling as the generic client: a fresh root
|
|
222
|
+
// insert after we've already rendered one means "replace the tree".
|
|
223
|
+
let hasRenderedRoot = false;
|
|
52
224
|
engine.onPatches((patches) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
225
|
+
visibility.setStatus("connected");
|
|
226
|
+
const createdIds = new Set(patches.filter((patch) => patch.type === "create").map((patch) => patch.id));
|
|
227
|
+
const hasReplacementRoot = patches.some((patch) => patch.type === "insert" &&
|
|
228
|
+
patch.parentId === "root" &&
|
|
229
|
+
createdIds.has(patch.id));
|
|
230
|
+
if (hasReplacementRoot && hasRenderedRoot) {
|
|
231
|
+
renderer.clear();
|
|
232
|
+
}
|
|
233
|
+
renderer.applyPatches(patches);
|
|
234
|
+
hasRenderedRoot = hasRenderedRoot || hasReplacementRoot;
|
|
57
235
|
});
|
|
58
|
-
// Show loading state
|
|
59
|
-
element.innerHTML = '<div class="hypen-app-loading">Connecting...</div>';
|
|
60
|
-
// Connect
|
|
61
236
|
engine
|
|
62
237
|
.connect()
|
|
63
|
-
.then(() => {
|
|
64
|
-
|
|
65
|
-
|
|
238
|
+
.then((result) => {
|
|
239
|
+
if (result && result.ok === false) {
|
|
240
|
+
visibility.setStatus("error", `HypenApp: Connection failed - ${result.error?.message ?? result.error}`);
|
|
241
|
+
log.error("HypenApp connection failed:", result.error);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
66
244
|
log.debug(`HypenApp connected to ${url}`);
|
|
67
245
|
})
|
|
68
246
|
.catch((error) => {
|
|
69
|
-
|
|
247
|
+
visibility.setStatus("error", `HypenApp: Connection failed - ${error.message}`);
|
|
70
248
|
log.error("HypenApp connection failed:", error);
|
|
71
249
|
});
|
|
72
|
-
// Handle disconnection
|
|
73
250
|
engine.onDisconnect(() => {
|
|
74
251
|
log.debug("HypenApp disconnected");
|
|
75
252
|
});
|
|
76
253
|
engine.onError((error) => {
|
|
77
254
|
log.error("HypenApp error:", error);
|
|
78
255
|
});
|
|
79
|
-
// Cleanup
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
log.debug("HypenApp cleaned up");
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
256
|
+
// Cleanup rides the renderer's element-disposal channel: the host
|
|
257
|
+
// DOMRenderer runs this on a real `remove` patch (and on `clear()`),
|
|
258
|
+
// but NOT on a Router `detach` — so a cached route keeps its live
|
|
259
|
+
// connection and re-attaches warm, while LRU eviction closes it.
|
|
260
|
+
getElementDisposables(element).addCallback(() => {
|
|
261
|
+
instance.dispose();
|
|
262
|
+
activeInstances.delete(element);
|
|
263
|
+
log.debug("HypenApp cleaned up");
|
|
92
264
|
});
|
|
93
|
-
// Observe parent for removal
|
|
94
|
-
if (element.parentNode) {
|
|
95
|
-
observer.observe(element.parentNode, { childList: true, subtree: true });
|
|
96
|
-
}
|
|
97
265
|
},
|
|
98
266
|
};
|
|
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;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Create element by type
|
|
181
|
-
*/
|
|
182
|
-
function createElement(type, props) {
|
|
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";
|
|
240
|
-
}
|
|
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;
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Apply a prop to an element
|
|
251
|
-
*/
|
|
252
|
-
function applyProp(el, name, value) {
|
|
253
|
-
// Text content
|
|
254
|
-
if (name === "0" || name === "text") {
|
|
255
|
-
el.textContent = String(value);
|
|
256
|
-
return;
|
|
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;
|
|
283
|
-
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);
|
|
292
|
-
}
|
|
293
|
-
};
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
// Other attributes
|
|
297
|
-
el.setAttribute(name, String(value));
|
|
298
|
-
}
|
|
299
267
|
/**
|
|
300
268
|
* Disconnect a HypenApp instance
|
|
301
269
|
*/
|
|
302
270
|
export function disconnectHypenApp(element) {
|
|
303
271
|
const instance = activeInstances.get(element);
|
|
304
272
|
if (instance) {
|
|
305
|
-
instance.engine
|
|
273
|
+
instance.engine?.disconnect();
|
|
306
274
|
activeInstances.delete(element);
|
|
307
275
|
}
|
|
308
276
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hypenapp.js","sourceRoot":"","sources":["../../../src/dom/components/hypenapp.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hypenapp.js","sourceRoot":"","sources":["../../../src/dom/components/hypenapp.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
9
9
|
export const iconHandler = {
|
|
10
|
-
create(
|
|
11
|
-
const el =
|
|
10
|
+
create() {
|
|
11
|
+
const el = document.createElement("span");
|
|
12
12
|
el.style.display = "inline-flex";
|
|
13
13
|
el.style.alignItems = "center";
|
|
14
14
|
el.style.justifyContent = "center";
|
|
@@ -17,7 +17,6 @@ export const iconHandler = {
|
|
|
17
17
|
return el;
|
|
18
18
|
},
|
|
19
19
|
applyProps(el, props) {
|
|
20
|
-
const doc = el.ownerDocument;
|
|
21
20
|
// Server-resolved icon data (from engine's ResourceRegistry)
|
|
22
21
|
const paths = props.__iconPaths;
|
|
23
22
|
const viewBox = props.__iconViewBox || "0 0 24 24";
|
|
@@ -26,7 +25,7 @@ export const iconHandler = {
|
|
|
26
25
|
const color = props.color || props["color.0"] || "currentColor";
|
|
27
26
|
if (paths && Array.isArray(paths)) {
|
|
28
27
|
// Render from pre-resolved SVG path data
|
|
29
|
-
const svg =
|
|
28
|
+
const svg = document.createElementNS(SVG_NS, "svg");
|
|
30
29
|
svg.setAttribute("xmlns", SVG_NS);
|
|
31
30
|
svg.setAttribute("width", String(size));
|
|
32
31
|
svg.setAttribute("height", String(size));
|
|
@@ -34,7 +33,7 @@ export const iconHandler = {
|
|
|
34
33
|
svg.setAttribute("fill", "none");
|
|
35
34
|
svg.style.display = "block";
|
|
36
35
|
for (const pathData of paths) {
|
|
37
|
-
const path =
|
|
36
|
+
const path = document.createElementNS(SVG_NS, "path");
|
|
38
37
|
path.setAttribute("d", pathData.d);
|
|
39
38
|
path.setAttribute("fill", pathData.fill || "none");
|
|
40
39
|
path.setAttribute("stroke", (pathData.stroke || "currentColor") === "currentColor"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.js","sourceRoot":"","sources":["../../../src/dom/components/icon.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,MAAM,GAAG,4BAA4B,CAAC;AAE5C,MAAM,CAAC,MAAM,WAAW,GAAqB;IAC3C,MAAM
|
|
1
|
+
{"version":3,"file":"icon.js","sourceRoot":"","sources":["../../../src/dom/components/icon.ts"],"names":[],"mappings":"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"}
|