what-core 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/render.js CHANGED
@@ -8,42 +8,41 @@ var insideComputed = false;
8
8
  var batchDepth = 0;
9
9
  var pendingEffects = [];
10
10
  var pendingNeedSort = false;
11
- var subSetOwner = /* @__PURE__ */ new WeakMap();
12
11
  var NEEDS_UPSTREAM = /* @__PURE__ */ Symbol("needs_upstream");
13
12
  function signal(initial, debugName) {
14
13
  let value = initial;
15
14
  const subs = /* @__PURE__ */ new Set();
16
- function sig(...args) {
17
- if (args.length === 0) {
18
- if (currentEffect) {
19
- subs.add(currentEffect);
20
- currentEffect.deps.push(subs);
21
- }
22
- return value;
23
- }
15
+ let lastTracked = null;
16
+ let lastTrackedEpoch = 0;
17
+ function _sigWrite(next) {
24
18
  if (__DEV__ && insideComputed) {
25
19
  console.warn(
26
20
  "[what] Signal.set() called inside a computed function. This may cause infinite loops. Use effect() instead." + (debugName ? ` (signal: ${debugName})` : "")
27
21
  );
28
22
  }
29
- const nextVal = typeof args[0] === "function" ? args[0](value) : args[0];
30
- if (Object.is(value, nextVal)) return;
23
+ const nextVal = typeof next === "function" ? next(value) : next;
24
+ if (value === nextVal || value !== value && nextVal !== nextVal) return;
31
25
  value = nextVal;
26
+ lastTracked = null;
32
27
  if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);
33
28
  if (subs.size > 0) notify(subs);
34
29
  }
35
- sig.set = (next) => {
36
- if (__DEV__ && insideComputed) {
37
- console.warn(
38
- "[what] Signal.set() called inside a computed function. This may cause infinite loops. Use effect() instead." + (debugName ? ` (signal: ${debugName})` : "")
39
- );
30
+ function sig(newVal) {
31
+ if (arguments.length === 0) {
32
+ const ce = currentEffect;
33
+ if (ce !== null) {
34
+ if (ce !== lastTracked || ce._epoch !== lastTrackedEpoch) {
35
+ lastTracked = ce;
36
+ lastTrackedEpoch = ce._epoch;
37
+ subs.add(ce);
38
+ ce.deps.push(subs);
39
+ }
40
+ }
41
+ return value;
40
42
  }
41
- const nextVal = typeof next === "function" ? next(value) : next;
42
- if (Object.is(value, nextVal)) return;
43
- value = nextVal;
44
- if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);
45
- if (subs.size > 0) notify(subs);
46
- };
43
+ _sigWrite(newVal);
44
+ }
45
+ sig.set = _sigWrite;
47
46
  sig.peek = () => value;
48
47
  sig.subscribe = (fn) => {
49
48
  return effect(() => fn(sig()));
@@ -60,7 +59,7 @@ function _updateLevel(e) {
60
59
  let maxDepLevel = 0;
61
60
  const deps = e.deps;
62
61
  for (let i = 0; i < deps.length; i++) {
63
- const owner = subSetOwner.get(deps[i]);
62
+ const owner = deps[i]._owner;
64
63
  if (owner) {
65
64
  const depLevel = owner._level;
66
65
  if (depLevel > maxDepLevel) maxDepLevel = depLevel;
@@ -106,8 +105,12 @@ function _createEffect(fn, lazy) {
106
105
  // reference to the computed's subscriber set
107
106
  _isDirty: null,
108
107
  // function to check if computed is dirty (set by computed())
109
- _markDirty: null
108
+ _markDirty: null,
110
109
  // function to mark computed dirty (set by computed())
110
+ _cleanup: null,
111
+ // cleanup function returned by effect fn (declared upfront for shape)
112
+ _epoch: 0
113
+ // incremented on cleanup — used by signal lastTracked cache
111
114
  };
112
115
  if (__DEV__ && __devtools) __devtools.onEffectCreate(e);
113
116
  return e;
@@ -137,12 +140,13 @@ function _runEffect(e) {
137
140
  if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);
138
141
  return;
139
142
  }
143
+ const singleDep = e.deps.length === 1 ? e.deps[0] : null;
140
144
  cleanup(e);
141
145
  if (e._cleanup) {
142
146
  try {
143
147
  e._cleanup();
144
148
  } catch (err) {
145
- if (__devtools?.onError) __devtools.onError(err, { type: "effect-cleanup", effect: e });
149
+ if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect-cleanup", effect: e });
146
150
  if (__DEV__) console.warn("[what] Error in effect cleanup:", err);
147
151
  }
148
152
  e._cleanup = null;
@@ -156,11 +160,14 @@ function _runEffect(e) {
156
160
  }
157
161
  } catch (err) {
158
162
  if (err === NEEDS_UPSTREAM) throw err;
159
- if (__devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
163
+ if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
160
164
  throw err;
161
165
  } finally {
162
166
  currentEffect = prev;
163
167
  }
168
+ if (singleDep !== null && e.deps.length === 1 && e.deps[0] === singleDep && !e._cleanup && !e._pending) {
169
+ e._stable = true;
170
+ }
164
171
  if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);
165
172
  }
166
173
  function _disposeEffect(e) {
@@ -180,45 +187,51 @@ function cleanup(e) {
180
187
  const deps = e.deps;
181
188
  for (let i = 0; i < deps.length; i++) deps[i].delete(e);
182
189
  deps.length = 0;
190
+ e._epoch++;
183
191
  }
184
192
  var notifyDepth = 0;
185
193
  var notifyQueue = null;
186
194
  var notifyQueueLen = 0;
195
+ function _processSubscriber(e) {
196
+ if (e.disposed) return;
197
+ if (e._onNotify) {
198
+ e._onNotify();
199
+ } else if (!e._pending) {
200
+ if (batchDepth === 0 && e._stable) {
201
+ const prev = currentEffect;
202
+ currentEffect = null;
203
+ try {
204
+ const result = e.fn();
205
+ if (typeof result === "function") {
206
+ if (e._cleanup) try {
207
+ e._cleanup();
208
+ } catch (err) {
209
+ }
210
+ e._cleanup = result;
211
+ }
212
+ } catch (err) {
213
+ if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
214
+ if (__DEV__) console.warn("[what] Error in stable effect:", err);
215
+ } finally {
216
+ currentEffect = prev;
217
+ }
218
+ } else {
219
+ e._pending = true;
220
+ const level = e._level;
221
+ const len = pendingEffects.length;
222
+ if (len > 0 && pendingEffects[len - 1]._level > level) {
223
+ pendingNeedSort = true;
224
+ }
225
+ pendingEffects.push(e);
226
+ }
227
+ }
228
+ }
187
229
  function notify(subs) {
188
230
  if (notifyDepth === 0) {
189
231
  notifyDepth = 1;
190
232
  try {
191
233
  for (const e of subs) {
192
- if (e.disposed) continue;
193
- if (e._onNotify) {
194
- e._onNotify();
195
- } else if (batchDepth === 0 && e._stable) {
196
- const prev = currentEffect;
197
- currentEffect = null;
198
- try {
199
- const result = e.fn();
200
- if (typeof result === "function") {
201
- if (e._cleanup) try {
202
- e._cleanup();
203
- } catch (err) {
204
- }
205
- e._cleanup = result;
206
- }
207
- } catch (err) {
208
- if (__devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
209
- if (__DEV__) console.warn("[what] Error in stable effect:", err);
210
- } finally {
211
- currentEffect = prev;
212
- }
213
- } else if (!e._pending) {
214
- e._pending = true;
215
- const level = e._level;
216
- const len = pendingEffects.length;
217
- if (len > 0 && pendingEffects[len - 1]._level > level) {
218
- pendingNeedSort = true;
219
- }
220
- pendingEffects.push(e);
221
- }
234
+ _processSubscriber(e);
222
235
  }
223
236
  if (notifyQueueLen > 0) {
224
237
  let qi = 0;
@@ -227,36 +240,7 @@ function notify(subs) {
227
240
  notifyQueue[qi] = null;
228
241
  qi++;
229
242
  for (const e of queuedSubs) {
230
- if (e.disposed) continue;
231
- if (e._onNotify) {
232
- e._onNotify();
233
- } else if (batchDepth === 0 && e._stable) {
234
- const prev = currentEffect;
235
- currentEffect = null;
236
- try {
237
- const result = e.fn();
238
- if (typeof result === "function") {
239
- if (e._cleanup) try {
240
- e._cleanup();
241
- } catch (err) {
242
- }
243
- e._cleanup = result;
244
- }
245
- } catch (err) {
246
- if (__devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
247
- if (__DEV__) console.warn("[what] Error in stable effect:", err);
248
- } finally {
249
- currentEffect = prev;
250
- }
251
- } else if (!e._pending) {
252
- e._pending = true;
253
- const level = e._level;
254
- const len = pendingEffects.length;
255
- if (len > 0 && pendingEffects[len - 1]._level > level) {
256
- pendingNeedSort = true;
257
- }
258
- pendingEffects.push(e);
259
- }
243
+ _processSubscriber(e);
260
244
  }
261
245
  }
262
246
  notifyQueueLen = 0;
@@ -312,8 +296,6 @@ function flush() {
312
296
  iterations++;
313
297
  }
314
298
  if (iterations >= 25) {
315
- for (let i = 0; i < pendingEffects.length; i++) pendingEffects[i]._pending = false;
316
- pendingEffects.length = 0;
317
299
  if (__DEV__) {
318
300
  const remaining = pendingEffects.slice(0, 3);
319
301
  const effectNames = remaining.map((e) => e.fn?.name || e.fn?.toString().slice(0, 60) || "(anonymous)");
@@ -323,6 +305,8 @@ function flush() {
323
305
  } else {
324
306
  console.warn("[what] Possible infinite effect loop detected");
325
307
  }
308
+ for (let i = 0; i < pendingEffects.length; i++) pendingEffects[i]._pending = false;
309
+ pendingEffects.length = 0;
326
310
  }
327
311
  } finally {
328
312
  isFlushing = false;
@@ -337,38 +321,43 @@ function untrack(fn) {
337
321
  currentEffect = prev;
338
322
  }
339
323
  }
340
- function createRoot(fn) {
324
+ function _disposeRoot(root) {
325
+ if (root._disposed) return;
326
+ root._disposed = true;
327
+ for (let i = root.children.length - 1; i >= 0; i--) {
328
+ _disposeRoot(root.children[i]);
329
+ }
330
+ root.children.length = 0;
331
+ for (let i = root.disposals.length - 1; i >= 0; i--) {
332
+ root.disposals[i]();
333
+ }
334
+ root.disposals.length = 0;
335
+ }
336
+ function _createItemScope(fn) {
341
337
  const prevRoot = currentRoot;
342
338
  const prevOwner = currentOwner;
343
- const root = {
339
+ const scope = {
344
340
  disposals: [],
345
- owner: currentOwner,
346
- // parent owner for ownership tree
341
+ owner: null,
342
+ // No parent registration
347
343
  children: [],
348
- // child roots (ownership tree)
344
+ // Kept for compat with effects that create sub-roots
349
345
  _disposed: false
350
346
  };
351
- if (currentOwner) {
352
- currentOwner.children.push(root);
353
- }
354
- currentRoot = root;
355
- currentOwner = root;
347
+ currentRoot = scope;
348
+ currentOwner = scope;
356
349
  try {
357
350
  const dispose = () => {
358
- if (root._disposed) return;
359
- root._disposed = true;
360
- for (let i = root.children.length - 1; i >= 0; i--) {
361
- _disposeRoot(root.children[i]);
362
- }
363
- root.children.length = 0;
364
- for (let i = root.disposals.length - 1; i >= 0; i--) {
365
- root.disposals[i]();
351
+ if (scope._disposed) return;
352
+ scope._disposed = true;
353
+ for (let i = scope.children.length - 1; i >= 0; i--) {
354
+ _disposeRoot(scope.children[i]);
366
355
  }
367
- root.disposals.length = 0;
368
- if (root.owner) {
369
- const idx = root.owner.children.indexOf(root);
370
- if (idx >= 0) root.owner.children.splice(idx, 1);
356
+ scope.children.length = 0;
357
+ for (let i = scope.disposals.length - 1; i >= 0; i--) {
358
+ scope.disposals[i]();
371
359
  }
360
+ scope.disposals.length = 0;
372
361
  };
373
362
  return fn(dispose);
374
363
  } finally {
@@ -376,18 +365,6 @@ function createRoot(fn) {
376
365
  currentOwner = prevOwner;
377
366
  }
378
367
  }
379
- function _disposeRoot(root) {
380
- if (root._disposed) return;
381
- root._disposed = true;
382
- for (let i = root.children.length - 1; i >= 0; i--) {
383
- _disposeRoot(root.children[i]);
384
- }
385
- root.children.length = 0;
386
- for (let i = root.disposals.length - 1; i >= 0; i--) {
387
- root.disposals[i]();
388
- }
389
- root.disposals.length = 0;
390
- }
391
368
 
392
369
  // packages/core/src/components.js
393
370
  var _getCurrentComponent = null;
@@ -520,9 +497,11 @@ function disposeTree(node) {
520
497
  if (node._componentCtx) {
521
498
  disposeComponent(node._componentCtx);
522
499
  }
523
- const commentCtx = _commentCtxMap.get(node);
524
- if (commentCtx) {
525
- disposeComponent(commentCtx);
500
+ if (node.nodeType === 8) {
501
+ const commentCtx = _commentCtxMap.get(node);
502
+ if (commentCtx) {
503
+ disposeComponent(commentCtx);
504
+ }
526
505
  }
527
506
  if (node._dispose) {
528
507
  try {
@@ -538,9 +517,10 @@ function disposeTree(node) {
538
517
  }
539
518
  }
540
519
  }
541
- if (node.childNodes) {
542
- for (const child of node.childNodes) {
543
- disposeTree(child);
520
+ const children = node.childNodes;
521
+ if (children && children.length > 0) {
522
+ for (let i = 0; i < children.length; i++) {
523
+ disposeTree(children[i]);
544
524
  }
545
525
  }
546
526
  }
@@ -605,6 +585,27 @@ function createDOM(vnode, parent, isSvg) {
605
585
  }
606
586
  return document.createTextNode(String(vnode));
607
587
  }
588
+ var _propsProxyHandler = {
589
+ get(target, key) {
590
+ if (key === "_sig") return void 0;
591
+ return target._sig()[key];
592
+ },
593
+ has(target, key) {
594
+ if (key === "_sig") return false;
595
+ return key in target._sig();
596
+ },
597
+ ownKeys(target) {
598
+ return Reflect.ownKeys(target._sig());
599
+ },
600
+ getOwnPropertyDescriptor(target, key) {
601
+ if (key === "_sig") return void 0;
602
+ const current = target._sig();
603
+ if (key in current) {
604
+ return { value: current[key], writable: false, enumerable: true, configurable: true };
605
+ }
606
+ return void 0;
607
+ }
608
+ };
608
609
  var componentStack = [];
609
610
  function getCurrentComponent() {
610
611
  return componentStack[componentStack.length - 1];
@@ -633,6 +634,21 @@ function createComponent(vnode, parent, isSvg) {
633
634
  if (Component === "__portal" || vnode.tag === "__portal") {
634
635
  return createPortalDOM(vnode, parent);
635
636
  }
637
+ const parentCtx = componentStack[componentStack.length - 1] || null;
638
+ let errorBoundary = null;
639
+ if (parentCtx) {
640
+ errorBoundary = parentCtx._errorBoundary || null;
641
+ if (!errorBoundary) {
642
+ let p = parentCtx._parentCtx;
643
+ while (p) {
644
+ if (p._errorBoundary) {
645
+ errorBoundary = p._errorBoundary;
646
+ break;
647
+ }
648
+ p = p._parentCtx;
649
+ }
650
+ }
651
+ }
636
652
  const ctx = {
637
653
  hooks: [],
638
654
  hookIndex: 0,
@@ -641,15 +657,8 @@ function createComponent(vnode, parent, isSvg) {
641
657
  mounted: false,
642
658
  disposed: false,
643
659
  Component,
644
- _parentCtx: componentStack[componentStack.length - 1] || null,
645
- _errorBoundary: (() => {
646
- let p = componentStack[componentStack.length - 1];
647
- while (p) {
648
- if (p._errorBoundary) return p._errorBoundary;
649
- p = p._parentCtx;
650
- }
651
- return null;
652
- })()
660
+ _parentCtx: parentCtx,
661
+ _errorBoundary: errorBoundary
653
662
  };
654
663
  const startComment = document.createComment("c:start");
655
664
  const endComment = document.createComment("c:end");
@@ -662,29 +671,15 @@ function createComponent(vnode, parent, isSvg) {
662
671
  mountedComponents.add(ctx);
663
672
  if (__DEV__ && __devtools?.onComponentMount) __devtools.onComponentMount(ctx);
664
673
  const propsChildren = children.length === 0 ? void 0 : children.length === 1 ? children[0] : children;
665
- const propsSignal = signal({ ...props, children: propsChildren });
674
+ let mergedProps;
675
+ if (propsChildren !== void 0) {
676
+ mergedProps = props ? Object.assign({}, props, { children: propsChildren }) : { children: propsChildren };
677
+ } else {
678
+ mergedProps = props ? Object.assign({}, props) : {};
679
+ }
680
+ const propsSignal = signal(mergedProps);
666
681
  ctx._propsSignal = propsSignal;
667
- const reactiveProps = new Proxy({}, {
668
- get(_, key) {
669
- const current = propsSignal();
670
- return current[key];
671
- },
672
- has(_, key) {
673
- const current = propsSignal();
674
- return key in current;
675
- },
676
- ownKeys() {
677
- const current = propsSignal();
678
- return Reflect.ownKeys(current);
679
- },
680
- getOwnPropertyDescriptor(_, key) {
681
- const current = propsSignal();
682
- if (key in current) {
683
- return { value: current[key], writable: false, enumerable: true, configurable: true };
684
- }
685
- return void 0;
686
- }
687
- });
682
+ const reactiveProps = new Proxy({ _sig: propsSignal }, _propsProxyHandler);
688
683
  componentStack.push(ctx);
689
684
  let result;
690
685
  try {
@@ -865,21 +860,22 @@ function createElementFromVNode(vnode, parent, isSvg) {
865
860
  if (props) {
866
861
  applyProps(el, props, {}, svgContext);
867
862
  }
868
- for (const child of children) {
869
- const node = createDOM(child, el, svgContext && tag !== "foreignObject");
863
+ const isSvgChildren = svgContext && tag !== "foreignObject";
864
+ for (let i = 0; i < children.length; i++) {
865
+ const node = createDOM(children[i], el, isSvgChildren);
870
866
  if (node) el.appendChild(node);
871
867
  }
872
868
  el._vnode = vnode;
873
869
  return el;
874
870
  }
875
871
  function applyProps(el, newProps, oldProps, isSvg) {
876
- newProps = newProps || {};
877
- oldProps = oldProps || {};
872
+ if (!newProps) return;
878
873
  for (const key in newProps) {
879
874
  if (key === "key" || key === "children") continue;
880
875
  if (key === "ref") {
881
- if (typeof newProps.ref === "function") newProps.ref(el);
882
- else if (newProps.ref) newProps.ref.current = el;
876
+ const ref = newProps.ref;
877
+ if (typeof ref === "function") ref(el);
878
+ else if (ref) ref.current = el;
883
879
  continue;
884
880
  }
885
881
  setProp(el, key, newProps[key], isSvg);
@@ -916,8 +912,9 @@ function setProp(el, key, value, isSvg) {
916
912
  if (!el._events) el._events = {};
917
913
  const wrappedHandler = (e) => {
918
914
  if (!e.nativeEvent) e.nativeEvent = e;
919
- return untrack(() => value(e));
915
+ return untrack(() => wrappedHandler._handler(e));
920
916
  };
917
+ wrappedHandler._handler = value;
921
918
  wrappedHandler._original = value;
922
919
  el._events[storageKey] = wrappedHandler;
923
920
  const eventOpts = value._eventOpts;
@@ -994,7 +991,11 @@ function setProp(el, key, value, isSvg) {
994
991
  function _$createComponent(Component, props, children) {
995
992
  if (children && children.length > 0) {
996
993
  const mergedChildren = children.length === 1 ? children[0] : children;
997
- props = props ? { ...props, children: mergedChildren } : { children: mergedChildren };
994
+ if (props) {
995
+ props.children = mergedChildren;
996
+ } else {
997
+ props = { children: mergedChildren };
998
+ }
998
999
  }
999
1000
  return createDOM({ tag: Component, props: props || {}, children: children || [], key: null, _vnode: true });
1000
1001
  }
@@ -1082,13 +1083,9 @@ function _$templateImpl(html) {
1082
1083
  if (tableInfo) {
1083
1084
  const t2 = document.createElement("template");
1084
1085
  t2.innerHTML = tableInfo.wrap + trimmed + tableInfo.unwrap;
1085
- return () => {
1086
- let node = t2.content.firstChild;
1087
- for (let i = 0; i < tableInfo.depth; i++) {
1088
- node = node.firstChild;
1089
- }
1090
- return node.cloneNode(true);
1091
- };
1086
+ let target = t2.content.firstChild;
1087
+ for (let i = 0; i < tableInfo.depth; i++) target = target.firstChild;
1088
+ return () => target.cloneNode(true);
1092
1089
  }
1093
1090
  const t = document.createElement("template");
1094
1091
  t.innerHTML = trimmed;
@@ -1118,12 +1115,45 @@ function svgTemplate(html) {
1118
1115
  }
1119
1116
  function insert(parent, child, marker) {
1120
1117
  if (typeof child === "function") {
1121
- let current = null;
1118
+ const first = child();
1119
+ const t = typeof first;
1120
+ if (t === "string" || t === "number") {
1121
+ const textNode = document.createTextNode(String(first));
1122
+ const m = marker || null;
1123
+ if (m) parent.insertBefore(textNode, m);
1124
+ else parent.appendChild(textNode);
1125
+ let current2 = textNode;
1126
+ let isTextFastPath = true;
1127
+ effect(() => {
1128
+ const val = child();
1129
+ const vt = typeof val;
1130
+ if (isTextFastPath && (vt === "string" || vt === "number")) {
1131
+ const str = String(val);
1132
+ if (textNode.data !== str) textNode.data = str;
1133
+ } else {
1134
+ isTextFastPath = false;
1135
+ current2 = reconcileInsert(parent, val, current2, m);
1136
+ }
1137
+ });
1138
+ return textNode;
1139
+ }
1140
+ let current = first != null ? reconcileInsert(parent, first, null, marker || null) : null;
1122
1141
  effect(() => {
1123
1142
  current = reconcileInsert(parent, child(), current, marker || null);
1124
1143
  });
1125
1144
  return current;
1126
1145
  }
1146
+ if (typeof child === "string" || typeof child === "number") {
1147
+ const textNode = document.createTextNode(String(child));
1148
+ if (marker) parent.insertBefore(textNode, marker);
1149
+ else parent.appendChild(textNode);
1150
+ return textNode;
1151
+ }
1152
+ if (child != null && typeof child === "object" && child.nodeType > 0) {
1153
+ if (marker) parent.insertBefore(child, marker);
1154
+ else parent.appendChild(child);
1155
+ return child;
1156
+ }
1127
1157
  return reconcileInsert(parent, child, null, marker || null);
1128
1158
  }
1129
1159
  function isDomNode2(value) {
@@ -1134,8 +1164,9 @@ function isDomNode2(value) {
1134
1164
  function isVNode2(value) {
1135
1165
  return !!value && typeof value === "object" && (value._vnode === true || "tag" in value);
1136
1166
  }
1167
+ var _hasSVGElement = typeof SVGElement !== "undefined";
1137
1168
  function isSvgParent(parent) {
1138
- return typeof SVGElement !== "undefined" && parent instanceof SVGElement && parent.tagName.toLowerCase() !== "foreignobject";
1169
+ return _hasSVGElement && parent instanceof SVGElement && parent.tagName !== "foreignObject";
1139
1170
  }
1140
1171
  function asNodeArray(value) {
1141
1172
  if (value == null) return [];
@@ -1192,18 +1223,39 @@ function reconcileInsert(parent, value, current, marker) {
1192
1223
  }
1193
1224
  if ((typeof value === "string" || typeof value === "number") && current && !Array.isArray(current) && current.nodeType === 3) {
1194
1225
  const text = String(value);
1195
- if (current.textContent !== text) current.textContent = text;
1226
+ if (current.data !== text) current.data = text;
1196
1227
  return current;
1197
1228
  }
1229
+ if (typeof value === "object" && value !== null && value.nodeType > 0 && !Array.isArray(value)) {
1230
+ if (value === current) return current;
1231
+ if (current && !Array.isArray(current) && current.nodeType > 0) {
1232
+ if (current.parentNode === parent) {
1233
+ disposeTree(current);
1234
+ parent.replaceChild(value, current);
1235
+ } else {
1236
+ if (targetMarker) parent.insertBefore(value, targetMarker);
1237
+ else parent.appendChild(value);
1238
+ }
1239
+ return value;
1240
+ }
1241
+ }
1198
1242
  const newNodes = valuesToNodes(value, parent, []);
1199
1243
  const oldNodes = asNodeArray(current);
1200
1244
  if (sameNodeArray(oldNodes, newNodes)) {
1201
1245
  return current;
1202
1246
  }
1203
- const keep = new Set(newNodes);
1247
+ const newLen = newNodes.length;
1204
1248
  for (let i = 0; i < oldNodes.length; i++) {
1205
1249
  const oldNode = oldNodes[i];
1206
- if (!keep.has(oldNode) && oldNode.parentNode === parent) {
1250
+ if (oldNode.parentNode !== parent) continue;
1251
+ let found = false;
1252
+ for (let j = 0; j < newLen; j++) {
1253
+ if (newNodes[j] === oldNode) {
1254
+ found = true;
1255
+ break;
1256
+ }
1257
+ }
1258
+ if (!found) {
1207
1259
  disposeTree(oldNode);
1208
1260
  parent.removeChild(oldNode);
1209
1261
  }
@@ -1238,7 +1290,7 @@ function mapArray(source, mapFn, options) {
1238
1290
  } else {
1239
1291
  reconcileList(parent, endMarker, items, newItems, mappedNodes, disposeFns, mapFn);
1240
1292
  }
1241
- items = newItems.slice();
1293
+ items = newItems.length > 0 ? newItems.slice() : newItems;
1242
1294
  });
1243
1295
  return endMarker;
1244
1296
  };
@@ -1249,10 +1301,15 @@ function reconcileList(parent, endMarker, oldItems, newItems, mappedNodes, dispo
1249
1301
  if (newLen === 0) {
1250
1302
  if (oldLen > 0) {
1251
1303
  for (let i = 0; i < oldLen; i++) {
1252
- disposeFns[i]?.();
1253
- if (mappedNodes[i]?.parentNode === parent) {
1254
- disposeTree(mappedNodes[i]);
1255
- parent.removeChild(mappedNodes[i]);
1304
+ if (disposeFns[i]) disposeFns[i]();
1305
+ }
1306
+ for (let i = oldLen - 1; i >= 0; i--) {
1307
+ const node = mappedNodes[i];
1308
+ if (node) {
1309
+ if (node._componentCtx || node._dispose || node._propEffects) {
1310
+ disposeTree(node);
1311
+ }
1312
+ if (node.parentNode === parent) parent.removeChild(node);
1256
1313
  }
1257
1314
  }
1258
1315
  mappedNodes.length = 0;
@@ -1264,7 +1321,7 @@ function reconcileList(parent, endMarker, oldItems, newItems, mappedNodes, dispo
1264
1321
  const frag = document.createDocumentFragment();
1265
1322
  for (let i = 0; i < newLen; i++) {
1266
1323
  const item = newItems[i];
1267
- const node = createRoot((dispose) => {
1324
+ const node = _createItemScope((dispose) => {
1268
1325
  disposeFns[i] = dispose;
1269
1326
  return mapFn(item, i);
1270
1327
  });
@@ -1308,7 +1365,7 @@ function reconcileList(parent, endMarker, oldItems, newItems, mappedNodes, dispo
1308
1365
  for (let i = start; i <= newEnd; i++) {
1309
1366
  const item = newItems[i];
1310
1367
  const idx = i;
1311
- newMapped[i] = createRoot((dispose) => {
1368
+ newMapped[i] = _createItemScope((dispose) => {
1312
1369
  newDispose[idx] = dispose;
1313
1370
  return mapFn(item, idx);
1314
1371
  });
@@ -1388,7 +1445,7 @@ function _reconcileMiddle(parent, endMarker, oldItems, newItems, mappedNodes, di
1388
1445
  if (!newMapped[i]) {
1389
1446
  const item = newItems[i];
1390
1447
  const idx = i;
1391
- newMapped[i] = createRoot((dispose) => {
1448
+ newMapped[i] = _createItemScope((dispose) => {
1392
1449
  newDispose[idx] = dispose;
1393
1450
  return mapFn(item, idx);
1394
1451
  });
@@ -1446,10 +1503,15 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
1446
1503
  if (newLen === 0) {
1447
1504
  if (oldLen > 0) {
1448
1505
  for (let i = 0; i < oldLen; i++) {
1449
- disposeFns[i]?.();
1450
- if (mappedNodes[i]?.parentNode === parent) {
1451
- disposeTree(mappedNodes[i]);
1452
- parent.removeChild(mappedNodes[i]);
1506
+ if (disposeFns[i]) disposeFns[i]();
1507
+ }
1508
+ for (let i = oldLen - 1; i >= 0; i--) {
1509
+ const node = mappedNodes[i];
1510
+ if (node) {
1511
+ if (node._componentCtx || node._dispose || node._propEffects) {
1512
+ disposeTree(node);
1513
+ }
1514
+ if (node.parentNode === parent) parent.removeChild(node);
1453
1515
  }
1454
1516
  }
1455
1517
  mappedNodes.length = 0;
@@ -1472,7 +1534,7 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
1472
1534
  } else {
1473
1535
  accessor = item;
1474
1536
  }
1475
- const node = createRoot((dispose) => {
1537
+ const node = _createItemScope((dispose) => {
1476
1538
  disposeFns[idx] = dispose;
1477
1539
  return mapFn(accessor, idx);
1478
1540
  });
@@ -1541,7 +1603,7 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
1541
1603
  } else {
1542
1604
  accessor = item;
1543
1605
  }
1544
- newMapped[i] = createRoot((dispose) => {
1606
+ newMapped[i] = _createItemScope((dispose) => {
1545
1607
  newDispose[idx] = dispose;
1546
1608
  return mapFn(accessor, idx);
1547
1609
  });
@@ -1597,7 +1659,7 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
1597
1659
  } else {
1598
1660
  accessor = item;
1599
1661
  }
1600
- newMapped[i] = createRoot((dispose) => {
1662
+ newMapped[i] = _createItemScope((dispose) => {
1601
1663
  newDispose[idx] = dispose;
1602
1664
  return mapFn(accessor, idx);
1603
1665
  });