what-core 0.10.0 → 0.11.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.
@@ -0,0 +1,1699 @@
1
+ import {
2
+ h
3
+ } from "./chunk-AZP2EOGX.js";
4
+
5
+ // packages/core/src/reactive.js
6
+ var __DEV__ = typeof process !== "undefined" ? true : true;
7
+ var __devtools = null;
8
+ function __setDevToolsHooks(hooks) {
9
+ if (__DEV__) __devtools = hooks;
10
+ }
11
+ var currentEffect = null;
12
+ var currentRoot = null;
13
+ var currentOwner = null;
14
+ var insideComputed = false;
15
+ var batchDepth = 0;
16
+ var pendingEffects = [];
17
+ var pendingNeedSort = false;
18
+ var NEEDS_UPSTREAM = /* @__PURE__ */ Symbol("needs_upstream");
19
+ var iterativeEvalStack = null;
20
+ function signal(initial, debugName) {
21
+ let value = initial;
22
+ const subs = /* @__PURE__ */ new Set();
23
+ let lastTracked = null;
24
+ let lastTrackedEpoch = 0;
25
+ function _sigWrite(next) {
26
+ if (__DEV__ && insideComputed) {
27
+ console.warn(
28
+ "[what] Signal.set() called inside a computed function. This may cause infinite loops. Use effect() instead." + (debugName ? ` (signal: ${debugName})` : "")
29
+ );
30
+ }
31
+ const nextVal = typeof next === "function" ? next(value) : next;
32
+ if (value === nextVal || value !== value && nextVal !== nextVal) return;
33
+ value = nextVal;
34
+ lastTracked = null;
35
+ if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);
36
+ if (subs.size > 0) notify(subs);
37
+ }
38
+ function sig(newVal) {
39
+ if (arguments.length === 0) {
40
+ const ce = currentEffect;
41
+ if (ce !== null) {
42
+ if (ce !== lastTracked || ce._epoch !== lastTrackedEpoch) {
43
+ lastTracked = ce;
44
+ lastTrackedEpoch = ce._epoch;
45
+ subs.add(ce);
46
+ ce.deps.push(subs);
47
+ }
48
+ }
49
+ return value;
50
+ }
51
+ _sigWrite(newVal);
52
+ }
53
+ sig.set = _sigWrite;
54
+ sig.peek = () => value;
55
+ sig.subscribe = (fn) => {
56
+ return effect(() => fn(sig()));
57
+ };
58
+ sig._signal = true;
59
+ if (__DEV__) {
60
+ sig._subs = subs;
61
+ if (debugName) sig._debugName = debugName;
62
+ }
63
+ if (__DEV__ && __devtools) __devtools.onSignalCreate(sig);
64
+ return sig;
65
+ }
66
+ function computed(fn) {
67
+ let value, dirty = true;
68
+ const subs = /* @__PURE__ */ new Set();
69
+ let lastTracked = null;
70
+ let lastTrackedEpoch = 0;
71
+ const inner = _createEffect(() => {
72
+ const prevInsideComputed = insideComputed;
73
+ if (__DEV__) insideComputed = true;
74
+ try {
75
+ value = fn();
76
+ dirty = false;
77
+ } finally {
78
+ if (__DEV__) insideComputed = prevInsideComputed;
79
+ }
80
+ }, true);
81
+ inner._level = 1;
82
+ inner._computed = true;
83
+ inner._computedSubs = subs;
84
+ subs._owner = inner;
85
+ inner._markDirty = () => {
86
+ dirty = true;
87
+ };
88
+ inner._isDirty = () => dirty;
89
+ function read() {
90
+ const ce = currentEffect;
91
+ if (ce !== null) {
92
+ if (ce !== lastTracked || ce._epoch !== lastTrackedEpoch) {
93
+ lastTracked = ce;
94
+ lastTrackedEpoch = ce._epoch;
95
+ subs.add(ce);
96
+ ce.deps.push(subs);
97
+ }
98
+ }
99
+ if (dirty) _evaluateComputed(inner);
100
+ return value;
101
+ }
102
+ inner._onNotify = () => {
103
+ dirty = true;
104
+ lastTracked = null;
105
+ if (subs.size > 0) notify(subs);
106
+ };
107
+ read._signal = true;
108
+ read.peek = () => {
109
+ if (dirty) _evaluateComputed(inner);
110
+ return value;
111
+ };
112
+ return read;
113
+ }
114
+ function _evaluateComputed(computedEffect) {
115
+ if (iterativeEvalStack !== null) {
116
+ iterativeEvalStack.push(computedEffect);
117
+ throw NEEDS_UPSTREAM;
118
+ }
119
+ const stack = [computedEffect];
120
+ iterativeEvalStack = stack;
121
+ try {
122
+ while (stack.length > 0) {
123
+ const current = stack[stack.length - 1];
124
+ if (!current._isDirty || !current._isDirty()) {
125
+ stack.pop();
126
+ continue;
127
+ }
128
+ let pushedUpstream = false;
129
+ const deps = current.deps;
130
+ for (let i = 0; i < deps.length; i++) {
131
+ const depOwner = deps[i]._owner;
132
+ if (depOwner && depOwner._computed && depOwner._isDirty && depOwner._isDirty()) {
133
+ stack.push(depOwner);
134
+ pushedUpstream = true;
135
+ }
136
+ }
137
+ if (pushedUpstream) {
138
+ continue;
139
+ }
140
+ try {
141
+ const prevDepsLen = current.deps.length;
142
+ _runEffect(current);
143
+ if (current.deps.length !== prevDepsLen) {
144
+ _updateLevel(current);
145
+ }
146
+ stack.pop();
147
+ } catch (err) {
148
+ if (err === NEEDS_UPSTREAM) {
149
+ current._markDirty();
150
+ } else {
151
+ throw err;
152
+ }
153
+ }
154
+ }
155
+ } finally {
156
+ iterativeEvalStack = null;
157
+ }
158
+ }
159
+ function _updateLevel(e) {
160
+ let maxDepLevel = 0;
161
+ const deps = e.deps;
162
+ for (let i = 0; i < deps.length; i++) {
163
+ const owner = deps[i]._owner;
164
+ if (owner) {
165
+ const depLevel = owner._level;
166
+ if (depLevel > maxDepLevel) maxDepLevel = depLevel;
167
+ }
168
+ }
169
+ e._level = maxDepLevel + 1;
170
+ }
171
+ var _noopDispose = () => {
172
+ };
173
+ function effect(fn, opts) {
174
+ const e = _createEffect(fn);
175
+ e._level = 1;
176
+ const prev = currentEffect;
177
+ currentEffect = e;
178
+ try {
179
+ const result = e.fn();
180
+ if (typeof result === "function") e._cleanup = result;
181
+ } finally {
182
+ currentEffect = prev;
183
+ }
184
+ _updateLevel(e);
185
+ if (opts?.stable) e._stable = true;
186
+ if (e.deps.length === 0 && e._cleanup === null) {
187
+ e.disposed = true;
188
+ if (__DEV__ && __devtools) __devtools.onEffectDispose(e);
189
+ return _noopDispose;
190
+ }
191
+ const dispose = () => _disposeEffect(e);
192
+ if (currentRoot) {
193
+ currentRoot.disposals.push(dispose);
194
+ }
195
+ return dispose;
196
+ }
197
+ function batch(fn) {
198
+ batchDepth++;
199
+ try {
200
+ fn();
201
+ } finally {
202
+ batchDepth--;
203
+ if (batchDepth === 0) flush();
204
+ }
205
+ }
206
+ function _createEffect(fn, lazy2) {
207
+ const e = {
208
+ fn,
209
+ deps: [],
210
+ // array of subscriber sets (cheaper than Set for typical 1-3 deps)
211
+ lazy: lazy2 || false,
212
+ _onNotify: null,
213
+ disposed: false,
214
+ _pending: false,
215
+ _stable: false,
216
+ // stable effects skip cleanup/re-subscribe on re-run
217
+ _level: 0,
218
+ // topological depth: signals=0, computed/effects=max(deps)+1
219
+ _computed: false,
220
+ // true for computed inner effects
221
+ _computedSubs: null,
222
+ // reference to the computed's subscriber set
223
+ _isDirty: null,
224
+ // function to check if computed is dirty (set by computed())
225
+ _markDirty: null,
226
+ // function to mark computed dirty (set by computed())
227
+ _cleanup: null,
228
+ // cleanup function returned by effect fn (declared upfront for shape)
229
+ _epoch: 0
230
+ // incremented on cleanup — used by signal lastTracked cache
231
+ };
232
+ if (__DEV__ && __devtools) __devtools.onEffectCreate(e);
233
+ return e;
234
+ }
235
+ function _runEffect(e) {
236
+ if (e.disposed) return;
237
+ if (e._stable) {
238
+ if (e._cleanup) {
239
+ try {
240
+ e._cleanup();
241
+ } catch (err) {
242
+ if (__DEV__) console.warn("[what] Error in effect cleanup:", err);
243
+ }
244
+ e._cleanup = null;
245
+ }
246
+ const prev2 = currentEffect;
247
+ currentEffect = null;
248
+ try {
249
+ const result = e.fn();
250
+ if (typeof result === "function") e._cleanup = result;
251
+ } catch (err) {
252
+ if (__devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
253
+ if (__DEV__) console.warn("[what] Error in stable effect:", err);
254
+ } finally {
255
+ currentEffect = prev2;
256
+ }
257
+ if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);
258
+ return;
259
+ }
260
+ const singleDep = e.deps.length === 1 ? e.deps[0] : null;
261
+ cleanup(e);
262
+ if (e._cleanup) {
263
+ try {
264
+ e._cleanup();
265
+ } catch (err) {
266
+ if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect-cleanup", effect: e });
267
+ if (__DEV__) console.warn("[what] Error in effect cleanup:", err);
268
+ }
269
+ e._cleanup = null;
270
+ }
271
+ const prev = currentEffect;
272
+ currentEffect = e;
273
+ try {
274
+ const result = e.fn();
275
+ if (typeof result === "function") {
276
+ e._cleanup = result;
277
+ }
278
+ } catch (err) {
279
+ if (err === NEEDS_UPSTREAM) throw err;
280
+ if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
281
+ throw err;
282
+ } finally {
283
+ currentEffect = prev;
284
+ }
285
+ if (singleDep !== null && e.deps.length === 1 && e.deps[0] === singleDep && !e._cleanup && !e._pending) {
286
+ e._stable = true;
287
+ }
288
+ if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);
289
+ }
290
+ function _disposeEffect(e) {
291
+ e.disposed = true;
292
+ if (__DEV__ && __devtools) __devtools.onEffectDispose(e);
293
+ cleanup(e);
294
+ if (e._cleanup) {
295
+ try {
296
+ e._cleanup();
297
+ } catch (err) {
298
+ if (__DEV__) console.warn("[what] Error in effect cleanup on dispose:", err);
299
+ }
300
+ e._cleanup = null;
301
+ }
302
+ }
303
+ function cleanup(e) {
304
+ const deps = e.deps;
305
+ for (let i = 0; i < deps.length; i++) deps[i].delete(e);
306
+ deps.length = 0;
307
+ e._epoch++;
308
+ }
309
+ var notifyDepth = 0;
310
+ var notifyQueue = null;
311
+ var notifyQueueLen = 0;
312
+ function _processSubscriber(e) {
313
+ if (e.disposed) return;
314
+ if (e._onNotify) {
315
+ e._onNotify();
316
+ } else if (!e._pending) {
317
+ if (batchDepth === 0 && e._stable) {
318
+ const prev = currentEffect;
319
+ currentEffect = null;
320
+ try {
321
+ const result = e.fn();
322
+ if (typeof result === "function") {
323
+ if (e._cleanup) try {
324
+ e._cleanup();
325
+ } catch (err) {
326
+ }
327
+ e._cleanup = result;
328
+ }
329
+ } catch (err) {
330
+ if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
331
+ if (__DEV__) console.warn("[what] Error in stable effect:", err);
332
+ } finally {
333
+ currentEffect = prev;
334
+ }
335
+ } else {
336
+ e._pending = true;
337
+ const level = e._level;
338
+ const len = pendingEffects.length;
339
+ if (len > 0 && pendingEffects[len - 1]._level > level) {
340
+ pendingNeedSort = true;
341
+ }
342
+ pendingEffects.push(e);
343
+ }
344
+ }
345
+ }
346
+ function notify(subs) {
347
+ if (notifyDepth === 0) {
348
+ notifyDepth = 1;
349
+ try {
350
+ for (const e of subs) {
351
+ _processSubscriber(e);
352
+ }
353
+ if (notifyQueueLen > 0) {
354
+ let qi = 0;
355
+ while (qi < notifyQueueLen) {
356
+ const queuedSubs = notifyQueue[qi];
357
+ notifyQueue[qi] = null;
358
+ qi++;
359
+ for (const e of queuedSubs) {
360
+ _processSubscriber(e);
361
+ }
362
+ }
363
+ notifyQueueLen = 0;
364
+ }
365
+ } finally {
366
+ notifyDepth = 0;
367
+ }
368
+ if (batchDepth === 0 && pendingEffects.length > 0) scheduleMicrotask();
369
+ } else {
370
+ if (notifyQueue === null) notifyQueue = [];
371
+ if (notifyQueueLen >= notifyQueue.length) {
372
+ notifyQueue.push(subs);
373
+ } else {
374
+ notifyQueue[notifyQueueLen] = subs;
375
+ }
376
+ notifyQueueLen++;
377
+ }
378
+ }
379
+ var microtaskScheduled = false;
380
+ function scheduleMicrotask() {
381
+ if (!microtaskScheduled) {
382
+ microtaskScheduled = true;
383
+ queueMicrotask(() => {
384
+ microtaskScheduled = false;
385
+ flush();
386
+ });
387
+ }
388
+ }
389
+ var isFlushing = false;
390
+ function flush() {
391
+ if (isFlushing) return;
392
+ isFlushing = true;
393
+ try {
394
+ let iterations = 0;
395
+ while (pendingEffects.length > 0 && iterations < 25) {
396
+ const batch2 = pendingEffects;
397
+ pendingEffects = [];
398
+ if (batch2.length > 1 && pendingNeedSort) {
399
+ batch2.sort((a, b) => a._level - b._level);
400
+ }
401
+ pendingNeedSort = false;
402
+ for (let i = 0; i < batch2.length; i++) {
403
+ const e = batch2[i];
404
+ e._pending = false;
405
+ if (!e.disposed && !e._onNotify) {
406
+ const prevDepsLen = e.deps.length;
407
+ try {
408
+ _runEffect(e);
409
+ } catch (err) {
410
+ if (err === NEEDS_UPSTREAM) throw err;
411
+ if (__DEV__ && __devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
412
+ try {
413
+ console.error("[what] Uncaught error in effect during update:", err);
414
+ } catch {
415
+ }
416
+ continue;
417
+ }
418
+ if (!e._computed && e.deps.length !== prevDepsLen) {
419
+ _updateLevel(e);
420
+ }
421
+ }
422
+ }
423
+ iterations++;
424
+ }
425
+ if (iterations >= 25) {
426
+ if (__DEV__) {
427
+ const remaining = pendingEffects.slice(0, 3);
428
+ const effectNames = remaining.map((e) => e.fn?.name || e.fn?.toString().slice(0, 60) || "(anonymous)");
429
+ console.warn(
430
+ `[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(", ")}`
431
+ );
432
+ } else {
433
+ console.warn("[what] Possible infinite effect loop detected");
434
+ }
435
+ for (let i = 0; i < pendingEffects.length; i++) pendingEffects[i]._pending = false;
436
+ pendingEffects.length = 0;
437
+ }
438
+ } finally {
439
+ isFlushing = false;
440
+ }
441
+ }
442
+ function memo(fn) {
443
+ let value;
444
+ const subs = /* @__PURE__ */ new Set();
445
+ const e = _createEffect(() => {
446
+ const next = fn();
447
+ if (!Object.is(value, next)) {
448
+ value = next;
449
+ for (const sub of subs) {
450
+ if (sub.disposed) continue;
451
+ if (sub._onNotify) {
452
+ sub._onNotify();
453
+ } else if (!sub._pending) {
454
+ sub._pending = true;
455
+ const level = sub._level;
456
+ const len = pendingEffects.length;
457
+ if (len > 0 && pendingEffects[len - 1]._level > level) {
458
+ pendingNeedSort = true;
459
+ }
460
+ pendingEffects.push(sub);
461
+ }
462
+ }
463
+ }
464
+ });
465
+ e._level = 1;
466
+ _runEffect(e);
467
+ _updateLevel(e);
468
+ subs._owner = e;
469
+ if (currentRoot) {
470
+ currentRoot.disposals.push(() => _disposeEffect(e));
471
+ }
472
+ function read() {
473
+ if (currentEffect) {
474
+ subs.add(currentEffect);
475
+ currentEffect.deps.push(subs);
476
+ }
477
+ return value;
478
+ }
479
+ read._signal = true;
480
+ read.peek = () => value;
481
+ return read;
482
+ }
483
+ function flushSync() {
484
+ if (isFlushing) {
485
+ if (__DEV__) {
486
+ console.warn(
487
+ "[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."
488
+ );
489
+ }
490
+ return;
491
+ }
492
+ if (currentEffect) {
493
+ if (__DEV__) {
494
+ console.warn(
495
+ "[what] flushSync() called during effect execution. This is a no-op to prevent infinite loops. Move flushSync() to an event handler or onMount callback."
496
+ );
497
+ }
498
+ return;
499
+ }
500
+ microtaskScheduled = false;
501
+ flush();
502
+ }
503
+ function untrack(fn) {
504
+ const prev = currentEffect;
505
+ currentEffect = null;
506
+ try {
507
+ return fn();
508
+ } finally {
509
+ currentEffect = prev;
510
+ }
511
+ }
512
+ function getOwner() {
513
+ return currentOwner;
514
+ }
515
+ function runWithOwner(owner, fn) {
516
+ const prev = currentOwner;
517
+ const prevRoot = currentRoot;
518
+ currentOwner = owner;
519
+ currentRoot = owner;
520
+ try {
521
+ return fn();
522
+ } finally {
523
+ currentOwner = prev;
524
+ currentRoot = prevRoot;
525
+ }
526
+ }
527
+ function createRoot(fn) {
528
+ const prevRoot = currentRoot;
529
+ const prevOwner = currentOwner;
530
+ const root = {
531
+ disposals: [],
532
+ owner: currentOwner,
533
+ // parent owner for ownership tree
534
+ children: [],
535
+ // child roots (ownership tree)
536
+ _disposed: false
537
+ };
538
+ if (currentOwner) {
539
+ currentOwner.children.push(root);
540
+ }
541
+ currentRoot = root;
542
+ currentOwner = root;
543
+ try {
544
+ const dispose = () => {
545
+ if (root._disposed) return;
546
+ root._disposed = true;
547
+ for (let i = root.children.length - 1; i >= 0; i--) {
548
+ _disposeRoot(root.children[i]);
549
+ }
550
+ root.children.length = 0;
551
+ for (let i = root.disposals.length - 1; i >= 0; i--) {
552
+ root.disposals[i]();
553
+ }
554
+ root.disposals.length = 0;
555
+ if (root.owner) {
556
+ const idx = root.owner.children.indexOf(root);
557
+ if (idx >= 0) root.owner.children.splice(idx, 1);
558
+ }
559
+ };
560
+ return fn(dispose);
561
+ } finally {
562
+ currentRoot = prevRoot;
563
+ currentOwner = prevOwner;
564
+ }
565
+ }
566
+ function _disposeRoot(root) {
567
+ if (root._disposed) return;
568
+ root._disposed = true;
569
+ for (let i = root.children.length - 1; i >= 0; i--) {
570
+ _disposeRoot(root.children[i]);
571
+ }
572
+ root.children.length = 0;
573
+ for (let i = root.disposals.length - 1; i >= 0; i--) {
574
+ root.disposals[i]();
575
+ }
576
+ root.disposals.length = 0;
577
+ }
578
+ function _createItemScope(fn) {
579
+ const prevRoot = currentRoot;
580
+ const prevOwner = currentOwner;
581
+ const scope = {
582
+ disposals: [],
583
+ owner: null,
584
+ // No parent registration
585
+ children: [],
586
+ // Kept for compat with effects that create sub-roots
587
+ _disposed: false
588
+ };
589
+ currentRoot = scope;
590
+ currentOwner = scope;
591
+ try {
592
+ const dispose = () => {
593
+ if (scope._disposed) return;
594
+ scope._disposed = true;
595
+ for (let i = scope.children.length - 1; i >= 0; i--) {
596
+ _disposeRoot(scope.children[i]);
597
+ }
598
+ scope.children.length = 0;
599
+ for (let i = scope.disposals.length - 1; i >= 0; i--) {
600
+ scope.disposals[i]();
601
+ }
602
+ scope.disposals.length = 0;
603
+ };
604
+ return fn(dispose);
605
+ } finally {
606
+ currentRoot = prevRoot;
607
+ currentOwner = prevOwner;
608
+ }
609
+ }
610
+ function onCleanup(fn) {
611
+ if (currentRoot) {
612
+ currentRoot.disposals.push(fn);
613
+ }
614
+ }
615
+ if (__DEV__ && typeof WeakRef !== "undefined") {
616
+ const PREINSTALL_CAP = 2e3;
617
+ const buffer = { signals: /* @__PURE__ */ new Set(), effects: /* @__PURE__ */ new Set(), components: [] };
618
+ __devtools = {
619
+ __isPreinstallBuffer: true,
620
+ onSignalCreate(sig) {
621
+ if (buffer.signals.size < PREINSTALL_CAP) buffer.signals.add(new WeakRef(sig));
622
+ },
623
+ onSignalUpdate() {
624
+ },
625
+ onEffectCreate(e) {
626
+ if (buffer.effects.size < PREINSTALL_CAP) buffer.effects.add(new WeakRef(e));
627
+ },
628
+ onEffectDispose() {
629
+ },
630
+ onEffectRun() {
631
+ },
632
+ onError() {
633
+ },
634
+ onComponentMount(ctx) {
635
+ if (buffer.components.length < PREINSTALL_CAP) buffer.components.push(ctx);
636
+ },
637
+ onComponentUnmount() {
638
+ },
639
+ __buffer: buffer
640
+ };
641
+ }
642
+ function __drainPreinstallBuffer() {
643
+ if (!__DEV__) return { signals: [], effects: [], components: [] };
644
+ const out = { signals: [], effects: [], components: [] };
645
+ const buf = typeof __preinstallSnapshot !== "undefined" ? __preinstallSnapshot : null;
646
+ if (!buf) return out;
647
+ for (const ref of buf.signals) {
648
+ const v = ref.deref?.();
649
+ if (v) out.signals.push(v);
650
+ }
651
+ for (const ref of buf.effects) {
652
+ const v = ref.deref?.();
653
+ if (v) out.effects.push(v);
654
+ }
655
+ for (const ctx of buf.components) out.components.push(ctx);
656
+ return out;
657
+ }
658
+ var __preinstallSnapshot = null;
659
+ if (__DEV__ && __devtools?.__isPreinstallBuffer) {
660
+ __preinstallSnapshot = __devtools.__buffer;
661
+ }
662
+
663
+ // packages/core/src/components.js
664
+ function memo2(Component, _areEqual) {
665
+ const MemoWrapper = function MemoWrapper2(props) {
666
+ return Component(props);
667
+ };
668
+ MemoWrapper.displayName = `Memo(${Component.name || "Anonymous"})`;
669
+ return MemoWrapper;
670
+ }
671
+ var _getCurrentComponent = null;
672
+ function _injectGetCurrentComponent(fn) {
673
+ _getCurrentComponent = fn;
674
+ }
675
+ function lazy(loader) {
676
+ let Component = null;
677
+ let loadPromise = null;
678
+ let loadError = null;
679
+ const listeners = /* @__PURE__ */ new Set();
680
+ function LazyWrapper(props) {
681
+ if (loadError) throw loadError;
682
+ if (Component) return h(Component, props);
683
+ if (!loadPromise) {
684
+ loadPromise = loader().then((mod) => {
685
+ Component = mod.default || mod;
686
+ listeners.forEach((fn) => fn());
687
+ listeners.clear();
688
+ }).catch((err) => {
689
+ loadError = err;
690
+ });
691
+ }
692
+ throw loadPromise;
693
+ }
694
+ LazyWrapper.displayName = "Lazy";
695
+ LazyWrapper._lazy = true;
696
+ LazyWrapper._onLoad = (fn) => {
697
+ if (Component) fn();
698
+ else listeners.add(fn);
699
+ };
700
+ return LazyWrapper;
701
+ }
702
+ function Suspense({ fallback, children }) {
703
+ const loading = signal(false);
704
+ const pendingPromises = /* @__PURE__ */ new Set();
705
+ const boundary = {
706
+ _suspense: true,
707
+ onSuspend(promise) {
708
+ loading.set(true);
709
+ pendingPromises.add(promise);
710
+ promise.finally(() => {
711
+ pendingPromises.delete(promise);
712
+ if (pendingPromises.size === 0) {
713
+ loading.set(false);
714
+ }
715
+ });
716
+ }
717
+ };
718
+ return {
719
+ tag: "__suspense",
720
+ props: { boundary, fallback, loading },
721
+ children: Array.isArray(children) ? children : [children],
722
+ _vnode: true
723
+ };
724
+ }
725
+ function ErrorBoundary({ fallback, children, onError }) {
726
+ const errorState = signal(null);
727
+ const handleError = (error) => {
728
+ errorState.set(error);
729
+ if (onError) {
730
+ try {
731
+ onError(error);
732
+ } catch (e) {
733
+ console.error("Error in onError handler:", e);
734
+ }
735
+ }
736
+ };
737
+ const reset = () => errorState.set(null);
738
+ return {
739
+ tag: "__errorBoundary",
740
+ props: { errorState, handleError, fallback, reset },
741
+ children: Array.isArray(children) ? children : [children],
742
+ _vnode: true
743
+ };
744
+ }
745
+ function reportError(error, startCtx) {
746
+ let ctx = startCtx || _getCurrentComponent?.();
747
+ while (ctx) {
748
+ if (ctx._errorBoundary) {
749
+ ctx._errorBoundary(error);
750
+ return true;
751
+ }
752
+ ctx = ctx._parentCtx;
753
+ }
754
+ return false;
755
+ }
756
+ function Show({ when, fallback = null, children }) {
757
+ const condition = typeof when === "function" ? when() : when;
758
+ return condition ? children : fallback;
759
+ }
760
+ function For({ each: each2, fallback = null, children }) {
761
+ const list = typeof each2 === "function" ? each2() : each2;
762
+ if (!list || list.length === 0) return fallback;
763
+ const renderFn = Array.isArray(children) ? children[0] : children;
764
+ if (typeof renderFn !== "function") {
765
+ console.warn("[what] For: children must be a render function, e.g. <For each={items}>{(item) => ...}</For>");
766
+ return fallback;
767
+ }
768
+ return list.map((item, index) => {
769
+ const vnode = renderFn(item, index);
770
+ if (vnode && typeof vnode === "object" && vnode.key == null) {
771
+ if (item != null && typeof item === "object") {
772
+ if (item.id != null) vnode.key = item.id;
773
+ else if (item.key != null) vnode.key = item.key;
774
+ } else if (typeof item === "string" || typeof item === "number") {
775
+ vnode.key = item;
776
+ }
777
+ }
778
+ return vnode;
779
+ });
780
+ }
781
+ function Switch({ fallback = null, children }) {
782
+ const kids = Array.isArray(children) ? children : [children];
783
+ for (const child of kids) {
784
+ if (child && child.tag === Match) {
785
+ const condition = typeof child.props.when === "function" ? child.props.when() : child.props.when;
786
+ if (condition) {
787
+ return child.children;
788
+ }
789
+ }
790
+ }
791
+ return fallback;
792
+ }
793
+ function Match({ when, children }) {
794
+ return { tag: Match, props: { when }, children, _vnode: true };
795
+ }
796
+ function Island({ component: Component, mode, mediaQuery, ...props }) {
797
+ const placeholder = h("div", { "data-island": Component.name || "Island", "data-hydrate": mode });
798
+ const wrapper = signal(null);
799
+ const hydrated = signal(false);
800
+ function doHydrate() {
801
+ if (hydrated()) return;
802
+ hydrated.set(true);
803
+ wrapper.set(h(Component, props));
804
+ }
805
+ function scheduleHydration(el) {
806
+ switch (mode) {
807
+ case "load":
808
+ queueMicrotask(doHydrate);
809
+ break;
810
+ case "idle":
811
+ if (typeof requestIdleCallback !== "undefined") {
812
+ requestIdleCallback(doHydrate);
813
+ } else {
814
+ setTimeout(doHydrate, 200);
815
+ }
816
+ break;
817
+ case "visible": {
818
+ const observer = new IntersectionObserver((entries) => {
819
+ if (entries[0].isIntersecting) {
820
+ observer.disconnect();
821
+ doHydrate();
822
+ }
823
+ });
824
+ observer.observe(el);
825
+ break;
826
+ }
827
+ case "interaction": {
828
+ const hydrate = () => {
829
+ el.removeEventListener("click", hydrate);
830
+ el.removeEventListener("focus", hydrate);
831
+ el.removeEventListener("mouseenter", hydrate);
832
+ doHydrate();
833
+ };
834
+ el.addEventListener("click", hydrate, { once: true });
835
+ el.addEventListener("focus", hydrate, { once: true });
836
+ el.addEventListener("mouseenter", hydrate, { once: true });
837
+ break;
838
+ }
839
+ case "media": {
840
+ if (!mediaQuery) {
841
+ doHydrate();
842
+ break;
843
+ }
844
+ const mq = window.matchMedia(mediaQuery);
845
+ if (mq.matches) {
846
+ queueMicrotask(doHydrate);
847
+ } else {
848
+ const checkMedia = () => {
849
+ if (mq.matches) {
850
+ mq.removeEventListener("change", checkMedia);
851
+ doHydrate();
852
+ }
853
+ };
854
+ mq.addEventListener("change", checkMedia);
855
+ }
856
+ break;
857
+ }
858
+ default:
859
+ queueMicrotask(doHydrate);
860
+ }
861
+ }
862
+ const refCallback = (el) => {
863
+ if (el) scheduleHydration(el);
864
+ };
865
+ return h(
866
+ "div",
867
+ { "data-island": Component.name || "Island", "data-hydrate": mode, ref: refCallback },
868
+ hydrated() ? wrapper() : null
869
+ );
870
+ }
871
+
872
+ // packages/core/src/helpers.js
873
+ var _eachWarned = false;
874
+ function each(list, fn, keyFn) {
875
+ if (!_eachWarned) {
876
+ _eachWarned = true;
877
+ console.warn("[what] each() is deprecated. Use the <For> component or Array.map() instead.");
878
+ }
879
+ if (!list || list.length === 0) return [];
880
+ return list.map((item, index) => {
881
+ const vnode = fn(item, index);
882
+ if (keyFn && vnode && typeof vnode === "object") {
883
+ vnode.key = keyFn(item, index);
884
+ }
885
+ return vnode;
886
+ });
887
+ }
888
+ function cls(...args) {
889
+ const classes = [];
890
+ for (const arg of args) {
891
+ if (!arg) continue;
892
+ if (typeof arg === "string") {
893
+ classes.push(arg);
894
+ } else if (typeof arg === "object") {
895
+ for (const [key, val] of Object.entries(arg)) {
896
+ if (val) classes.push(key);
897
+ }
898
+ }
899
+ }
900
+ return classes.join(" ");
901
+ }
902
+ function style(obj) {
903
+ if (typeof obj === "string") return obj;
904
+ return Object.entries(obj).filter(([, v]) => v != null && v !== "").map(([k, v]) => `${camelToKebab(k)}:${v}`).join(";");
905
+ }
906
+ function camelToKebab(str) {
907
+ return str.replace(/([A-Z])/g, "-$1").toLowerCase();
908
+ }
909
+ function debounce(fn, ms) {
910
+ let timer;
911
+ return (...args) => {
912
+ clearTimeout(timer);
913
+ timer = setTimeout(() => fn(...args), ms);
914
+ };
915
+ }
916
+ function throttle(fn, ms) {
917
+ let last = 0;
918
+ return (...args) => {
919
+ const now = Date.now();
920
+ if (now - last >= ms) {
921
+ last = now;
922
+ fn(...args);
923
+ }
924
+ };
925
+ }
926
+ var _getCurrentComponentRef = null;
927
+ function _setComponentRef(fn) {
928
+ _getCurrentComponentRef = fn;
929
+ }
930
+ function useMediaQuery(query) {
931
+ if (typeof window === "undefined") return signal(false);
932
+ const mq = window.matchMedia(query);
933
+ const s = signal(mq.matches);
934
+ const handler = (e) => s.set(e.matches);
935
+ mq.addEventListener("change", handler);
936
+ const ctx = _getCurrentComponentRef?.();
937
+ if (ctx) {
938
+ ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];
939
+ ctx._cleanupCallbacks.push(() => mq.removeEventListener("change", handler));
940
+ }
941
+ return s;
942
+ }
943
+ function useLocalStorage(key, initial) {
944
+ let stored;
945
+ try {
946
+ const raw = localStorage.getItem(key);
947
+ stored = raw !== null ? JSON.parse(raw) : initial;
948
+ } catch {
949
+ stored = initial;
950
+ }
951
+ const s = signal(stored);
952
+ const dispose = effect(() => {
953
+ try {
954
+ localStorage.setItem(key, JSON.stringify(s()));
955
+ } catch (e) {
956
+ if (__DEV__) console.warn("[what] localStorage write failed (quota exceeded?):", e);
957
+ }
958
+ });
959
+ let storageHandler = null;
960
+ if (typeof window !== "undefined") {
961
+ storageHandler = (e) => {
962
+ if (e.key === key && e.newValue !== null) {
963
+ try {
964
+ s.set(JSON.parse(e.newValue));
965
+ } catch (err) {
966
+ if (__DEV__) console.warn("[what] localStorage parse failed:", err);
967
+ }
968
+ }
969
+ };
970
+ window.addEventListener("storage", storageHandler);
971
+ }
972
+ const ctx = _getCurrentComponentRef?.();
973
+ if (ctx) {
974
+ ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];
975
+ ctx._cleanupCallbacks.push(() => {
976
+ dispose();
977
+ if (storageHandler) window.removeEventListener("storage", storageHandler);
978
+ });
979
+ }
980
+ return s;
981
+ }
982
+ function Portal({ target, children }) {
983
+ if (typeof document === "undefined") return null;
984
+ const container = typeof target === "string" ? document.querySelector(target) : target;
985
+ if (!container) return null;
986
+ return { tag: "__portal", props: { container }, children: Array.isArray(children) ? children : [children], _vnode: true };
987
+ }
988
+ function useClickOutside(ref, handler) {
989
+ if (typeof document === "undefined") return;
990
+ const listener = (e) => {
991
+ const el = ref.current || ref;
992
+ if (!el || el.contains(e.target)) return;
993
+ handler(e);
994
+ };
995
+ document.addEventListener("mousedown", listener);
996
+ document.addEventListener("touchstart", listener);
997
+ const ctx = _getCurrentComponentRef?.();
998
+ if (ctx) {
999
+ ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];
1000
+ ctx._cleanupCallbacks.push(() => {
1001
+ document.removeEventListener("mousedown", listener);
1002
+ document.removeEventListener("touchstart", listener);
1003
+ });
1004
+ }
1005
+ }
1006
+ function transition(name, active) {
1007
+ return {
1008
+ class: active ? `${name}-enter ${name}-enter-active` : `${name}-leave ${name}-leave-active`
1009
+ };
1010
+ }
1011
+
1012
+ // packages/core/src/dom.js
1013
+ var SVG_ELEMENTS = /* @__PURE__ */ new Set([
1014
+ "svg",
1015
+ "path",
1016
+ "circle",
1017
+ "rect",
1018
+ "line",
1019
+ "polyline",
1020
+ "polygon",
1021
+ "ellipse",
1022
+ "g",
1023
+ "defs",
1024
+ "use",
1025
+ "symbol",
1026
+ "clipPath",
1027
+ "mask",
1028
+ "pattern",
1029
+ "image",
1030
+ "text",
1031
+ "tspan",
1032
+ "textPath",
1033
+ "foreignObject",
1034
+ "linearGradient",
1035
+ "radialGradient",
1036
+ "stop",
1037
+ "marker",
1038
+ "animate",
1039
+ "animateTransform",
1040
+ "animateMotion",
1041
+ "set",
1042
+ "filter",
1043
+ "feBlend",
1044
+ "feColorMatrix",
1045
+ "feComponentTransfer",
1046
+ "feComposite",
1047
+ "feConvolveMatrix",
1048
+ "feDiffuseLighting",
1049
+ "feDisplacementMap",
1050
+ "feFlood",
1051
+ "feGaussianBlur",
1052
+ "feImage",
1053
+ "feMerge",
1054
+ "feMergeNode",
1055
+ "feMorphology",
1056
+ "feOffset",
1057
+ "feSpecularLighting",
1058
+ "feTile",
1059
+ "feTurbulence"
1060
+ ]);
1061
+ var SVG_NS = "http://www.w3.org/2000/svg";
1062
+ var mountedComponents = /* @__PURE__ */ new Set();
1063
+ var _commentCtxMap = /* @__PURE__ */ new WeakMap();
1064
+ function isDomNode(value) {
1065
+ if (!value || typeof value !== "object") return false;
1066
+ if (typeof Node !== "undefined" && value instanceof Node) return true;
1067
+ return typeof value.nodeType === "number" && typeof value.nodeName === "string";
1068
+ }
1069
+ function isVNode(value) {
1070
+ return !!value && typeof value === "object" && (value._vnode === true || "tag" in value);
1071
+ }
1072
+ function disposeComponent(ctx) {
1073
+ if (ctx.disposed) return;
1074
+ ctx.disposed = true;
1075
+ if (ctx.cleanups) {
1076
+ for (const cleanup2 of ctx.cleanups) {
1077
+ try {
1078
+ cleanup2();
1079
+ } catch (e) {
1080
+ console.error("[what] cleanup error:", e);
1081
+ }
1082
+ }
1083
+ }
1084
+ if (ctx.effects) {
1085
+ for (const dispose of ctx.effects) {
1086
+ try {
1087
+ dispose();
1088
+ } catch (e) {
1089
+ }
1090
+ }
1091
+ }
1092
+ if (ctx.hooks) {
1093
+ for (const hook of ctx.hooks) {
1094
+ if (hook && typeof hook.cleanup === "function") {
1095
+ try {
1096
+ hook.cleanup();
1097
+ } catch (e) {
1098
+ console.error("[what] hook cleanup error:", e);
1099
+ }
1100
+ }
1101
+ }
1102
+ }
1103
+ if (ctx._cleanupCallbacks) {
1104
+ for (const fn of ctx._cleanupCallbacks) {
1105
+ try {
1106
+ fn();
1107
+ } catch (e) {
1108
+ console.error("[what] onCleanup error:", e);
1109
+ }
1110
+ }
1111
+ }
1112
+ if (__DEV__ && __devtools?.onComponentUnmount) __devtools.onComponentUnmount(ctx);
1113
+ mountedComponents.delete(ctx);
1114
+ }
1115
+ function disposeTree(node) {
1116
+ if (!node) return;
1117
+ if (node._componentCtx) {
1118
+ disposeComponent(node._componentCtx);
1119
+ }
1120
+ if (node.nodeType === 8) {
1121
+ const commentCtx = _commentCtxMap.get(node);
1122
+ if (commentCtx) {
1123
+ disposeComponent(commentCtx);
1124
+ }
1125
+ }
1126
+ if (node._dispose) {
1127
+ try {
1128
+ node._dispose();
1129
+ } catch (e) {
1130
+ }
1131
+ }
1132
+ if (node._propEffects) {
1133
+ for (const key in node._propEffects) {
1134
+ try {
1135
+ node._propEffects[key]();
1136
+ } catch (e) {
1137
+ }
1138
+ }
1139
+ }
1140
+ const children = node.childNodes;
1141
+ if (children && children.length > 0) {
1142
+ for (let i = 0; i < children.length; i++) {
1143
+ disposeTree(children[i]);
1144
+ }
1145
+ }
1146
+ }
1147
+ function mount(vnode, container) {
1148
+ if (typeof container === "string") {
1149
+ container = document.querySelector(container);
1150
+ }
1151
+ disposeTree(container);
1152
+ container.textContent = "";
1153
+ const node = createDOM(vnode, container);
1154
+ if (node) container.appendChild(node);
1155
+ return () => {
1156
+ disposeTree(container);
1157
+ container.textContent = "";
1158
+ };
1159
+ }
1160
+ function createDOM(vnode, parent, isSvg) {
1161
+ if (vnode == null || vnode === false || vnode === true) {
1162
+ return document.createComment("");
1163
+ }
1164
+ if (typeof vnode === "string" || typeof vnode === "number") {
1165
+ return document.createTextNode(String(vnode));
1166
+ }
1167
+ if (isDomNode(vnode)) {
1168
+ return vnode;
1169
+ }
1170
+ if (typeof vnode === "function" && vnode._mapArray) {
1171
+ const frag = document.createDocumentFragment();
1172
+ const endMarker = document.createComment("/list-frag");
1173
+ frag.appendChild(endMarker);
1174
+ vnode(frag, endMarker);
1175
+ return frag;
1176
+ }
1177
+ if (typeof vnode === "function") {
1178
+ const startMarker = document.createComment("fn");
1179
+ const endMarker = document.createComment("/fn");
1180
+ let currentNodes = [];
1181
+ const frag = document.createDocumentFragment();
1182
+ frag.appendChild(startMarker);
1183
+ frag.appendChild(endMarker);
1184
+ const dispose = effect(() => {
1185
+ const val = vnode();
1186
+ const vnodes = val == null || val === false || val === true ? [] : Array.isArray(val) ? val : [val];
1187
+ const realParent = endMarker.parentNode;
1188
+ if (!realParent) return;
1189
+ for (const old of currentNodes) {
1190
+ disposeTree(old);
1191
+ if (old.parentNode === realParent) realParent.removeChild(old);
1192
+ }
1193
+ currentNodes = [];
1194
+ for (const v of vnodes) {
1195
+ const node = createDOM(v, realParent, parent?._isSvg);
1196
+ if (node) {
1197
+ if (node.nodeType === 11) {
1198
+ const children = Array.from(node.childNodes);
1199
+ realParent.insertBefore(node, endMarker);
1200
+ for (const child of children) currentNodes.push(child);
1201
+ } else {
1202
+ realParent.insertBefore(node, endMarker);
1203
+ currentNodes.push(node);
1204
+ }
1205
+ }
1206
+ }
1207
+ });
1208
+ startMarker._dispose = dispose;
1209
+ endMarker._dispose = dispose;
1210
+ return frag;
1211
+ }
1212
+ if (Array.isArray(vnode)) {
1213
+ const frag = document.createDocumentFragment();
1214
+ for (const child of vnode) {
1215
+ const node = createDOM(child, parent, isSvg);
1216
+ if (node) frag.appendChild(node);
1217
+ }
1218
+ return frag;
1219
+ }
1220
+ if (isVNode(vnode) && typeof vnode.tag === "function") {
1221
+ return createComponent(vnode, parent, isSvg);
1222
+ }
1223
+ if (isVNode(vnode) && typeof vnode.tag === "string") {
1224
+ if (vnode.tag === "__errorBoundary") return createErrorBoundary(vnode, parent);
1225
+ if (vnode.tag === "__suspense") return createSuspenseBoundary(vnode, parent);
1226
+ if (vnode.tag === "__portal") return createPortalDOM(vnode, parent);
1227
+ return createElementFromVNode(vnode, parent, isSvg);
1228
+ }
1229
+ return document.createTextNode(String(vnode));
1230
+ }
1231
+ var _propsProxyHandler = {
1232
+ get(target, key) {
1233
+ if (key === "_sig") return void 0;
1234
+ if (key === "__proto__" || key === "constructor" || key === "prototype") return void 0;
1235
+ return target._sig()[key];
1236
+ },
1237
+ has(target, key) {
1238
+ if (key === "_sig") return false;
1239
+ return key in target._sig();
1240
+ },
1241
+ ownKeys(target) {
1242
+ return Reflect.ownKeys(target._sig());
1243
+ },
1244
+ getOwnPropertyDescriptor(target, key) {
1245
+ if (key === "_sig") return void 0;
1246
+ const current = target._sig();
1247
+ if (key in current) {
1248
+ return { value: current[key], writable: false, enumerable: true, configurable: true };
1249
+ }
1250
+ return void 0;
1251
+ },
1252
+ set(target, key) {
1253
+ return false;
1254
+ }
1255
+ };
1256
+ var componentStack = [];
1257
+ function getCurrentComponent() {
1258
+ return componentStack[componentStack.length - 1];
1259
+ }
1260
+ _injectGetCurrentComponent(getCurrentComponent);
1261
+ _setComponentRef(getCurrentComponent);
1262
+ function getComponentStack() {
1263
+ return componentStack;
1264
+ }
1265
+ function createComponent(vnode, parent, isSvg) {
1266
+ let { tag: Component, props, children } = vnode;
1267
+ if (typeof Component === "function" && (Component.prototype?.isReactComponent || Component.prototype?.render)) {
1268
+ const ClassComp = Component;
1269
+ Component = function ClassComponentBridge(props2) {
1270
+ const instance = new ClassComp(props2);
1271
+ return instance.render();
1272
+ };
1273
+ Component.displayName = ClassComp.displayName || ClassComp.name || "ClassComponent";
1274
+ }
1275
+ if (Component === "__errorBoundary" || vnode.tag === "__errorBoundary") {
1276
+ return createErrorBoundary(vnode, parent);
1277
+ }
1278
+ if (Component === "__suspense" || vnode.tag === "__suspense") {
1279
+ return createSuspenseBoundary(vnode, parent);
1280
+ }
1281
+ if (Component === "__portal" || vnode.tag === "__portal") {
1282
+ return createPortalDOM(vnode, parent);
1283
+ }
1284
+ const parentCtx = componentStack[componentStack.length - 1] || null;
1285
+ let errorBoundary = null;
1286
+ if (parentCtx) {
1287
+ errorBoundary = parentCtx._errorBoundary || null;
1288
+ if (!errorBoundary) {
1289
+ let p = parentCtx._parentCtx;
1290
+ while (p) {
1291
+ if (p._errorBoundary) {
1292
+ errorBoundary = p._errorBoundary;
1293
+ break;
1294
+ }
1295
+ p = p._parentCtx;
1296
+ }
1297
+ }
1298
+ }
1299
+ const ctx = {
1300
+ hooks: [],
1301
+ hookIndex: 0,
1302
+ effects: [],
1303
+ cleanups: [],
1304
+ mounted: false,
1305
+ disposed: false,
1306
+ Component,
1307
+ _parentCtx: parentCtx,
1308
+ _errorBoundary: errorBoundary
1309
+ };
1310
+ const startComment = document.createComment("c:start");
1311
+ const endComment = document.createComment("c:end");
1312
+ _commentCtxMap.set(startComment, ctx);
1313
+ ctx._startComment = startComment;
1314
+ ctx._endComment = endComment;
1315
+ const container = document.createDocumentFragment();
1316
+ container._componentCtx = ctx;
1317
+ ctx._wrapper = startComment;
1318
+ mountedComponents.add(ctx);
1319
+ if (__DEV__ && __devtools?.onComponentMount) __devtools.onComponentMount(ctx);
1320
+ const propsChildren = children.length === 0 ? void 0 : children.length === 1 ? children[0] : children;
1321
+ let mergedProps;
1322
+ if (propsChildren !== void 0) {
1323
+ mergedProps = props ? Object.assign({}, props, { children: propsChildren }) : { children: propsChildren };
1324
+ } else {
1325
+ mergedProps = props ? Object.assign({}, props) : {};
1326
+ }
1327
+ const propsSignal = signal(mergedProps);
1328
+ ctx._propsSignal = propsSignal;
1329
+ const reactiveProps = new Proxy({ _sig: propsSignal }, _propsProxyHandler);
1330
+ componentStack.push(ctx);
1331
+ let result;
1332
+ try {
1333
+ result = untrack(() => Component(reactiveProps));
1334
+ } catch (error) {
1335
+ componentStack.pop();
1336
+ if (!reportError(error, ctx)) {
1337
+ console.error("[what] Uncaught error in component:", Component.name || "Anonymous", error);
1338
+ throw error;
1339
+ }
1340
+ container.appendChild(startComment);
1341
+ container.appendChild(endComment);
1342
+ return container;
1343
+ }
1344
+ componentStack.pop();
1345
+ ctx.mounted = true;
1346
+ if (ctx._mountCallbacks) {
1347
+ queueMicrotask(() => {
1348
+ if (ctx.disposed) return;
1349
+ for (const fn of ctx._mountCallbacks) {
1350
+ try {
1351
+ fn();
1352
+ } catch (e) {
1353
+ console.error("[what] onMount error:", e);
1354
+ }
1355
+ }
1356
+ });
1357
+ }
1358
+ container.appendChild(startComment);
1359
+ const vnodes = Array.isArray(result) ? result : [result];
1360
+ for (const v of vnodes) {
1361
+ const node = createDOM(v, container, isSvg);
1362
+ if (node) container.appendChild(node);
1363
+ }
1364
+ container.appendChild(endComment);
1365
+ return container;
1366
+ }
1367
+ function createErrorBoundary(vnode, parent) {
1368
+ const { errorState, handleError, fallback, reset } = vnode.props;
1369
+ const children = vnode.children;
1370
+ const startComment = document.createComment("eb:start");
1371
+ const endComment = document.createComment("eb:end");
1372
+ const boundaryCtx = {
1373
+ hooks: [],
1374
+ hookIndex: 0,
1375
+ effects: [],
1376
+ cleanups: [],
1377
+ mounted: false,
1378
+ disposed: false,
1379
+ _parentCtx: componentStack[componentStack.length - 1] || null,
1380
+ _errorBoundary: handleError,
1381
+ _startComment: startComment,
1382
+ _endComment: endComment
1383
+ };
1384
+ _commentCtxMap.set(startComment, boundaryCtx);
1385
+ const container = document.createDocumentFragment();
1386
+ container._componentCtx = boundaryCtx;
1387
+ container.appendChild(startComment);
1388
+ container.appendChild(endComment);
1389
+ const dispose = effect(() => {
1390
+ const error = errorState();
1391
+ componentStack.push(boundaryCtx);
1392
+ if (startComment.parentNode) {
1393
+ while (startComment.nextSibling && startComment.nextSibling !== endComment) {
1394
+ const old = startComment.nextSibling;
1395
+ disposeTree(old);
1396
+ old.parentNode.removeChild(old);
1397
+ }
1398
+ }
1399
+ let vnodes;
1400
+ if (error) {
1401
+ vnodes = typeof fallback === "function" ? [fallback({ error, reset })] : [fallback];
1402
+ } else {
1403
+ vnodes = children;
1404
+ }
1405
+ vnodes = Array.isArray(vnodes) ? vnodes : [vnodes];
1406
+ for (const v of vnodes) {
1407
+ const node = createDOM(v, parent);
1408
+ if (node) {
1409
+ if (endComment.parentNode) {
1410
+ endComment.parentNode.insertBefore(node, endComment);
1411
+ } else {
1412
+ container.insertBefore(node, endComment);
1413
+ }
1414
+ }
1415
+ }
1416
+ componentStack.pop();
1417
+ });
1418
+ boundaryCtx.effects.push(dispose);
1419
+ return container;
1420
+ }
1421
+ function createSuspenseBoundary(vnode, parent) {
1422
+ const { boundary, fallback, loading } = vnode.props;
1423
+ const children = vnode.children;
1424
+ const startComment = document.createComment("sb:start");
1425
+ const endComment = document.createComment("sb:end");
1426
+ const boundaryCtx = {
1427
+ hooks: [],
1428
+ hookIndex: 0,
1429
+ effects: [],
1430
+ cleanups: [],
1431
+ mounted: false,
1432
+ disposed: false,
1433
+ _parentCtx: componentStack[componentStack.length - 1] || null,
1434
+ _startComment: startComment,
1435
+ _endComment: endComment
1436
+ };
1437
+ _commentCtxMap.set(startComment, boundaryCtx);
1438
+ const container = document.createDocumentFragment();
1439
+ container._componentCtx = boundaryCtx;
1440
+ container.appendChild(startComment);
1441
+ container.appendChild(endComment);
1442
+ const dispose = effect(() => {
1443
+ const isLoading = loading();
1444
+ const vnodes = isLoading ? [fallback] : children;
1445
+ const normalized = Array.isArray(vnodes) ? vnodes : [vnodes];
1446
+ componentStack.push(boundaryCtx);
1447
+ if (startComment.parentNode) {
1448
+ while (startComment.nextSibling && startComment.nextSibling !== endComment) {
1449
+ const old = startComment.nextSibling;
1450
+ disposeTree(old);
1451
+ old.parentNode.removeChild(old);
1452
+ }
1453
+ }
1454
+ for (const v of normalized) {
1455
+ const node = createDOM(v, parent);
1456
+ if (node) {
1457
+ if (endComment.parentNode) {
1458
+ endComment.parentNode.insertBefore(node, endComment);
1459
+ } else {
1460
+ container.insertBefore(node, endComment);
1461
+ }
1462
+ }
1463
+ }
1464
+ componentStack.pop();
1465
+ });
1466
+ boundaryCtx.effects.push(dispose);
1467
+ return container;
1468
+ }
1469
+ function createPortalDOM(vnode, parent) {
1470
+ const { container } = vnode.props;
1471
+ const children = vnode.children;
1472
+ if (!container) {
1473
+ console.warn("[what] Portal: target container not found");
1474
+ return document.createComment("portal:empty");
1475
+ }
1476
+ const portalCtx = {
1477
+ hooks: [],
1478
+ hookIndex: 0,
1479
+ effects: [],
1480
+ cleanups: [],
1481
+ mounted: false,
1482
+ disposed: false,
1483
+ _parentCtx: componentStack[componentStack.length - 1] || null
1484
+ };
1485
+ const placeholder = document.createComment("portal");
1486
+ placeholder._componentCtx = portalCtx;
1487
+ const portalNodes = [];
1488
+ for (const child of children) {
1489
+ const node = createDOM(child, container);
1490
+ if (node) {
1491
+ container.appendChild(node);
1492
+ portalNodes.push(node);
1493
+ }
1494
+ }
1495
+ portalCtx._cleanupCallbacks = [() => {
1496
+ for (const node of portalNodes) {
1497
+ disposeTree(node);
1498
+ if (node.parentNode) node.parentNode.removeChild(node);
1499
+ }
1500
+ }];
1501
+ return placeholder;
1502
+ }
1503
+ function createElementFromVNode(vnode, parent, isSvg) {
1504
+ const { tag, props, children } = vnode;
1505
+ const svgContext = isSvg || SVG_ELEMENTS.has(tag);
1506
+ const el = svgContext ? document.createElementNS(SVG_NS, tag) : document.createElement(tag);
1507
+ if (props) {
1508
+ applyProps(el, props, {}, svgContext);
1509
+ }
1510
+ const isSvgChildren = svgContext && tag !== "foreignObject";
1511
+ for (let i = 0; i < children.length; i++) {
1512
+ const node = createDOM(children[i], el, isSvgChildren);
1513
+ if (node) el.appendChild(node);
1514
+ }
1515
+ el._vnode = vnode;
1516
+ return el;
1517
+ }
1518
+ function applyProps(el, newProps, oldProps, isSvg) {
1519
+ if (!newProps) return;
1520
+ for (const key in newProps) {
1521
+ if (key === "key" || key === "children") continue;
1522
+ if (key === "ref") {
1523
+ const ref = newProps.ref;
1524
+ if (typeof ref === "function") ref(el);
1525
+ else if (ref) ref.current = el;
1526
+ continue;
1527
+ }
1528
+ setProp(el, key, newProps[key], isSvg);
1529
+ }
1530
+ }
1531
+ function _setSelectValue(el, value) {
1532
+ el.value = value;
1533
+ if (el.value !== String(value)) {
1534
+ queueMicrotask(() => {
1535
+ el.value = value;
1536
+ });
1537
+ }
1538
+ }
1539
+ function setProp(el, key, value, isSvg) {
1540
+ if (typeof value === "function" && !(key.startsWith("on") && key.length > 2) && key !== "ref") {
1541
+ if (!el._propEffects) el._propEffects = {};
1542
+ if (el._propEffects[key]) {
1543
+ try {
1544
+ el._propEffects[key]();
1545
+ } catch (e) {
1546
+ }
1547
+ }
1548
+ el._propEffects[key] = effect(() => {
1549
+ const resolved = value();
1550
+ setProp(el, key, resolved, isSvg);
1551
+ });
1552
+ return;
1553
+ }
1554
+ if (key.startsWith("on") && key.length > 2) {
1555
+ let eventName = key.slice(2);
1556
+ let useCapture = false;
1557
+ if (eventName.endsWith("Capture")) {
1558
+ eventName = eventName.slice(0, -7);
1559
+ useCapture = true;
1560
+ }
1561
+ const event = eventName.toLowerCase();
1562
+ const storageKey = useCapture ? event + "_capture" : event;
1563
+ const old = el._events?.[storageKey];
1564
+ if (old && old._original === value) return;
1565
+ if (old) el.removeEventListener(event, old, useCapture);
1566
+ if (value == null) return;
1567
+ if (!el._events) el._events = {};
1568
+ const wrappedHandler = (e) => {
1569
+ if (!e.nativeEvent) e.nativeEvent = e;
1570
+ return untrack(() => wrappedHandler._handler(e));
1571
+ };
1572
+ wrappedHandler._handler = value;
1573
+ wrappedHandler._original = value;
1574
+ el._events[storageKey] = wrappedHandler;
1575
+ const eventOpts = value._eventOpts;
1576
+ el.addEventListener(event, wrappedHandler, eventOpts || useCapture || void 0);
1577
+ return;
1578
+ }
1579
+ if (key === "className" || key === "class") {
1580
+ if (isSvg) {
1581
+ el.setAttribute("class", value || "");
1582
+ } else {
1583
+ el.className = value || "";
1584
+ }
1585
+ return;
1586
+ }
1587
+ if (key === "style") {
1588
+ if (typeof value === "string") {
1589
+ el.style.cssText = value;
1590
+ el._prevStyle = null;
1591
+ } else if (typeof value === "object") {
1592
+ const oldStyle = el._prevStyle || {};
1593
+ for (const prop in oldStyle) {
1594
+ if (!(prop in value)) el.style[prop] = "";
1595
+ }
1596
+ for (const prop in value) {
1597
+ el.style[prop] = value[prop] ?? "";
1598
+ }
1599
+ el._prevStyle = { ...value };
1600
+ }
1601
+ return;
1602
+ }
1603
+ if (key === "dangerouslySetInnerHTML") {
1604
+ const html = value?.__html ?? "";
1605
+ if (__DEV__ && typeof html === "string" && /(<script|onerror\s*=|onload\s*=|javascript:)/i.test(html)) {
1606
+ console.warn("[what] dangerouslySetInnerHTML contains potential XSS vectors. Ensure content is sanitized.");
1607
+ }
1608
+ el.innerHTML = html;
1609
+ return;
1610
+ }
1611
+ if (key === "innerHTML") {
1612
+ if (value == null) return;
1613
+ if (value && typeof value === "object" && "__html" in value) {
1614
+ const html = value.__html ?? "";
1615
+ if (__DEV__ && typeof html === "string" && /(<script|onerror\s*=|onload\s*=|javascript:)/i.test(html)) {
1616
+ console.warn("[what] dangerouslySetInnerHTML contains potential XSS vectors. Ensure content is sanitized.");
1617
+ }
1618
+ el.innerHTML = html;
1619
+ } else {
1620
+ if (__DEV__) {
1621
+ console.warn(
1622
+ "[what] innerHTML received a raw string. This is a security risk (XSS). Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead."
1623
+ );
1624
+ }
1625
+ return;
1626
+ }
1627
+ return;
1628
+ }
1629
+ if (typeof value === "boolean") {
1630
+ if (value) el.setAttribute(key, "");
1631
+ else el.removeAttribute(key);
1632
+ return;
1633
+ }
1634
+ if (key.startsWith("data-") || key.startsWith("aria-")) {
1635
+ el.setAttribute(key, value);
1636
+ return;
1637
+ }
1638
+ if (isSvg) {
1639
+ if (value === false || value == null) {
1640
+ el.removeAttribute(key);
1641
+ } else {
1642
+ el.setAttribute(key, value === true ? "" : String(value));
1643
+ }
1644
+ return;
1645
+ }
1646
+ if (key === "value" && el.tagName === "SELECT") {
1647
+ _setSelectValue(el, value);
1648
+ return;
1649
+ }
1650
+ if (key in el) {
1651
+ el[key] = value;
1652
+ } else {
1653
+ el.setAttribute(key, value);
1654
+ }
1655
+ }
1656
+
1657
+ export {
1658
+ __DEV__,
1659
+ __setDevToolsHooks,
1660
+ signal,
1661
+ computed,
1662
+ effect,
1663
+ batch,
1664
+ memo,
1665
+ flushSync,
1666
+ untrack,
1667
+ getOwner,
1668
+ runWithOwner,
1669
+ createRoot,
1670
+ _createItemScope,
1671
+ onCleanup,
1672
+ __drainPreinstallBuffer,
1673
+ memo2,
1674
+ lazy,
1675
+ Suspense,
1676
+ ErrorBoundary,
1677
+ Show,
1678
+ For,
1679
+ Switch,
1680
+ Match,
1681
+ Island,
1682
+ each,
1683
+ cls,
1684
+ style,
1685
+ debounce,
1686
+ throttle,
1687
+ useMediaQuery,
1688
+ useLocalStorage,
1689
+ Portal,
1690
+ useClickOutside,
1691
+ transition,
1692
+ disposeTree,
1693
+ mount,
1694
+ createDOM,
1695
+ getCurrentComponent,
1696
+ getComponentStack,
1697
+ _setSelectValue
1698
+ };
1699
+ //# sourceMappingURL=chunk-GZRA4IAJ.js.map