what-core 0.8.3 → 0.10.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.
Files changed (55) hide show
  1. package/dist/chunk-AW3BAPIK.js +1685 -0
  2. package/dist/chunk-AW3BAPIK.js.map +7 -0
  3. package/dist/chunk-AZP2EOGX.js +188 -0
  4. package/dist/chunk-AZP2EOGX.js.map +7 -0
  5. package/dist/chunk-F2HUXI22.js +1675 -0
  6. package/dist/chunk-F2HUXI22.js.map +7 -0
  7. package/dist/chunk-KBM6CWG4.min.js +2 -0
  8. package/dist/chunk-KBM6CWG4.min.js.map +7 -0
  9. package/dist/chunk-KL7TNUIU.min.js +2 -0
  10. package/dist/chunk-KL7TNUIU.min.js.map +7 -0
  11. package/dist/chunk-L6XOF7P4.min.js +2 -0
  12. package/dist/chunk-L6XOF7P4.min.js.map +7 -0
  13. package/dist/chunk-M7UEET5O.js +1323 -0
  14. package/dist/chunk-M7UEET5O.js.map +7 -0
  15. package/dist/chunk-O3SKPRTY.min.js +2 -0
  16. package/dist/chunk-O3SKPRTY.min.js.map +7 -0
  17. package/dist/chunk-RN6QIBWL.min.js +2 -0
  18. package/dist/chunk-RN6QIBWL.min.js.map +7 -0
  19. package/dist/chunk-VMTTYB4L.min.js +2 -0
  20. package/dist/chunk-VMTTYB4L.min.js.map +7 -0
  21. package/dist/chunk-VP4WLF5A.js +1323 -0
  22. package/dist/chunk-VP4WLF5A.js.map +7 -0
  23. package/dist/chunk-YA3W4XKH.js +1323 -0
  24. package/dist/chunk-YA3W4XKH.js.map +7 -0
  25. package/dist/index.js +212 -2785
  26. package/dist/index.js.map +4 -4
  27. package/dist/index.min.js +6 -6
  28. package/dist/index.min.js.map +4 -4
  29. package/dist/jsx-dev-runtime.js +4 -53
  30. package/dist/jsx-dev-runtime.js.map +3 -3
  31. package/dist/jsx-dev-runtime.min.js +1 -1
  32. package/dist/jsx-dev-runtime.min.js.map +4 -4
  33. package/dist/jsx-runtime.js +4 -53
  34. package/dist/jsx-runtime.js.map +3 -3
  35. package/dist/jsx-runtime.min.js +1 -1
  36. package/dist/jsx-runtime.min.js.map +4 -4
  37. package/dist/render.js +22 -2044
  38. package/dist/render.js.map +4 -4
  39. package/dist/render.min.js +1 -1
  40. package/dist/render.min.js.map +4 -4
  41. package/dist/testing.js +13 -1079
  42. package/dist/testing.js.map +4 -4
  43. package/dist/testing.min.js +1 -1
  44. package/dist/testing.min.js.map +4 -4
  45. package/package.json +2 -2
  46. package/src/dom.js +54 -6
  47. package/src/h.js +15 -3
  48. package/src/head.js +72 -2
  49. package/src/hooks.js +65 -4
  50. package/src/hydration-data.js +34 -0
  51. package/src/index.js +9 -2
  52. package/src/reactive.js +78 -1
  53. package/src/render.js +450 -105
  54. package/src/server-context.js +48 -0
  55. package/src/store.js +6 -2
