@fynixorg/ui 1.0.11 → 1.0.12
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/LICENSE +21 -0
- package/dist/README.md +36 -0
- package/dist/context/context.d.ts +19 -0
- package/dist/context/context.d.ts.map +1 -0
- package/dist/context/context.js +3 -11
- package/dist/context/context.js.map +3 -3
- package/dist/custom/button.d.ts +2 -0
- package/dist/custom/button.d.ts.map +1 -0
- package/dist/custom/button.js +2 -9
- package/dist/custom/button.js.map +3 -3
- package/dist/custom/index.d.ts +3 -0
- package/dist/custom/index.d.ts.map +1 -0
- package/dist/custom/index.js +2 -7
- package/dist/custom/index.js.map +3 -3
- package/dist/custom/path.d.ts +14 -0
- package/dist/custom/path.d.ts.map +1 -0
- package/dist/custom/path.js +17 -34
- package/dist/custom/path.js.map +3 -3
- package/dist/error/errorOverlay.d.ts +3 -0
- package/dist/error/errorOverlay.d.ts.map +1 -0
- package/dist/error/errorOverlay.js +82 -91
- package/dist/error/errorOverlay.js.map +3 -3
- package/dist/fynix/index.d.ts +5 -0
- package/dist/fynix/index.d.ts.map +1 -0
- package/dist/fynix/index.js +2 -7
- package/dist/fynix/index.js.map +3 -3
- package/dist/hooks/nixAsync.d.ts +14 -0
- package/dist/hooks/nixAsync.d.ts.map +1 -0
- package/dist/hooks/nixAsync.js +38 -43
- package/dist/hooks/nixAsync.js.map +3 -3
- package/dist/hooks/nixAsyncCache.d.ts +14 -0
- package/dist/hooks/nixAsyncCache.d.ts.map +1 -0
- package/dist/hooks/nixAsyncCache.js +57 -59
- package/dist/hooks/nixAsyncCache.js.map +3 -3
- package/dist/hooks/nixAsyncDebounce.d.ts +22 -0
- package/dist/hooks/nixAsyncDebounce.d.ts.map +1 -0
- package/dist/hooks/nixAsyncDebounce.js +74 -85
- package/dist/hooks/nixAsyncDebounce.js.map +3 -3
- package/dist/hooks/nixAsyncQuery.d.ts +16 -0
- package/dist/hooks/nixAsyncQuery.d.ts.map +1 -0
- package/dist/hooks/nixAsyncQuery.js +85 -79
- package/dist/hooks/nixAsyncQuery.js.map +3 -3
- package/dist/hooks/nixCallback.d.ts +2 -0
- package/dist/hooks/nixCallback.d.ts.map +1 -0
- package/dist/hooks/nixCallback.js +30 -40
- package/dist/hooks/nixCallback.js.map +3 -3
- package/dist/hooks/nixComputed.d.ts +16 -0
- package/dist/hooks/nixComputed.d.ts.map +1 -0
- package/dist/hooks/nixComputed.js +166 -198
- package/dist/hooks/nixComputed.js.map +4 -4
- package/dist/hooks/nixDebounce.d.ts +11 -0
- package/dist/hooks/nixDebounce.d.ts.map +1 -0
- package/dist/hooks/nixDebounce.js +53 -58
- package/dist/hooks/nixDebounce.js.map +3 -3
- package/dist/hooks/nixEffect.d.ts +4 -0
- package/dist/hooks/nixEffect.d.ts.map +1 -0
- package/dist/hooks/nixEffect.js +65 -75
- package/dist/hooks/nixEffect.js.map +3 -3
- package/dist/hooks/nixForm.d.ts +33 -0
- package/dist/hooks/nixForm.d.ts.map +1 -0
- package/dist/hooks/nixForm.js +110 -120
- package/dist/hooks/nixForm.js.map +3 -3
- package/dist/hooks/nixFormAsync.d.ts +42 -0
- package/dist/hooks/nixFormAsync.d.ts.map +1 -0
- package/dist/hooks/nixFormAsync.js +158 -167
- package/dist/hooks/nixFormAsync.js.map +3 -3
- package/dist/hooks/nixInterval.d.ts +2 -0
- package/dist/hooks/nixInterval.d.ts.map +1 -0
- package/dist/hooks/nixInterval.js +21 -27
- package/dist/hooks/nixInterval.js.map +3 -3
- package/dist/hooks/nixLazy.d.ts +8 -0
- package/dist/hooks/nixLazy.d.ts.map +1 -0
- package/dist/hooks/nixLazy.js +53 -58
- package/dist/hooks/nixLazy.js.map +3 -3
- package/dist/hooks/nixLazyAsync.d.ts +10 -0
- package/dist/hooks/nixLazyAsync.d.ts.map +1 -0
- package/dist/hooks/nixLazyAsync.js +65 -71
- package/dist/hooks/nixLazyAsync.js.map +3 -3
- package/dist/hooks/nixLazyFormAsync.d.ts +50 -0
- package/dist/hooks/nixLazyFormAsync.d.ts.map +1 -0
- package/dist/hooks/nixLazyFormAsync.js +209 -213
- package/dist/hooks/nixLazyFormAsync.js.map +3 -3
- package/dist/hooks/nixLocalStorage.d.ts +5 -0
- package/dist/hooks/nixLocalStorage.d.ts.map +1 -0
- package/dist/hooks/nixLocalStorage.js +21 -25
- package/dist/hooks/nixLocalStorage.js.map +3 -3
- package/dist/hooks/nixMemo.d.ts +2 -0
- package/dist/hooks/nixMemo.d.ts.map +1 -0
- package/dist/hooks/nixMemo.js +27 -31
- package/dist/hooks/nixMemo.js.map +3 -3
- package/dist/hooks/nixPrevious.d.ts +2 -0
- package/dist/hooks/nixPrevious.d.ts.map +1 -0
- package/dist/hooks/nixPrevious.js +13 -19
- package/dist/hooks/nixPrevious.js.map +3 -3
- package/dist/hooks/nixRef.d.ts +4 -0
- package/dist/hooks/nixRef.d.ts.map +1 -0
- package/dist/hooks/nixRef.js +14 -20
- package/dist/hooks/nixRef.js.map +3 -3
- package/dist/hooks/nixState.d.ts +15 -0
- package/dist/hooks/nixState.d.ts.map +1 -0
- package/dist/hooks/nixState.js +120 -173
- package/dist/hooks/nixState.js.map +3 -3
- package/dist/hooks/nixStore.d.ts +7 -0
- package/dist/hooks/nixStore.d.ts.map +1 -0
- package/dist/hooks/nixStore.js +48 -54
- package/dist/hooks/nixStore.js.map +3 -3
- package/dist/package.json +213 -0
- package/dist/plugins/vite-plugin-res.d.ts +41 -0
- package/dist/plugins/vite-plugin-res.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-res.js +620 -36
- package/dist/plugins/vite-plugin-res.js.map +4 -4
- package/dist/router/router.d.ts +35 -0
- package/dist/router/router.d.ts.map +1 -0
- package/dist/router/router.js +520 -486
- package/dist/router/router.js.map +3 -3
- package/dist/runtime.d.ts +62 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +833 -820
- package/dist/runtime.js.map +4 -4
- package/package.json +227 -44
- package/types/fnx.d.ts +72 -0
- package/types/fynix-ui.d.ts +323 -0
- package/types/global.d.ts +46 -6
- package/types/index.d.ts +37 -0
- package/types/vite-env.d.ts +553 -0
- package/runtime.d.ts +0 -83
- package/types/jsx.d.ts +0 -692
package/dist/runtime.js
CHANGED
|
@@ -1,869 +1,882 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { activeContext, setActiveContext } from "./context/context";
|
|
2
|
+
import { Button, Path } from "./custom/index";
|
|
3
3
|
import { removeErrorOverlay, showErrorOverlay } from "./error/errorOverlay";
|
|
4
|
-
import { setActiveContext, activeContext } from "./context/context.js";
|
|
5
|
-
import { nixStore } from "./hooks/nixStore";
|
|
6
|
-
import { nixState } from "./hooks/nixState";
|
|
7
|
-
import { nixEffect } from "./hooks/nixEffect";
|
|
8
4
|
import { nixAsync } from "./hooks/nixAsync";
|
|
9
|
-
import { nixMemo } from "./hooks/nixMemo";
|
|
10
|
-
import { nixCallback } from "./hooks/nixCallback";
|
|
11
|
-
import { nixComputed } from "./hooks/nixComputed";
|
|
12
|
-
import { nixDebounce } from "./hooks/nixDebounce";
|
|
13
|
-
import { nixInterval } from "./hooks/nixInterval";
|
|
14
|
-
import { nixRef } from "./hooks/nixRef";
|
|
15
|
-
import { nixLocalStorage } from "./hooks/nixLocalStorage";
|
|
16
|
-
import { nixPrevious } from "./hooks/nixPrevious";
|
|
17
|
-
import { nixLazy, Suspense } from "./hooks/nixLazy.js";
|
|
18
|
-
import { nixForm } from "./hooks/nixForm.js";
|
|
19
|
-
import { Path, Button } from "./custom/index.js";
|
|
20
5
|
import { nixAsyncCached } from "./hooks/nixAsyncCache";
|
|
21
6
|
import { nixAsyncDebounce } from "./hooks/nixAsyncDebounce";
|
|
22
7
|
import { nixAsyncQuery } from "./hooks/nixAsyncQuery";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
8
|
+
import { nixCallback } from "./hooks/nixCallback";
|
|
9
|
+
import { nixComputed } from "./hooks/nixComputed";
|
|
10
|
+
import { nixDebounce } from "./hooks/nixDebounce";
|
|
11
|
+
import { nixEffect, nixEffectAlways, nixEffectOnce } from "./hooks/nixEffect";
|
|
12
|
+
import { nixForm } from "./hooks/nixForm";
|
|
25
13
|
import { nixFormAsync } from "./hooks/nixFormAsync";
|
|
14
|
+
import { nixInterval } from "./hooks/nixInterval";
|
|
15
|
+
import { nixLazy, Suspense } from "./hooks/nixLazy";
|
|
26
16
|
import { nixLazyAsync } from "./hooks/nixLazyAsync";
|
|
27
17
|
import { nixLazyFormAsync } from "./hooks/nixLazyFormAsync";
|
|
28
|
-
import
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
18
|
+
import { nixLocalStorage } from "./hooks/nixLocalStorage";
|
|
19
|
+
import { nixMemo } from "./hooks/nixMemo";
|
|
20
|
+
import { nixPrevious } from "./hooks/nixPrevious";
|
|
21
|
+
import { nixRef } from "./hooks/nixRef";
|
|
22
|
+
import { nixState } from "./hooks/nixState";
|
|
23
|
+
import { nixStore } from "./hooks/nixStore";
|
|
24
|
+
import createFynix from "./router/router";
|
|
25
|
+
export const TEXT = Symbol("text");
|
|
26
|
+
export const Fragment = Symbol("Fragment");
|
|
27
|
+
const BOOLEAN_ATTRS = new Set([
|
|
28
|
+
"checked",
|
|
29
|
+
"selected",
|
|
30
|
+
"disabled",
|
|
31
|
+
"readonly",
|
|
32
|
+
"multiple",
|
|
33
|
+
"autoplay",
|
|
34
|
+
"controls",
|
|
35
|
+
"loop",
|
|
36
|
+
"muted",
|
|
37
|
+
"open",
|
|
38
|
+
"required",
|
|
39
|
+
"reversed",
|
|
40
|
+
"scoped",
|
|
41
|
+
"seamless",
|
|
42
|
+
"autofocus",
|
|
43
|
+
"novalidate",
|
|
44
|
+
"formnovalidate",
|
|
49
45
|
]);
|
|
50
|
-
const DOM_PROPERTIES =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
const DOM_PROPERTIES = new Set([
|
|
47
|
+
"value",
|
|
48
|
+
"checked",
|
|
49
|
+
"selected",
|
|
50
|
+
"selectedIndex",
|
|
51
|
+
"innerHTML",
|
|
52
|
+
"textContent",
|
|
53
|
+
"innerText",
|
|
58
54
|
]);
|
|
59
|
-
function createTextVNode(text) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
55
|
+
export function createTextVNode(text) {
|
|
56
|
+
if (text == null || text === false) {
|
|
57
|
+
return { type: TEXT, props: { nodeValue: "" }, key: null };
|
|
58
|
+
}
|
|
59
|
+
if (text && typeof text === "object" && text._isNixState) {
|
|
60
|
+
const vnode = {
|
|
61
|
+
type: TEXT,
|
|
62
|
+
props: { nodeValue: String(text.value) },
|
|
63
|
+
key: null,
|
|
64
|
+
_state: text,
|
|
65
|
+
_cleanup: null,
|
|
66
|
+
};
|
|
67
|
+
vnode._cleanup = text.subscribe(() => {
|
|
68
|
+
if (vnode._domNode) {
|
|
69
|
+
vnode._domNode.nodeValue = String(text.value);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return vnode;
|
|
73
|
+
}
|
|
74
|
+
return { type: TEXT, props: { nodeValue: String(text) }, key: null };
|
|
78
75
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
76
|
+
export function h(type, props = null, ...children) {
|
|
77
|
+
const normalizedProps = props === null || typeof props !== "object" || Array.isArray(props)
|
|
78
|
+
? {}
|
|
79
|
+
: props;
|
|
80
|
+
const flatChildren = [];
|
|
81
|
+
for (const c of children.flat(Infinity)) {
|
|
82
|
+
if (c == null || c === false)
|
|
83
|
+
continue;
|
|
84
|
+
if (c && typeof c === "object" && "_isNixState" in c) {
|
|
85
|
+
flatChildren.push(createTextVNode(c));
|
|
86
|
+
}
|
|
87
|
+
else if (typeof c === "string" || typeof c === "number") {
|
|
88
|
+
flatChildren.push(createTextVNode(c));
|
|
89
|
+
}
|
|
90
|
+
else if (c && typeof c === "object" && "type" in c) {
|
|
91
|
+
if (c.type === Fragment) {
|
|
92
|
+
const fragmentChildren = (c.props.children || []).filter((x) => x != null && x !== false);
|
|
93
|
+
flatChildren.push(...fragmentChildren);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
flatChildren.push(c);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
flatChildren.push(createTextVNode(String(c)));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const key = normalizedProps.key ?? null;
|
|
104
|
+
if (key !== undefined)
|
|
105
|
+
delete normalizedProps.key;
|
|
106
|
+
if (type === Fragment) {
|
|
107
|
+
return { type: Fragment, props: { children: flatChildren }, key };
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
type,
|
|
111
|
+
props: { ...normalizedProps, children: flatChildren },
|
|
112
|
+
key,
|
|
113
|
+
};
|
|
106
114
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const Fynix = h;
|
|
115
|
+
h.Fragment = ({ children }) => children || [];
|
|
116
|
+
export const Fynix = h;
|
|
110
117
|
Fynix.Fragment = h.Fragment;
|
|
111
|
-
const componentInstances =
|
|
118
|
+
const componentInstances = new WeakMap();
|
|
112
119
|
let rootRenderFn = null;
|
|
113
|
-
const pendingRerenders =
|
|
120
|
+
const pendingRerenders = new WeakSet();
|
|
114
121
|
function beginComponent(vnode) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return ctx;
|
|
122
|
+
let ctx = componentInstances.get(vnode);
|
|
123
|
+
if (!ctx) {
|
|
124
|
+
ctx = {
|
|
125
|
+
hooks: [],
|
|
126
|
+
hookIndex: 0,
|
|
127
|
+
effects: [],
|
|
128
|
+
cleanups: [],
|
|
129
|
+
_vnode: vnode,
|
|
130
|
+
_accessedStates: new Set(),
|
|
131
|
+
_subscriptions: new Set(),
|
|
132
|
+
_subscriptionCleanups: [],
|
|
133
|
+
version: 0,
|
|
134
|
+
rerender: null,
|
|
135
|
+
Component: vnode.type,
|
|
136
|
+
_isMounted: false,
|
|
137
|
+
_isRerendering: false,
|
|
138
|
+
};
|
|
139
|
+
componentInstances.set(vnode, ctx);
|
|
140
|
+
}
|
|
141
|
+
ctx.hookIndex = 0;
|
|
142
|
+
ctx._accessedStates.clear();
|
|
143
|
+
setActiveContext(ctx);
|
|
144
|
+
ctx.version++;
|
|
145
|
+
return ctx;
|
|
140
146
|
}
|
|
141
|
-
__name(beginComponent, "beginComponent");
|
|
142
147
|
function endComponent() {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return;
|
|
146
|
-
ctx._accessedStates.forEach((state) => {
|
|
147
|
-
if (!ctx._subscriptions.has(state)) {
|
|
148
|
-
if (!ctx.rerender) {
|
|
149
|
-
let rerenderTimeout = null;
|
|
150
|
-
ctx.rerender = /* @__PURE__ */ __name(function rerender() {
|
|
151
|
-
if (ctx._isRerendering || pendingRerenders.has(ctx)) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
if (rerenderTimeout) {
|
|
155
|
-
clearTimeout(rerenderTimeout);
|
|
156
|
-
}
|
|
157
|
-
rerenderTimeout = setTimeout(() => {
|
|
158
|
-
if (ctx._isRerendering || !ctx._isMounted)
|
|
159
|
-
return;
|
|
160
|
-
ctx._isRerendering = true;
|
|
161
|
-
pendingRerenders.add(ctx);
|
|
162
|
-
try {
|
|
163
|
-
removeErrorOverlay();
|
|
164
|
-
const vnode = ctx._vnode;
|
|
165
|
-
const oldRendered = vnode._rendered;
|
|
166
|
-
beginComponent(vnode);
|
|
167
|
-
const newRendered = ctx.Component(vnode.props);
|
|
168
|
-
endComponent();
|
|
169
|
-
vnode._rendered = newRendered;
|
|
170
|
-
const domNode = vnode._domNode;
|
|
171
|
-
if (domNode && domNode.parentNode) {
|
|
172
|
-
patch(domNode.parentNode, newRendered, oldRendered).then(() => {
|
|
173
|
-
vnode._domNode = newRendered?._domNode;
|
|
174
|
-
}).finally(() => {
|
|
175
|
-
ctx._isRerendering = false;
|
|
176
|
-
pendingRerenders.delete(ctx);
|
|
177
|
-
});
|
|
178
|
-
} else if (rootRenderFn) {
|
|
179
|
-
rootRenderFn().finally(() => {
|
|
180
|
-
ctx._isRerendering = false;
|
|
181
|
-
pendingRerenders.delete(ctx);
|
|
182
|
-
});
|
|
183
|
-
} else {
|
|
184
|
-
ctx._isRerendering = false;
|
|
185
|
-
pendingRerenders.delete(ctx);
|
|
186
|
-
}
|
|
187
|
-
} catch (err) {
|
|
188
|
-
console.error("[Fynix] Component rerender error:", err);
|
|
189
|
-
showErrorOverlay(err);
|
|
190
|
-
ctx._isRerendering = false;
|
|
191
|
-
pendingRerenders.delete(ctx);
|
|
192
|
-
}
|
|
193
|
-
rerenderTimeout = null;
|
|
194
|
-
}, 0);
|
|
195
|
-
}, "rerender");
|
|
196
|
-
}
|
|
197
|
-
const unsub = state.subscribe(() => {
|
|
198
|
-
if (ctx.rerender && ctx._isMounted) {
|
|
199
|
-
if (typeof queueMicrotask === "function")
|
|
200
|
-
queueMicrotask(() => ctx.rerender());
|
|
201
|
-
else
|
|
202
|
-
setTimeout(ctx.rerender, 0);
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
ctx._subscriptions.add(state);
|
|
206
|
-
ctx._subscriptionCleanups.push(unsub);
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
setActiveContext(null);
|
|
210
|
-
}
|
|
211
|
-
__name(endComponent, "endComponent");
|
|
212
|
-
function renderComponent(Component, props = {}) {
|
|
213
|
-
const vnode = { type: Component, props };
|
|
214
|
-
const ctx = beginComponent(vnode);
|
|
215
|
-
ctx.Component = Component;
|
|
216
|
-
if (!ctx.rerender) {
|
|
217
|
-
let rerenderTimeout = null;
|
|
218
|
-
ctx.rerender = () => {
|
|
219
|
-
if (ctx._isRerendering || pendingRerenders.has(ctx))
|
|
148
|
+
const ctx = activeContext;
|
|
149
|
+
if (!ctx)
|
|
220
150
|
return;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
151
|
+
ctx._accessedStates.forEach((state) => {
|
|
152
|
+
if (!ctx._subscriptions.has(state)) {
|
|
153
|
+
if (!ctx.rerender) {
|
|
154
|
+
let rerenderTimeout = null;
|
|
155
|
+
ctx.rerender = function rerender() {
|
|
156
|
+
if (ctx._isRerendering || pendingRerenders.has(ctx)) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (rerenderTimeout) {
|
|
160
|
+
clearTimeout(rerenderTimeout);
|
|
161
|
+
}
|
|
162
|
+
rerenderTimeout = setTimeout(async () => {
|
|
163
|
+
if (ctx._isRerendering || !ctx._isMounted)
|
|
164
|
+
return;
|
|
165
|
+
ctx._isRerendering = true;
|
|
166
|
+
pendingRerenders.add(ctx);
|
|
167
|
+
try {
|
|
168
|
+
removeErrorOverlay();
|
|
169
|
+
const vnode = ctx._vnode;
|
|
170
|
+
const oldRendered = vnode._rendered;
|
|
171
|
+
beginComponent(vnode);
|
|
172
|
+
const result = ctx.Component(vnode.props);
|
|
173
|
+
const newRendered = result instanceof Promise ? await result : result;
|
|
174
|
+
endComponent();
|
|
175
|
+
vnode._rendered = newRendered;
|
|
176
|
+
const domNode = vnode._domNode;
|
|
177
|
+
if (domNode && domNode.parentNode) {
|
|
178
|
+
await patch(domNode.parentNode, newRendered, oldRendered);
|
|
179
|
+
if (newRendered && typeof newRendered === "object") {
|
|
180
|
+
vnode._domNode = newRendered._domNode;
|
|
181
|
+
}
|
|
182
|
+
ctx._isRerendering = false;
|
|
183
|
+
pendingRerenders.delete(ctx);
|
|
184
|
+
}
|
|
185
|
+
else if (rootRenderFn) {
|
|
186
|
+
await rootRenderFn();
|
|
187
|
+
ctx._isRerendering = false;
|
|
188
|
+
pendingRerenders.delete(ctx);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
ctx._isRerendering = false;
|
|
192
|
+
pendingRerenders.delete(ctx);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
console.error("[Fynix] Component rerender error:", err);
|
|
197
|
+
showErrorOverlay(err);
|
|
198
|
+
ctx._isRerendering = false;
|
|
199
|
+
pendingRerenders.delete(ctx);
|
|
200
|
+
}
|
|
201
|
+
rerenderTimeout = null;
|
|
202
|
+
}, 0);
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const unsub = state.subscribe(() => {
|
|
206
|
+
if (ctx.rerender && ctx._isMounted) {
|
|
207
|
+
if (typeof queueMicrotask === "function") {
|
|
208
|
+
queueMicrotask(() => ctx.rerender());
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
setTimeout(ctx.rerender, 0);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
244
214
|
});
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
215
|
+
ctx._subscriptions.add(state);
|
|
216
|
+
ctx._subscriptionCleanups.push(unsub);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
setActiveContext(null);
|
|
220
|
+
}
|
|
221
|
+
export function renderComponent(Component, props = {}) {
|
|
222
|
+
const vnode = { type: Component, props, key: null };
|
|
223
|
+
const ctx = beginComponent(vnode);
|
|
224
|
+
ctx.Component = Component;
|
|
225
|
+
if (!ctx.rerender) {
|
|
226
|
+
let rerenderTimeout = null;
|
|
227
|
+
ctx.rerender = () => {
|
|
228
|
+
if (ctx._isRerendering || pendingRerenders.has(ctx))
|
|
229
|
+
return;
|
|
230
|
+
if (rerenderTimeout) {
|
|
231
|
+
clearTimeout(rerenderTimeout);
|
|
232
|
+
}
|
|
233
|
+
rerenderTimeout = setTimeout(async () => {
|
|
234
|
+
if (ctx._isRerendering || !ctx._isMounted)
|
|
235
|
+
return;
|
|
236
|
+
ctx._isRerendering = true;
|
|
237
|
+
pendingRerenders.add(ctx);
|
|
238
|
+
try {
|
|
239
|
+
removeErrorOverlay();
|
|
240
|
+
const vnode = ctx._vnode;
|
|
241
|
+
const oldRendered = vnode._rendered;
|
|
242
|
+
beginComponent(vnode);
|
|
243
|
+
const result = ctx.Component(vnode.props);
|
|
244
|
+
const newRendered = result instanceof Promise ? await result : result;
|
|
245
|
+
endComponent();
|
|
246
|
+
vnode._rendered = newRendered;
|
|
247
|
+
const domNode = vnode._domNode;
|
|
248
|
+
if (domNode && domNode.parentNode) {
|
|
249
|
+
await patch(domNode.parentNode, newRendered, oldRendered);
|
|
250
|
+
if (newRendered && typeof newRendered === "object") {
|
|
251
|
+
vnode._domNode = newRendered._domNode;
|
|
252
|
+
}
|
|
253
|
+
ctx._isRerendering = false;
|
|
254
|
+
pendingRerenders.delete(ctx);
|
|
255
|
+
}
|
|
256
|
+
else if (rootRenderFn) {
|
|
257
|
+
await rootRenderFn();
|
|
258
|
+
ctx._isRerendering = false;
|
|
259
|
+
pendingRerenders.delete(ctx);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
ctx._isRerendering = false;
|
|
263
|
+
pendingRerenders.delete(ctx);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
console.error("[Fynix] Component rerender error:", err);
|
|
268
|
+
showErrorOverlay(err);
|
|
269
|
+
ctx._isRerendering = false;
|
|
270
|
+
pendingRerenders.delete(ctx);
|
|
271
|
+
}
|
|
272
|
+
rerenderTimeout = null;
|
|
273
|
+
}, 0);
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
try {
|
|
277
|
+
removeErrorOverlay();
|
|
278
|
+
const result = Component(props);
|
|
279
|
+
if (result instanceof Promise) {
|
|
280
|
+
const placeholderVNode = h("div", null, "Loading...");
|
|
281
|
+
ctx._vnode = vnode;
|
|
282
|
+
vnode._rendered = placeholderVNode;
|
|
283
|
+
ctx._isMounted = true;
|
|
284
|
+
result
|
|
285
|
+
.then((resolvedVNode) => {
|
|
286
|
+
vnode._rendered = resolvedVNode;
|
|
287
|
+
if (ctx.rerender) {
|
|
288
|
+
ctx.rerender();
|
|
289
|
+
}
|
|
290
|
+
})
|
|
291
|
+
.catch((err) => {
|
|
292
|
+
console.error("[Fynix] Async component error:", err);
|
|
293
|
+
showErrorOverlay(err);
|
|
249
294
|
});
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
removeErrorOverlay();
|
|
266
|
-
const result = Component(props);
|
|
267
|
-
ctx._vnode = vnode;
|
|
268
|
-
vnode._rendered = result;
|
|
269
|
-
ctx._isMounted = true;
|
|
270
|
-
return result;
|
|
271
|
-
} catch (err) {
|
|
272
|
-
console.error("[Fynix] Component render error:", err);
|
|
273
|
-
showErrorOverlay(err);
|
|
274
|
-
return h("div", { style: "color:red" }, `Error: ${err.message}`);
|
|
275
|
-
} finally {
|
|
276
|
-
endComponent();
|
|
277
|
-
}
|
|
295
|
+
return placeholderVNode;
|
|
296
|
+
}
|
|
297
|
+
ctx._vnode = vnode;
|
|
298
|
+
vnode._rendered = result;
|
|
299
|
+
ctx._isMounted = true;
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
catch (err) {
|
|
303
|
+
console.error("[Fynix] Component render error:", err);
|
|
304
|
+
showErrorOverlay(err);
|
|
305
|
+
return h("div", { style: "color:red" }, `Error: ${err.message}`);
|
|
306
|
+
}
|
|
307
|
+
finally {
|
|
308
|
+
endComponent();
|
|
309
|
+
}
|
|
278
310
|
}
|
|
279
|
-
|
|
280
|
-
const delegatedEvents = /* @__PURE__ */ new Map();
|
|
311
|
+
const delegatedEvents = new Map();
|
|
281
312
|
let eventIdCounter = 1;
|
|
282
313
|
function ensureDelegated(eventType) {
|
|
283
|
-
|
|
284
|
-
return;
|
|
285
|
-
delegatedEvents.set(eventType, /* @__PURE__ */ new Map());
|
|
286
|
-
document.addEventListener(eventType, (e) => {
|
|
287
|
-
let cur = e.target;
|
|
288
|
-
while (cur && cur !== document) {
|
|
289
|
-
if (cur.nodeType !== 1)
|
|
290
|
-
break;
|
|
291
|
-
const eid = cur._rest_eid;
|
|
292
|
-
const map = delegatedEvents.get(eventType);
|
|
293
|
-
if (eid != null && map?.has(eid)) {
|
|
294
|
-
map.get(eid)(e);
|
|
314
|
+
if (delegatedEvents.has(eventType))
|
|
295
315
|
return;
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
316
|
+
delegatedEvents.set(eventType, new Map());
|
|
317
|
+
document.addEventListener(eventType, (e) => {
|
|
318
|
+
let cur = e.target;
|
|
319
|
+
while (cur && cur !== document) {
|
|
320
|
+
if (cur.nodeType !== 1)
|
|
321
|
+
break;
|
|
322
|
+
const el = cur;
|
|
323
|
+
const eid = el._rest_eid;
|
|
324
|
+
const map = delegatedEvents.get(eventType);
|
|
325
|
+
if (eid != null && map?.has(eid)) {
|
|
326
|
+
map.get(eid)(e);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
cur = cur.parentElement;
|
|
330
|
+
}
|
|
331
|
+
});
|
|
300
332
|
}
|
|
301
|
-
__name(ensureDelegated, "ensureDelegated");
|
|
302
333
|
function registerDelegatedHandler(el, eventName, fn) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
334
|
+
if (!fn || el.nodeType !== 1)
|
|
335
|
+
return;
|
|
336
|
+
const anyEl = el;
|
|
337
|
+
const eid = anyEl._rest_eid ?? (anyEl._rest_eid = ++eventIdCounter);
|
|
338
|
+
ensureDelegated(eventName);
|
|
339
|
+
delegatedEvents.get(eventName).set(eid, (e) => {
|
|
340
|
+
try {
|
|
341
|
+
fn.call(el, e);
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
console.error("[Fynix] Event handler error:", err);
|
|
345
|
+
showErrorOverlay(err);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
315
348
|
}
|
|
316
|
-
__name(registerDelegatedHandler, "registerDelegatedHandler");
|
|
317
349
|
function setProperty(el, key, value) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
if (
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
350
|
+
const k = key.toLowerCase();
|
|
351
|
+
if (key === "r-class" || key === "rc") {
|
|
352
|
+
if (typeof value === "string") {
|
|
353
|
+
el.setAttribute("class", value);
|
|
354
|
+
}
|
|
355
|
+
else if (value && (value._isNixState || value._isRestState)) {
|
|
356
|
+
el.setAttribute("class", value.value);
|
|
357
|
+
const anyEl = el;
|
|
358
|
+
if (!anyEl._fynixCleanups)
|
|
359
|
+
anyEl._fynixCleanups = [];
|
|
360
|
+
const unsub = value.subscribe(() => el.setAttribute("class", value.value));
|
|
361
|
+
anyEl._fynixCleanups.push(unsub);
|
|
362
|
+
}
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
if (key.startsWith("r-")) {
|
|
366
|
+
registerDelegatedHandler(el, key.slice(2).toLowerCase(), value);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (key === "style" && typeof value === "object") {
|
|
370
|
+
Object.assign(el.style, value);
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (key === "innerHTML" || key === "outerHTML") {
|
|
374
|
+
console.warn("[Fynix] Security: innerHTML/outerHTML not allowed. Use textContent or children.");
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
if (BOOLEAN_ATTRS.has(k)) {
|
|
378
|
+
if (value) {
|
|
379
|
+
el.setAttribute(k, "");
|
|
380
|
+
el[k] = true;
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
el.removeAttribute(k);
|
|
384
|
+
el[k] = false;
|
|
385
|
+
}
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (DOM_PROPERTIES.has(key)) {
|
|
389
|
+
el[key] = value ?? "";
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
if (key.startsWith("data-") || key.startsWith("aria-")) {
|
|
393
|
+
if (value != null && value !== false) {
|
|
394
|
+
el.setAttribute(key, value);
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
el.removeAttribute(key);
|
|
398
|
+
}
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
if ((key === "href" || key === "src") && typeof value === "string") {
|
|
402
|
+
if (value.trim().toLowerCase().startsWith("javascript:")) {
|
|
403
|
+
console.warn("[Fynix] Security: javascript: protocol blocked in", key);
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (value != null && value !== false) {
|
|
408
|
+
el.setAttribute(key, value);
|
|
409
|
+
}
|
|
376
410
|
}
|
|
377
|
-
__name(setProperty, "setProperty");
|
|
378
411
|
async function createDom(vnode, existing = null) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
vnode
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
412
|
+
if (vnode == null) {
|
|
413
|
+
return document.createTextNode("");
|
|
414
|
+
}
|
|
415
|
+
if (typeof vnode === "string" || typeof vnode === "number") {
|
|
416
|
+
return document.createTextNode(String(vnode));
|
|
417
|
+
}
|
|
418
|
+
if (vnode instanceof Promise) {
|
|
419
|
+
const placeholder = document.createTextNode("Loading...");
|
|
420
|
+
vnode
|
|
421
|
+
.then(async (resolved) => {
|
|
422
|
+
try {
|
|
423
|
+
const dom = await createDom(resolved);
|
|
424
|
+
if (placeholder.parentNode) {
|
|
425
|
+
placeholder.replaceWith(dom);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
catch (err) {
|
|
429
|
+
console.error("[Fynix] Async component error:", err);
|
|
430
|
+
if (placeholder.parentNode) {
|
|
431
|
+
placeholder.textContent = "Error loading component";
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
})
|
|
435
|
+
.catch((err) => {
|
|
436
|
+
console.error("[Fynix] Async component promise error:", err);
|
|
437
|
+
if (placeholder.parentNode) {
|
|
438
|
+
placeholder.textContent = "Error loading async component";
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
return placeholder;
|
|
442
|
+
}
|
|
443
|
+
const vnodeObj = vnode;
|
|
444
|
+
if (vnodeObj.type === TEXT) {
|
|
445
|
+
const textNode = existing || document.createTextNode(vnodeObj.props.nodeValue ?? "");
|
|
446
|
+
vnodeObj._domNode = textNode;
|
|
447
|
+
return textNode;
|
|
448
|
+
}
|
|
449
|
+
if (vnodeObj.type === Fragment) {
|
|
450
|
+
const frag = document.createDocumentFragment();
|
|
451
|
+
for (const child of vnodeObj.props?.children || []) {
|
|
452
|
+
frag.appendChild(await createDom(child));
|
|
453
|
+
}
|
|
454
|
+
vnodeObj._domNode = frag;
|
|
455
|
+
return frag;
|
|
456
|
+
}
|
|
457
|
+
if (typeof vnodeObj.type === "function") {
|
|
458
|
+
const rendered = await renderMaybeAsyncComponent(vnodeObj.type, vnodeObj.props, vnodeObj);
|
|
459
|
+
vnodeObj._rendered = rendered;
|
|
460
|
+
const dom = await createDom(rendered);
|
|
461
|
+
vnodeObj._domNode = dom;
|
|
462
|
+
return dom;
|
|
463
|
+
}
|
|
464
|
+
const el = existing || document.createElement(vnodeObj.type);
|
|
465
|
+
for (const [k, v] of Object.entries(vnodeObj.props || {})) {
|
|
466
|
+
if (k !== "children") {
|
|
467
|
+
setProperty(el, k, v);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
for (const child of vnodeObj.props?.children || []) {
|
|
471
|
+
el.appendChild(await createDom(child));
|
|
472
|
+
}
|
|
473
|
+
vnodeObj._domNode = el;
|
|
474
|
+
return el;
|
|
436
475
|
}
|
|
437
|
-
__name(createDom, "createDom");
|
|
438
476
|
async function renderMaybeAsyncComponent(Component, props, vnode) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
477
|
+
const ctx = beginComponent(vnode);
|
|
478
|
+
removeErrorOverlay();
|
|
479
|
+
try {
|
|
480
|
+
const result = await Component(props);
|
|
481
|
+
ctx._vnode = vnode;
|
|
482
|
+
vnode._rendered = result;
|
|
483
|
+
ctx._isMounted = true;
|
|
484
|
+
endComponent();
|
|
485
|
+
return result ?? null;
|
|
486
|
+
}
|
|
487
|
+
catch (err) {
|
|
488
|
+
console.error("[Fynix] async render error:", err);
|
|
489
|
+
showErrorOverlay(err);
|
|
490
|
+
ctx._isMounted = false;
|
|
491
|
+
endComponent();
|
|
492
|
+
return h("div", { style: "color:red" }, `Error: ${err.message}`);
|
|
493
|
+
}
|
|
455
494
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
)
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
return;
|
|
468
|
-
if (!newVNode && oldVNode) {
|
|
469
|
-
const domNode = oldVNode._domNode;
|
|
470
|
-
if (domNode?.parentNode)
|
|
471
|
-
domNode.parentNode.removeChild(domNode);
|
|
472
|
-
unmountVNode(oldVNode);
|
|
473
|
-
return;
|
|
474
|
-
}
|
|
475
|
-
if (newVNode && !oldVNode) {
|
|
476
|
-
const newDom = await createDom(newVNode);
|
|
477
|
-
if (newDom instanceof Node) {
|
|
478
|
-
parent.appendChild(newDom);
|
|
479
|
-
}
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
const newIsPrimitive = typeof newVNode === "string" || typeof newVNode === "number";
|
|
483
|
-
const oldIsPrimitive = typeof oldVNode === "string" || typeof oldVNode === "number";
|
|
484
|
-
if (newIsPrimitive || oldIsPrimitive) {
|
|
485
|
-
if (newIsPrimitive && oldIsPrimitive && newVNode === oldVNode)
|
|
486
|
-
return;
|
|
487
|
-
const newDom = await createDom(newVNode);
|
|
488
|
-
const oldDom = oldVNode._domNode || parent.firstChild;
|
|
489
|
-
if (oldDom?.parentNode && newDom instanceof Node) {
|
|
490
|
-
oldDom.parentNode.replaceChild(newDom, oldDom);
|
|
491
|
-
}
|
|
492
|
-
if (oldVNode && typeof oldVNode === "object") {
|
|
493
|
-
unmountVNode(oldVNode);
|
|
494
|
-
}
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
const newType = newVNode.type;
|
|
498
|
-
const oldType = oldVNode.type;
|
|
499
|
-
if (newType !== oldType) {
|
|
500
|
-
const newDom = await createDom(newVNode);
|
|
501
|
-
const oldDom = oldVNode._domNode;
|
|
502
|
-
if (oldDom?.parentNode && newDom instanceof Node) {
|
|
503
|
-
oldDom.parentNode.replaceChild(newDom, oldDom);
|
|
504
|
-
}
|
|
505
|
-
unmountVNode(oldVNode);
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
if (newType === TEXT) {
|
|
509
|
-
const oldDom = oldVNode._domNode;
|
|
510
|
-
const newText = newVNode.props.nodeValue ?? "";
|
|
511
|
-
const oldText = oldVNode.props.nodeValue ?? "";
|
|
512
|
-
if (newText !== oldText && oldDom) {
|
|
513
|
-
oldDom.nodeValue = newText;
|
|
514
|
-
}
|
|
515
|
-
newVNode._domNode = oldDom;
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
if (newType === Fragment) {
|
|
519
|
-
const newChildren2 = newVNode.props?.children || [];
|
|
520
|
-
const oldChildren2 = oldVNode.props?.children || [];
|
|
521
|
-
await patchChildren(parent, newChildren2, oldChildren2);
|
|
522
|
-
newVNode._domNode = oldVNode._domNode;
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
if (typeof newType === "function") {
|
|
526
|
-
const oldCtx = componentInstances.get(oldVNode);
|
|
527
|
-
if (oldCtx && newType === oldType) {
|
|
528
|
-
componentInstances.delete(oldVNode);
|
|
529
|
-
componentInstances.set(newVNode, oldCtx);
|
|
530
|
-
oldCtx._vnode = newVNode;
|
|
531
|
-
beginComponent(newVNode);
|
|
532
|
-
const rendered = await oldCtx.Component(newVNode.props);
|
|
533
|
-
endComponent();
|
|
534
|
-
newVNode._rendered = rendered;
|
|
535
|
-
const oldRendered = oldVNode._rendered;
|
|
536
|
-
const oldDom = oldVNode._domNode;
|
|
537
|
-
if (oldDom?.parentNode instanceof Node) {
|
|
538
|
-
await patch(oldDom.parentNode, rendered, oldRendered);
|
|
539
|
-
newVNode._domNode = rendered?._domNode || oldDom;
|
|
540
|
-
}
|
|
541
|
-
} else {
|
|
542
|
-
const rendered = await renderMaybeAsyncComponent(
|
|
543
|
-
newType,
|
|
544
|
-
newVNode.props,
|
|
545
|
-
newVNode
|
|
546
|
-
);
|
|
547
|
-
newVNode._rendered = rendered;
|
|
548
|
-
const oldRendered = oldVNode._rendered;
|
|
549
|
-
const oldDom = oldVNode._domNode;
|
|
550
|
-
if (oldDom?.parentNode instanceof Node) {
|
|
551
|
-
await patch(oldDom.parentNode, rendered, oldRendered);
|
|
552
|
-
newVNode._domNode = rendered?._domNode || oldDom;
|
|
553
|
-
} else {
|
|
554
|
-
const newDom = await createDom(rendered);
|
|
555
|
-
if (parent && newDom instanceof Node) {
|
|
556
|
-
parent.appendChild(newDom);
|
|
495
|
+
export async function patch(parent, newVNode, oldVNode) {
|
|
496
|
+
if (!(parent instanceof Node)) {
|
|
497
|
+
console.error("[Fynix] patch() expects a DOM Node, got:", typeof parent, parent);
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
if (!newVNode && !oldVNode)
|
|
501
|
+
return;
|
|
502
|
+
if (!newVNode && oldVNode) {
|
|
503
|
+
const domNode = oldVNode._domNode;
|
|
504
|
+
if (domNode?.parentNode) {
|
|
505
|
+
domNode.parentNode.removeChild(domNode);
|
|
557
506
|
}
|
|
558
|
-
newVNode._domNode = newDom;
|
|
559
|
-
}
|
|
560
|
-
if (oldCtx && newType !== oldType) {
|
|
561
507
|
unmountVNode(oldVNode);
|
|
562
|
-
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
if (newVNode && !oldVNode) {
|
|
511
|
+
const newDom = await createDom(newVNode);
|
|
512
|
+
if (newDom instanceof Node) {
|
|
513
|
+
parent.appendChild(newDom);
|
|
514
|
+
}
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const newIsPrimitive = typeof newVNode === "string" || typeof newVNode === "number";
|
|
518
|
+
const oldIsPrimitive = typeof oldVNode === "string" || typeof oldVNode === "number";
|
|
519
|
+
if (newIsPrimitive || oldIsPrimitive) {
|
|
520
|
+
if (newIsPrimitive &&
|
|
521
|
+
oldIsPrimitive &&
|
|
522
|
+
String(newVNode) === String(oldVNode))
|
|
523
|
+
return;
|
|
524
|
+
const newDom = await createDom(newVNode);
|
|
525
|
+
const oldDom = oldVNode?._domNode || parent.firstChild;
|
|
526
|
+
if (oldDom?.parentNode && newDom instanceof Node) {
|
|
527
|
+
oldDom.parentNode.replaceChild(newDom, oldDom);
|
|
528
|
+
}
|
|
529
|
+
if (oldVNode && typeof oldVNode === "object") {
|
|
530
|
+
unmountVNode(oldVNode);
|
|
531
|
+
}
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
const newVN = newVNode;
|
|
535
|
+
const oldVN = oldVNode;
|
|
536
|
+
const newType = newVN.type;
|
|
537
|
+
const oldType = oldVN.type;
|
|
538
|
+
if (newType !== oldType) {
|
|
539
|
+
const newDom = await createDom(newVN);
|
|
540
|
+
const oldDom = oldVN._domNode;
|
|
541
|
+
if (oldDom?.parentNode && newDom instanceof Node) {
|
|
542
|
+
oldDom.parentNode.replaceChild(newDom, oldDom);
|
|
543
|
+
}
|
|
544
|
+
unmountVNode(oldVN);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
if (newType === TEXT) {
|
|
548
|
+
const oldDom = oldVN._domNode;
|
|
549
|
+
const newText = newVN.props.nodeValue ?? "";
|
|
550
|
+
const oldText = oldVN.props.nodeValue ?? "";
|
|
551
|
+
if (newText !== oldText && oldDom) {
|
|
552
|
+
oldDom.nodeValue = newText;
|
|
553
|
+
}
|
|
554
|
+
newVN._domNode = oldDom;
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
if (newType === Fragment) {
|
|
558
|
+
const newChildren = newVN.props?.children || [];
|
|
559
|
+
const oldChildren = oldVN.props?.children || [];
|
|
560
|
+
await patchChildren(parent, newChildren, oldChildren);
|
|
561
|
+
newVN._domNode = oldVN._domNode;
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
if (typeof newType === "function") {
|
|
565
|
+
const oldCtx = componentInstances.get(oldVN);
|
|
566
|
+
if (oldCtx && newType === oldType) {
|
|
567
|
+
componentInstances.delete(oldVN);
|
|
568
|
+
componentInstances.set(newVN, oldCtx);
|
|
569
|
+
oldCtx._vnode = newVN;
|
|
570
|
+
beginComponent(newVN);
|
|
571
|
+
const rendered = await oldCtx.Component(newVN.props);
|
|
572
|
+
endComponent();
|
|
573
|
+
newVN._rendered = rendered;
|
|
574
|
+
const oldRendered = oldVN._rendered;
|
|
575
|
+
const oldDom = oldVN._domNode;
|
|
576
|
+
if (oldDom?.parentNode instanceof Node) {
|
|
577
|
+
await patch(oldDom.parentNode, rendered, oldRendered);
|
|
578
|
+
newVN._domNode = rendered?._domNode || oldDom;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
else {
|
|
582
|
+
const rendered = await renderMaybeAsyncComponent(newType, newVN.props, newVN);
|
|
583
|
+
newVN._rendered = rendered;
|
|
584
|
+
const oldRendered = oldVN._rendered;
|
|
585
|
+
const oldDom = oldVN._domNode;
|
|
586
|
+
if (oldDom?.parentNode instanceof Node) {
|
|
587
|
+
await patch(oldDom.parentNode, rendered, oldRendered);
|
|
588
|
+
newVN._domNode = rendered?._domNode || oldDom;
|
|
589
|
+
}
|
|
590
|
+
else {
|
|
591
|
+
const newDom = await createDom(rendered);
|
|
592
|
+
if (parent && newDom instanceof Node) {
|
|
593
|
+
parent.appendChild(newDom);
|
|
594
|
+
}
|
|
595
|
+
newVN._domNode = newDom;
|
|
596
|
+
}
|
|
597
|
+
if (oldCtx && newType !== oldType) {
|
|
598
|
+
unmountVNode(oldVN);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
const el = oldVN._domNode;
|
|
604
|
+
if (!el || el.nodeType !== 1) {
|
|
605
|
+
const newDom = await createDom(newVN);
|
|
606
|
+
if (parent && newDom instanceof Node) {
|
|
607
|
+
parent.appendChild(newDom);
|
|
608
|
+
}
|
|
609
|
+
unmountVNode(oldVN);
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
updateProps(el, newVN.props, oldVN.props);
|
|
613
|
+
newVN._domNode = el;
|
|
614
|
+
const newChildren = newVN.props?.children || [];
|
|
615
|
+
const oldChildren = oldVN.props?.children || [];
|
|
616
|
+
await patchChildren(el, newChildren, oldChildren);
|
|
580
617
|
}
|
|
581
|
-
__name(patch, "patch");
|
|
582
618
|
async function patchChildren(parent, newChildren, oldChildren) {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
619
|
+
if (!(parent instanceof Node))
|
|
620
|
+
return;
|
|
621
|
+
const hasKeys = newChildren.some((c) => c?.key != null) ||
|
|
622
|
+
oldChildren.some((c) => c?.key != null);
|
|
623
|
+
if (!hasKeys) {
|
|
624
|
+
const maxLen = Math.max(newChildren.length, oldChildren.length);
|
|
625
|
+
for (let i = 0; i < maxLen; i++) {
|
|
626
|
+
const newChild = newChildren[i];
|
|
627
|
+
const oldChild = oldChildren[i];
|
|
628
|
+
if (i >= newChildren.length) {
|
|
629
|
+
const dom = oldChild?._domNode;
|
|
630
|
+
if (dom?.parentNode) {
|
|
631
|
+
dom.parentNode.removeChild(dom);
|
|
632
|
+
}
|
|
633
|
+
unmountVNode(oldChild);
|
|
634
|
+
}
|
|
635
|
+
else if (i >= oldChildren.length) {
|
|
636
|
+
const newDom = await createDom(newChild);
|
|
637
|
+
if (newDom instanceof Node) {
|
|
638
|
+
parent.appendChild(newDom);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
await patch(parent, newChild, oldChild);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
const oldKeyMap = new Map();
|
|
648
|
+
oldChildren.forEach((child) => {
|
|
649
|
+
if (child?.key != null) {
|
|
650
|
+
oldKeyMap.set(child.key, child);
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
const newKeySet = new Set(newChildren.filter((c) => c?.key != null).map((c) => c.key));
|
|
654
|
+
oldChildren.forEach((oldChild) => {
|
|
655
|
+
if (oldChild?.key != null && !newKeySet.has(oldChild.key)) {
|
|
656
|
+
const dom = oldChild._domNode;
|
|
657
|
+
if (dom?.parentNode) {
|
|
658
|
+
dom.parentNode.removeChild(dom);
|
|
659
|
+
}
|
|
660
|
+
unmountVNode(oldChild);
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
for (let i = 0; i < newChildren.length; i++) {
|
|
664
|
+
const newChild = newChildren[i];
|
|
665
|
+
const key = newChild?.key;
|
|
666
|
+
if (key != null && oldKeyMap.has(key)) {
|
|
667
|
+
const oldChild = oldKeyMap.get(key);
|
|
668
|
+
const oldDom = oldChild._domNode;
|
|
669
|
+
const childNodes = Array.from(parent.childNodes);
|
|
670
|
+
const currentPos = childNodes.indexOf(oldDom);
|
|
671
|
+
const desiredPos = i;
|
|
672
|
+
if (currentPos !== desiredPos) {
|
|
673
|
+
const refNode = childNodes[desiredPos] || null;
|
|
674
|
+
if (oldDom && oldDom.parentNode === parent) {
|
|
675
|
+
parent.insertBefore(oldDom, refNode);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
await patch(parent, newChild, oldChild);
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
const newDom = await createDom(newChild);
|
|
682
|
+
if (newDom instanceof Node) {
|
|
683
|
+
const childNodes = Array.from(parent.childNodes);
|
|
684
|
+
const refNode = childNodes[i] || null;
|
|
685
|
+
parent.insertBefore(newDom, refNode);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
651
689
|
}
|
|
652
|
-
__name(patchChildren, "patchChildren");
|
|
653
690
|
function unmountVNode(vnode) {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
try {
|
|
658
|
-
vnode._cleanup();
|
|
659
|
-
} catch (e) {
|
|
660
|
-
console.error("[Fynix] Text vnode cleanup error:", e);
|
|
661
|
-
}
|
|
662
|
-
vnode._cleanup = null;
|
|
663
|
-
}
|
|
664
|
-
if (typeof vnode.type === "function") {
|
|
665
|
-
const ctx = componentInstances.get(vnode);
|
|
666
|
-
if (ctx) {
|
|
667
|
-
ctx._isMounted = false;
|
|
668
|
-
ctx._subscriptionCleanups.forEach((u) => {
|
|
691
|
+
if (!vnode)
|
|
692
|
+
return;
|
|
693
|
+
if (vnode._cleanup && typeof vnode._cleanup === "function") {
|
|
669
694
|
try {
|
|
670
|
-
|
|
671
|
-
} catch (e) {
|
|
672
|
-
console.error("[Fynix] Cleanup error:", e);
|
|
695
|
+
vnode._cleanup();
|
|
673
696
|
}
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
vnode.
|
|
714
|
-
|
|
715
|
-
|
|
697
|
+
catch (e) {
|
|
698
|
+
console.error("[Fynix] Text vnode cleanup error:", e);
|
|
699
|
+
}
|
|
700
|
+
vnode._cleanup = null;
|
|
701
|
+
}
|
|
702
|
+
if (typeof vnode.type === "function") {
|
|
703
|
+
const ctx = componentInstances.get(vnode);
|
|
704
|
+
if (ctx) {
|
|
705
|
+
ctx._isMounted = false;
|
|
706
|
+
ctx._subscriptionCleanups.forEach((u) => {
|
|
707
|
+
try {
|
|
708
|
+
u();
|
|
709
|
+
}
|
|
710
|
+
catch (e) {
|
|
711
|
+
console.error("[Fynix] Cleanup error:", e);
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
ctx.cleanups.forEach((c) => {
|
|
715
|
+
try {
|
|
716
|
+
c?.();
|
|
717
|
+
}
|
|
718
|
+
catch (e) {
|
|
719
|
+
console.error("[Fynix] Effect cleanup error:", e);
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
ctx._subscriptions.clear();
|
|
723
|
+
ctx._accessedStates.clear();
|
|
724
|
+
ctx._subscriptionCleanups = [];
|
|
725
|
+
ctx.cleanups = [];
|
|
726
|
+
ctx.hooks = [];
|
|
727
|
+
ctx.effects = [];
|
|
728
|
+
ctx.rerender = null;
|
|
729
|
+
ctx._vnode = null;
|
|
730
|
+
componentInstances.delete(vnode);
|
|
731
|
+
pendingRerenders.delete(ctx);
|
|
732
|
+
}
|
|
733
|
+
unmountVNode(vnode._rendered);
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
if (vnode._domNode && vnode._domNode.nodeType === 1) {
|
|
737
|
+
const anyNode = vnode._domNode;
|
|
738
|
+
const eid = anyNode._rest_eid;
|
|
739
|
+
if (eid) {
|
|
740
|
+
delegatedEvents.forEach((map) => map.delete(eid));
|
|
741
|
+
}
|
|
742
|
+
if (anyNode._fynixCleanups) {
|
|
743
|
+
anyNode._fynixCleanups.forEach((cleanup) => {
|
|
744
|
+
try {
|
|
745
|
+
cleanup();
|
|
746
|
+
}
|
|
747
|
+
catch (e) {
|
|
748
|
+
console.error("[Fynix] Element cleanup error:", e);
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
anyNode._fynixCleanups = null;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
if (vnode.props?.children) {
|
|
755
|
+
vnode.props.children.forEach((c) => unmountVNode(c));
|
|
756
|
+
}
|
|
757
|
+
vnode._domNode = null;
|
|
758
|
+
vnode._rendered = null;
|
|
716
759
|
}
|
|
717
|
-
__name(unmountVNode, "unmountVNode");
|
|
718
760
|
function updateProps(el, newProps = {}, oldProps = {}) {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
761
|
+
if (!el || el.nodeType !== 1)
|
|
762
|
+
return;
|
|
763
|
+
for (const k of Object.keys(oldProps)) {
|
|
764
|
+
if (k === "children")
|
|
765
|
+
continue;
|
|
766
|
+
if (!(k in newProps)) {
|
|
767
|
+
if (k.startsWith("r-")) {
|
|
768
|
+
const anyEl = el;
|
|
769
|
+
const eid = anyEl._rest_eid;
|
|
770
|
+
if (eid && delegatedEvents.has(k.slice(2).toLowerCase())) {
|
|
771
|
+
delegatedEvents.get(k.slice(2).toLowerCase()).delete(eid);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
else if (BOOLEAN_ATTRS.has(k.toLowerCase())) {
|
|
775
|
+
el.removeAttribute(k);
|
|
776
|
+
el[k] = false;
|
|
777
|
+
}
|
|
778
|
+
else if (DOM_PROPERTIES.has(k)) {
|
|
779
|
+
el[k] = "";
|
|
780
|
+
}
|
|
781
|
+
else {
|
|
782
|
+
el.removeAttribute(k);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
for (const [k, v] of Object.entries(newProps)) {
|
|
787
|
+
if (k === "children")
|
|
788
|
+
continue;
|
|
789
|
+
if (oldProps[k] !== v) {
|
|
790
|
+
setProperty(el, k, v);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
745
793
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
root
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
async function renderApp() {
|
|
769
|
-
if (isRendering) {
|
|
770
|
-
return;
|
|
771
|
-
}
|
|
772
|
-
isRendering = true;
|
|
773
|
-
try {
|
|
774
|
-
removeErrorOverlay();
|
|
775
|
-
const propsToUse = window.__lastRouteProps || window.__fynix__?.lastRouteProps || currentProps;
|
|
776
|
-
if (!appVNode) {
|
|
777
|
-
appVNode = { type: Component, props: propsToUse, key: null };
|
|
778
|
-
if (root instanceof Element) {
|
|
779
|
-
root.innerHTML = "";
|
|
780
|
-
const dom = await createDom(appVNode);
|
|
781
|
-
if (dom instanceof Node) {
|
|
782
|
-
root.appendChild(dom);
|
|
783
|
-
}
|
|
784
|
-
} else {
|
|
785
|
-
console.error("[Fynix] Mount error: root is not a DOM Element", root);
|
|
786
|
-
return;
|
|
787
|
-
}
|
|
788
|
-
oldVNode = appVNode;
|
|
789
|
-
} else {
|
|
790
|
-
appVNode.props = propsToUse;
|
|
791
|
-
if (root instanceof Node) {
|
|
792
|
-
await patch(root, appVNode, oldVNode);
|
|
793
|
-
oldVNode = appVNode;
|
|
794
|
-
} else {
|
|
795
|
-
console.error("[Fynix] Patch error: root is not a DOM Node", root);
|
|
796
|
-
return;
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
} catch (err) {
|
|
800
|
-
console.error("[Fynix] Mount error:", err);
|
|
801
|
-
showErrorOverlay(err);
|
|
802
|
-
} finally {
|
|
803
|
-
isRendering = false;
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
__name(renderApp, "renderApp");
|
|
807
|
-
rootRenderFn = renderApp;
|
|
808
|
-
window.__fynix__ = window.__fynix__ || {};
|
|
809
|
-
window.__fynix__.rerender = renderApp;
|
|
810
|
-
renderApp();
|
|
811
|
-
if (import.meta.hot) {
|
|
812
|
-
if (!window.__fynix__.hmr) {
|
|
813
|
-
window.__fynix__.hmr = async ({ mod }) => {
|
|
794
|
+
export function mount(AppComponent, root, props = {}) {
|
|
795
|
+
if (typeof root === "string") {
|
|
796
|
+
const element = document.querySelector(root);
|
|
797
|
+
if (!element) {
|
|
798
|
+
console.error("[Fynix] Mount error: Element not found for selector:", root);
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
root = element;
|
|
802
|
+
}
|
|
803
|
+
if (!(root instanceof Element)) {
|
|
804
|
+
console.error("[Fynix] Mount error: Invalid root element", root);
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
let Component = AppComponent;
|
|
808
|
+
let oldVNode = null;
|
|
809
|
+
let currentProps = props;
|
|
810
|
+
let appVNode = null;
|
|
811
|
+
let isRendering = false;
|
|
812
|
+
async function renderApp() {
|
|
813
|
+
if (isRendering)
|
|
814
|
+
return;
|
|
815
|
+
isRendering = true;
|
|
814
816
|
try {
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
if (appVNode) {
|
|
819
|
-
|
|
817
|
+
removeErrorOverlay();
|
|
818
|
+
const win = window;
|
|
819
|
+
const propsToUse = win.__lastRouteProps || win.__fynix__?.lastRouteProps || currentProps;
|
|
820
|
+
if (!appVNode) {
|
|
821
|
+
appVNode = { type: Component, props: propsToUse, key: null };
|
|
822
|
+
if (root instanceof Element) {
|
|
823
|
+
root.innerHTML = "";
|
|
824
|
+
const dom = await createDom(appVNode);
|
|
825
|
+
if (dom instanceof Node) {
|
|
826
|
+
root.appendChild(dom);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
else {
|
|
830
|
+
console.error("[Fynix] Mount error: root is not a DOM Element", root);
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
oldVNode = appVNode;
|
|
834
|
+
}
|
|
835
|
+
else {
|
|
836
|
+
appVNode.props = propsToUse;
|
|
837
|
+
if (root instanceof Node) {
|
|
838
|
+
await patch(root, appVNode, oldVNode);
|
|
839
|
+
oldVNode = appVNode;
|
|
840
|
+
}
|
|
841
|
+
else {
|
|
842
|
+
console.error("[Fynix] Patch error: root is not a DOM Node", root);
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
820
845
|
}
|
|
821
|
-
window.__fynix__.rerender?.();
|
|
822
|
-
}
|
|
823
|
-
} catch (err) {
|
|
824
|
-
console.error("[Fynix HMR] update error:", err);
|
|
825
|
-
showErrorOverlay(err);
|
|
826
846
|
}
|
|
827
|
-
|
|
828
|
-
|
|
847
|
+
catch (err) {
|
|
848
|
+
console.error("[Fynix] Mount error:", err);
|
|
849
|
+
showErrorOverlay(err);
|
|
850
|
+
}
|
|
851
|
+
finally {
|
|
852
|
+
isRendering = false;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
rootRenderFn = renderApp;
|
|
856
|
+
const win = window;
|
|
857
|
+
win.__fynix__ = win.__fynix__ || {};
|
|
858
|
+
win.__fynix__.rerender = renderApp;
|
|
859
|
+
renderApp();
|
|
860
|
+
if (import.meta.hot) {
|
|
861
|
+
if (!win.__fynix__.hmr) {
|
|
862
|
+
win.__fynix__.hmr = async ({ mod }) => {
|
|
863
|
+
try {
|
|
864
|
+
const UpdatedComponent = mod.App || mod.default;
|
|
865
|
+
if (UpdatedComponent) {
|
|
866
|
+
Component = UpdatedComponent;
|
|
867
|
+
if (appVNode) {
|
|
868
|
+
appVNode.type = UpdatedComponent;
|
|
869
|
+
}
|
|
870
|
+
win.__fynix__.rerender?.();
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
catch (err) {
|
|
874
|
+
console.error("[Fynix HMR] update error:", err);
|
|
875
|
+
showErrorOverlay(err);
|
|
876
|
+
}
|
|
877
|
+
};
|
|
878
|
+
import.meta.hot.accept();
|
|
879
|
+
}
|
|
829
880
|
}
|
|
830
|
-
}
|
|
831
881
|
}
|
|
832
|
-
|
|
833
|
-
export {
|
|
834
|
-
Button,
|
|
835
|
-
Fragment,
|
|
836
|
-
Fynix,
|
|
837
|
-
Path,
|
|
838
|
-
Suspense,
|
|
839
|
-
TEXT,
|
|
840
|
-
createFynix,
|
|
841
|
-
createTextVNode,
|
|
842
|
-
h,
|
|
843
|
-
mount,
|
|
844
|
-
nixAsync,
|
|
845
|
-
nixAsyncCached,
|
|
846
|
-
nixAsyncDebounce,
|
|
847
|
-
nixAsyncQuery,
|
|
848
|
-
nixCallback,
|
|
849
|
-
nixComputed,
|
|
850
|
-
nixDebounce,
|
|
851
|
-
nixEffect,
|
|
852
|
-
nixEffectAlways,
|
|
853
|
-
nixEffectOnce,
|
|
854
|
-
nixForm,
|
|
855
|
-
nixFormAsync,
|
|
856
|
-
nixInterval,
|
|
857
|
-
nixLazy,
|
|
858
|
-
nixLazyAsync,
|
|
859
|
-
nixLazyFormAsync,
|
|
860
|
-
nixLocalStorage,
|
|
861
|
-
nixMemo,
|
|
862
|
-
nixPrevious,
|
|
863
|
-
nixRef,
|
|
864
|
-
nixState,
|
|
865
|
-
nixStore,
|
|
866
|
-
patch,
|
|
867
|
-
renderComponent
|
|
868
|
-
};
|
|
869
|
-
//# sourceMappingURL=runtime.js.map
|
|
882
|
+
export { Button, createFynix, nixAsync, nixAsyncCached, nixAsyncDebounce, nixAsyncQuery, nixCallback, nixComputed, nixDebounce, nixEffect, nixEffectAlways, nixEffectOnce, nixForm, nixFormAsync, nixInterval, nixLazy, nixLazyAsync, nixLazyFormAsync, nixLocalStorage, nixMemo, nixPrevious, nixRef, nixState, nixStore, Path, Suspense, };
|