@fynixorg/ui 1.0.11 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/LICENSE +21 -0
  2. package/dist/README.md +36 -0
  3. package/dist/context/context.d.ts +19 -0
  4. package/dist/context/context.d.ts.map +1 -0
  5. package/dist/context/context.js +3 -11
  6. package/dist/context/context.js.map +3 -3
  7. package/dist/custom/button.d.ts +2 -0
  8. package/dist/custom/button.d.ts.map +1 -0
  9. package/dist/custom/button.js +2 -9
  10. package/dist/custom/button.js.map +3 -3
  11. package/dist/custom/index.d.ts +3 -0
  12. package/dist/custom/index.d.ts.map +1 -0
  13. package/dist/custom/index.js +2 -7
  14. package/dist/custom/index.js.map +3 -3
  15. package/dist/custom/path.d.ts +14 -0
  16. package/dist/custom/path.d.ts.map +1 -0
  17. package/dist/custom/path.js +17 -34
  18. package/dist/custom/path.js.map +3 -3
  19. package/dist/error/errorOverlay.d.ts +3 -0
  20. package/dist/error/errorOverlay.d.ts.map +1 -0
  21. package/dist/error/errorOverlay.js +82 -91
  22. package/dist/error/errorOverlay.js.map +3 -3
  23. package/dist/fynix/index.d.ts +5 -0
  24. package/dist/fynix/index.d.ts.map +1 -0
  25. package/dist/fynix/index.js +2 -7
  26. package/dist/fynix/index.js.map +3 -3
  27. package/dist/hooks/nixAsync.d.ts +14 -0
  28. package/dist/hooks/nixAsync.d.ts.map +1 -0
  29. package/dist/hooks/nixAsync.js +38 -43
  30. package/dist/hooks/nixAsync.js.map +3 -3
  31. package/dist/hooks/nixAsyncCache.d.ts +14 -0
  32. package/dist/hooks/nixAsyncCache.d.ts.map +1 -0
  33. package/dist/hooks/nixAsyncCache.js +57 -59
  34. package/dist/hooks/nixAsyncCache.js.map +3 -3
  35. package/dist/hooks/nixAsyncDebounce.d.ts +22 -0
  36. package/dist/hooks/nixAsyncDebounce.d.ts.map +1 -0
  37. package/dist/hooks/nixAsyncDebounce.js +74 -85
  38. package/dist/hooks/nixAsyncDebounce.js.map +3 -3
  39. package/dist/hooks/nixAsyncQuery.d.ts +16 -0
  40. package/dist/hooks/nixAsyncQuery.d.ts.map +1 -0
  41. package/dist/hooks/nixAsyncQuery.js +85 -79
  42. package/dist/hooks/nixAsyncQuery.js.map +3 -3
  43. package/dist/hooks/nixCallback.d.ts +2 -0
  44. package/dist/hooks/nixCallback.d.ts.map +1 -0
  45. package/dist/hooks/nixCallback.js +30 -40
  46. package/dist/hooks/nixCallback.js.map +3 -3
  47. package/dist/hooks/nixComputed.d.ts +16 -0
  48. package/dist/hooks/nixComputed.d.ts.map +1 -0
  49. package/dist/hooks/nixComputed.js +166 -198
  50. package/dist/hooks/nixComputed.js.map +4 -4
  51. package/dist/hooks/nixDebounce.d.ts +11 -0
  52. package/dist/hooks/nixDebounce.d.ts.map +1 -0
  53. package/dist/hooks/nixDebounce.js +53 -58
  54. package/dist/hooks/nixDebounce.js.map +3 -3
  55. package/dist/hooks/nixEffect.d.ts +4 -0
  56. package/dist/hooks/nixEffect.d.ts.map +1 -0
  57. package/dist/hooks/nixEffect.js +65 -75
  58. package/dist/hooks/nixEffect.js.map +3 -3
  59. package/dist/hooks/nixForm.d.ts +33 -0
  60. package/dist/hooks/nixForm.d.ts.map +1 -0
  61. package/dist/hooks/nixForm.js +110 -120
  62. package/dist/hooks/nixForm.js.map +3 -3
  63. package/dist/hooks/nixFormAsync.d.ts +42 -0
  64. package/dist/hooks/nixFormAsync.d.ts.map +1 -0
  65. package/dist/hooks/nixFormAsync.js +158 -167
  66. package/dist/hooks/nixFormAsync.js.map +3 -3
  67. package/dist/hooks/nixInterval.d.ts +2 -0
  68. package/dist/hooks/nixInterval.d.ts.map +1 -0
  69. package/dist/hooks/nixInterval.js +21 -27
  70. package/dist/hooks/nixInterval.js.map +3 -3
  71. package/dist/hooks/nixLazy.d.ts +8 -0
  72. package/dist/hooks/nixLazy.d.ts.map +1 -0
  73. package/dist/hooks/nixLazy.js +53 -58
  74. package/dist/hooks/nixLazy.js.map +3 -3
  75. package/dist/hooks/nixLazyAsync.d.ts +10 -0
  76. package/dist/hooks/nixLazyAsync.d.ts.map +1 -0
  77. package/dist/hooks/nixLazyAsync.js +65 -71
  78. package/dist/hooks/nixLazyAsync.js.map +3 -3
  79. package/dist/hooks/nixLazyFormAsync.d.ts +50 -0
  80. package/dist/hooks/nixLazyFormAsync.d.ts.map +1 -0
  81. package/dist/hooks/nixLazyFormAsync.js +209 -213
  82. package/dist/hooks/nixLazyFormAsync.js.map +3 -3
  83. package/dist/hooks/nixLocalStorage.d.ts +5 -0
  84. package/dist/hooks/nixLocalStorage.d.ts.map +1 -0
  85. package/dist/hooks/nixLocalStorage.js +21 -25
  86. package/dist/hooks/nixLocalStorage.js.map +3 -3
  87. package/dist/hooks/nixMemo.d.ts +2 -0
  88. package/dist/hooks/nixMemo.d.ts.map +1 -0
  89. package/dist/hooks/nixMemo.js +27 -31
  90. package/dist/hooks/nixMemo.js.map +3 -3
  91. package/dist/hooks/nixPrevious.d.ts +2 -0
  92. package/dist/hooks/nixPrevious.d.ts.map +1 -0
  93. package/dist/hooks/nixPrevious.js +13 -19
  94. package/dist/hooks/nixPrevious.js.map +3 -3
  95. package/dist/hooks/nixRef.d.ts +4 -0
  96. package/dist/hooks/nixRef.d.ts.map +1 -0
  97. package/dist/hooks/nixRef.js +14 -20
  98. package/dist/hooks/nixRef.js.map +3 -3
  99. package/dist/hooks/nixState.d.ts +15 -0
  100. package/dist/hooks/nixState.d.ts.map +1 -0
  101. package/dist/hooks/nixState.js +120 -173
  102. package/dist/hooks/nixState.js.map +3 -3
  103. package/dist/hooks/nixStore.d.ts +7 -0
  104. package/dist/hooks/nixStore.d.ts.map +1 -0
  105. package/dist/hooks/nixStore.js +48 -54
  106. package/dist/hooks/nixStore.js.map +3 -3
  107. package/dist/package.json +213 -0
  108. package/dist/plugins/vite-plugin-res.d.ts +41 -0
  109. package/dist/plugins/vite-plugin-res.d.ts.map +1 -0
  110. package/dist/plugins/vite-plugin-res.js +620 -36
  111. package/dist/plugins/vite-plugin-res.js.map +4 -4
  112. package/dist/router/router.d.ts +35 -0
  113. package/dist/router/router.d.ts.map +1 -0
  114. package/dist/router/router.js +520 -486
  115. package/dist/router/router.js.map +3 -3
  116. package/dist/runtime.d.ts +62 -0
  117. package/dist/runtime.d.ts.map +1 -0
  118. package/dist/runtime.js +833 -820
  119. package/dist/runtime.js.map +4 -4
  120. package/package.json +227 -44
  121. package/types/fnx.d.ts +72 -0
  122. package/types/fynix-ui.d.ts +323 -0
  123. package/types/global.d.ts +46 -6
  124. package/types/index.d.ts +37 -0
  125. package/types/vite-env.d.ts +553 -0
  126. package/runtime.d.ts +0 -83
  127. package/types/jsx.d.ts +0 -692