package/dist/testing.js CHANGED
@@ -1,1079 +1,13 @@
1
- // packages/core/src/reactive.js
2
- var __DEV__ = typeof process !== "undefined" ? true : true;
3
- var __devtools = null;
4
- var currentEffect = null;
5
- var currentRoot = null;
6
- var currentOwner = null;
7
- var insideComputed = false;
8
- var batchDepth = 0;
9
- var pendingEffects = [];
10
- var pendingNeedSort = false;
11
- var NEEDS_UPSTREAM = /* @__PURE__ */ Symbol("needs_upstream");
12
- function signal(initial, debugName) {
13
- let value = initial;
14
- const subs = /* @__PURE__ */ new Set();
15
- let lastTracked = null;
16
- let lastTrackedEpoch = 0;
17
- function _sigWrite(next) {
18
- if (__DEV__ && insideComputed) {
19
- console.warn(
20
- "[what] Signal.set() called inside a computed function. This may cause infinite loops. Use effect() instead." + (debugName ? ` (signal: ${debugName})` : "")
21
- );
22
- }
23
- const nextVal = typeof next === "function" ? next(value) : next;
24
- if (value === nextVal || value !== value && nextVal !== nextVal) return;
25
- value = nextVal;
26
- lastTracked = null;
27
- if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);
28
- if (subs.size > 0) notify(subs);
29
- }
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;
42
- }
43
- _sigWrite(newVal);
44
- }
45
- sig.set = _sigWrite;
46
- sig.peek = () => value;
47
- sig.subscribe = (fn) => {
48
- return effect(() => fn(sig()));
49
- };
50
- sig._signal = true;
51
- if (__DEV__) {
52
- sig._subs = subs;
53
- if (debugName) sig._debugName = debugName;
54
- }
55
- if (__DEV__ && __devtools) __devtools.onSignalCreate(sig);
56
- return sig;
57
- }
58
- function _updateLevel(e) {
59
- let maxDepLevel = 0;
60
- const deps = e.deps;
61
- for (let i = 0; i < deps.length; i++) {
62
- const owner = deps[i]._owner;
63
- if (owner) {
64
- const depLevel = owner._level;
65
- if (depLevel > maxDepLevel) maxDepLevel = depLevel;
66
- }
67
- }
68
- e._level = maxDepLevel + 1;
69
- }
70
- function effect(fn, opts) {
71
- const e = _createEffect(fn);
72
- e._level = 1;
73
- const prev = currentEffect;
74
- currentEffect = e;
75
- try {
76
- const result = e.fn();
77
- if (typeof result === "function") e._cleanup = result;
78
- } finally {
79
- currentEffect = prev;
80
- }
81
- _updateLevel(e);
82
- if (opts?.stable) e._stable = true;
83
- const dispose = () => _disposeEffect(e);
84
- if (currentRoot) {
85
- currentRoot.disposals.push(dispose);
86
- }
87
- return dispose;
88
- }
89
- function _createEffect(fn, lazy) {
90
- const e = {
91
- fn,
92
- deps: [],
93
- // array of subscriber sets (cheaper than Set for typical 1-3 deps)
94
- lazy: lazy || false,
95
- _onNotify: null,
96
- disposed: false,
97
- _pending: false,
98
- _stable: false,
99
- // stable effects skip cleanup/re-subscribe on re-run
100
- _level: 0,
101
- // topological depth: signals=0, computed/effects=max(deps)+1
102
- _computed: false,
103
- // true for computed inner effects
104
- _computedSubs: null,
105
- // reference to the computed's subscriber set
106
- _isDirty: null,
107
- // function to check if computed is dirty (set by computed())
108
- _markDirty: null,
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
114
- };
115
- if (__DEV__ && __devtools) __devtools.onEffectCreate(e);
116
- return e;
117
- }
118
- function _runEffect(e) {
119
- if (e.disposed) return;
120
- if (e._stable) {
121
- if (e._cleanup) {
122
- try {
123
- e._cleanup();
124
- } catch (err) {
125
- if (__DEV__) console.warn("[what] Error in effect cleanup:", err);
126
- }
127
- e._cleanup = null;
128
- }
129
- const prev2 = currentEffect;
130
- currentEffect = null;
131
- try {
132
- const result = e.fn();
133
- if (typeof result === "function") e._cleanup = result;
134
- } catch (err) {
135
- if (__devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
136
- if (__DEV__) console.warn("[what] Error in stable effect:", err);
137
- } finally {
138
- currentEffect = prev2;
139
- }
140
- if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);
141
- return;
142
- }
143
- const singleDep = e.deps.length === 1 ? e.deps[0] : null;
144
- cleanup(e);
145
- if (e._cleanup) {
146
- try {
147
- e._cleanup();
148
- } catch (err) {
149
- if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect-cleanup", effect: e });
150
- if (__DEV__) console.warn("[what] Error in effect cleanup:", err);
151
- }
152
- e._cleanup = null;
153
- }
154
- const prev = currentEffect;
155
- currentEffect = e;
156
- try {
157
- const result = e.fn();
158
- if (typeof result === "function") {
159
- e._cleanup = result;
160
- }
161
- } catch (err) {
162
- if (err === NEEDS_UPSTREAM) throw err;
163
- if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
164
- throw err;
165
- } finally {
166
- currentEffect = prev;
167
- }
168
- if (singleDep !== null && e.deps.length === 1 && e.deps[0] === singleDep && !e._cleanup && !e._pending) {
169
- e._stable = true;
170
- }
171
- if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);
172
- }
173
- function _disposeEffect(e) {
174
- e.disposed = true;
175
- if (__DEV__ && __devtools) __devtools.onEffectDispose(e);
176
- cleanup(e);
177
- if (e._cleanup) {
178
- try {
179
- e._cleanup();
180
- } catch (err) {
181
- if (__DEV__) console.warn("[what] Error in effect cleanup on dispose:", err);
182
- }
183
- e._cleanup = null;
184
- }
185
- }
186
- function cleanup(e) {
187
- const deps = e.deps;
188
- for (let i = 0; i < deps.length; i++) deps[i].delete(e);
189
- deps.length = 0;
190
- e._epoch++;
191
- }
192
- var notifyDepth = 0;
193
- var notifyQueue = null;
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
- }
229
- function notify(subs) {
230
- if (notifyDepth === 0) {
231
- notifyDepth = 1;
232
- try {
233
- for (const e of subs) {
234
- _processSubscriber(e);
235
- }
236
- if (notifyQueueLen > 0) {
237
- let qi = 0;
238
- while (qi < notifyQueueLen) {
239
- const queuedSubs = notifyQueue[qi];
240
- notifyQueue[qi] = null;
241
- qi++;
242
- for (const e of queuedSubs) {
243
- _processSubscriber(e);
244
- }
245
- }
246
- notifyQueueLen = 0;
247
- }
248
- } finally {
249
- notifyDepth = 0;
250
- }
251
- if (batchDepth === 0 && pendingEffects.length > 0) scheduleMicrotask();
252
- } else {
253
- if (notifyQueue === null) notifyQueue = [];
254
- if (notifyQueueLen >= notifyQueue.length) {
255
- notifyQueue.push(subs);
256
- } else {
257
- notifyQueue[notifyQueueLen] = subs;
258
- }
259
- notifyQueueLen++;
260
- }
261
- }
262
- var microtaskScheduled = false;
263
- function scheduleMicrotask() {
264
- if (!microtaskScheduled) {
265
- microtaskScheduled = true;
266
- queueMicrotask(() => {
267
- microtaskScheduled = false;
268
- flush();
269
- });
270
- }
271
- }
272
- var isFlushing = false;
273
- function flush() {
274
- if (isFlushing) return;
275
- isFlushing = true;
276
- try {
277
- let iterations = 0;
278
- while (pendingEffects.length > 0 && iterations < 25) {
279
- const batch2 = pendingEffects;
280
- pendingEffects = [];
281
- if (batch2.length > 1 && pendingNeedSort) {
282
- batch2.sort((a, b) => a._level - b._level);
283
- }
284
- pendingNeedSort = false;
285
- for (let i = 0; i < batch2.length; i++) {
286
- const e = batch2[i];
287
- e._pending = false;
288
- if (!e.disposed && !e._onNotify) {
289
- const prevDepsLen = e.deps.length;
290
- _runEffect(e);
291
- if (!e._computed && e.deps.length !== prevDepsLen) {
292
- _updateLevel(e);
293
- }
294
- }
295
- }
296
- iterations++;
297
- }
298
- if (iterations >= 25) {
299
- if (__DEV__) {
300
- const remaining = pendingEffects.slice(0, 3);
301
- const effectNames = remaining.map((e) => e.fn?.name || e.fn?.toString().slice(0, 60) || "(anonymous)");
302
- console.warn(
303
- `[what] Possible infinite effect loop detected (25 iterations). Likely cause: an effect writes to a signal it also reads, creating a cycle. Use untrack() to read signals without subscribing. Looping effects: ${effectNames.join(", ")}`
304
- );
305
- } else {
306
- console.warn("[what] Possible infinite effect loop detected");
307
- }
308
- for (let i = 0; i < pendingEffects.length; i++) pendingEffects[i]._pending = false;
309
- pendingEffects.length = 0;
310
- }
311
- } finally {
312
- isFlushing = false;
313
- }
314
- }
315
- function flushSync() {
316
- if (isFlushing) {
317
- if (__DEV__) {
318
- console.warn(
319
- "[what] flushSync() called during an active flush (e.g., inside a component render or effect). This is a no-op to prevent infinite loops. Move flushSync() to an event handler or onMount callback."
320
- );
321
- }
322
- return;
323
- }
324
- if (currentEffect) {
325
- if (__DEV__) {
326
- console.warn(
327
- "[what] flushSync() called during effect execution. This is a no-op to prevent infinite loops. Move flushSync() to an event handler or onMount callback."
328
- );
329
- }
330
- return;
331
- }
332
- microtaskScheduled = false;
333
- flush();
334
- }
335
- function untrack(fn) {
336
- const prev = currentEffect;
337
- currentEffect = null;
338
- try {
339
- return fn();
340
- } finally {
341
- currentEffect = prev;
342
- }
343
- }
344
- function createRoot(fn) {
345
- const prevRoot = currentRoot;
346
- const prevOwner = currentOwner;
347
- const root = {
348
- disposals: [],
349
- owner: currentOwner,
350
- // parent owner for ownership tree
351
- children: [],
352
- // child roots (ownership tree)
353
- _disposed: false
354
- };
355
- if (currentOwner) {
356
- currentOwner.children.push(root);
357
- }
358
- currentRoot = root;
359
- currentOwner = root;
360
- try {
361
- const dispose = () => {
362
- if (root._disposed) return;
363
- root._disposed = true;
364
- for (let i = root.children.length - 1; i >= 0; i--) {
365
- _disposeRoot(root.children[i]);
366
- }
367
- root.children.length = 0;
368
- for (let i = root.disposals.length - 1; i >= 0; i--) {
369
- root.disposals[i]();
370
- }
371
- root.disposals.length = 0;
372
- if (root.owner) {
373
- const idx = root.owner.children.indexOf(root);
374
- if (idx >= 0) root.owner.children.splice(idx, 1);
375
- }
376
- };
377
- return fn(dispose);
378
- } finally {
379
- currentRoot = prevRoot;
380
- currentOwner = prevOwner;
381
- }
382
- }
383
- function _disposeRoot(root) {
384
- if (root._disposed) return;
385
- root._disposed = true;
386
- for (let i = root.children.length - 1; i >= 0; i--) {
387
- _disposeRoot(root.children[i]);
388
- }
389
- root.children.length = 0;
390
- for (let i = root.disposals.length - 1; i >= 0; i--) {
391
- root.disposals[i]();
392
- }
393
- root.disposals.length = 0;
394
- }
395
-
396
- // packages/core/src/h.js
397
- var EMPTY_OBJ = /* @__PURE__ */ Object.create(null);
398
- var EMPTY_ARR = [];
399
- function h(tag, props) {
400
- props = props || EMPTY_OBJ;
401
- const argLen = arguments.length;
402
- let flat;
403
- if (argLen <= 2) {
404
- flat = EMPTY_ARR;
405
- } else if (argLen === 3) {
406
- flat = _flattenSingle(arguments[2]);
407
- } else {
408
- const out = [];
409
- for (let i = 2; i < argLen; i++) {
410
- _flattenInto(arguments[i], out);
411
- }
412
- flat = out;
413
- }
414
- const key = props.key ?? null;
415
- if (props.key !== void 0) {
416
- props = { ...props };
417
- delete props.key;
418
- }
419
- return { tag, props, children: flat, key, _vnode: true };
420
- }
421
- function _flattenSingle(child) {
422
- if (child == null || child === false || child === true) return EMPTY_ARR;
423
- if (Array.isArray(child)) {
424
- const out = [];
425
- _flattenInto(child, out);
426
- return out;
427
- }
428
- if (typeof child === "object" && child._vnode) return [child];
429
- if (typeof child === "function") return [child];
430
- return [String(child)];
431
- }
432
- function _flattenInto(child, out) {
433
- if (child == null || child === false || child === true) return;
434
- if (Array.isArray(child)) {
435
- for (let i = 0; i < child.length; i++) {
436
- _flattenInto(child[i], out);
437
- }
438
- } else if (typeof child === "object" && child._vnode) {
439
- out.push(child);
440
- } else if (typeof child === "function") {
441
- out.push(child);
442
- } else {
443
- out.push(String(child));
444
- }
445
- }
446
-
447
- // packages/core/src/components.js
448
- var _getCurrentComponent = null;
449
- function _injectGetCurrentComponent(fn) {
450
- _getCurrentComponent = fn;
451
- }
452
- function reportError(error, startCtx) {
453
- let ctx = startCtx || _getCurrentComponent?.();
454
- while (ctx) {
455
- if (ctx._errorBoundary) {
456
- ctx._errorBoundary(error);
457
- return true;
458
- }
459
- ctx = ctx._parentCtx;
460
- }
461
- return false;
462
- }
463
-
464
- // packages/core/src/helpers.js
465
- var _getCurrentComponentRef = null;
466
- function _setComponentRef(fn) {
467
- _getCurrentComponentRef = fn;
468
- }
469
-
470
- // packages/core/src/dom.js
471
- var SVG_ELEMENTS = /* @__PURE__ */ new Set([
472
- "svg",
473
- "path",
474
- "circle",
475
- "rect",
476
- "line",
477
- "polyline",
478
- "polygon",
479
- "ellipse",
480
- "g",
481
- "defs",
482
- "use",
483
- "symbol",
484
- "clipPath",
485
- "mask",
486
- "pattern",
487
- "image",
488
- "text",
489
- "tspan",
490
- "textPath",
491
- "foreignObject",
492
- "linearGradient",
493
- "radialGradient",
494
- "stop",
495
- "marker",
496
- "animate",
497
- "animateTransform",
498
- "animateMotion",
499
- "set",
500
- "filter",
501
- "feBlend",
502
- "feColorMatrix",
503
- "feComponentTransfer",
504
- "feComposite",
505
- "feConvolveMatrix",
506
- "feDiffuseLighting",
507
- "feDisplacementMap",
508
- "feFlood",
509
- "feGaussianBlur",
510
- "feImage",
511
- "feMerge",
512
- "feMergeNode",
513
- "feMorphology",
514
- "feOffset",
515
- "feSpecularLighting",
516
- "feTile",
517
- "feTurbulence"
518
- ]);
519
- var SVG_NS = "http://www.w3.org/2000/svg";
520
- var mountedComponents = /* @__PURE__ */ new Set();
521
- var _commentCtxMap = /* @__PURE__ */ new WeakMap();
522
- function isDomNode(value) {
523
- if (!value || typeof value !== "object") return false;
524
- if (typeof Node !== "undefined" && value instanceof Node) return true;
525
- return typeof value.nodeType === "number" && typeof value.nodeName === "string";
526
- }
527
- function isVNode(value) {
528
- return !!value && typeof value === "object" && (value._vnode === true || "tag" in value);
529
- }
530
- function disposeComponent(ctx) {
531
- if (ctx.disposed) return;
532
- ctx.disposed = true;
533
- if (ctx.cleanups) {
534
- for (const cleanup3 of ctx.cleanups) {
535
- try {
536
- cleanup3();
537
- } catch (e) {
538
- console.error("[what] cleanup error:", e);
539
- }
540
- }
541
- }
542
- if (ctx.effects) {
543
- for (const dispose of ctx.effects) {
544
- try {
545
- dispose();
546
- } catch (e) {
547
- }
548
- }
549
- }
550
- if (ctx.hooks) {
551
- for (const hook of ctx.hooks) {
552
- if (hook && typeof hook.cleanup === "function") {
553
- try {
554
- hook.cleanup();
555
- } catch (e) {
556
- console.error("[what] hook cleanup error:", e);
557
- }
558
- }
559
- }
560
- }
561
- if (ctx._cleanupCallbacks) {
562
- for (const fn of ctx._cleanupCallbacks) {
563
- try {
564
- fn();
565
- } catch (e) {
566
- console.error("[what] onCleanup error:", e);
567
- }
568
- }
569
- }
570
- if (__DEV__ && __devtools?.onComponentUnmount) __devtools.onComponentUnmount(ctx);
571
- mountedComponents.delete(ctx);
572
- }
573
- function disposeTree(node) {
574
- if (!node) return;
575
- if (node._componentCtx) {
576
- disposeComponent(node._componentCtx);
577
- }
578
- if (node.nodeType === 8) {
579
- const commentCtx = _commentCtxMap.get(node);
580
- if (commentCtx) {
581
- disposeComponent(commentCtx);
582
- }
583
- }
584
- if (node._dispose) {
585
- try {
586
- node._dispose();
587
- } catch (e) {
588
- }
589
- }
590
- if (node._propEffects) {
591
- for (const key in node._propEffects) {
592
- try {
593
- node._propEffects[key]();
594
- } catch (e) {
595
- }
596
- }
597
- }
598
- const children = node.childNodes;
599
- if (children && children.length > 0) {
600
- for (let i = 0; i < children.length; i++) {
601
- disposeTree(children[i]);
602
- }
603
- }
604
- }
605
- function mount(vnode, container2) {
606
- if (typeof container2 === "string") {
607
- container2 = document.querySelector(container2);
608
- }
609
- disposeTree(container2);
610
- container2.textContent = "";
611
- const node = createDOM(vnode, container2);
612
- if (node) container2.appendChild(node);
613
- return () => {
614
- disposeTree(container2);
615
- container2.textContent = "";
616
- };
617
- }
618
- function createDOM(vnode, parent, isSvg) {
619
- if (vnode == null || vnode === false || vnode === true) {
620
- return document.createComment("");
621
- }
622
- if (typeof vnode === "string" || typeof vnode === "number") {
623
- return document.createTextNode(String(vnode));
624
- }
625
- if (isDomNode(vnode)) {
626
- return vnode;
627
- }
628
- if (typeof vnode === "function") {
629
- const startMarker = document.createComment("fn");
630
- const endMarker = document.createComment("/fn");
631
- let currentNodes = [];
632
- const frag = document.createDocumentFragment();
633
- frag.appendChild(startMarker);
634
- frag.appendChild(endMarker);
635
- const dispose = effect(() => {
636
- const val = vnode();
637
- const vnodes = val == null || val === false || val === true ? [] : Array.isArray(val) ? val : [val];
638
- const realParent = endMarker.parentNode;
639
- if (!realParent) return;
640
- for (const old of currentNodes) {
641
- disposeTree(old);
642
- if (old.parentNode === realParent) realParent.removeChild(old);
643
- }
644
- currentNodes = [];
645
- for (const v of vnodes) {
646
- const node = createDOM(v, realParent, parent?._isSvg);
647
- if (node) {
648
- if (node.nodeType === 11) {
649
- const children = Array.from(node.childNodes);
650
- realParent.insertBefore(node, endMarker);
651
- for (const child of children) currentNodes.push(child);
652
- } else {
653
- realParent.insertBefore(node, endMarker);
654
- currentNodes.push(node);
655
- }
656
- }
657
- }
658
- });
659
- startMarker._dispose = dispose;
660
- endMarker._dispose = dispose;
661
- return frag;
662
- }
663
- if (Array.isArray(vnode)) {
664
- const frag = document.createDocumentFragment();
665
- for (const child of vnode) {
666
- const node = createDOM(child, parent, isSvg);
667
- if (node) frag.appendChild(node);
668
- }
669
- return frag;
670
- }
671
- if (isVNode(vnode) && typeof vnode.tag === "function") {
672
- return createComponent(vnode, parent, isSvg);
673
- }
674
- if (isVNode(vnode)) {
675
- return createElementFromVNode(vnode, parent, isSvg);
676
- }
677
- return document.createTextNode(String(vnode));
678
- }
679
- var _propsProxyHandler = {
680
- get(target, key) {
681
- if (key === "_sig") return void 0;
682
- return target._sig()[key];
683
- },
684
- has(target, key) {
685
- if (key === "_sig") return false;
686
- return key in target._sig();
687
- },
688
- ownKeys(target) {
689
- return Reflect.ownKeys(target._sig());
690
- },
691
- getOwnPropertyDescriptor(target, key) {
692
- if (key === "_sig") return void 0;
693
- const current = target._sig();
694
- if (key in current) {
695
- return { value: current[key], writable: false, enumerable: true, configurable: true };
696
- }
697
- return void 0;
698
- }
699
- };
700
- var componentStack = [];
701
- function getCurrentComponent() {
702
- return componentStack[componentStack.length - 1];
703
- }
704
- _injectGetCurrentComponent(getCurrentComponent);
705
- _setComponentRef(getCurrentComponent);
706
- function createComponent(vnode, parent, isSvg) {
707
- let { tag: Component, props, children } = vnode;
708
- if (typeof Component === "function" && (Component.prototype?.isReactComponent || Component.prototype?.render)) {
709
- const ClassComp = Component;
710
- Component = function ClassComponentBridge(props2) {
711
- const instance = new ClassComp(props2);
712
- return instance.render();
713
- };
714
- Component.displayName = ClassComp.displayName || ClassComp.name || "ClassComponent";
715
- }
716
- if (Component === "__errorBoundary" || vnode.tag === "__errorBoundary") {
717
- return createErrorBoundary(vnode, parent);
718
- }
719
- if (Component === "__suspense" || vnode.tag === "__suspense") {
720
- return createSuspenseBoundary(vnode, parent);
721
- }
722
- if (Component === "__portal" || vnode.tag === "__portal") {
723
- return createPortalDOM(vnode, parent);
724
- }
725
- const parentCtx = componentStack[componentStack.length - 1] || null;
726
- let errorBoundary = null;
727
- if (parentCtx) {
728
- errorBoundary = parentCtx._errorBoundary || null;
729
- if (!errorBoundary) {
730
- let p = parentCtx._parentCtx;
731
- while (p) {
732
- if (p._errorBoundary) {
733
- errorBoundary = p._errorBoundary;
734
- break;
735
- }
736
- p = p._parentCtx;
737
- }
738
- }
739
- }
740
- const ctx = {
741
- hooks: [],
742
- hookIndex: 0,
743
- effects: [],
744
- cleanups: [],
745
- mounted: false,
746
- disposed: false,
747
- Component,
748
- _parentCtx: parentCtx,
749
- _errorBoundary: errorBoundary
750
- };
751
- const startComment = document.createComment("c:start");
752
- const endComment = document.createComment("c:end");
753
- _commentCtxMap.set(startComment, ctx);
754
- ctx._startComment = startComment;
755
- ctx._endComment = endComment;
756
- const container2 = document.createDocumentFragment();
757
- container2._componentCtx = ctx;
758
- ctx._wrapper = startComment;
759
- mountedComponents.add(ctx);
760
- if (__DEV__ && __devtools?.onComponentMount) __devtools.onComponentMount(ctx);
761
- const propsChildren = children.length === 0 ? void 0 : children.length === 1 ? children[0] : children;
762
- let mergedProps;
763
- if (propsChildren !== void 0) {
764
- mergedProps = props ? Object.assign({}, props, { children: propsChildren }) : { children: propsChildren };
765
- } else {
766
- mergedProps = props ? Object.assign({}, props) : {};
767
- }
768
- const propsSignal = signal(mergedProps);
769
- ctx._propsSignal = propsSignal;
770
- const reactiveProps = new Proxy({ _sig: propsSignal }, _propsProxyHandler);
771
- componentStack.push(ctx);
772
- let result;
773
- try {
774
- result = Component(reactiveProps);
775
- } catch (error) {
776
- componentStack.pop();
777
- if (!reportError(error, ctx)) {
778
- console.error("[what] Uncaught error in component:", Component.name || "Anonymous", error);
779
- throw error;
780
- }
781
- container2.appendChild(startComment);
782
- container2.appendChild(endComment);
783
- return container2;
784
- }
785
- componentStack.pop();
786
- ctx.mounted = true;
787
- if (ctx._mountCallbacks) {
788
- queueMicrotask(() => {
789
- if (ctx.disposed) return;
790
- for (const fn of ctx._mountCallbacks) {
791
- try {
792
- fn();
793
- } catch (e) {
794
- console.error("[what] onMount error:", e);
795
- }
796
- }
797
- });
798
- }
799
- container2.appendChild(startComment);
800
- const vnodes = Array.isArray(result) ? result : [result];
801
- for (const v of vnodes) {
802
- const node = createDOM(v, container2, isSvg);
803
- if (node) container2.appendChild(node);
804
- }
805
- container2.appendChild(endComment);
806
- return container2;
807
- }
808
- function createErrorBoundary(vnode, parent) {
809
- const { errorState, handleError, fallback, reset } = vnode.props;
810
- const children = vnode.children;
811
- const startComment = document.createComment("eb:start");
812
- const endComment = document.createComment("eb:end");
813
- const boundaryCtx = {
814
- hooks: [],
815
- hookIndex: 0,
816
- effects: [],
817
- cleanups: [],
818
- mounted: false,
819
- disposed: false,
820
- _parentCtx: componentStack[componentStack.length - 1] || null,
821
- _errorBoundary: handleError,
822
- _startComment: startComment,
823
- _endComment: endComment
824
- };
825
- _commentCtxMap.set(startComment, boundaryCtx);
826
- const container2 = document.createDocumentFragment();
827
- container2._componentCtx = boundaryCtx;
828
- container2.appendChild(startComment);
829
- container2.appendChild(endComment);
830
- const dispose = effect(() => {
831
- const error = errorState();
832
- componentStack.push(boundaryCtx);
833
- if (startComment.parentNode) {
834
- while (startComment.nextSibling && startComment.nextSibling !== endComment) {
835
- const old = startComment.nextSibling;
836
- disposeTree(old);
837
- old.parentNode.removeChild(old);
838
- }
839
- }
840
- let vnodes;
841
- if (error) {
842
- vnodes = typeof fallback === "function" ? [fallback({ error, reset })] : [fallback];
843
- } else {
844
- vnodes = children;
845
- }
846
- vnodes = Array.isArray(vnodes) ? vnodes : [vnodes];
847
- for (const v of vnodes) {
848
- const node = createDOM(v, parent);
849
- if (node) {
850
- if (endComment.parentNode) {
851
- endComment.parentNode.insertBefore(node, endComment);
852
- } else {
853
- container2.insertBefore(node, endComment);
854
- }
855
- }
856
- }
857
- componentStack.pop();
858
- });
859
- boundaryCtx.effects.push(dispose);
860
- return container2;
861
- }
862
- function createSuspenseBoundary(vnode, parent) {
863
- const { boundary, fallback, loading } = vnode.props;
864
- const children = vnode.children;
865
- const startComment = document.createComment("sb:start");
866
- const endComment = document.createComment("sb:end");
867
- const boundaryCtx = {
868
- hooks: [],
869
- hookIndex: 0,
870
- effects: [],
871
- cleanups: [],
872
- mounted: false,
873
- disposed: false,
874
- _parentCtx: componentStack[componentStack.length - 1] || null,
875
- _startComment: startComment,
876
- _endComment: endComment
877
- };
878
- _commentCtxMap.set(startComment, boundaryCtx);
879
- const container2 = document.createDocumentFragment();
880
- container2._componentCtx = boundaryCtx;
881
- container2.appendChild(startComment);
882
- container2.appendChild(endComment);
883
- const dispose = effect(() => {
884
- const isLoading = loading();
885
- const vnodes = isLoading ? [fallback] : children;
886
- const normalized = Array.isArray(vnodes) ? vnodes : [vnodes];
887
- componentStack.push(boundaryCtx);
888
- if (startComment.parentNode) {
889
- while (startComment.nextSibling && startComment.nextSibling !== endComment) {
890
- const old = startComment.nextSibling;
891
- disposeTree(old);
892
- old.parentNode.removeChild(old);
893
- }
894
- }
895
- for (const v of normalized) {
896
- const node = createDOM(v, parent);
897
- if (node) {
898
- if (endComment.parentNode) {
899
- endComment.parentNode.insertBefore(node, endComment);
900
- } else {
901
- container2.insertBefore(node, endComment);
902
- }
903
- }
904
- }
905
- componentStack.pop();
906
- });
907
- boundaryCtx.effects.push(dispose);
908
- return container2;
909
- }
910
- function createPortalDOM(vnode, parent) {
911
- const { container: container2 } = vnode.props;
912
- const children = vnode.children;
913
- if (!container2) {
914
- console.warn("[what] Portal: target container not found");
915
- return document.createComment("portal:empty");
916
- }
917
- const portalCtx = {
918
- hooks: [],
919
- hookIndex: 0,
920
- effects: [],
921
- cleanups: [],
922
- mounted: false,
923
- disposed: false,
924
- _parentCtx: componentStack[componentStack.length - 1] || null
925
- };
926
- const placeholder = document.createComment("portal");
927
- placeholder._componentCtx = portalCtx;
928
- const portalNodes = [];
929
- for (const child of children) {
930
- const node = createDOM(child, container2);
931
- if (node) {
932
- container2.appendChild(node);
933
- portalNodes.push(node);
934
- }
935
- }
936
- portalCtx._cleanupCallbacks = [() => {
937
- for (const node of portalNodes) {
938
- disposeTree(node);
939
- if (node.parentNode) node.parentNode.removeChild(node);
940
- }
941
- }];
942
- return placeholder;
943
- }
944
- function createElementFromVNode(vnode, parent, isSvg) {
945
- const { tag, props, children } = vnode;
946
- const svgContext = isSvg || SVG_ELEMENTS.has(tag);
947
- const el = svgContext ? document.createElementNS(SVG_NS, tag) : document.createElement(tag);
948
- if (props) {
949
- applyProps(el, props, {}, svgContext);
950
- }
951
- const isSvgChildren = svgContext && tag !== "foreignObject";
952
- for (let i = 0; i < children.length; i++) {
953
- const node = createDOM(children[i], el, isSvgChildren);
954
- if (node) el.appendChild(node);
955
- }
956
- el._vnode = vnode;
957
- return el;
958
- }
959
- function applyProps(el, newProps, oldProps, isSvg) {
960
- if (!newProps) return;
961
- for (const key in newProps) {
962
- if (key === "key" || key === "children") continue;
963
- if (key === "ref") {
964
- const ref = newProps.ref;
965
- if (typeof ref === "function") ref(el);
966
- else if (ref) ref.current = el;
967
- continue;
968
- }
969
- setProp(el, key, newProps[key], isSvg);
970
- }
971
- }
972
- function setProp(el, key, value, isSvg) {
973
- if (typeof value === "function" && !(key.startsWith("on") && key.length > 2) && key !== "ref") {
974
- if (!el._propEffects) el._propEffects = {};
975
- if (el._propEffects[key]) {
976
- try {
977
- el._propEffects[key]();
978
- } catch (e) {
979
- }
980
- }
981
- el._propEffects[key] = effect(() => {
982
- const resolved = value();
983
- setProp(el, key, resolved, isSvg);
984
- });
985
- return;
986
- }
987
- if (key.startsWith("on") && key.length > 2) {
988
- let eventName = key.slice(2);
989
- let useCapture = false;
990
- if (eventName.endsWith("Capture")) {
991
- eventName = eventName.slice(0, -7);
992
- useCapture = true;
993
- }
994
- const event = eventName.toLowerCase();
995
- const storageKey = useCapture ? event + "_capture" : event;
996
- const old = el._events?.[storageKey];
997
- if (old && old._original === value) return;
998
- if (old) el.removeEventListener(event, old, useCapture);
999
- if (value == null) return;
1000
- if (!el._events) el._events = {};
1001
- const wrappedHandler = (e) => {
1002
- if (!e.nativeEvent) e.nativeEvent = e;
1003
- return untrack(() => wrappedHandler._handler(e));
1004
- };
1005
- wrappedHandler._handler = value;
1006
- wrappedHandler._original = value;
1007
- el._events[storageKey] = wrappedHandler;
1008
- const eventOpts = value._eventOpts;
1009
- el.addEventListener(event, wrappedHandler, eventOpts || useCapture || void 0);
1010
- return;
1011
- }
1012
- if (key === "className" || key === "class") {
1013
- if (isSvg) {
1014
- el.setAttribute("class", value || "");
1015
- } else {
1016
- el.className = value || "";
1017
- }
1018
- return;
1019
- }
1020
- if (key === "style") {
1021
- if (typeof value === "string") {
1022
- el.style.cssText = value;
1023
- el._prevStyle = null;
1024
- } else if (typeof value === "object") {
1025
- const oldStyle = el._prevStyle || {};
1026
- for (const prop in oldStyle) {
1027
- if (!(prop in value)) el.style[prop] = "";
1028
- }
1029
- for (const prop in value) {
1030
- el.style[prop] = value[prop] ?? "";
1031
- }
1032
- el._prevStyle = { ...value };
1033
- }
1034
- return;
1035
- }
1036
- if (key === "dangerouslySetInnerHTML") {
1037
- el.innerHTML = value?.__html ?? "";
1038
- return;
1039
- }
1040
- if (key === "innerHTML") {
1041
- if (value == null) return;
1042
- if (value && typeof value === "object" && "__html" in value) {
1043
- el.innerHTML = value.__html ?? "";
1044
- } else {
1045
- if (__DEV__) {
1046
- console.warn(
1047
- "[what] innerHTML received a raw string. This is a security risk (XSS). Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead."
1048
- );
1049
- }
1050
- return;
1051
- }
1052
- return;
1053
- }
1054
- if (typeof value === "boolean") {
1055
- if (value) el.setAttribute(key, "");
1056
- else el.removeAttribute(key);
1057
- return;
1058
- }
1059
- if (key.startsWith("data-") || key.startsWith("aria-")) {
1060
- el.setAttribute(key, value);
1061
- return;
1062
- }
1063
- if (isSvg) {
1064
- if (value === false || value == null) {
1065
- el.removeAttribute(key);
1066
- } else {
1067
- el.setAttribute(key, value === true ? "" : String(value));
1068
- }
1069
- return;
1070
- }
1071
- if (key in el) {
1072
- el[key] = value;
1073
- } else {
1074
- el.setAttribute(key, value);
1075
- }
1076
- }
1
+ import {
2
+ createRoot,
3
+ effect,
4
+ flushSync,
5
+ mount,
6
+ signal
7
+ } from "./chunk-AW3BAPIK.js";
8
+ import {
9
+ h
10
+ } from "./chunk-AZP2EOGX.js";
1077
11
 
1078
12
  // packages/core/src/testing.js
1079
13
  var container = null;
@@ -1085,7 +19,7 @@ function setupDOM() {
1085
19
  }
1086
20
  return container;
1087
21
  }
1088
- function cleanup2() {
22
+ function cleanup() {
1089
23
  if (container) {
1090
24
  container.innerHTML = "";
1091
25
  if (container.parentNode) {
@@ -1151,7 +85,7 @@ function renderTest(Component, props) {
1151
85
  unmount() {
1152
86
  if (unmountFn) unmountFn();
1153
87
  if (rootDispose) rootDispose();
1154
- cleanup2();
88
+ cleanup();
1155
89
  },
1156
90
  // Query helpers
1157
91
  getByText: (text) => queryByText(target, text),
@@ -1487,7 +421,7 @@ var screen = {
1487
421
  };
1488
422
  export {
1489
423
  act,
1490
- cleanup2 as cleanup,
424
+ cleanup,
1491
425
  createTestSignal,
1492
426
  expect,
1493
427
  fireEvent,