what-core 0.6.2 → 0.8.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]);
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]);
362
355
  }
363
- root.children.length = 0;
364
- for (let i = root.disposals.length - 1; i >= 0; i--) {
365
- root.disposals[i]();
366
- }
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;
@@ -991,10 +988,18 @@ function setProp(el, key, value, isSvg) {
991
988
  }
992
989
 
993
990
  // packages/core/src/render.js
991
+ var _onTextInsert = null;
992
+ function _setTextInsertHook(fn) {
993
+ _onTextInsert = typeof fn === "function" ? fn : null;
994
+ }
994
995
  function _$createComponent(Component, props, children) {
995
996
  if (children && children.length > 0) {
996
997
  const mergedChildren = children.length === 1 ? children[0] : children;
997
- props = props ? { ...props, children: mergedChildren } : { children: mergedChildren };
998
+ if (props) {
999
+ props.children = mergedChildren;
1000
+ } else {
1001
+ props = { children: mergedChildren };
1002
+ }
998
1003
  }
999
1004
  return createDOM({ tag: Component, props: props || {}, children: children || [], key: null, _vnode: true });
1000
1005
  }
@@ -1082,13 +1087,9 @@ function _$templateImpl(html) {
1082
1087
  if (tableInfo) {
1083
1088
  const t2 = document.createElement("template");
1084
1089
  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
- };
1090
+ let target = t2.content.firstChild;
1091
+ for (let i = 0; i < tableInfo.depth; i++) target = target.firstChild;
1092
+ return () => target.cloneNode(true);
1092
1093
  }
1093
1094
  const t = document.createElement("template");
1094
1095
  t.innerHTML = trimmed;
@@ -1118,12 +1119,47 @@ function svgTemplate(html) {
1118
1119
  }
1119
1120
  function insert(parent, child, marker) {
1120
1121
  if (typeof child === "function") {
1121
- let current = null;
1122
+ const first = child();
1123
+ const t = typeof first;
1124
+ if (t === "string" || t === "number") {
1125
+ const textNode = document.createTextNode(String(first));
1126
+ const m = marker || null;
1127
+ if (m) parent.insertBefore(textNode, m);
1128
+ else parent.appendChild(textNode);
1129
+ if (_onTextInsert) _onTextInsert(parent, String(first));
1130
+ let current2 = textNode;
1131
+ let isTextFastPath = true;
1132
+ effect(() => {
1133
+ const val = child();
1134
+ const vt = typeof val;
1135
+ if (isTextFastPath && (vt === "string" || vt === "number")) {
1136
+ const str = String(val);
1137
+ if (textNode.data !== str) textNode.data = str;
1138
+ if (_onTextInsert) _onTextInsert(parent, str);
1139
+ } else {
1140
+ isTextFastPath = false;
1141
+ current2 = reconcileInsert(parent, val, current2, m);
1142
+ }
1143
+ });
1144
+ return textNode;
1145
+ }
1146
+ let current = first != null ? reconcileInsert(parent, first, null, marker || null) : null;
1122
1147
  effect(() => {
1123
1148
  current = reconcileInsert(parent, child(), current, marker || null);
1124
1149
  });
1125
1150
  return current;
1126
1151
  }
1152
+ if (typeof child === "string" || typeof child === "number") {
1153
+ const textNode = document.createTextNode(String(child));
1154
+ if (marker) parent.insertBefore(textNode, marker);
1155
+ else parent.appendChild(textNode);
1156
+ return textNode;
1157
+ }
1158
+ if (child != null && typeof child === "object" && child.nodeType > 0) {
1159
+ if (marker) parent.insertBefore(child, marker);
1160
+ else parent.appendChild(child);
1161
+ return child;
1162
+ }
1127
1163
  return reconcileInsert(parent, child, null, marker || null);
1128
1164
  }