package/dist/runtime.js CHANGED
@@ -1,869 +1,882 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
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 { nixEffectAlways } from "./hooks/nixEffect";
24
- import { nixEffectOnce } from "./hooks/nixEffect";
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 createFynix from "./router/router.js";
29
- const TEXT = Symbol("text");
30
- const Fragment = Symbol("Fragment");
31
- const BOOLEAN_ATTRS = /* @__PURE__ */ new Set([
32
- "checked",
33
- "selected",
34
- "disabled",
35
- "readonly",
36
- "multiple",
37
- "autoplay",
38
- "controls",
39
- "loop",
40
- "muted",
41
- "open",
42
- "required",
43
- "reversed",
44
- "scoped",
45
- "seamless",
46
- "autofocus",
47
- "novalidate",
48
- "formnovalidate"
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 = /* @__PURE__ */ new Set([
51
- "value",
52
- "checked",
53
- "selected",
54
- "selectedIndex",
55
- "innerHTML",
56
- "textContent",
57
- "innerText"
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
- if (text == null || text === false)
61
- return { type: TEXT, props: { nodeValue: "" }, key: null };
62
- if (text && typeof text === "object" && text._isNixState) {
63
- const vnode = {
64
- type: TEXT,
65
- props: { nodeValue: String(text.value) },
66
- key: null,
67
- _state: text,
68
- _cleanup: null
69
- // FIX: Track subscription cleanup
70
- };
71
- vnode._cleanup = text.subscribe(() => {
72
- if (vnode._domNode)
73
- vnode._domNode.nodeValue = String(text.value);
74
- });
75
- return vnode;
76
- }
77
- return { type: TEXT, props: { nodeValue: String(text) }, key: null };
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
- __name(createTextVNode, "createTextVNode");
80
- function h(type, props = {}, ...children) {
81
- if (props === null || typeof props !== "object" || Array.isArray(props))
82
- props = {};
83
- const flatChildren = [];
84
- for (const c of children.flat(Infinity)) {
85
- if (c == null || c === false)
86
- continue;
87
- if (c && typeof c === "object" && c._isNixState)
88
- flatChildren.push(createTextVNode(c));
89
- else if (typeof c === "string" || typeof c === "number")
90
- flatChildren.push(createTextVNode(c));
91
- else if (c?.type === Fragment)
92
- flatChildren.push(
93
- ...(c.props.children || []).filter((x) => x != null && x !== false)
94
- );
95
- else if (c?.type)
96
- flatChildren.push(c);
97
- else
98
- flatChildren.push(createTextVNode(String(c)));
99
- }
100
- const key = props.key ?? null;
101
- if (key)
102
- delete props.key;
103
- if (type === Fragment)
104
- return { type: Fragment, props: { children: flatChildren }, key };
105
- return { type, props: { ...props, children: flatChildren }, key };
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
- __name(h, "h");
108
- h.Fragment = ({ children }) => children;
109
- const Fynix = h;
115
+ h.Fragment = ({ children }) => children || [];
116
+ export const Fynix = h;
110
117
  Fynix.Fragment = h.Fragment;
111
- const componentInstances = /* @__PURE__ */ new WeakMap();
118
+ const componentInstances = new WeakMap();
112
119
  let rootRenderFn = null;
113
- const pendingRerenders = /* @__PURE__ */ new WeakSet();
120
+ const pendingRerenders = new WeakSet();
114
121
  function beginComponent(vnode) {
115
- let ctx = componentInstances.get(vnode);
116
- if (!ctx) {
117
- ctx = {
118
- hooks: [],
119
- hookIndex: 0,
120
- effects: [],
121
- cleanups: [],
122
- _vnode: vnode,
123
- _accessedStates: /* @__PURE__ */ new Set(),
124
- _subscriptions: /* @__PURE__ */ new Set(),
125
- _subscriptionCleanups: [],
126
- version: 0,
127
- /** @type {undefined | (() => void)} */
128
- rerender: void 0,
129
- Component: vnode.type,
130
- _isMounted: false,
131
- _isRerendering: false
132
- };
133
- componentInstances.set(vnode, ctx);
134
- }
135
- ctx.hookIndex = 0;
136
- ctx._accessedStates.clear();
137
- setActiveContext(ctx);
138
- ctx.version++;
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
- const ctx = activeContext;
144
- if (!ctx)
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
- if (rerenderTimeout) {
222
- clearTimeout(rerenderTimeout);
223
- }
224
- rerenderTimeout = setTimeout(() => {
225
- if (ctx._isRerendering || !ctx._isMounted)
226
- return;
227
- ctx._isRerendering = true;
228
- pendingRerenders.add(ctx);
229
- try {
230
- removeErrorOverlay();
231
- const vnode2 = ctx._vnode;
232
- const oldRendered = vnode2._rendered;
233
- beginComponent(vnode2);
234
- const newRendered = ctx.Component(vnode2.props);
235
- endComponent();
236
- vnode2._rendered = newRendered;
237
- const domNode = vnode2._domNode;
238
- if (domNode && domNode.parentNode) {
239
- patch(domNode.parentNode, newRendered, oldRendered).then(() => {
240
- vnode2._domNode = newRendered?._domNode;
241
- }).finally(() => {
242
- ctx._isRerendering = false;
243
- pendingRerenders.delete(ctx);
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
- } else if (rootRenderFn) {
246
- rootRenderFn().finally(() => {
247
- ctx._isRerendering = false;
248
- pendingRerenders.delete(ctx);
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
- } else {
251
- ctx._isRerendering = false;
252
- pendingRerenders.delete(ctx);
253
- }
254
- } catch (err) {
255
- console.error("[Fynix] Component rerender error:", err);
256
- showErrorOverlay(err);
257
- ctx._isRerendering = false;
258
- pendingRerenders.delete(ctx);
259
- }
260
- rerenderTimeout = null;
261
- }, 0);
262
- };
263
- }
264
- try {
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
- __name(renderComponent, "renderComponent");
280
- const delegatedEvents = /* @__PURE__ */ new Map();
311
+ const delegatedEvents = new Map();
281
312
  let eventIdCounter = 1;
282
313
  function ensureDelegated(eventType) {
283
- if (delegatedEvents.has(eventType))
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
- cur = cur.parentElement;
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
- if (!fn || el.nodeType !== 1)
304
- return;
305
- const eid = el._rest_eid ?? (el._rest_eid = ++eventIdCounter);
306
- ensureDelegated(eventName);
307
- delegatedEvents.get(eventName).set(eid, (e) => {
308
- try {
309
- fn.call(el, e);
310
- } catch (err) {
311
- console.error("[Fynix] Event handler error:", err);
312
- showErrorOverlay(err);
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
- const k = key.toLowerCase();
319
- if (key === "r-class" || key === "rc") {
320
- if (typeof value === "string")
321
- el.setAttribute("class", value);
322
- else if (value && (value._isNixState || value._isRestState)) {
323
- el.setAttribute("class", value.value);
324
- if (!el._fynixCleanups)
325
- el._fynixCleanups = [];
326
- const unsub = value.subscribe(
327
- () => el.setAttribute("class", value.value)
328
- );
329
- el._fynixCleanups.push(unsub);
330
- }
331
- return;
332
- }
333
- if (key.startsWith("r-")) {
334
- registerDelegatedHandler(el, key.slice(2).toLowerCase(), value);
335
- return;
336
- }
337
- if (key === "style" && typeof value === "object") {
338
- Object.assign(el.style, value);
339
- return;
340
- }
341
- if (key === "innerHTML" || key === "outerHTML") {
342
- console.warn(
343
- "[Fynix] Security: innerHTML/outerHTML not allowed. Use textContent or children."
344
- );
345
- return;
346
- }
347
- if (BOOLEAN_ATTRS.has(k)) {
348
- if (value) {
349
- el.setAttribute(k, "");
350
- el[k] = true;
351
- } else {
352
- el.removeAttribute(k);
353
- el[k] = false;
354
- }
355
- return;
356
- }
357
- if (DOM_PROPERTIES.has(key)) {
358
- el[key] = value ?? "";
359
- return;
360
- }
361
- if (key.startsWith("data-") || key.startsWith("aria-")) {
362
- if (value != null && value !== false)
363
- el.setAttribute(key, value);
364
- else
365
- el.removeAttribute(key);
366
- return;
367
- }
368
- if ((key === "href" || key === "src") && typeof value === "string") {
369
- if (value.trim().toLowerCase().startsWith("javascript:")) {
370
- console.warn("[Fynix] Security: javascript: protocol blocked in", key);
371
- return;
372
- }
373
- }
374
- if (value != null && value !== false)
375
- el.setAttribute(key, value);
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
- if (vnode == null || vnode === false)
380
- return document.createTextNode("");
381
- if (typeof vnode === "string" || typeof vnode === "number")
382
- return document.createTextNode(String(vnode));
383
- if (vnode.type === TEXT) {
384
- const textNode = existing || document.createTextNode(vnode.props.nodeValue ?? "");
385
- vnode._domNode = textNode;
386
- return textNode;
387
- }
388
- if (vnode instanceof Promise) {
389
- const placeholder = document.createTextNode("Loading...");
390
- vnode.then(async (resolved) => {
391
- try {
392
- const dom = await createDom(resolved);
393
- if (placeholder.parentNode) {
394
- placeholder.replaceWith(dom);
395
- }
396
- } catch (err) {
397
- console.error("[Fynix] Async component error:", err);
398
- if (placeholder.parentNode) {
399
- placeholder.textContent = "Error loading component";
400
- }
401
- }
402
- }).catch((err) => {
403
- console.error("[Fynix] Async component promise error:", err);
404
- if (placeholder.parentNode) {
405
- placeholder.textContent = "Error loading async component";
406
- }
407
- });
408
- return placeholder;
409
- }
410
- if (vnode.type === Fragment) {
411
- const frag = document.createDocumentFragment();
412
- for (const child of vnode.props?.children || [])
413
- frag.appendChild(await createDom(child));
414
- vnode._domNode = frag;
415
- return frag;
416
- }
417
- if (typeof vnode.type === "function") {
418
- const rendered = await renderMaybeAsyncComponent(
419
- vnode.type,
420
- vnode.props,
421
- vnode
422
- );
423
- vnode._rendered = rendered;
424
- const dom = await createDom(rendered);
425
- vnode._domNode = dom;
426
- return dom;
427
- }
428
- const el = existing || document.createElement(vnode.type);
429
- for (const [k, v] of Object.entries(vnode.props || {}))
430
- if (k !== "children")
431
- setProperty(el, k, v);
432
- for (const child of vnode.props?.children || [])
433
- el.appendChild(await createDom(child));
434
- vnode._domNode = el;
435
- return el;
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
- const ctx = beginComponent(vnode);
440
- removeErrorOverlay();
441
- try {
442
- const result = await Component(props);
443
- ctx._vnode = vnode;
444
- vnode._rendered = result;
445
- ctx._isMounted = true;
446
- endComponent();
447
- return result ?? null;
448
- } catch (err) {
449
- console.error("[Fynix] async render error:", err);
450
- showErrorOverlay(err);
451
- ctx._isMounted = false;
452
- endComponent();
453
- return h("div", { style: "color:red" }, `Error: ${err.message}`);
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
- __name(renderMaybeAsyncComponent, "renderMaybeAsyncComponent");
457
- async function patch(parent, newVNode, oldVNode) {
458
- if (!(parent instanceof Node)) {
459
- console.error(
460
- "[Fynix] patch() expects a DOM Node, got:",
461
- typeof parent,
462
- parent
463
- );
464
- return;
465
- }
466
- if (!newVNode && !oldVNode)
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
- return;
565
- }
566
- const el = oldVNode._domNode;
567
- if (!el || el.nodeType !== 1) {
568
- const newDom = await createDom(newVNode);
569
- if (parent && newDom instanceof Node) {
570
- parent.appendChild(newDom);
571
- }
572
- unmountVNode(oldVNode);
573
- return;
574
- }
575
- updateProps(el, newVNode.props, oldVNode.props);
576
- newVNode._domNode = el;
577
- const newChildren = newVNode.props?.children || [];
578
- const oldChildren = oldVNode.props?.children || [];
579
- await patchChildren(el, newChildren, oldChildren);
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
- if (!(parent instanceof Node))
584
- return;
585
- const hasKeys = newChildren.some((c) => c?.key != null) || oldChildren.some((c) => c?.key != null);
586
- if (!hasKeys) {
587
- const maxLen = Math.max(newChildren.length, oldChildren.length);
588
- for (let i = 0; i < maxLen; i++) {
589
- const newChild = newChildren[i];
590
- const oldChild = oldChildren[i];
591
- if (i >= newChildren.length) {
592
- const dom = oldChild?._domNode;
593
- if (dom?.parentNode)
594
- dom.parentNode.removeChild(dom);
595
- unmountVNode(oldChild);
596
- } else if (i >= oldChildren.length) {
597
- const newDom = await createDom(newChild);
598
- if (newDom instanceof Node) {
599
- parent.appendChild(newDom);
600
- }
601
- } else {
602
- await patch(parent, newChild, oldChild);
603
- }
604
- }
605
- return;
606
- }
607
- const oldKeyMap = /* @__PURE__ */ new Map();
608
- const oldIndexMap = /* @__PURE__ */ new Map();
609
- oldChildren.forEach((child, idx) => {
610
- if (child?.key != null) {
611
- oldKeyMap.set(child.key, child);
612
- oldIndexMap.set(child.key, idx);
613
- }
614
- });
615
- const newKeySet = new Set(
616
- newChildren.filter((c) => c?.key != null).map((c) => c.key)
617
- );
618
- oldChildren.forEach((oldChild) => {
619
- if (oldChild?.key != null && !newKeySet.has(oldChild.key)) {
620
- const dom = oldChild._domNode;
621
- if (dom?.parentNode)
622
- dom.parentNode.removeChild(dom);
623
- unmountVNode(oldChild);
624
- }
625
- });
626
- for (let i = 0; i < newChildren.length; i++) {
627
- const newChild = newChildren[i];
628
- const key = newChild?.key;
629
- if (key != null && oldKeyMap.has(key)) {
630
- const oldChild = oldKeyMap.get(key);
631
- const oldDom = oldChild._domNode;
632
- const childNodes = Array.from(parent.childNodes);
633
- const currentPos = childNodes.indexOf(oldDom);
634
- const desiredPos = i;
635
- if (currentPos !== desiredPos) {
636
- const refNode = childNodes[desiredPos] || null;
637
- if (oldDom && oldDom.parentNode === parent) {
638
- parent.insertBefore(oldDom, refNode);
639
- }
640
- }
641
- await patch(parent, newChild, oldChild);
642
- } else {
643
- const newDom = await createDom(newChild);
644
- if (newDom instanceof Node) {
645
- const childNodes = Array.from(parent.childNodes);
646
- const refNode = childNodes[i] || null;
647
- parent.insertBefore(newDom, refNode);
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
- if (!vnode)
655
- return;
656
- if (vnode._cleanup && typeof vnode._cleanup === "function") {
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
- u();
671
- } catch (e) {
672
- console.error("[Fynix] Cleanup error:", e);
695
+ vnode._cleanup();
673
696
  }
674
- });
675
- ctx.cleanups.forEach((c) => {
676
- try {
677
- c?.();
678
- } catch (e) {
679
- console.error("[Fynix] Effect cleanup error:", e);
680
- }
681
- });
682
- ctx._subscriptions.clear();
683
- ctx._accessedStates.clear();
684
- ctx._subscriptionCleanups = [];
685
- ctx.cleanups = [];
686
- ctx.hooks = [];
687
- ctx.effects = [];
688
- ctx.rerender = null;
689
- ctx._vnode = null;
690
- componentInstances.delete(vnode);
691
- pendingRerenders.delete(ctx);
692
- }
693
- unmountVNode(vnode._rendered);
694
- return;
695
- }
696
- if (vnode._domNode && vnode._domNode.nodeType === 1) {
697
- const eid = vnode._domNode._rest_eid;
698
- if (eid) {
699
- delegatedEvents.forEach((map) => map.delete(eid));
700
- }
701
- if (vnode._domNode._fynixCleanups) {
702
- vnode._domNode._fynixCleanups.forEach((cleanup) => {
703
- try {
704
- cleanup();
705
- } catch (e) {
706
- console.error("[Fynix] Element cleanup error:", e);
707
- }
708
- });
709
- vnode._domNode._fynixCleanups = null;
710
- }
711
- }
712
- if (vnode.props?.children)
713
- vnode.props.children.forEach((c) => unmountVNode(c));
714
- vnode._domNode = null;
715
- vnode._rendered = null;
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
- if (!el || el.nodeType !== 1)
720
- return;
721
- for (const k of Object.keys(oldProps)) {
722
- if (k === "children")
723
- continue;
724
- if (!(k in newProps)) {
725
- if (k.startsWith("r-")) {
726
- const eid = el._rest_eid;
727
- if (eid && delegatedEvents.has(k.slice(2).toLowerCase())) {
728
- delegatedEvents.get(k.slice(2).toLowerCase()).delete(eid);
729
- }
730
- } else if (BOOLEAN_ATTRS.has(k.toLowerCase())) {
731
- el.removeAttribute(k);
732
- el[k] = false;
733
- } else if (DOM_PROPERTIES.has(k))
734
- el[k] = "";
735
- else
736
- el.removeAttribute(k);
737
- }
738
- }
739
- for (const [k, v] of Object.entries(newProps)) {
740
- if (k === "children")
741
- continue;
742
- if (oldProps[k] !== v)
743
- setProperty(el, k, v);
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
- __name(updateProps, "updateProps");
747
- function mount(AppComponent, root, hydrate = false, props = {}) {
748
- if (typeof root === "string") {
749
- const element = document.querySelector(root);
750
- if (!element) {
751
- console.error(
752
- "[Fynix] Mount error: Element not found for selector:",
753
- root
754
- );
755
- return;
756
- }
757
- root = element;
758
- }
759
- if (!(root instanceof Element)) {
760
- console.error("[Fynix] Mount error: Invalid root element", root);
761
- return;
762
- }
763
- let Component = AppComponent;
764
- let oldVNode = null;
765
- let currentProps = props;
766
- let appVNode = null;
767
- let isRendering = false;
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
- const UpdatedComponent = mod.App || mod.default;
816
- if (UpdatedComponent) {
817
- Component = UpdatedComponent;
818
- if (appVNode) {
819
- appVNode.type = UpdatedComponent;
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
- import.meta.hot.accept();
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
- __name(mount, "mount");
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, };