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/index.js CHANGED
@@ -11,43 +11,42 @@ var insideComputed = false;
11
11
  var batchDepth = 0;
12
12
  var pendingEffects = [];
13
13
  var pendingNeedSort = false;
14
- var subSetOwner = /* @__PURE__ */ new WeakMap();
15
14
  var NEEDS_UPSTREAM = /* @__PURE__ */ Symbol("needs_upstream");
16
15
  var iterativeEvalStack = null;
17
16
  function signal(initial, debugName) {
18
17
  let value = initial;
19
18
  const subs = /* @__PURE__ */ new Set();
20
- function sig(...args) {
21
- if (args.length === 0) {
22
- if (currentEffect) {
23
- subs.add(currentEffect);
24
- currentEffect.deps.push(subs);
25
- }
26
- return value;
27
- }
19
+ let lastTracked = null;
20
+ let lastTrackedEpoch = 0;
21
+ function _sigWrite(next) {
28
22
  if (__DEV__ && insideComputed) {
29
23
  console.warn(
30
24
  "[what] Signal.set() called inside a computed function. This may cause infinite loops. Use effect() instead." + (debugName ? ` (signal: ${debugName})` : "")
31
25
  );
32
26
  }
33
- const nextVal = typeof args[0] === "function" ? args[0](value) : args[0];
34
- if (Object.is(value, nextVal)) return;
27
+ const nextVal = typeof next === "function" ? next(value) : next;
28
+ if (value === nextVal || value !== value && nextVal !== nextVal) return;
35
29
  value = nextVal;
30
+ lastTracked = null;
36
31
  if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);
37
32
  if (subs.size > 0) notify(subs);
38
33
  }
39
- sig.set = (next) => {
40
- if (__DEV__ && insideComputed) {
41
- console.warn(
42
- "[what] Signal.set() called inside a computed function. This may cause infinite loops. Use effect() instead." + (debugName ? ` (signal: ${debugName})` : "")
43
- );
34
+ function sig(newVal) {
35
+ if (arguments.length === 0) {
36
+ const ce = currentEffect;
37
+ if (ce !== null) {
38
+ if (ce !== lastTracked || ce._epoch !== lastTrackedEpoch) {
39
+ lastTracked = ce;
40
+ lastTrackedEpoch = ce._epoch;
41
+ subs.add(ce);
42
+ ce.deps.push(subs);
43
+ }
44
+ }
45
+ return value;
44
46
  }
45
- const nextVal = typeof next === "function" ? next(value) : next;
46
- if (Object.is(value, nextVal)) return;
47
- value = nextVal;
48
- if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);
49
- if (subs.size > 0) notify(subs);
50
- };
47
+ _sigWrite(newVal);
48
+ }
49
+ sig.set = _sigWrite;
51
50
  sig.peek = () => value;
52
51
  sig.subscribe = (fn) => {
53
52
  return effect(() => fn(sig()));
@@ -63,6 +62,8 @@ function signal(initial, debugName) {
63
62
  function computed(fn) {
64
63
  let value, dirty = true;
65
64
  const subs = /* @__PURE__ */ new Set();
65
+ let lastTracked = null;
66
+ let lastTrackedEpoch = 0;
66
67
  const inner = _createEffect(() => {
67
68
  const prevInsideComputed = insideComputed;
68
69
  if (__DEV__) insideComputed = true;
@@ -76,21 +77,27 @@ function computed(fn) {
76
77
  inner._level = 1;
77
78
  inner._computed = true;
78
79
  inner._computedSubs = subs;
79
- subSetOwner.set(subs, inner);
80
+ subs._owner = inner;
80
81
  inner._markDirty = () => {
81
82
  dirty = true;
82
83
  };
83
84
  inner._isDirty = () => dirty;
84
85
  function read() {
85
- if (currentEffect) {
86
- subs.add(currentEffect);
87
- currentEffect.deps.push(subs);
86
+ const ce = currentEffect;
87
+ if (ce !== null) {
88
+ if (ce !== lastTracked || ce._epoch !== lastTrackedEpoch) {
89
+ lastTracked = ce;
90
+ lastTrackedEpoch = ce._epoch;
91
+ subs.add(ce);
92
+ ce.deps.push(subs);
93
+ }
88
94
  }
89
95
  if (dirty) _evaluateComputed(inner);
90
96
  return value;
91
97
  }
92
98
  inner._onNotify = () => {
93
99
  dirty = true;
100
+ lastTracked = null;
94
101
  if (subs.size > 0) notify(subs);
95
102
  };
96
103
  read._signal = true;
@@ -117,7 +124,7 @@ function _evaluateComputed(computedEffect) {
117
124
  let pushedUpstream = false;
118
125
  const deps = current.deps;
119
126
  for (let i = 0; i < deps.length; i++) {
120
- const depOwner = subSetOwner.get(deps[i]);
127
+ const depOwner = deps[i]._owner;
121
128
  if (depOwner && depOwner._computed && depOwner._isDirty && depOwner._isDirty()) {
122
129
  stack.push(depOwner);
123
130
  pushedUpstream = true;
@@ -149,7 +156,7 @@ function _updateLevel(e) {
149
156
  let maxDepLevel = 0;
150
157
  const deps = e.deps;
151
158
  for (let i = 0; i < deps.length; i++) {
152
- const owner = subSetOwner.get(deps[i]);
159
+ const owner = deps[i]._owner;
153
160
  if (owner) {
154
161
  const depLevel = owner._level;
155
162
  if (depLevel > maxDepLevel) maxDepLevel = depLevel;
@@ -204,8 +211,12 @@ function _createEffect(fn, lazy2) {
204
211
  // reference to the computed's subscriber set
205
212
  _isDirty: null,
206
213
  // function to check if computed is dirty (set by computed())
207
- _markDirty: null
214
+ _markDirty: null,
208
215
  // function to mark computed dirty (set by computed())
216
+ _cleanup: null,
217
+ // cleanup function returned by effect fn (declared upfront for shape)
218
+ _epoch: 0
219
+ // incremented on cleanup — used by signal lastTracked cache
209
220
  };
210
221
  if (__DEV__ && __devtools) __devtools.onEffectCreate(e);
211
222
  return e;
@@ -235,12 +246,13 @@ function _runEffect(e) {
235
246
  if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);
236
247
  return;
237
248
  }
249
+ const singleDep = e.deps.length === 1 ? e.deps[0] : null;
238
250
  cleanup(e);
239
251
  if (e._cleanup) {
240
252
  try {
241
253
  e._cleanup();
242
254
  } catch (err) {
243
- if (__devtools?.onError) __devtools.onError(err, { type: "effect-cleanup", effect: e });
255
+ if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect-cleanup", effect: e });
244
256
  if (__DEV__) console.warn("[what] Error in effect cleanup:", err);
245
257
  }
246
258
  e._cleanup = null;
@@ -254,11 +266,14 @@ function _runEffect(e) {
254
266
  }
255
267
  } catch (err) {
256
268
  if (err === NEEDS_UPSTREAM) throw err;
257
- if (__devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
269
+ if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
258
270
  throw err;
259
271
  } finally {
260
272
  currentEffect = prev;
261
273
  }
274
+ if (singleDep !== null && e.deps.length === 1 && e.deps[0] === singleDep && !e._cleanup && !e._pending) {
275
+ e._stable = true;
276
+ }
262
277
  if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);
263
278
  }
264
279
  function _disposeEffect(e) {
@@ -278,45 +293,51 @@ function cleanup(e) {
278
293
  const deps = e.deps;
279
294
  for (let i = 0; i < deps.length; i++) deps[i].delete(e);
280
295
  deps.length = 0;
296
+ e._epoch++;
281
297
  }
282
298
  var notifyDepth = 0;
283
299
  var notifyQueue = null;
284
300
  var notifyQueueLen = 0;
301
+ function _processSubscriber(e) {
302
+ if (e.disposed) return;
303
+ if (e._onNotify) {
304
+ e._onNotify();
305
+ } else if (!e._pending) {
306
+ if (batchDepth === 0 && e._stable) {
307
+ const prev = currentEffect;
308
+ currentEffect = null;
309
+ try {
310
+ const result = e.fn();
311
+ if (typeof result === "function") {
312
+ if (e._cleanup) try {
313
+ e._cleanup();
314
+ } catch (err) {
315
+ }
316
+ e._cleanup = result;
317
+ }
318
+ } catch (err) {
319
+ if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
320
+ if (__DEV__) console.warn("[what] Error in stable effect:", err);
321
+ } finally {
322
+ currentEffect = prev;
323
+ }
324
+ } else {
325
+ e._pending = true;
326
+ const level = e._level;
327
+ const len = pendingEffects.length;
328
+ if (len > 0 && pendingEffects[len - 1]._level > level) {
329
+ pendingNeedSort = true;
330
+ }
331
+ pendingEffects.push(e);
332
+ }
333
+ }
334
+ }
285
335
  function notify(subs) {
286
336
  if (notifyDepth === 0) {
287
337
  notifyDepth = 1;
288
338
  try {
289
339
  for (const e of subs) {
290
- if (e.disposed) continue;
291
- if (e._onNotify) {
292
- e._onNotify();
293
- } else if (batchDepth === 0 && e._stable) {
294
- const prev = currentEffect;
295
- currentEffect = null;
296
- try {
297
- const result = e.fn();
298
- if (typeof result === "function") {
299
- if (e._cleanup) try {
300
- e._cleanup();
301
- } catch (err) {
302
- }
303
- e._cleanup = result;
304
- }
305
- } catch (err) {
306
- if (__devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
307
- if (__DEV__) console.warn("[what] Error in stable effect:", err);
308
- } finally {
309
- currentEffect = prev;
310
- }
311
- } else if (!e._pending) {
312
- e._pending = true;
313
- const level = e._level;
314
- const len = pendingEffects.length;
315
- if (len > 0 && pendingEffects[len - 1]._level > level) {
316
- pendingNeedSort = true;
317
- }
318
- pendingEffects.push(e);
319
- }
340
+ _processSubscriber(e);
320
341
  }
321
342
  if (notifyQueueLen > 0) {
322
343
  let qi = 0;
@@ -325,36 +346,7 @@ function notify(subs) {
325
346
  notifyQueue[qi] = null;
326
347
  qi++;
327
348
  for (const e of queuedSubs) {
328
- if (e.disposed) continue;
329
- if (e._onNotify) {
330
- e._onNotify();
331
- } else if (batchDepth === 0 && e._stable) {
332
- const prev = currentEffect;
333
- currentEffect = null;
334
- try {
335
- const result = e.fn();
336
- if (typeof result === "function") {
337
- if (e._cleanup) try {
338
- e._cleanup();
339
- } catch (err) {
340
- }
341
- e._cleanup = result;
342
- }
343
- } catch (err) {
344
- if (__devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
345
- if (__DEV__) console.warn("[what] Error in stable effect:", err);
346
- } finally {
347
- currentEffect = prev;
348
- }
349
- } else if (!e._pending) {
350
- e._pending = true;
351
- const level = e._level;
352
- const len = pendingEffects.length;
353
- if (len > 0 && pendingEffects[len - 1]._level > level) {
354
- pendingNeedSort = true;
355
- }
356
- pendingEffects.push(e);
357
- }
349
+ _processSubscriber(e);
358
350
  }
359
351
  }
360
352
  notifyQueueLen = 0;
@@ -410,8 +402,6 @@ function flush() {
410
402
  iterations++;
411
403
  }
412
404
  if (iterations >= 25) {
413
- for (let i = 0; i < pendingEffects.length; i++) pendingEffects[i]._pending = false;
414
- pendingEffects.length = 0;
415
405
  if (__DEV__) {
416
406
  const remaining = pendingEffects.slice(0, 3);
417
407
  const effectNames = remaining.map((e) => e.fn?.name || e.fn?.toString().slice(0, 60) || "(anonymous)");
@@ -421,6 +411,8 @@ function flush() {
421
411
  } else {
422
412
  console.warn("[what] Possible infinite effect loop detected");
423
413
  }
414
+ for (let i = 0; i < pendingEffects.length; i++) pendingEffects[i]._pending = false;
415
+ pendingEffects.length = 0;
424
416
  }
425
417
  } finally {
426
418
  isFlushing = false;
@@ -452,7 +444,7 @@ function memo(fn) {
452
444
  e._level = 1;
453
445
  _runEffect(e);
454
446
  _updateLevel(e);
455
- subSetOwner.set(subs, e);
447
+ subs._owner = e;
456
448
  if (currentRoot) {
457
449
  currentRoot.disposals.push(() => _disposeEffect(e));
458
450
  }
@@ -562,6 +554,38 @@ function _disposeRoot(root) {
562
554
  }
563
555
  root.disposals.length = 0;
564
556
  }
557
+ function _createItemScope(fn) {
558
+ const prevRoot = currentRoot;
559
+ const prevOwner = currentOwner;
560
+ const scope = {
561
+ disposals: [],
562
+ owner: null,
563
+ // No parent registration
564
+ children: [],
565
+ // Kept for compat with effects that create sub-roots
566
+ _disposed: false
567
+ };
568
+ currentRoot = scope;
569
+ currentOwner = scope;
570
+ try {
571
+ const dispose = () => {
572
+ if (scope._disposed) return;
573
+ scope._disposed = true;
574
+ for (let i = scope.children.length - 1; i >= 0; i--) {
575
+ _disposeRoot(scope.children[i]);
576
+ }
577
+ scope.children.length = 0;
578
+ for (let i = scope.disposals.length - 1; i >= 0; i--) {
579
+ scope.disposals[i]();
580
+ }
581
+ scope.disposals.length = 0;
582
+ };
583
+ return fn(dispose);
584
+ } finally {
585
+ currentRoot = prevRoot;
586
+ currentOwner = prevOwner;
587
+ }
588
+ }
565
589
  function onCleanup(fn) {
566
590
  if (currentRoot) {
567
591
  currentRoot.disposals.push(fn);
@@ -570,9 +594,22 @@ function onCleanup(fn) {
570
594
 
571
595
  // packages/core/src/h.js
572
596
  var EMPTY_OBJ = /* @__PURE__ */ Object.create(null);
573
- function h(tag, props, ...children) {
597
+ var EMPTY_ARR = [];
598
+ function h(tag, props) {
574
599
  props = props || EMPTY_OBJ;
575
- const flat = flattenChildren(children);
600
+ const argLen = arguments.length;
601
+ let flat;
602
+ if (argLen <= 2) {
603
+ flat = EMPTY_ARR;
604
+ } else if (argLen === 3) {
605
+ flat = _flattenSingle(arguments[2]);
606
+ } else {
607
+ const out = [];
608
+ for (let i = 2; i < argLen; i++) {
609
+ _flattenInto(arguments[i], out);
610
+ }
611
+ flat = out;
612
+ }
576
613
  const key = props.key ?? null;
577
614
  if (props.key !== void 0) {
578
615
  props = { ...props };
@@ -583,22 +620,30 @@ function h(tag, props, ...children) {
583
620
  function Fragment({ children }) {
584
621
  return children;
585
622
  }
586
- function flattenChildren(children) {
587
- const out = [];
588
- for (let i = 0; i < children.length; i++) {
589
- const child = children[i];
590
- if (child == null || child === false || child === true) continue;
591
- if (Array.isArray(child)) {
592
- out.push(...flattenChildren(child));
593
- } else if (typeof child === "object" && child._vnode) {
594
- out.push(child);
595
- } else if (typeof child === "function") {
596
- out.push(child);
597
- } else {
598
- out.push(String(child));
623
+ function _flattenSingle(child) {
624
+ if (child == null || child === false || child === true) return EMPTY_ARR;
625
+ if (Array.isArray(child)) {
626
+ const out = [];
627
+ _flattenInto(child, out);
628
+ return out;
629
+ }
630
+ if (typeof child === "object" && child._vnode) return [child];
631
+ if (typeof child === "function") return [child];
632
+ return [String(child)];
633
+ }
634
+ function _flattenInto(child, out) {
635
+ if (child == null || child === false || child === true) return;
636
+ if (Array.isArray(child)) {
637
+ for (let i = 0; i < child.length; i++) {
638
+ _flattenInto(child[i], out);
599
639
  }
640
+ } else if (typeof child === "object" && child._vnode) {
641
+ out.push(child);
642
+ } else if (typeof child === "function") {
643
+ out.push(child);
644
+ } else {
645
+ out.push(String(child));
600
646
  }
601
- return out;
602
647
  }
603
648
  function html(strings, ...values) {
604
649
  const src = strings.reduce((acc, str, i) => acc + str + (i < values.length ? `\0${i}\0` : ""), "");
@@ -1177,9 +1222,11 @@ function disposeTree(node) {
1177
1222
  if (node._componentCtx) {
1178
1223
  disposeComponent(node._componentCtx);
1179
1224
  }
1180
- const commentCtx = _commentCtxMap.get(node);
1181
- if (commentCtx) {
1182
- disposeComponent(commentCtx);
1225
+ if (node.nodeType === 8) {
1226
+ const commentCtx = _commentCtxMap.get(node);
1227
+ if (commentCtx) {
1228
+ disposeComponent(commentCtx);
1229
+ }
1183
1230
  }
1184
1231
  if (node._dispose) {
1185
1232
  try {
@@ -1195,9 +1242,10 @@ function disposeTree(node) {
1195
1242
  }
1196
1243
  }
1197
1244
  }
1198
- if (node.childNodes) {
1199
- for (const child of node.childNodes) {
1200
- disposeTree(child);
1245
+ const children = node.childNodes;
1246
+ if (children && children.length > 0) {
1247
+ for (let i = 0; i < children.length; i++) {
1248
+ disposeTree(children[i]);
1201
1249
  }
1202
1250
  }
1203
1251
  }
@@ -1275,6 +1323,27 @@ function createDOM(vnode, parent, isSvg) {
1275
1323
  }
1276
1324
  return document.createTextNode(String(vnode));
1277
1325
  }
1326
+ var _propsProxyHandler = {
1327
+ get(target, key) {
1328
+ if (key === "_sig") return void 0;
1329
+ return target._sig()[key];
1330
+ },
1331
+ has(target, key) {
1332
+ if (key === "_sig") return false;
1333
+ return key in target._sig();
1334
+ },
1335
+ ownKeys(target) {
1336
+ return Reflect.ownKeys(target._sig());
1337
+ },
1338
+ getOwnPropertyDescriptor(target, key) {
1339
+ if (key === "_sig") return void 0;
1340
+ const current = target._sig();
1341
+ if (key in current) {
1342
+ return { value: current[key], writable: false, enumerable: true, configurable: true };
1343
+ }
1344
+ return void 0;
1345
+ }
1346
+ };
1278
1347
  var componentStack = [];
1279
1348
  function getCurrentComponent() {
1280
1349
  return componentStack[componentStack.length - 1];
@@ -1303,6 +1372,21 @@ function createComponent(vnode, parent, isSvg) {
1303
1372
  if (Component === "__portal" || vnode.tag === "__portal") {
1304
1373
  return createPortalDOM(vnode, parent);
1305
1374
  }
1375
+ const parentCtx = componentStack[componentStack.length - 1] || null;
1376
+ let errorBoundary = null;
1377
+ if (parentCtx) {
1378
+ errorBoundary = parentCtx._errorBoundary || null;
1379
+ if (!errorBoundary) {
1380
+ let p = parentCtx._parentCtx;
1381
+ while (p) {
1382
+ if (p._errorBoundary) {
1383
+ errorBoundary = p._errorBoundary;
1384
+ break;
1385
+ }
1386
+ p = p._parentCtx;
1387
+ }
1388
+ }
1389
+ }
1306
1390
  const ctx = {
1307
1391
  hooks: [],
1308
1392
  hookIndex: 0,
@@ -1311,15 +1395,8 @@ function createComponent(vnode, parent, isSvg) {
1311
1395
  mounted: false,
1312
1396
  disposed: false,
1313
1397
  Component,
1314
- _parentCtx: componentStack[componentStack.length - 1] || null,
1315
- _errorBoundary: (() => {
1316
- let p = componentStack[componentStack.length - 1];
1317
- while (p) {
1318
- if (p._errorBoundary) return p._errorBoundary;
1319
- p = p._parentCtx;
1320
- }
1321
- return null;
1322
- })()
1398
+ _parentCtx: parentCtx,
1399
+ _errorBoundary: errorBoundary
1323
1400
  };
1324
1401
  const startComment = document.createComment("c:start");
1325
1402
  const endComment = document.createComment("c:end");
@@ -1332,29 +1409,15 @@ function createComponent(vnode, parent, isSvg) {
1332
1409
  mountedComponents.add(ctx);
1333
1410
  if (__DEV__ && __devtools?.onComponentMount) __devtools.onComponentMount(ctx);
1334
1411
  const propsChildren = children.length === 0 ? void 0 : children.length === 1 ? children[0] : children;
1335
- const propsSignal = signal({ ...props, children: propsChildren });
1412
+ let mergedProps;
1413
+ if (propsChildren !== void 0) {
1414
+ mergedProps = props ? Object.assign({}, props, { children: propsChildren }) : { children: propsChildren };
1415
+ } else {
1416
+ mergedProps = props ? Object.assign({}, props) : {};
1417
+ }
1418
+ const propsSignal = signal(mergedProps);
1336
1419
  ctx._propsSignal = propsSignal;
1337
- const reactiveProps = new Proxy({}, {
1338
- get(_, key) {
1339
- const current = propsSignal();
1340
- return current[key];
1341
- },
1342
- has(_, key) {
1343
- const current = propsSignal();
1344
- return key in current;
1345
- },
1346
- ownKeys() {
1347
- const current = propsSignal();
1348
- return Reflect.ownKeys(current);
1349
- },
1350
- getOwnPropertyDescriptor(_, key) {
1351
- const current = propsSignal();
1352
- if (key in current) {
1353
- return { value: current[key], writable: false, enumerable: true, configurable: true };
1354
- }
1355
- return void 0;
1356
- }
1357
- });
1420
+ const reactiveProps = new Proxy({ _sig: propsSignal }, _propsProxyHandler);
1358
1421
  componentStack.push(ctx);
1359
1422
  let result;
1360
1423
  try {
@@ -1535,21 +1598,22 @@ function createElementFromVNode(vnode, parent, isSvg) {
1535
1598
  if (props) {
1536
1599
  applyProps(el, props, {}, svgContext);
1537
1600
  }
1538
- for (const child of children) {
1539
- const node = createDOM(child, el, svgContext && tag !== "foreignObject");
1601
+ const isSvgChildren = svgContext && tag !== "foreignObject";
1602
+ for (let i = 0; i < children.length; i++) {
1603
+ const node = createDOM(children[i], el, isSvgChildren);
1540
1604
  if (node) el.appendChild(node);
1541
1605
  }
1542
1606
  el._vnode = vnode;
1543
1607
  return el;
1544
1608
  }
1545
1609
  function applyProps(el, newProps, oldProps, isSvg) {
1546
- newProps = newProps || {};
1547
- oldProps = oldProps || {};
1610
+ if (!newProps) return;
1548
1611
  for (const key in newProps) {
1549
1612
  if (key === "key" || key === "children") continue;
1550
1613
  if (key === "ref") {
1551
- if (typeof newProps.ref === "function") newProps.ref(el);
1552
- else if (newProps.ref) newProps.ref.current = el;
1614
+ const ref = newProps.ref;
1615
+ if (typeof ref === "function") ref(el);
1616
+ else if (ref) ref.current = el;
1553
1617
  continue;
1554
1618
  }
1555
1619
  setProp(el, key, newProps[key], isSvg);
@@ -1586,8 +1650,9 @@ function setProp(el, key, value, isSvg) {
1586
1650
  if (!el._events) el._events = {};
1587
1651
  const wrappedHandler = (e) => {
1588
1652
  if (!e.nativeEvent) e.nativeEvent = e;
1589
- return untrack(() => value(e));
1653
+ return untrack(() => wrappedHandler._handler(e));
1590
1654
  };
1655
+ wrappedHandler._handler = value;
1591
1656
  wrappedHandler._original = value;
1592
1657
  el._events[storageKey] = wrappedHandler;
1593
1658
  const eventOpts = value._eventOpts;
@@ -1664,7 +1729,11 @@ function setProp(el, key, value, isSvg) {
1664
1729
  function _$createComponent(Component, props, children) {
1665
1730
  if (children && children.length > 0) {
1666
1731
  const mergedChildren = children.length === 1 ? children[0] : children;
1667
- props = props ? { ...props, children: mergedChildren } : { children: mergedChildren };
1732
+ if (props) {
1733
+ props.children = mergedChildren;
1734
+ } else {
1735
+ props = { children: mergedChildren };
1736
+ }
1668
1737
  }
1669
1738
  return createDOM({ tag: Component, props: props || {}, children: children || [], key: null, _vnode: true });
1670
1739
  }
@@ -1752,13 +1821,9 @@ function _$templateImpl(html2) {
1752
1821
  if (tableInfo) {
1753
1822
  const t2 = document.createElement("template");
1754
1823
  t2.innerHTML = tableInfo.wrap + trimmed + tableInfo.unwrap;
1755
- return () => {
1756
- let node = t2.content.firstChild;
1757
- for (let i = 0; i < tableInfo.depth; i++) {
1758
- node = node.firstChild;
1759
- }
1760
- return node.cloneNode(true);
1761
- };
1824
+ let target = t2.content.firstChild;
1825
+ for (let i = 0; i < tableInfo.depth; i++) target = target.firstChild;
1826
+ return () => target.cloneNode(true);
1762
1827
  }
1763
1828
  const t = document.createElement("template");
1764
1829
  t.innerHTML = trimmed;
@@ -1788,12 +1853,45 @@ function svgTemplate(html2) {
1788
1853
  }
1789
1854
  function insert(parent, child, marker) {
1790
1855
  if (typeof child === "function") {
1791
- let current = null;
1856
+ const first = child();
1857
+ const t = typeof first;
1858
+ if (t === "string" || t === "number") {
1859
+ const textNode = document.createTextNode(String(first));
1860
+ const m = marker || null;
1861
+ if (m) parent.insertBefore(textNode, m);
1862
+ else parent.appendChild(textNode);
1863
+ let current2 = textNode;
1864
+ let isTextFastPath = true;
1865
+ effect(() => {
1866
+ const val = child();
1867
+ const vt = typeof val;
1868
+ if (isTextFastPath && (vt === "string" || vt === "number")) {
1869
+ const str = String(val);
1870
+ if (textNode.data !== str) textNode.data = str;
1871
+ } else {
1872
+ isTextFastPath = false;
1873
+ current2 = reconcileInsert(parent, val, current2, m);
1874
+ }
1875
+ });
1876
+ return textNode;
1877
+ }
1878
+ let current = first != null ? reconcileInsert(parent, first, null, marker || null) : null;
1792
1879
  effect(() => {
1793
1880
  current = reconcileInsert(parent, child(), current, marker || null);
1794
1881
  });
1795
1882
  return current;
1796
1883
  }
1884
+ if (typeof child === "string" || typeof child === "number") {
1885
+ const textNode = document.createTextNode(String(child));
1886
+ if (marker) parent.insertBefore(textNode, marker);
1887
+ else parent.appendChild(textNode);
1888
+ return textNode;
1889
+ }
1890
+ if (child != null && typeof child === "object" && child.nodeType > 0) {
1891
+ if (marker) parent.insertBefore(child, marker);
1892
+ else parent.appendChild(child);
1893
+ return child;
1894
+ }
1797
1895
  return reconcileInsert(parent, child, null, marker || null);
1798
1896
  }
1799
1897
  function isDomNode2(value) {
@@ -1804,8 +1902,9 @@ function isDomNode2(value) {
1804
1902
  function isVNode2(value) {
1805
1903
  return !!value && typeof value === "object" && (value._vnode === true || "tag" in value);
1806
1904
  }
1905
+ var _hasSVGElement = typeof SVGElement !== "undefined";
1807
1906
  function isSvgParent(parent) {
1808
- return typeof SVGElement !== "undefined" && parent instanceof SVGElement && parent.tagName.toLowerCase() !== "foreignobject";
1907
+ return _hasSVGElement && parent instanceof SVGElement && parent.tagName !== "foreignObject";
1809
1908
  }
1810
1909
  function asNodeArray(value) {
1811
1910
  if (value == null) return [];
@@ -1862,18 +1961,39 @@ function reconcileInsert(parent, value, current, marker) {
1862
1961
  }
1863
1962
  if ((typeof value === "string" || typeof value === "number") && current && !Array.isArray(current) && current.nodeType === 3) {
1864
1963
  const text = String(value);
1865
- if (current.textContent !== text) current.textContent = text;
1964
+ if (current.data !== text) current.data = text;
1866
1965
  return current;
1867
1966
  }
1967
+ if (typeof value === "object" && value !== null && value.nodeType > 0 && !Array.isArray(value)) {
1968
+ if (value === current) return current;
1969
+ if (current && !Array.isArray(current) && current.nodeType > 0) {
1970
+ if (current.parentNode === parent) {
1971
+ disposeTree(current);
1972
+ parent.replaceChild(value, current);
1973
+ } else {
1974
+ if (targetMarker) parent.insertBefore(value, targetMarker);
1975
+ else parent.appendChild(value);
1976
+ }
1977
+ return value;
1978
+ }
1979
+ }
1868
1980
  const newNodes = valuesToNodes(value, parent, []);
1869
1981
  const oldNodes = asNodeArray(current);
1870
1982
  if (sameNodeArray(oldNodes, newNodes)) {
1871
1983
  return current;
1872
1984
  }
1873
- const keep = new Set(newNodes);
1985
+ const newLen = newNodes.length;
1874
1986
  for (let i = 0; i < oldNodes.length; i++) {
1875
1987
  const oldNode = oldNodes[i];
1876
- if (!keep.has(oldNode) && oldNode.parentNode === parent) {
1988
+ if (oldNode.parentNode !== parent) continue;
1989
+ let found = false;
1990
+ for (let j = 0; j < newLen; j++) {
1991
+ if (newNodes[j] === oldNode) {
1992
+ found = true;
1993
+ break;
1994
+ }
1995
+ }
1996
+ if (!found) {
1877
1997
  disposeTree(oldNode);
1878
1998
  parent.removeChild(oldNode);
1879
1999
  }
@@ -1908,7 +2028,7 @@ function mapArray(source, mapFn, options) {
1908
2028
  } else {
1909
2029
  reconcileList(parent, endMarker, items, newItems, mappedNodes, disposeFns, mapFn);
1910
2030
  }
1911
- items = newItems.slice();
2031
+ items = newItems.length > 0 ? newItems.slice() : newItems;
1912
2032
  });
1913
2033
  return endMarker;
1914
2034
  };
@@ -1919,10 +2039,15 @@ function reconcileList(parent, endMarker, oldItems, newItems, mappedNodes, dispo
1919
2039
  if (newLen === 0) {
1920
2040
  if (oldLen > 0) {
1921
2041
  for (let i = 0; i < oldLen; i++) {
1922
- disposeFns[i]?.();
1923
- if (mappedNodes[i]?.parentNode === parent) {
1924
- disposeTree(mappedNodes[i]);
1925
- parent.removeChild(mappedNodes[i]);
2042
+ if (disposeFns[i]) disposeFns[i]();
2043
+ }
2044
+ for (let i = oldLen - 1; i >= 0; i--) {
2045
+ const node = mappedNodes[i];
2046
+ if (node) {
2047
+ if (node._componentCtx || node._dispose || node._propEffects) {
2048
+ disposeTree(node);
2049
+ }
2050
+ if (node.parentNode === parent) parent.removeChild(node);
1926
2051
  }
1927
2052
  }
1928
2053
  mappedNodes.length = 0;
@@ -1934,7 +2059,7 @@ function reconcileList(parent, endMarker, oldItems, newItems, mappedNodes, dispo
1934
2059
  const frag = document.createDocumentFragment();
1935
2060
  for (let i = 0; i < newLen; i++) {
1936
2061
  const item = newItems[i];
1937
- const node = createRoot((dispose) => {
2062
+ const node = _createItemScope((dispose) => {
1938
2063
  disposeFns[i] = dispose;
1939
2064
  return mapFn(item, i);
1940
2065
  });
@@ -1978,7 +2103,7 @@ function reconcileList(parent, endMarker, oldItems, newItems, mappedNodes, dispo
1978
2103
  for (let i = start; i <= newEnd; i++) {
1979
2104
  const item = newItems[i];
1980
2105
  const idx = i;
1981
- newMapped[i] = createRoot((dispose) => {
2106
+ newMapped[i] = _createItemScope((dispose) => {
1982
2107
  newDispose[idx] = dispose;
1983
2108
  return mapFn(item, idx);
1984
2109
  });
@@ -2058,7 +2183,7 @@ function _reconcileMiddle(parent, endMarker, oldItems, newItems, mappedNodes, di
2058
2183
  if (!newMapped[i]) {
2059
2184
  const item = newItems[i];
2060
2185
  const idx = i;
2061
- newMapped[i] = createRoot((dispose) => {
2186
+ newMapped[i] = _createItemScope((dispose) => {
2062
2187
  newDispose[idx] = dispose;
2063
2188
  return mapFn(item, idx);
2064
2189
  });
@@ -2116,10 +2241,15 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
2116
2241
  if (newLen === 0) {
2117
2242
  if (oldLen > 0) {
2118
2243
  for (let i = 0; i < oldLen; i++) {
2119
- disposeFns[i]?.();
2120
- if (mappedNodes[i]?.parentNode === parent) {
2121
- disposeTree(mappedNodes[i]);
2122
- parent.removeChild(mappedNodes[i]);
2244
+ if (disposeFns[i]) disposeFns[i]();
2245
+ }
2246
+ for (let i = oldLen - 1; i >= 0; i--) {
2247
+ const node = mappedNodes[i];
2248
+ if (node) {
2249
+ if (node._componentCtx || node._dispose || node._propEffects) {
2250
+ disposeTree(node);
2251
+ }
2252
+ if (node.parentNode === parent) parent.removeChild(node);
2123
2253
  }
2124
2254
  }
2125
2255
  mappedNodes.length = 0;
@@ -2142,7 +2272,7 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
2142
2272
  } else {
2143
2273
  accessor = item;
2144
2274
  }
2145
- const node = createRoot((dispose) => {
2275
+ const node = _createItemScope((dispose) => {
2146
2276
  disposeFns[idx] = dispose;
2147
2277
  return mapFn(accessor, idx);
2148
2278
  });
@@ -2211,7 +2341,7 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
2211
2341
  } else {
2212
2342
  accessor = item;
2213
2343
  }
2214
- newMapped[i] = createRoot((dispose) => {
2344
+ newMapped[i] = _createItemScope((dispose) => {
2215
2345
  newDispose[idx] = dispose;
2216
2346
  return mapFn(accessor, idx);
2217
2347
  });
@@ -2267,7 +2397,7 @@ function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disp
2267
2397
  } else {
2268
2398
  accessor = item;
2269
2399
  }
2270
- newMapped[i] = createRoot((dispose) => {
2400
+ newMapped[i] = _createItemScope((dispose) => {
2271
2401
  newDispose[idx] = dispose;
2272
2402
  return mapFn(accessor, idx);
2273
2403
  });