1129
1165
  function isDomNode2(value) {
@@ -1134,8 +1170,9 @@ function isDomNode2(value) {
1134
1170
  function isVNode2(value) {
1135
1171
  return !!value && typeof value === "object" && (value._vnode === true || "tag" in value);
1136
1172
  }
1173
+ var _hasSVGElement = typeof SVGElement !== "undefined";
1137
1174
  function isSvgParent(parent) {
1138
- return typeof SVGElement !== "undefined" && parent instanceof SVGElement && parent.tagName.toLowerCase() !== "foreignobject";
1175
+ return _hasSVGElement && parent instanceof SVGElement && parent.tagName !== "foreignObject";
1139
1176
  }
1140
1177
  function asNodeArray(value) {
1141
1178
  if (value == null) return [];
@@ -1192,18 +1229,39 @@ function reconcileInsert(parent, value, current, marker) {
1192
1229
  }
1193
1230
  if ((typeof value === "string" || typeof value === "number") && current && !Array.isArray(current) && current.nodeType === 3) {
1194
1231
  const text = String(value);
1195
- if (current.textContent !== text) current.textContent = text;
1232
+ if (current.data !== text) current.data = text;
1196
1233
  return current;
1197
1234
  }
1235
+ if (typeof value === "object" && value !== null && value.nodeType > 0 && !Array.isArray(value)) {
1236
+ if (value === current) return current;
1237
+ if (current && !Array.isArray(current) && current.nodeType > 0) {
1238
+ if (current.parentNode === parent) {
1239
+ disposeTree(current);
1240
+ parent.replaceChild(value, current);
1241
+ } else {
1242
+ if (targetMarker) parent.insertBefore(value, targetMarker);
1243
+ else parent.appendChild(value);
1244
+ }
1245
+ return value;
1246
+ }
1247
+ }
1198
1248
  const newNodes = valuesToNodes(value, parent, []);
1199
1249
  const oldNodes = asNodeArray(current);
1200
1250
  if (sameNodeArray(oldNodes, newNodes)) {
1201
1251
  return current;
1202
1252
  }
1203
- const keep = new Set(newNodes);
1253
+ const newLen = newNodes.length;
1204
1254
  for (let i = 0; i < oldNodes.length; i++) {
1205
1255
  const oldNode = oldNodes[i];
1206
- if (!keep.has(oldNode) && oldNode.parentNode === parent) {
1256
+ if (oldNode.parentNode !== parent) continue;
1257
+ let found = false;
1258
+ for (let j = 0; j < newLen; j++) {
1259
+ if (newNodes[j] === oldNode) {
1260
+ found = true;
1261
+ break;
1262
+ }
1263
+ }
1264
+ if (!found) {
1207
1265
  disposeTree(oldNode);
1208
1266
  parent.removeChild(oldNode);
1209
1267
  }
@@ -1238,7 +1296,7 @@ function mapArray(source, mapFn, options) {
1238
1296
  } else {
1239
1297
  reconcileList(parent, endMarker, items, newItems, mappedNodes, disposeFns, mapFn);
1240
1298
  }
1241
- items = newItems.slice();
1299
+ items = newItems.length > 0 ? newItems.slice() : newItems;
1242
1300
  });
1243
1301
  return endMarker;
1244
1302
  };
@@ -1249,10 +1307,15 @@ function reconcileList(parent, endMarker, oldItems, newItems, mappedNodes, dispo
1249
1307
  if (newLen === 0) {
1250
1308
  if (oldLen > 0) {
1251
1309
  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]);
1310
+ if (disposeFns[i]) disposeFns[i]();
1311
+ }
1312
+ for (let i = oldLen - 1; i >= 0; i--) {
1313
+ const node = mappedNodes[i];
1314
+ if (node) {
1315
+ if (node._componentCtx || node._dispose || node._propEffects) {
1316
+ disposeTree(node);
1317
+ }
1318
+ if (node.parentNode === parent) parent.removeChild(node);
1256
1319
  }
1257
1320
  }
1258
1321
  mappedNodes.length = 0;
@@ -1264,7 +1327,7 @@ function reconcileList(parent, endMarker, oldItems, newItems, mappedNodes, dispo
1264
1327
  const frag = document.createDocumentFragment();
1265
1328
  for (let i = 0; i < newLen; i++) {
1266
1329
  const item = newItems[i];
1267
- const node = createRoot((dispose) => {
1330
+ const node = _createItemScope((dispose) => {
1268
1331
  disposeFns[i] = dispose;
1269
1332
  return mapFn(item, i);
1270
1333
  });
@@ -1308,7 +1371,7 @@ function reconcileList(parent, endMarker, oldItems, newItems, mappedNodes, dispo
1308
1371
  for (let i = start; i <= newEnd; i++) {
1309
1372
  const item = newItems[i];
1310
1373
  const idx = i;
1311
- newMapped[i] = createRoot((dispose) => {
1374
+ newMapped[i] = _createItemScope((dispose) => {
1312
1375
  newDispose[idx] = dispose;
1313
1376
  return mapFn(item, idx);
1314
1377
  });
@@ -1388,7 +1451,7 @@ function _reconcileMiddle(parent, endMarker, oldItems, newItems, mappedNodes, di
1388
1451
  if (!newMapped[i]) {
1389
1452
  const item = newItems[i];
1390
1453
  const idx = i;
1391
- newMapped[i] = createRoot((dispose) => {
1454
+ newMapped[i] = _createItemScope((dispose) => {
1392
1455
  newDispose[idx] = dispose;
1393
1456
  return mapFn(item, idx);
1394
1457
  });
@@ -1446,10 +1509,15 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
1446
1509
  if (newLen === 0) {
1447
1510
  if (oldLen > 0) {
1448
1511
  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]);
1512
+ if (disposeFns[i]) disposeFns[i]();
1513
+ }
1514
+ for (let i = oldLen - 1; i >= 0; i--) {
1515
+ const node = mappedNodes[i];
1516
+ if (node) {
1517
+ if (node._componentCtx || node._dispose || node._propEffects) {
1518
+ disposeTree(node);
1519
+ }
1520
+ if (node.parentNode === parent) parent.removeChild(node);
1453
1521
  }
1454
1522
  }
1455
1523
  mappedNodes.length = 0;
@@ -1472,7 +1540,7 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
1472
1540
  } else {
1473
1541
  accessor = item;
1474
1542
  }
1475
- const node = createRoot((dispose) => {
1543
+ const node = _createItemScope((dispose) => {
1476
1544
  disposeFns[idx] = dispose;
1477
1545
  return mapFn(accessor, idx);
1478
1546
  });
@@ -1541,7 +1609,7 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
1541
1609
  } else {
1542
1610
  accessor = item;
1543
1611
  }
1544
- newMapped[i] = createRoot((dispose) => {
1612
+ newMapped[i] = _createItemScope((dispose) => {
1545
1613
  newDispose[idx] = dispose;
1546
1614
  return mapFn(accessor, idx);
1547
1615
  });
@@ -1597,7 +1665,7 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
1597
1665
  } else {
1598
1666
  accessor = item;
1599
1667
  }
1600
- newMapped[i] = createRoot((dispose) => {
1668
+ newMapped[i] = _createItemScope((dispose) => {
1601
1669
  newDispose[idx] = dispose;
1602
1670
  return mapFn(accessor, idx);
1603
1671
  });
@@ -1976,6 +2044,7 @@ function hydrateElementProps(el, props) {
1976
2044
  export {
1977
2045
  _$createComponent,
1978
2046
  _$templateImpl as _$template,
2047
+ _setTextInsertHook,
1979
2048
  template as _template,
1980
2049
  classList,
1981
2050
  delegateEvents,