sibujs 4.13.0 → 4.14.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 (107) hide show
  1. package/README.md +1 -1
  2. package/dist/browser.cjs +15 -2
  3. package/dist/browser.js +9 -7
  4. package/dist/build.cjs +880 -281
  5. package/dist/build.d.cts +68 -3
  6. package/dist/build.d.ts +68 -3
  7. package/dist/build.js +88 -30
  8. package/dist/cdn.dev.global.js +12 -12
  9. package/dist/cdn.full.dev.global.js +13 -13
  10. package/dist/cdn.full.global.js +12 -12
  11. package/dist/cdn.global.js +12 -12
  12. package/dist/{chunk-7K7W4AA5.js → chunk-2TTRW2TE.js} +6 -6
  13. package/dist/{chunk-J6FW5TV6.js → chunk-3HEX6QJQ.js} +5 -3
  14. package/dist/chunk-3HZOSMPX.js +90 -0
  15. package/dist/{chunk-GNSRXK34.js → chunk-4FJSAUKB.js} +11 -3
  16. package/dist/{chunk-IV74C2YX.js → chunk-4TQDTWWN.js} +6 -5
  17. package/dist/{chunk-L3QHS4O4.js → chunk-7ILEHTVX.js} +1 -1
  18. package/dist/{chunk-CK5F2IR5.js → chunk-A454RAEK.js} +4 -4
  19. package/dist/{chunk-BRRRVLHQ.js → chunk-AE32RGWX.js} +10 -6
  20. package/dist/{chunk-EXXSN3BW.js → chunk-B3HOT4TK.js} +1 -1
  21. package/dist/{chunk-F4W7WYXY.js → chunk-BKZ5N6NK.js} +8 -6
  22. package/dist/{chunk-MNEITZ27.js → chunk-BNXRWZZV.js} +49 -8
  23. package/dist/chunk-BOYKGGVD.js +2015 -0
  24. package/dist/{chunk-G6366I2A.js → chunk-CCKUNHVU.js} +2 -2
  25. package/dist/{chunk-346BYZL2.js → chunk-CJ7KS3DF.js} +16 -10
  26. package/dist/chunk-CNPT6NKV.js +1859 -0
  27. package/dist/{chunk-ENFRHCMK.js → chunk-F67F77IA.js} +2 -2
  28. package/dist/{chunk-TUCPL2HB.js → chunk-GIJ33UJZ.js} +1 -1
  29. package/dist/chunk-GVAMIU6K.js +195 -0
  30. package/dist/{chunk-HDKDBC6V.js → chunk-HQIAL7F2.js} +8 -6
  31. package/dist/{chunk-ZE5LF44R.js → chunk-JTFQ7IL4.js} +8 -8
  32. package/dist/{chunk-AM6DZLBM.js → chunk-LJMX4SQ7.js} +2 -2
  33. package/dist/{chunk-HVVRXRGO.js → chunk-MIRKTVH4.js} +7 -14
  34. package/dist/{chunk-YJ57VR6Y.js → chunk-N7A6FKWW.js} +5 -3
  35. package/dist/chunk-NT3ZYB5S.js +167 -0
  36. package/dist/{chunk-Z3EZX6DZ.js → chunk-QS6GMWDD.js} +151 -86
  37. package/dist/chunk-R5U7XKVJ.js +16 -0
  38. package/dist/{chunk-3C56VNCK.js → chunk-RVR5NPFL.js} +3 -3
  39. package/dist/{chunk-F2UWOZ6J.js → chunk-RVWJGWCL.js} +2 -2
  40. package/dist/{chunk-NYNYSPK7.js → chunk-S37PZD6I.js} +30 -45
  41. package/dist/{chunk-QV5WEOFD.js → chunk-SVULV7O4.js} +119 -26
  42. package/dist/{chunk-C2FAO6VQ.js → chunk-TLS4NVIB.js} +5 -5
  43. package/dist/{chunk-M25RIH6Y.js → chunk-UUIKJJIK.js} +10 -8
  44. package/dist/chunk-UYTYNCMZ.js +199 -0
  45. package/dist/chunk-VM2U5LEL.js +2596 -0
  46. package/dist/{chunk-24L5RDPS.js → chunk-Y4LUM2XS.js} +8 -6
  47. package/dist/data.cjs +265 -35
  48. package/dist/data.d.cts +31 -1
  49. package/dist/data.d.ts +31 -1
  50. package/dist/data.js +16 -10
  51. package/dist/devtools.cjs +15 -2
  52. package/dist/devtools.js +9 -7
  53. package/dist/{dispose-GEIG2KOF.js → dispose-EIHHHDC7.js} +3 -1
  54. package/dist/ecosystem.cjs +62 -23
  55. package/dist/ecosystem.js +14 -12
  56. package/dist/extras.cjs +3520 -270
  57. package/dist/extras.d.cts +3 -3
  58. package/dist/extras.d.ts +3 -3
  59. package/dist/extras.js +39 -29
  60. package/dist/index.cjs +442 -253
  61. package/dist/index.d.cts +93 -283
  62. package/dist/index.d.ts +93 -283
  63. package/dist/index.js +26 -16
  64. package/dist/motion.cjs +12 -1
  65. package/dist/motion.js +6 -4
  66. package/dist/patterns.cjs +15 -2
  67. package/dist/patterns.js +10 -8
  68. package/dist/performance.cjs +36 -2
  69. package/dist/performance.d.cts +2 -2
  70. package/dist/performance.d.ts +2 -2
  71. package/dist/performance.js +14 -10
  72. package/dist/plugins.cjs +5225 -1807
  73. package/dist/plugins.d.cts +8 -834
  74. package/dist/plugins.d.ts +8 -834
  75. package/dist/plugins.js +64 -2329
  76. package/dist/prerenderServer-MXJEVWA3.js +350 -0
  77. package/dist/renderRoute-DP20XwMS.d.cts +86 -0
  78. package/dist/renderRoute-fxgsm2Ir.d.ts +86 -0
  79. package/dist/routeHead-CE9SV-cH.d.cts +995 -0
  80. package/dist/routeHead-DzVxPviY.d.ts +995 -0
  81. package/dist/{routeMiddleware-B1sp4P7a.d.ts → routeMiddleware-BySbueoE.d.ts} +0 -25
  82. package/dist/{routeMiddleware-CedQTsLK.d.cts → routeMiddleware-CijZD5eW.d.cts} +0 -25
  83. package/dist/ssr-JpGpHnpC.d.cts +841 -0
  84. package/dist/ssr-JpGpHnpC.d.ts +841 -0
  85. package/dist/{ssr-VBM6J5SJ.js → ssr-NECEU4X4.js} +15 -6
  86. package/dist/ssr-dom.cjs +1862 -0
  87. package/dist/ssr-dom.d.cts +341 -0
  88. package/dist/ssr-dom.d.ts +341 -0
  89. package/dist/ssr-dom.js +19 -0
  90. package/dist/ssr.cjs +7630 -2064
  91. package/dist/ssr.d.cts +63 -5
  92. package/dist/ssr.d.ts +63 -5
  93. package/dist/ssr.js +136 -14
  94. package/dist/testing.cjs +6543 -87
  95. package/dist/testing.d.cts +80 -1
  96. package/dist/testing.d.ts +80 -1
  97. package/dist/testing.js +117 -4
  98. package/dist/ui.cjs +36 -2
  99. package/dist/ui.js +17 -14
  100. package/dist/widgets.cjs +14 -1
  101. package/dist/widgets.js +11 -9
  102. package/package.json +9 -2
  103. package/dist/chunk-2F4PSJ5Z.js +0 -765
  104. package/dist/chunk-7XHATCIH.js +0 -121
  105. package/dist/chunk-B36ADEIR.js +0 -21
  106. package/dist/ssr-Db0Sgdu3.d.cts +0 -245
  107. package/dist/ssr-Db0Sgdu3.d.ts +0 -245
package/dist/extras.cjs CHANGED
@@ -41,6 +41,7 @@ __export(extras_exports, {
41
41
  announce: () => announce,
42
42
  antdAdapter: () => antdAdapter,
43
43
  aria: () => aria,
44
+ assembleDocument: () => assembleDocument,
44
45
  assertType: () => assertType,
45
46
  battery: () => battery,
46
47
  bindAttrs: () => bindAttrs,
@@ -237,6 +238,7 @@ __export(extras_exports, {
237
238
  renderToReadableStream: () => renderToReadableStream,
238
239
  renderToStream: () => renderToStream,
239
240
  renderToString: () => renderToString,
241
+ renderToStringWith: () => renderToStringWith,
240
242
  renderToSuspenseStream: () => renderToSuspenseStream,
241
243
  renderWithLoader: () => renderWithLoader,
242
244
  required: () => required,
@@ -315,6 +317,7 @@ __export(extras_exports, {
315
317
  withRetry: () => withRetry,
316
318
  withScopedStyle: () => withScopedStyle,
317
319
  withWrapper: () => withWrapper,
320
+ withholdTransfer: () => withholdTransfer,
318
321
  worker: () => worker,
319
322
  workerFn: () => workerFn,
320
323
  yieldToMain: () => yieldToMain,
@@ -399,13 +402,13 @@ function claimedByBoundary(error, context) {
399
402
  }
400
403
  }
401
404
  function resolveEventTarget(node) {
402
- const ELEMENT_NODE = 1;
403
- let current = node;
404
- while (current) {
405
- if (current.nodeType === ELEMENT_NODE && typeof current.dispatchEvent === "function") {
406
- return current;
405
+ const ELEMENT_NODE2 = 1;
406
+ let current2 = node;
407
+ while (current2) {
408
+ if (current2.nodeType === ELEMENT_NODE2 && typeof current2.dispatchEvent === "function") {
409
+ return current2;
407
410
  }
408
- current = current.parentNode;
411
+ current2 = current2.parentNode;
409
412
  }
410
413
  const self2 = node;
411
414
  return typeof self2.dispatchEvent === "function" ? self2 : null;
@@ -414,10 +417,21 @@ function defaultReport(error, context) {
414
417
  if (typeof console === "undefined") return;
415
418
  console.error(`[SibuJS] Uncaught error during ${describe(context)}: ${error.message}`, error);
416
419
  }
420
+ function requestErrorSink() {
421
+ const shared = globalThis[/* @__PURE__ */ Symbol.for("sibujs.ssr.v1")];
422
+ if (!shared) return void 0;
423
+ const store = shared.als ? shared.als.getStore() : shared.fallbackDepth > 0 ? shared.fallbackStore : void 0;
424
+ return store?.errors;
425
+ }
417
426
  function reportError(error, context) {
418
427
  const err = normalizeError(error);
419
428
  untrackedRun(() => {
420
429
  if (claimedByBoundary(err, context)) return;
430
+ const sink = requestErrorSink();
431
+ if (sink) {
432
+ sink.push({ error: err, context });
433
+ return;
434
+ }
421
435
  const s2 = state();
422
436
  const handler = s2.handler;
423
437
  if (handler && s2.handlerDepth === 0) {
@@ -438,6 +452,110 @@ function reportError(error, context) {
438
452
  });
439
453
  }
440
454
 
455
+ // src/core/rendering/adoptScope.ts
456
+ var current = null;
457
+ function inAdoptScope() {
458
+ return current?.s.on === true;
459
+ }
460
+ function currentSink() {
461
+ return current?.s.on ? current.s : null;
462
+ }
463
+ function createScopedElement(tag, ns) {
464
+ const c = current;
465
+ if (c?.s.on) {
466
+ const el = c.s.el(tag, ns, c.p + (c.n++).toString(36));
467
+ if (el) return el;
468
+ }
469
+ return ns ? document.createElementNS(ns, tag) : document.createElement(tag);
470
+ }
471
+ function captureScope() {
472
+ const c = current;
473
+ return c?.s.on ? { p: `${c.p}${(c.n++).toString(36)}.`, n: 0, s: c.s } : null;
474
+ }
475
+ function inScope(scope, fn) {
476
+ const prev = current;
477
+ if (!scope && !prev) return fn();
478
+ current = scope?.s.on ? { p: scope.p, n: 0, s: scope.s } : null;
479
+ try {
480
+ return fn();
481
+ } finally {
482
+ current = prev;
483
+ }
484
+ }
485
+
486
+ // src/core/rendering/hydrationHooks.ts
487
+ var _a;
488
+ var slot = globalThis[_a = /* @__PURE__ */ Symbol.for("sibujs.hydration.v2")] ?? (globalThis[_a] = { a: /* @__PURE__ */ new Set(), c: null });
489
+ function isHydrating() {
490
+ return slot.a.size > 0;
491
+ }
492
+ function ownSession() {
493
+ return currentSink()?.h ?? slot.c;
494
+ }
495
+ function hydrationOwners() {
496
+ const own = ownSession();
497
+ return own ? own.open ? [own] : [] : Array.from(slot.a);
498
+ }
499
+ function notify(session) {
500
+ for (const wake of Array.from(session.wake)) wake();
501
+ }
502
+ function holdHydration(sessions, entry) {
503
+ for (const s2 of sessions) s2.pending.add(entry);
504
+ return () => {
505
+ for (const s2 of sessions) if (s2.pending.delete(entry)) notify(s2);
506
+ };
507
+ }
508
+ function inHydration(session, fn) {
509
+ const prev = slot.c;
510
+ slot.c = session;
511
+ try {
512
+ return fn();
513
+ } finally {
514
+ slot.c = prev;
515
+ }
516
+ }
517
+ function beginHydration() {
518
+ const own = ownSession();
519
+ const session = {
520
+ done: [],
521
+ pending: /* @__PURE__ */ new Set(),
522
+ wake: /* @__PURE__ */ new Set(),
523
+ up: own?.open ? own : null,
524
+ open: true,
525
+ end() {
526
+ if (!session.open) return;
527
+ session.open = false;
528
+ slot.a.delete(session);
529
+ session.pending.clear();
530
+ notify(session);
531
+ const up = session.up;
532
+ session.up = null;
533
+ const callbacks = session.done.splice(0);
534
+ if (up?.open) {
535
+ up.done.push(...callbacks);
536
+ if (up.pending.delete(session)) notify(up);
537
+ return;
538
+ }
539
+ let failed = false;
540
+ let error;
541
+ inHydration(session, () => {
542
+ for (const fn of callbacks) {
543
+ try {
544
+ fn();
545
+ } catch (err) {
546
+ if (!failed) error = err;
547
+ failed = true;
548
+ }
549
+ }
550
+ });
551
+ if (failed) throw error;
552
+ }
553
+ };
554
+ if (session.up) session.up.pending.add(session);
555
+ slot.a.add(session);
556
+ return session;
557
+ }
558
+
441
559
  // src/core/rendering/dispose.ts
442
560
  var elementDisposers = /* @__PURE__ */ new WeakMap();
443
561
  var MAX_DRAIN_TEARDOWNS = 1e4;
@@ -534,9 +652,9 @@ function dispose(node) {
534
652
  const stack = [node];
535
653
  const order = [];
536
654
  while (stack.length > 0) {
537
- const current = stack.pop();
538
- order.push(current);
539
- const children = Array.from(current.childNodes);
655
+ const current2 = stack.pop();
656
+ order.push(current2);
657
+ const children = Array.from(current2.childNodes);
540
658
  for (let i2 = 0; i2 < children.length; i2++) {
541
659
  stack.push(children[i2]);
542
660
  }
@@ -575,13 +693,27 @@ function disposeNodeOwn(node) {
575
693
  }
576
694
  }
577
695
  function replaceChildrenSafely(parent, ...next) {
696
+ if (isHydrating() && next.length > 0 && next[0] === parent.firstChild) {
697
+ let ok = true;
698
+ for (let i2 = 1; i2 < next.length && ok; i2++) ok = next[i2 - 1].nextSibling === next[i2];
699
+ if (ok) {
700
+ let rest = next[next.length - 1].nextSibling;
701
+ while (rest) {
702
+ const following = rest.nextSibling;
703
+ dispose(rest);
704
+ parent.removeChild(rest);
705
+ rest = following;
706
+ }
707
+ return;
708
+ }
709
+ }
578
710
  for (let i2 = 0; i2 < next.length; i2++) {
579
711
  const node = next[i2];
580
712
  node.parentNode?.removeChild(node);
581
713
  }
582
- const current = Array.from(parent.childNodes);
583
- for (let i2 = 0; i2 < current.length; i2++) {
584
- dispose(current[i2]);
714
+ const current2 = Array.from(parent.childNodes);
715
+ for (let i2 = 0; i2 < current2.length; i2++) {
716
+ dispose(current2[i2]);
585
717
  }
586
718
  parent.replaceChildren(...next);
587
719
  }
@@ -1154,7 +1286,7 @@ function forEachSubscriber(signal2, visit) {
1154
1286
  }
1155
1287
 
1156
1288
  // src/reactivity/track.ts
1157
- var _runtimeVersion = true ? "4.13.0" : "dev";
1289
+ var _runtimeVersion = true ? "4.14.0" : "dev";
1158
1290
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
1159
1291
  function resolveReactiveApi() {
1160
1292
  const g2 = globalThis;
@@ -1336,6 +1468,25 @@ function derived(getter, options) {
1336
1468
  return computedGetter;
1337
1469
  }
1338
1470
 
1471
+ // src/core/rendering/streamBoundary.ts
1472
+ var _a2;
1473
+ var slot2 = globalThis[_a2 = /* @__PURE__ */ Symbol.for("sibujs.streamBoundary.v1")] ?? (globalThis[_a2] = { hook: null, current: null });
1474
+ function currentBoundary() {
1475
+ return slot2.current;
1476
+ }
1477
+ function runInBoundary(boundary, fn) {
1478
+ const prev = slot2.current;
1479
+ slot2.current = boundary;
1480
+ try {
1481
+ return fn();
1482
+ } finally {
1483
+ slot2.current = prev;
1484
+ }
1485
+ }
1486
+ function setBoundaryHook(hook) {
1487
+ slot2.hook = hook;
1488
+ }
1489
+
1339
1490
  // src/core/ssr-context.ts
1340
1491
  var SSR_KEY = /* @__PURE__ */ Symbol.for("sibujs.ssr.v1");
1341
1492
  function detectSSRShared() {
@@ -1351,6 +1502,8 @@ function detectSSRShared() {
1351
1502
  }
1352
1503
  if (mod) detected = new mod.AsyncLocalStorage();
1353
1504
  }
1505
+ const globalAls = globalThis.AsyncLocalStorage;
1506
+ if (!detected && typeof globalAls === "function") detected = new globalAls();
1354
1507
  } catch {
1355
1508
  detected = null;
1356
1509
  }
@@ -1364,6 +1517,23 @@ var _shared = globalThis[SSR_KEY] ?? (globalThis[SSR_KEY] = detectSSRShared());
1364
1517
  var als = _shared.als;
1365
1518
  var fallbackStore = _shared.fallbackStore;
1366
1519
  _shared.fallbackDepth ?? (_shared.fallbackDepth = 0);
1520
+ var _alsWarned = false;
1521
+ function warnMissingAsyncLocalStorage() {
1522
+ if (_alsWarned || als) return;
1523
+ const isNode = typeof process !== "undefined" && !!process.versions?.node;
1524
+ if (!isNode) return;
1525
+ _alsWarned = true;
1526
+ const version = process.versions.node;
1527
+ devWarn(
1528
+ `SSR request isolation is UNAVAILABLE on this runtime (Node ${version}). AsyncLocalStorage could not be loaded, so concurrent requests share one SSR store: request state and the query cache can bleed between them. Node >= 22.3 is required for isolated SSR under ESM; the CommonJS build works on older versions. A fully synchronous render is unaffected.`
1529
+ );
1530
+ }
1531
+ function assertRequestIsolation(api) {
1532
+ if (als || typeof window !== "undefined") return;
1533
+ throw new Error(
1534
+ `[SibuJS SSR] ${api} needs AsyncLocalStorage to keep concurrent requests apart, and this runtime has none. Use Node >= 22.3 (or the CommonJS build on older Node), Deno or Bun, or enable AsyncLocalStorage on your edge runtime (Cloudflare Workers: the nodejs_compat flag).`
1535
+ );
1536
+ }
1367
1537
  function getSSRStore() {
1368
1538
  if (als) {
1369
1539
  const s2 = als.getStore();
@@ -1389,6 +1559,63 @@ function getRequestScopedCache(name) {
1389
1559
  }
1390
1560
  return c;
1391
1561
  }
1562
+ function requestSlot(name, create) {
1563
+ const store = getRequestStore();
1564
+ if (!store) return void 0;
1565
+ const slots = store.slots ?? (store.slots = /* @__PURE__ */ new Map());
1566
+ if (!slots.has(name) && create) slots.set(name, create());
1567
+ return slots.get(name);
1568
+ }
1569
+ var PRERENDER_HOST = /* @__PURE__ */ Symbol.for("sibujs.prerender.v1");
1570
+ function isServer() {
1571
+ return getSSRStore().ssr || globalThis[PRERENDER_HOST] !== void 0;
1572
+ }
1573
+ function runInSSRContext(fn) {
1574
+ const store = {
1575
+ ssr: true,
1576
+ suspenseIdCounter: 0,
1577
+ idCounter: 0,
1578
+ locale: void 0,
1579
+ pending: /* @__PURE__ */ new Set(),
1580
+ wake: null
1581
+ };
1582
+ if (als) {
1583
+ return als.run(store, fn);
1584
+ }
1585
+ warnMissingAsyncLocalStorage();
1586
+ const prev = { ...fallbackStore };
1587
+ Object.assign(fallbackStore, store);
1588
+ _shared.fallbackDepth++;
1589
+ try {
1590
+ return fn();
1591
+ } finally {
1592
+ _shared.fallbackDepth--;
1593
+ for (const key of Object.keys(fallbackStore)) {
1594
+ if (!(key in prev)) delete fallbackStore[key];
1595
+ }
1596
+ Object.assign(fallbackStore, prev);
1597
+ }
1598
+ }
1599
+ function trackPending(promise, label2, hydration = true) {
1600
+ const store = getRequestStore();
1601
+ const pending = store?.pending;
1602
+ const sessions = pending || !hydration ? [] : hydrationOwners();
1603
+ if (!pending && sessions.length === 0) return promise;
1604
+ const entry = { label: label2, since: Date.now(), boundary: currentBoundary() ?? void 0 };
1605
+ pending?.add(entry);
1606
+ const release = holdHydration(sessions, entry);
1607
+ const done = () => {
1608
+ pending?.delete(entry);
1609
+ store?.wake?.();
1610
+ release();
1611
+ };
1612
+ try {
1613
+ Promise.resolve(promise).then(done, done);
1614
+ } catch {
1615
+ done();
1616
+ }
1617
+ return promise;
1618
+ }
1392
1619
 
1393
1620
  // src/core/signals/effect.ts
1394
1621
  var _g = globalThis;
@@ -1454,7 +1681,7 @@ function disposeEffect(ctx) {
1454
1681
  }
1455
1682
  function effect(effectFn, options) {
1456
1683
  devAssert(typeof effectFn === "function", "effect: argument must be a function.");
1457
- if (isSSR()) return () => {
1684
+ if (isSSR() && !options?.server) return () => {
1458
1685
  };
1459
1686
  const ctx = {
1460
1687
  fn: effectFn,
@@ -1651,6 +1878,98 @@ function globalSingleton(key, create) {
1651
1878
  return g2[key] ?? (g2[key] = create());
1652
1879
  }
1653
1880
 
1881
+ // src/utils/guards.ts
1882
+ var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
1883
+ function isUnsafeKey(key) {
1884
+ return UNSAFE_KEYS.has(key);
1885
+ }
1886
+ function readOwnGlobal(key) {
1887
+ if (typeof window === "undefined") return void 0;
1888
+ if (!Object.hasOwn(window, key)) return void 0;
1889
+ const value = window[key];
1890
+ if (typeof Node !== "undefined" && value instanceof Node) return void 0;
1891
+ return value;
1892
+ }
1893
+ function stripUnsafeKeys(obj) {
1894
+ const out = {};
1895
+ for (const k of Object.keys(obj)) {
1896
+ if (!isUnsafeKey(k)) out[k] = obj[k];
1897
+ }
1898
+ return out;
1899
+ }
1900
+
1901
+ // src/utils/transfer.ts
1902
+ var TRANSFER_GLOBAL = "__SIBU_TRANSFER__";
1903
+ var TRANSFER_VERSION = 1;
1904
+ var REGISTRY_KEY2 = /* @__PURE__ */ Symbol.for("sibujs.transfer.v1");
1905
+ function registry() {
1906
+ const g2 = globalThis;
1907
+ let r = g2[REGISTRY_KEY2];
1908
+ if (!r) {
1909
+ r = { collectors: /* @__PURE__ */ new Map(), payload: void 0 };
1910
+ g2[REGISTRY_KEY2] = r;
1911
+ }
1912
+ return r;
1913
+ }
1914
+ function registerTransferCollector(section2, collect) {
1915
+ registry().collectors.set(section2, collect);
1916
+ }
1917
+ function collectTransfer() {
1918
+ if (!getRequestStore()) return null;
1919
+ const out = {};
1920
+ let any = false;
1921
+ for (const [section2, collect] of registry().collectors) {
1922
+ const entries = collect();
1923
+ if (!entries) continue;
1924
+ const safe = {};
1925
+ for (const key of Object.keys(entries)) if (!isUnsafeKey(key)) safe[key] = entries[key];
1926
+ if (Object.keys(safe).length > 0) {
1927
+ out[section2] = safe;
1928
+ any = true;
1929
+ }
1930
+ }
1931
+ if (!any) return null;
1932
+ out.v = TRANSFER_VERSION;
1933
+ return out;
1934
+ }
1935
+ function isPlainRecord(value) {
1936
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
1937
+ const proto = Object.getPrototypeOf(value);
1938
+ return proto === Object.prototype || proto === null;
1939
+ }
1940
+ function readPayload() {
1941
+ const r = registry();
1942
+ if (r.payload !== void 0) return r.payload;
1943
+ r.payload = null;
1944
+ if (typeof window === "undefined" || getRequestStore()) return null;
1945
+ const raw = readOwnGlobal(TRANSFER_GLOBAL);
1946
+ if (!isPlainRecord(raw) || raw.v !== TRANSFER_VERSION) return null;
1947
+ const sections = /* @__PURE__ */ Object.create(null);
1948
+ for (const key of Object.keys(raw)) {
1949
+ const section2 = raw[key];
1950
+ if (key === "v" || isUnsafeKey(key) || !isPlainRecord(section2)) continue;
1951
+ const entries = /* @__PURE__ */ Object.create(null);
1952
+ for (const k of Object.keys(section2)) if (!isUnsafeKey(k)) entries[k] = section2[k];
1953
+ sections[key] = entries;
1954
+ }
1955
+ r.payload = sections;
1956
+ return sections;
1957
+ }
1958
+ function takeTransferred(section2, key) {
1959
+ const entries = readPayload()?.[section2];
1960
+ if (!entries || !Object.hasOwn(entries, key)) return void 0;
1961
+ const value = entries[key];
1962
+ delete entries[key];
1963
+ return value;
1964
+ }
1965
+ function takeTransferredSection(section2) {
1966
+ const payload = readPayload();
1967
+ const entries = payload?.[section2];
1968
+ if (!payload || !entries) return {};
1969
+ delete payload[section2];
1970
+ return entries;
1971
+ }
1972
+
1654
1973
  // src/data/abort.ts
1655
1974
  function isAbortError(error) {
1656
1975
  return typeof error === "object" && error !== null && error.name === "AbortError";
@@ -1845,8 +2164,34 @@ function sharedView(entry) {
1845
2164
  }
1846
2165
  var globalQueryCache = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.query.cache.v1"), () => /* @__PURE__ */ new Map());
1847
2166
  function getActiveQueryCache() {
1848
- return getRequestScopedCache("query") ?? globalQueryCache;
1849
- }
2167
+ const requestCache = getRequestScopedCache("query");
2168
+ if (requestCache) return requestCache;
2169
+ primeFromTransfer();
2170
+ return globalQueryCache;
2171
+ }
2172
+ var SERVER_EFFECT = { server: true };
2173
+ function primeFromTransfer() {
2174
+ const entries = takeTransferredSection("q");
2175
+ const now = Date.now();
2176
+ for (const key of Object.keys(entries)) {
2177
+ const record = entries[key];
2178
+ if (!record || typeof record !== "object" || record.d === void 0) continue;
2179
+ if (globalQueryCache.has(key)) continue;
2180
+ const entry = getOrCreateEntry(globalQueryCache, key, record.d);
2181
+ const t = typeof record.t === "number" && Number.isFinite(record.t) ? record.t : now;
2182
+ entry.dataUpdatedAt = Math.min(t, now);
2183
+ }
2184
+ }
2185
+ registerTransferCollector("q", () => {
2186
+ const cache = getRequestScopedCache("query");
2187
+ if (!cache) return void 0;
2188
+ const out = {};
2189
+ for (const [key, entry] of cache) {
2190
+ if (entry.noTransfer || entry.data === void 0 || entry.error) continue;
2191
+ out[key] = { d: entry.data, t: entry.dataUpdatedAt };
2192
+ }
2193
+ return out;
2194
+ });
1850
2195
  function abandonEntry(entry) {
1851
2196
  if (entry.gcTimer) clearTimeout(entry.gcTimer);
1852
2197
  entry.gcTimer = null;
@@ -1892,11 +2237,13 @@ function query(key, fetcher, options = {}) {
1892
2237
  onError,
1893
2238
  onSettled,
1894
2239
  select: select3,
1895
- structuralSharing = true
2240
+ structuralSharing = true,
2241
+ ssr = true
1896
2242
  } = options;
2243
+ const onServer = isSSR();
1897
2244
  const resolveKey = typeof key === "function" ? key : () => key;
1898
2245
  const enabledGate = typeof enabled === "function" ? derived(() => Boolean(enabled())) : null;
1899
- const isEnabled = enabledGate ?? (() => Boolean(enabled));
2246
+ const isEnabled = onServer && !ssr ? () => false : enabledGate ?? (() => Boolean(enabled));
1900
2247
  const cache = getActiveQueryCache();
1901
2248
  const [data2, setData] = signal(initialData);
1902
2249
  const [isFetching, setIsFetching] = signal(false);
@@ -1970,7 +2317,7 @@ function query(key, fetcher, options = {}) {
1970
2317
  selectedEntry = entry;
1971
2318
  selectedValue = value;
1972
2319
  setData(value);
1973
- }) : null;
2320
+ }, SERVER_EFFECT) : null;
1974
2321
  function detachFromEntry() {
1975
2322
  const entry = attachedEntry;
1976
2323
  const key2 = attachedKey;
@@ -1984,9 +2331,9 @@ function query(key, fetcher, options = {}) {
1984
2331
  if (cache.get(key2) !== entry) return;
1985
2332
  if (entry.gcTimer !== null) clearTimeout(entry.gcTimer);
1986
2333
  entry.gcTimer = setTimeout(() => {
1987
- const current = cache.get(key2);
1988
- if (current === entry && current.subscribers <= 0) {
1989
- abandonEntry(current);
2334
+ const current2 = cache.get(key2);
2335
+ if (current2 === entry && current2.subscribers <= 0) {
2336
+ abandonEntry(current2);
1990
2337
  cache.delete(key2);
1991
2338
  }
1992
2339
  }, cacheTime);
@@ -2053,7 +2400,7 @@ function query(key, fetcher, options = {}) {
2053
2400
  runCallback("query onSettled", () => onSettled?.());
2054
2401
  return;
2055
2402
  }
2056
- entry.promise = promise;
2403
+ entry.promise = trackPending(promise, `query:${key2}`, false);
2057
2404
  try {
2058
2405
  const result = await promise;
2059
2406
  if (entry.generation !== generation) return;
@@ -2125,6 +2472,7 @@ function query(key, fetcher, options = {}) {
2125
2472
  return;
2126
2473
  }
2127
2474
  const entry = getOrCreateEntry(cache, key2, initialData);
2475
+ if (!ssr) entry.noTransfer = true;
2128
2476
  const reattached = attachedEntry !== entry;
2129
2477
  attachToEntry(entry, key2);
2130
2478
  if (keyChanged) setIsFetching(entry.promise !== null);
@@ -2146,15 +2494,15 @@ function query(key, fetcher, options = {}) {
2146
2494
  if (on && (entry.data === void 0 || isDataStale)) {
2147
2495
  doFetch();
2148
2496
  }
2149
- });
2150
- if (refetchInterval && refetchInterval > 0) {
2497
+ }, SERVER_EFFECT);
2498
+ if (!onServer && refetchInterval && refetchInterval > 0) {
2151
2499
  intervalTimer = setInterval(() => {
2152
2500
  if (!disposed && currentKey) doFetch();
2153
2501
  }, refetchInterval);
2154
2502
  }
2155
2503
  let focusHandler = null;
2156
2504
  let onlineHandler = null;
2157
- if (typeof globalThis !== "undefined" && typeof globalThis.addEventListener === "function") {
2505
+ if (!onServer && typeof globalThis !== "undefined" && typeof globalThis.addEventListener === "function") {
2158
2506
  if (refetchOnWindowFocus) {
2159
2507
  focusHandler = () => {
2160
2508
  if (!disposed && currentKey) doFetch();
@@ -2498,12 +2846,12 @@ function infiniteQuery(key, fetcher, options) {
2498
2846
  // src/data/previous.ts
2499
2847
  function previous(getter) {
2500
2848
  const [previous2, setPrevious] = signal(void 0);
2501
- let current = getter();
2849
+ let current2 = getter();
2502
2850
  const stop2 = effect(() => {
2503
2851
  const next = getter();
2504
- if (!Object.is(next, current)) {
2505
- setPrevious(current);
2506
- current = next;
2852
+ if (!Object.is(next, current2)) {
2853
+ setPrevious(current2);
2854
+ current2 = next;
2507
2855
  }
2508
2856
  });
2509
2857
  Object.defineProperty(previous2, "dispose", {
@@ -2583,6 +2931,28 @@ function throttle(getter, interval) {
2583
2931
  }
2584
2932
 
2585
2933
  // src/data/resource.ts
2934
+ function transferSlot() {
2935
+ return requestSlot("resource:transfer", () => /* @__PURE__ */ new Map());
2936
+ }
2937
+ function withheldSlot() {
2938
+ return requestSlot("resource:transfer:withheld", () => /* @__PURE__ */ new Set());
2939
+ }
2940
+ registerTransferCollector("r", () => {
2941
+ const slot4 = transferSlot();
2942
+ if (!slot4 || slot4.size === 0) return void 0;
2943
+ const withheld = withheldSlot();
2944
+ const out = {};
2945
+ let any = false;
2946
+ for (const [key, value] of slot4) {
2947
+ if (withheld?.has(key)) continue;
2948
+ out[key] = value;
2949
+ any = true;
2950
+ }
2951
+ return any ? out : void 0;
2952
+ });
2953
+ function withholdTransfer(key) {
2954
+ withheldSlot()?.add(key);
2955
+ }
2586
2956
  function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
2587
2957
  let source2 = null;
2588
2958
  let fetcher;
@@ -2596,10 +2966,14 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
2596
2966
  fetcher = (_source, info) => rawFetcher(info);
2597
2967
  options = fetcherOrOptions ?? {};
2598
2968
  }
2599
- const [data2, setData] = signal(options.initialValue);
2969
+ const transferred = options.key !== void 0 ? takeTransferred("r", options.key) : void 0;
2970
+ const hydrated = transferred !== void 0;
2971
+ const initialValue = hydrated ? transferred : options.initialValue;
2972
+ const onServer = isSSR();
2973
+ const [data2, setData] = signal(initialValue);
2600
2974
  const [loading, setLoading] = signal(false);
2601
2975
  const [error, setError] = signal(void 0);
2602
- let currentData = options.initialValue;
2976
+ let currentData = initialValue;
2603
2977
  function commitData(next, explicit) {
2604
2978
  const sharing = options.structuralSharing ?? true;
2605
2979
  const shared = untracked2(
@@ -2607,6 +2981,7 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
2607
2981
  );
2608
2982
  currentData = shared.ok ? shared.value : next;
2609
2983
  setData(currentData);
2984
+ if (onServer && options.key !== void 0) transferSlot()?.set(options.key, currentData);
2610
2985
  return currentData;
2611
2986
  }
2612
2987
  let abortController = null;
@@ -2652,19 +3027,28 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
2652
3027
  }
2653
3028
  }
2654
3029
  }
3030
+ const run = (sourceValue) => trackPending(doFetch(sourceValue), "resource", false);
2655
3031
  if (source2) {
2656
- effectCleanup = effect(() => {
2657
- const sourceValue = source2();
2658
- doFetch(sourceValue);
2659
- });
2660
- } else if (options.immediate !== false) {
2661
- doFetch(void 0);
3032
+ let skipFirst = hydrated;
3033
+ effectCleanup = effect(
3034
+ () => {
3035
+ const sourceValue = source2();
3036
+ if (skipFirst) {
3037
+ skipFirst = false;
3038
+ return;
3039
+ }
3040
+ run(sourceValue);
3041
+ },
3042
+ { server: true }
3043
+ );
3044
+ } else if (options.immediate !== false && !hydrated) {
3045
+ run(void 0);
2662
3046
  }
2663
3047
  return {
2664
3048
  data: data2,
2665
3049
  loading,
2666
3050
  error,
2667
- refetch: () => doFetch(source2 ? source2() : void 0),
3051
+ refetch: () => run(source2 ? source2() : void 0),
2668
3052
  mutate: (value) => {
2669
3053
  const newValue = typeof value === "function" ? value(currentData) : value;
2670
3054
  commitData(newValue, true);
@@ -2965,8 +3349,27 @@ function currentScope() {
2965
3349
  }
2966
3350
  return scope;
2967
3351
  }
3352
+ function automaticKey(loader, context) {
3353
+ const key = `loader:${context.path}${loader.name ? `:${loader.name}` : ""}`;
3354
+ const cache = getRequestScopedCache("routeLoader");
3355
+ if (!cache) return key;
3356
+ let owners = cache.get("owners");
3357
+ if (!owners) {
3358
+ owners = /* @__PURE__ */ new Map();
3359
+ cache.set("owners", owners);
3360
+ }
3361
+ const owner = owners.get(key);
3362
+ if (owner === void 0) {
3363
+ owners.set(key, loader);
3364
+ return key;
3365
+ }
3366
+ if (owner === loader) return key;
3367
+ withholdTransfer(key);
3368
+ return void 0;
3369
+ }
2968
3370
  function executeLoader(loader, context, options) {
2969
- const res = resource(({ signal: signal2 }) => loader(context, { signal: signal2 }), options);
3371
+ const key = options?.key ?? automaticKey(loader, context);
3372
+ const res = resource(({ signal: signal2 }) => loader(context, { signal: signal2 }), { ...options, key });
2970
3373
  const disposeResource = res.dispose;
2971
3374
  res.dispose = () => {
2972
3375
  _disposed.add(res);
@@ -3241,19 +3644,19 @@ function sanitizeSrcset(value) {
3241
3644
  if (url.endsWith(",")) {
3242
3645
  url = url.replace(/,+$/, "");
3243
3646
  } else {
3244
- let current = "";
3647
+ let current2 = "";
3245
3648
  let inParens = false;
3246
3649
  while (i2 < n) {
3247
3650
  const ch = input2[i2];
3248
3651
  if (inParens) {
3249
- current += ch;
3652
+ current2 += ch;
3250
3653
  if (ch === ")") inParens = false;
3251
3654
  i2++;
3252
3655
  continue;
3253
3656
  }
3254
3657
  if (isSrcsetWhitespace(ch)) {
3255
- if (current) descriptors.push(current);
3256
- current = "";
3658
+ if (current2) descriptors.push(current2);
3659
+ current2 = "";
3257
3660
  i2++;
3258
3661
  continue;
3259
3662
  }
@@ -3262,10 +3665,10 @@ function sanitizeSrcset(value) {
3262
3665
  break;
3263
3666
  }
3264
3667
  if (ch === "(") inParens = true;
3265
- current += ch;
3668
+ current2 += ch;
3266
3669
  i2++;
3267
3670
  }
3268
- if (current) descriptors.push(current);
3671
+ if (current2) descriptors.push(current2);
3269
3672
  }
3270
3673
  if (url === "") continue;
3271
3674
  if (descriptors.length > 1) continue;
@@ -4016,26 +4419,6 @@ function clipboard() {
4016
4419
  return { text: text2, copy, copied, dispose: dispose2 };
4017
4420
  }
4018
4421
 
4019
- // src/utils/guards.ts
4020
- var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
4021
- function isUnsafeKey(key) {
4022
- return UNSAFE_KEYS.has(key);
4023
- }
4024
- function readOwnGlobal(key) {
4025
- if (typeof window === "undefined") return void 0;
4026
- if (!Object.hasOwn(window, key)) return void 0;
4027
- const value = window[key];
4028
- if (typeof Node !== "undefined" && value instanceof Node) return void 0;
4029
- return value;
4030
- }
4031
- function stripUnsafeKeys(obj) {
4032
- const out = {};
4033
- for (const k of Object.keys(obj)) {
4034
- if (!isUnsafeKey(k)) out[k] = obj[k];
4035
- }
4036
- return out;
4037
- }
4038
-
4039
4422
  // src/browser/dragDrop.ts
4040
4423
  function resolveTarget2(target) {
4041
4424
  return typeof target === "function" ? target : () => target.current;
@@ -4689,7 +5072,7 @@ function wakeLock() {
4689
5072
  };
4690
5073
  }
4691
5074
  const api = navigator.wakeLock;
4692
- let current = null;
5075
+ let current2 = null;
4693
5076
  let desire = false;
4694
5077
  let generation = 0;
4695
5078
  let inflight = null;
@@ -4699,8 +5082,8 @@ function wakeLock() {
4699
5082
  setActive(value);
4700
5083
  }
4701
5084
  function syncReleasedState() {
4702
- if (current?.released) {
4703
- current = null;
5085
+ if (current2?.released) {
5086
+ current2 = null;
4704
5087
  publishActive(false);
4705
5088
  }
4706
5089
  }
@@ -4714,7 +5097,7 @@ function wakeLock() {
4714
5097
  if (disposed) return;
4715
5098
  desire = true;
4716
5099
  syncReleasedState();
4717
- if (current && !current.released) {
5100
+ if (current2 && !current2.released) {
4718
5101
  publishActive(true);
4719
5102
  return;
4720
5103
  }
@@ -4733,8 +5116,8 @@ function wakeLock() {
4733
5116
  }
4734
5117
  try {
4735
5118
  sentinel.addEventListener("release", () => {
4736
- if (current !== sentinel) return;
4737
- current = null;
5119
+ if (current2 !== sentinel) return;
5120
+ current2 = null;
4738
5121
  publishActive(false);
4739
5122
  });
4740
5123
  } catch (listenerError) {
@@ -4747,7 +5130,7 @@ function wakeLock() {
4747
5130
  publishActive(false);
4748
5131
  return;
4749
5132
  }
4750
- current = sentinel;
5133
+ current2 = sentinel;
4751
5134
  publishActive(true);
4752
5135
  } catch (err) {
4753
5136
  if (generation === myGeneration) publishActive(false);
@@ -4765,8 +5148,8 @@ function wakeLock() {
4765
5148
  desire = false;
4766
5149
  generation++;
4767
5150
  inflight = null;
4768
- const held = current;
4769
- current = null;
5151
+ const held = current2;
5152
+ current2 = null;
4770
5153
  publishActive(false);
4771
5154
  if (held && !held.released) {
4772
5155
  await held.release();
@@ -4774,7 +5157,7 @@ function wakeLock() {
4774
5157
  }
4775
5158
  const onVisibility = () => {
4776
5159
  syncReleasedState();
4777
- if (!desire || current || document.hidden) return;
5160
+ if (!desire || current2 || document.hidden) return;
4778
5161
  request().catch((err) => {
4779
5162
  reportError(err, { phase: "async", name: "wakeLock(visibility re-acquire)" });
4780
5163
  });
@@ -4786,8 +5169,8 @@ function wakeLock() {
4786
5169
  generation++;
4787
5170
  inflight = null;
4788
5171
  document.removeEventListener("visibilitychange", onVisibility);
4789
- const held = current;
4790
- current = null;
5172
+ const held = current2;
5173
+ current2 = null;
4791
5174
  setActive(false);
4792
5175
  disposed = true;
4793
5176
  if (held && !held.released) {
@@ -5302,7 +5685,7 @@ function imageLoader(src) {
5302
5685
  }
5303
5686
  };
5304
5687
  }
5305
- let current = null;
5688
+ let current2 = null;
5306
5689
  let currentSettled = false;
5307
5690
  let disposed = false;
5308
5691
  let startToken = 0;
@@ -5315,9 +5698,9 @@ function imageLoader(src) {
5315
5698
  });
5316
5699
  }
5317
5700
  function abandonCurrent() {
5318
- if (!current) return;
5319
- const prev = current;
5320
- current = null;
5701
+ if (!current2) return;
5702
+ const prev = current2;
5703
+ current2 = null;
5321
5704
  prev.onload = null;
5322
5705
  prev.onerror = null;
5323
5706
  if (!currentSettled) prev.src = "";
@@ -5333,10 +5716,10 @@ function imageLoader(src) {
5333
5716
  return;
5334
5717
  }
5335
5718
  const img2 = new Image();
5336
- current = img2;
5719
+ current2 = img2;
5337
5720
  currentSettled = false;
5338
5721
  img2.onload = () => {
5339
- if (disposed || current !== img2) return;
5722
+ if (disposed || current2 !== img2) return;
5340
5723
  currentSettled = true;
5341
5724
  batch(() => {
5342
5725
  setImage(img2);
@@ -5346,7 +5729,7 @@ function imageLoader(src) {
5346
5729
  });
5347
5730
  };
5348
5731
  img2.onerror = () => {
5349
- if (disposed || current !== img2) return;
5732
+ if (disposed || current2 !== img2) return;
5350
5733
  currentSettled = true;
5351
5734
  setStatus("error");
5352
5735
  };
@@ -5500,10 +5883,10 @@ function persisted(key, initial, options = {}) {
5500
5883
  const [value, setValue] = signal(restored);
5501
5884
  let applyingFromStorage = false;
5502
5885
  const stopPersistEffect = effect(() => {
5503
- const current = value();
5886
+ const current2 = value();
5504
5887
  if (applyingFromStorage) return;
5505
5888
  try {
5506
- let serialized = serialize(current);
5889
+ let serialized = serialize(current2);
5507
5890
  if (encrypt) serialized = encrypt(serialized);
5508
5891
  storage?.setItem(key, serialized);
5509
5892
  } catch {
@@ -5850,9 +6233,9 @@ function timeline(initial, maxHistory = 100) {
5850
6233
  const canUndo = derived(() => index() > 0);
5851
6234
  const canRedo = derived(() => index() < history2().length - 1);
5852
6235
  function set(next) {
5853
- const current = value();
5854
- const newValue = typeof next === "function" ? next(current) : next;
5855
- if (Object.is(newValue, current)) return;
6236
+ const current2 = value();
6237
+ const newValue = typeof next === "function" ? next(current2) : next;
6238
+ if (Object.is(newValue, current2)) return;
5856
6239
  const hist = history2();
5857
6240
  const idx = index();
5858
6241
  const newHistory = hist.slice(0, idx + 1);
@@ -6095,10 +6478,10 @@ function globalStore(config) {
6095
6478
  const actionFn = config.actions[action];
6096
6479
  if (!actionFn) throw new Error(`Unknown action: ${String(action)}`);
6097
6480
  const execute = () => {
6098
- const current = getState();
6099
- const rawPatch = actionFn(current, payload);
6481
+ const current2 = getState();
6482
+ const rawPatch = actionFn(current2, payload);
6100
6483
  const patch = stripUnsafeKeys(rawPatch);
6101
- setState({ ...current, ...patch });
6484
+ setState({ ...current2, ...patch });
6102
6485
  notifyListeners2(getState());
6103
6486
  };
6104
6487
  perform(() => {
@@ -6757,7 +7140,7 @@ function springSignal(initial, options) {
6757
7140
  const damping = options?.damping ?? 0.8;
6758
7141
  const precision = options?.precision ?? 0.01;
6759
7142
  const [value, setValue] = signal(initial);
6760
- let current = initial;
7143
+ let current2 = initial;
6761
7144
  let velocity = 0;
6762
7145
  let target = initial;
6763
7146
  let rafId = null;
@@ -6774,18 +7157,18 @@ function springSignal(initial, options) {
6774
7157
  lastTime = now;
6775
7158
  const dt2 = Number.isFinite(rawDt) && rawDt > 0 ? rawDt : REF_DT_MS;
6776
7159
  const ratio = Math.min(MAX_STEP_RATIO, Math.max(0.1, dt2 / REF_DT_MS));
6777
- const force = -stiffness * (current - target);
7160
+ const force = -stiffness * (current2 - target);
6778
7161
  const dampingForce = -damping * velocity;
6779
7162
  velocity += (force + dampingForce) * ratio;
6780
- current += velocity * ratio;
6781
- if (Math.abs(current - target) < precision && Math.abs(velocity) < precision) {
6782
- current = target;
7163
+ current2 += velocity * ratio;
7164
+ if (Math.abs(current2 - target) < precision && Math.abs(velocity) < precision) {
7165
+ current2 = target;
6783
7166
  velocity = 0;
6784
7167
  lastTime = 0;
6785
- setValue(current);
7168
+ setValue(current2);
6786
7169
  return;
6787
7170
  }
6788
- setValue(current);
7171
+ setValue(current2);
6789
7172
  if (disposed || rafId !== null) return;
6790
7173
  rafId = requestAnimationFrame(tick);
6791
7174
  }
@@ -6799,11 +7182,11 @@ function springSignal(initial, options) {
6799
7182
  if (disposed) return;
6800
7183
  target = newTarget;
6801
7184
  if (!canAnimate() || prefersReducedMotion()) {
6802
- current = newTarget;
7185
+ current2 = newTarget;
6803
7186
  velocity = 0;
6804
7187
  cancelFrame();
6805
7188
  lastTime = 0;
6806
- setValue(current);
7189
+ setValue(current2);
6807
7190
  return;
6808
7191
  }
6809
7192
  if (rafId === null) {
@@ -6998,7 +7381,7 @@ function form(config) {
6998
7381
  }
6999
7382
  return false;
7000
7383
  };
7001
- const isDirty = derived(() => {
7384
+ const isDirty2 = derived(() => {
7002
7385
  for (const [name, cfg] of fieldEntries) {
7003
7386
  if (!valueEquals(fieldMap[name].value(), cfg.initial)) return true;
7004
7387
  }
@@ -7062,7 +7445,7 @@ function form(config) {
7062
7445
  disposed = true;
7063
7446
  errors.dispose();
7064
7447
  isValid.dispose();
7065
- isDirty.dispose();
7448
+ isDirty2.dispose();
7066
7449
  touchedState.dispose();
7067
7450
  values.dispose();
7068
7451
  for (const error of fieldErrors) error.dispose();
@@ -7071,7 +7454,7 @@ function form(config) {
7071
7454
  fields: fieldMap,
7072
7455
  errors,
7073
7456
  isValid,
7074
- isDirty,
7457
+ isDirty: isDirty2,
7075
7458
  submitting,
7076
7459
  touched: touchedState,
7077
7460
  values,
@@ -8036,8 +8419,8 @@ function commitSafeAttribute(el, name, value, options) {
8036
8419
  else el.removeAttribute(name);
8037
8420
  return true;
8038
8421
  }
8039
- const current = ns ? el.getAttributeNS(ns, localName) : el.getAttribute(name);
8040
- if (current === safe) return true;
8422
+ const current2 = ns ? el.getAttributeNS(ns, localName) : el.getAttribute(name);
8423
+ if (current2 === safe) return true;
8041
8424
  if (ns) el.setAttributeNS(ns, name, safe);
8042
8425
  else el.setAttribute(name, safe);
8043
8426
  return true;
@@ -8874,9 +9257,9 @@ function narrowEmbedAllow(value) {
8874
9257
  function getEmbedRecord(frame) {
8875
9258
  return state2.frames.get(frame);
8876
9259
  }
8877
- function intersect(current, permitted, separator) {
9260
+ function intersect(current2, permitted, separator) {
8878
9261
  const allowed = permitted.split(separator);
8879
- return current.split(separator).filter((token) => token && allowed.includes(token)).join(separator);
9262
+ return current2.split(separator).filter((token) => token && allowed.includes(token)).join(separator);
8880
9263
  }
8881
9264
  function embedSerializedAttribute(record, seen, name, value) {
8882
9265
  switch (name) {
@@ -8980,67 +9363,2864 @@ function escapeHeadAttrValue(value) {
8980
9363
  function serializeHeadEntry(tag, attrs) {
8981
9364
  const plan = tag === "meta" ? planMetaEntry(attrs, STATIC_VALUE_RESOLVER) : planHeadElementEntry(attrs, STATIC_VALUE_RESOLVER);
8982
9365
  if (plan.kind === "drop") return "";
8983
- const pairs = Array.from(plan.attributes, ([name, value]) => `${name}="${escapeHeadAttrValue(value)}"`).join(" ");
9366
+ return serializePlannedHeadEntry(tag, plan.attributes);
9367
+ }
9368
+ function serializePlannedHeadEntry(tag, attributes) {
9369
+ const pairs = Array.from(attributes, ([name, value]) => `${name}="${escapeHeadAttrValue(value)}"`).join(" ");
8984
9370
  return `<${tag} ${pairs} />`;
8985
9371
  }
8986
9372
 
8987
- // src/platform/ssr.ts
8988
- function isForbiddenSsrAttr(lowerName) {
8989
- return isHtmlContentAttribute(lowerName);
8990
- }
8991
- var SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
8992
- function isSafeAttrName(name) {
8993
- return SAFE_ATTR_NAME.test(name);
8994
- }
8995
- function ssrErrorComment(err) {
8996
- if (DEV) {
8997
- const msg = escapeHtml(err instanceof Error ? err.message : String(err));
8998
- return `<!--SSR error: ${safeCommentText(msg)}-->`;
9373
+ // src/platform/serverDom.ts
9374
+ var HTML_NS3 = "http://www.w3.org/1999/xhtml";
9375
+ var SVG_NS3 = "http://www.w3.org/2000/svg";
9376
+ var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
9377
+ var ELEMENT_NODE = 1;
9378
+ var ATTRIBUTE_NODE = 2;
9379
+ var TEXT_NODE = 3;
9380
+ var COMMENT_NODE = 8;
9381
+ var DOCUMENT_NODE = 9;
9382
+ var DOCUMENT_FRAGMENT_NODE = 11;
9383
+ function callerFrame() {
9384
+ const stack = new Error().stack ?? "";
9385
+ const lines = stack.split("\n").slice(1);
9386
+ for (const line2 of lines) {
9387
+ if (line2.includes("serverDom")) continue;
9388
+ const trimmed = line2.trim();
9389
+ if (trimmed) return trimmed.replace(/^at\s+/, "");
9390
+ }
9391
+ return "(unknown caller)";
9392
+ }
9393
+ var warnedSites = /* @__PURE__ */ new Set();
9394
+ function reportBrowserApi(api) {
9395
+ const frame = callerFrame();
9396
+ const entry = `${api} at ${frame}`;
9397
+ requestSlot("browserApis", () => /* @__PURE__ */ new Set())?.add(entry);
9398
+ if (DEV && !warnedSites.has(entry) && warnedSites.size < 200) {
9399
+ warnedSites.add(entry);
9400
+ console.warn(
9401
+ `[SibuJS SSR] ${api} was used during a server render (${frame}). It only exists in a browser: move the code into onMount() or an effect, or render it with ClientOnly().`
9402
+ );
8999
9403
  }
9000
- return "<!--SSR error-->";
9404
+ return frame;
9001
9405
  }
9002
- function safeCommentText(text2) {
9003
- return text2.replace(/-->/g, "--&gt;").replace(/--!>/g, "--!&gt;").replace(/<!--/g, "&lt;!--").replace(/--$/g, "--&#45;");
9406
+ function unavailable(api) {
9407
+ const frame = reportBrowserApi(api);
9408
+ throw new Error(
9409
+ `[SibuJS SSR] ${api} is not available in the SibuJS server DOM (called from ${frame}). It needs a browser: call it from onMount() or an effect, or render the component with ClientOnly().`
9410
+ );
9004
9411
  }
9005
- var VOID_ELEMENTS = /* @__PURE__ */ new Set([
9006
- "area",
9007
- "base",
9008
- "br",
9009
- "col",
9010
- "embed",
9011
- "hr",
9012
- "img",
9013
- "input",
9014
- "link",
9015
- "meta",
9016
- "param",
9017
- "source",
9018
- "track",
9019
- "wbr"
9020
- ]);
9021
- function findNativeGetter(proto, name) {
9022
- for (let p2 = proto; p2; p2 = Object.getPrototypeOf(p2)) {
9023
- const get = Object.getOwnPropertyDescriptor(p2, name)?.get;
9024
- if (get) return get;
9025
- }
9026
- return null;
9412
+ function invalidCharacter(name) {
9413
+ const Ctor = globalThis.DOMException;
9414
+ const message = `"${name}" did not match the Name production`;
9415
+ throw Ctor ? new Ctor(message, "InvalidCharacterError") : new Error(message);
9027
9416
  }
9028
- var nativeAccessorsByRealm = /* @__PURE__ */ new WeakMap();
9029
- function nativeAccessors() {
9030
- const realm = Element;
9031
- let accessors = nativeAccessorsByRealm.get(realm);
9032
- if (!accessors) {
9033
- accessors = {
9034
- attributes: findNativeGetter(Element.prototype, "attributes"),
9035
- tagName: findNativeGetter(Element.prototype, "tagName"),
9036
- childNodes: findNativeGetter(Node.prototype, "childNodes"),
9037
- getAttribute: Element.prototype.getAttribute
9417
+ var NAME_RE = /^[A-Za-z_:][-A-Za-z0-9_.:·À-￿]*$/;
9418
+ var ServerNodeList = class extends Array {
9419
+ static get [Symbol.species]() {
9420
+ return Array;
9421
+ }
9422
+ item(index) {
9423
+ return this[index] ?? null;
9424
+ }
9425
+ };
9426
+ var observations = [];
9427
+ function queueRecord(record) {
9428
+ if (observations.length === 0) return;
9429
+ for (const obs of observations) {
9430
+ const o = obs.options;
9431
+ const wants = record.type === "childList" ? o.childList : record.type === "attributes" ? o.attributes : o.characterData;
9432
+ if (!wants) continue;
9433
+ if (obs.target !== record.target && !(o.subtree && obs.target.contains(record.target))) continue;
9434
+ obs.observer._enqueue(record);
9435
+ }
9436
+ }
9437
+ var ServerMutationObserver = class {
9438
+ constructor(callback) {
9439
+ this.callback = callback;
9440
+ this.records = [];
9441
+ this.scheduled = false;
9442
+ }
9443
+ observe(target, options = {}) {
9444
+ const opts = { ...options };
9445
+ if (opts.attributeFilter || opts.attributeOldValue) opts.attributes ?? (opts.attributes = true);
9446
+ if (opts.characterDataOldValue) opts.characterData ?? (opts.characterData = true);
9447
+ const existing = observations.find((o) => o.observer === this && o.target === target);
9448
+ if (existing) existing.options = opts;
9449
+ else observations.push({ observer: this, target, options: opts });
9450
+ }
9451
+ disconnect() {
9452
+ for (let i2 = observations.length - 1; i2 >= 0; i2--) if (observations[i2].observer === this) observations.splice(i2, 1);
9453
+ this.records = [];
9454
+ }
9455
+ takeRecords() {
9456
+ const out = this.records;
9457
+ this.records = [];
9458
+ return out;
9459
+ }
9460
+ /** @internal */
9461
+ _enqueue(record) {
9462
+ this.records.push(record);
9463
+ if (this.scheduled) return;
9464
+ this.scheduled = true;
9465
+ queueMicrotask(() => {
9466
+ this.scheduled = false;
9467
+ const records = this.takeRecords();
9468
+ if (records.length > 0) this.callback(records, this);
9469
+ });
9470
+ }
9471
+ };
9472
+ var _ServerNode = class _ServerNode {
9473
+ constructor(ownerDocument) {
9474
+ this.ownerDocument = ownerDocument;
9475
+ /** @internal */
9476
+ this._parent = null;
9477
+ /** @internal */
9478
+ this._prev = null;
9479
+ /** @internal */
9480
+ this._next = null;
9481
+ /** @internal */
9482
+ this._first = null;
9483
+ /** @internal */
9484
+ this._last = null;
9485
+ /** @internal */
9486
+ this._count = 0;
9487
+ /** @internal */
9488
+ this._list = null;
9489
+ /** @internal */
9490
+ this._listeners = null;
9491
+ }
9492
+ get nodeType() {
9493
+ return 0;
9494
+ }
9495
+ get nodeName() {
9496
+ return "";
9497
+ }
9498
+ get nodeValue() {
9499
+ return null;
9500
+ }
9501
+ set nodeValue(_value) {
9502
+ }
9503
+ get parentNode() {
9504
+ return this._parent;
9505
+ }
9506
+ get parentElement() {
9507
+ return this._parent instanceof ServerElement ? this._parent : null;
9508
+ }
9509
+ get firstChild() {
9510
+ return this._first;
9511
+ }
9512
+ get lastChild() {
9513
+ return this._last;
9514
+ }
9515
+ get nextSibling() {
9516
+ return this._next;
9517
+ }
9518
+ get previousSibling() {
9519
+ return this._prev;
9520
+ }
9521
+ get childNodes() {
9522
+ if (!this._list) {
9523
+ const list = new ServerNodeList();
9524
+ for (let n = this._first; n; n = n._next) list.push(n);
9525
+ this._list = list;
9526
+ }
9527
+ return this._list;
9528
+ }
9529
+ hasChildNodes() {
9530
+ return this._first !== null;
9531
+ }
9532
+ get isConnected() {
9533
+ let n = this;
9534
+ while (n) {
9535
+ if (n.nodeType === DOCUMENT_NODE) return true;
9536
+ n = n._parent;
9537
+ }
9538
+ return false;
9539
+ }
9540
+ getRootNode() {
9541
+ let n = this;
9542
+ while (n._parent) n = n._parent;
9543
+ return n;
9544
+ }
9545
+ get textContent() {
9546
+ let out = "";
9547
+ for (let n = this._first; n; n = n._next) {
9548
+ if (n.nodeType === TEXT_NODE) out += n.data;
9549
+ else if (n.nodeType === ELEMENT_NODE || n.nodeType === DOCUMENT_FRAGMENT_NODE) out += n.textContent ?? "";
9550
+ }
9551
+ return out;
9552
+ }
9553
+ set textContent(value) {
9554
+ while (this._first) this.removeChild(this._first);
9555
+ const text2 = value == null ? "" : String(value);
9556
+ if (text2 !== "") this.appendChild(new ServerText(this.ownerDocument, text2));
9557
+ }
9558
+ contains(other) {
9559
+ for (let n = other; n; n = n._parent) if (n === this) return true;
9560
+ return false;
9561
+ }
9562
+ compareDocumentPosition(other) {
9563
+ if (other === this) return 0;
9564
+ if (this.getRootNode() !== other.getRootNode()) return 1 | 32;
9565
+ if (this.contains(other)) return 16 | 4;
9566
+ if (other.contains(this)) return 8 | 2;
9567
+ const chain = (n) => {
9568
+ const out = [];
9569
+ for (let c = n; c; c = c._parent) out.unshift(c);
9570
+ return out;
9038
9571
  };
9039
- nativeAccessorsByRealm.set(realm, accessors);
9572
+ const a2 = chain(this);
9573
+ const b2 = chain(other);
9574
+ let i2 = 0;
9575
+ while (a2[i2] === b2[i2]) i2++;
9576
+ for (let n = a2[i2]._next; n; n = n._next) if (n === b2[i2]) return 4;
9577
+ return 2;
9578
+ }
9579
+ // ── Mutation ──
9580
+ /** @internal */
9581
+ _assertParentOf(node) {
9582
+ if (!(node instanceof _ServerNode))
9583
+ throw new TypeError("Failed to execute on Node: parameter is not of type 'Node'.");
9584
+ if (node.contains(this)) {
9585
+ const Ctor = globalThis.DOMException;
9586
+ const message = "The new child element contains the parent.";
9587
+ throw Ctor ? new Ctor(message, "HierarchyRequestError") : new Error(message);
9588
+ }
9589
+ }
9590
+ insertBefore(node, ref) {
9591
+ if (ref && ref._parent !== this) {
9592
+ const Ctor = globalThis.DOMException;
9593
+ const message = "The node before which the new node is to be inserted is not a child of this node.";
9594
+ throw Ctor ? new Ctor(message, "NotFoundError") : new Error(message);
9595
+ }
9596
+ if (node.nodeType === DOCUMENT_FRAGMENT_NODE) {
9597
+ const moved = [];
9598
+ while (node._first) {
9599
+ const child = node._first;
9600
+ node._unlink(child, true);
9601
+ moved.push(child);
9602
+ }
9603
+ for (const child of moved) this._link(child, ref, true);
9604
+ if (moved.length > 0) this._recordChildList(moved, [], moved[0]._prev, ref);
9605
+ return node;
9606
+ }
9607
+ this._assertParentOf(node);
9608
+ if (ref === node) ref = node._next;
9609
+ if (node._parent) node._parent.removeChild(node);
9610
+ this._link(node, ref, false);
9611
+ this._recordChildList([node], [], node._prev, node._next);
9612
+ return node;
9613
+ }
9614
+ appendChild(node) {
9615
+ return this.insertBefore(node, null);
9616
+ }
9617
+ removeChild(node) {
9618
+ if (node._parent !== this) {
9619
+ const Ctor = globalThis.DOMException;
9620
+ const message = "The node to be removed is not a child of this node.";
9621
+ throw Ctor ? new Ctor(message, "NotFoundError") : new Error(message);
9622
+ }
9623
+ const prev = node._prev;
9624
+ const next = node._next;
9625
+ this._unlink(node, false);
9626
+ this._recordChildList([], [node], prev, next);
9627
+ return node;
9628
+ }
9629
+ replaceChild(node, old) {
9630
+ if (node === old) return old;
9631
+ const next = old._next === node ? node._next : old._next;
9632
+ this.removeChild(old);
9633
+ this.insertBefore(node, next);
9634
+ return old;
9635
+ }
9636
+ /** @internal */
9637
+ _link(node, ref, quiet) {
9638
+ node._parent = this;
9639
+ if (ref) {
9640
+ node._prev = ref._prev;
9641
+ node._next = ref;
9642
+ if (ref._prev) ref._prev._next = node;
9643
+ else this._first = node;
9644
+ ref._prev = node;
9645
+ } else {
9646
+ node._prev = this._last;
9647
+ node._next = null;
9648
+ if (this._last) this._last._next = node;
9649
+ else this._first = node;
9650
+ this._last = node;
9651
+ }
9652
+ this._count++;
9653
+ this._list = null;
9654
+ void quiet;
9655
+ }
9656
+ /** @internal */
9657
+ _unlink(node, quiet) {
9658
+ if (node._prev) node._prev._next = node._next;
9659
+ else this._first = node._next;
9660
+ if (node._next) node._next._prev = node._prev;
9661
+ else this._last = node._prev;
9662
+ node._parent = null;
9663
+ node._prev = null;
9664
+ node._next = null;
9665
+ this._count--;
9666
+ this._list = null;
9667
+ void quiet;
9668
+ }
9669
+ /** @internal */
9670
+ _recordChildList(added, removed, prev, next) {
9671
+ if (observations.length === 0) return;
9672
+ queueRecord({
9673
+ type: "childList",
9674
+ target: this,
9675
+ addedNodes: added,
9676
+ removedNodes: removed,
9677
+ previousSibling: prev,
9678
+ nextSibling: next,
9679
+ attributeName: null,
9680
+ attributeNamespace: null,
9681
+ oldValue: null
9682
+ });
9040
9683
  }
9041
- return accessors;
9684
+ // ── ChildNode / ParentNode ──
9685
+ remove() {
9686
+ this._parent?.removeChild(this);
9687
+ }
9688
+ replaceWith(...nodes) {
9689
+ const parent = this._parent;
9690
+ if (!parent) return;
9691
+ const next = this._next;
9692
+ parent.removeChild(this);
9693
+ for (const n of nodes) parent.insertBefore(toNode(this.ownerDocument, n), next);
9694
+ }
9695
+ before(...nodes) {
9696
+ const parent = this._parent;
9697
+ if (!parent) return;
9698
+ for (const n of nodes) parent.insertBefore(toNode(this.ownerDocument, n), this);
9699
+ }
9700
+ after(...nodes) {
9701
+ const parent = this._parent;
9702
+ if (!parent) return;
9703
+ const next = this._next;
9704
+ for (const n of nodes) parent.insertBefore(toNode(this.ownerDocument, n), next);
9705
+ }
9706
+ append(...nodes) {
9707
+ for (const n of nodes) this.appendChild(toNode(this.ownerDocument, n));
9708
+ }
9709
+ prepend(...nodes) {
9710
+ const first = this._first;
9711
+ for (const n of nodes) this.insertBefore(toNode(this.ownerDocument, n), first);
9712
+ }
9713
+ replaceChildren(...nodes) {
9714
+ while (this._first) this.removeChild(this._first);
9715
+ this.append(...nodes);
9716
+ }
9717
+ get children() {
9718
+ const list = new ServerNodeList();
9719
+ for (let n = this._first; n; n = n._next) if (n.nodeType === ELEMENT_NODE) list.push(n);
9720
+ return list;
9721
+ }
9722
+ get childElementCount() {
9723
+ let c = 0;
9724
+ for (let n = this._first; n; n = n._next) if (n.nodeType === ELEMENT_NODE) c++;
9725
+ return c;
9726
+ }
9727
+ get firstElementChild() {
9728
+ for (let n = this._first; n; n = n._next) if (n.nodeType === ELEMENT_NODE) return n;
9729
+ return null;
9730
+ }
9731
+ get lastElementChild() {
9732
+ for (let n = this._last; n; n = n._prev) if (n.nodeType === ELEMENT_NODE) return n;
9733
+ return null;
9734
+ }
9735
+ get nextElementSibling() {
9736
+ for (let n = this._next; n; n = n._next) if (n.nodeType === ELEMENT_NODE) return n;
9737
+ return null;
9738
+ }
9739
+ get previousElementSibling() {
9740
+ for (let n = this._prev; n; n = n._prev) if (n.nodeType === ELEMENT_NODE) return n;
9741
+ return null;
9742
+ }
9743
+ querySelector(selector) {
9744
+ const sel = compileSelector(selector);
9745
+ let found = null;
9746
+ walkElements(this, (el) => {
9747
+ if (matchesCompiled(el, sel, this)) {
9748
+ found = el;
9749
+ return true;
9750
+ }
9751
+ return false;
9752
+ });
9753
+ return found;
9754
+ }
9755
+ querySelectorAll(selector) {
9756
+ const sel = compileSelector(selector);
9757
+ const out = new ServerNodeList();
9758
+ walkElements(this, (el) => {
9759
+ if (matchesCompiled(el, sel, this)) out.push(el);
9760
+ return false;
9761
+ });
9762
+ return out;
9763
+ }
9764
+ getElementsByTagName(name) {
9765
+ return this.querySelectorAll(name === "*" ? "*" : name);
9766
+ }
9767
+ getElementsByClassName(names) {
9768
+ const selector = names.trim().split(/\s+/).filter(Boolean).map((n) => `.${n}`).join("");
9769
+ return selector ? this.querySelectorAll(selector) : new ServerNodeList();
9770
+ }
9771
+ cloneNode(deep = false) {
9772
+ const copy = this._shallowClone();
9773
+ if (deep) for (let n = this._first; n; n = n._next) copy.appendChild(n.cloneNode(true));
9774
+ return copy;
9775
+ }
9776
+ /** @internal */
9777
+ _shallowClone() {
9778
+ return new _ServerNode(this.ownerDocument);
9779
+ }
9780
+ isEqualNode(other) {
9781
+ return !!other && serializeForDebug(this) === serializeForDebug(other);
9782
+ }
9783
+ isSameNode(other) {
9784
+ return other === this;
9785
+ }
9786
+ normalize() {
9787
+ for (let n = this._first; n; ) {
9788
+ const next = n._next;
9789
+ if (n.nodeType === TEXT_NODE) {
9790
+ const text2 = n;
9791
+ if (text2.data === "") this.removeChild(n);
9792
+ else
9793
+ while (text2._next && text2._next.nodeType === TEXT_NODE) {
9794
+ text2.data += text2._next.data;
9795
+ this.removeChild(text2._next);
9796
+ }
9797
+ } else n.normalize();
9798
+ n = n._parent === this ? n._next : next;
9799
+ }
9800
+ }
9801
+ // ── EventTarget ──
9802
+ addEventListener(type, fn, options) {
9803
+ if (!fn) return;
9804
+ const capture = typeof options === "boolean" ? options : !!options?.capture;
9805
+ const once = typeof options === "object" && !!options?.once;
9806
+ const map2 = this._listeners ?? (this._listeners = /* @__PURE__ */ new Map());
9807
+ const list = map2.get(type) ?? [];
9808
+ if (list.some((l) => l.fn === fn && l.capture === capture)) return;
9809
+ list.push({ fn, capture, once });
9810
+ map2.set(type, list);
9811
+ const signal2 = typeof options === "object" ? options?.signal : void 0;
9812
+ signal2?.addEventListener("abort", () => this.removeEventListener(type, fn, options), { once: true });
9813
+ }
9814
+ removeEventListener(type, fn, options) {
9815
+ const list = this._listeners?.get(type);
9816
+ if (!list || !fn) return;
9817
+ const capture = typeof options === "boolean" ? options : !!options?.capture;
9818
+ const i2 = list.findIndex((l) => l.fn === fn && l.capture === capture);
9819
+ if (i2 !== -1) list.splice(i2, 1);
9820
+ }
9821
+ dispatchEvent(event) {
9822
+ const ev = event;
9823
+ let stopped = false;
9824
+ let stoppedNow = false;
9825
+ const ownStop = ev.stopPropagation.bind(ev);
9826
+ const ownStopNow = ev.stopImmediatePropagation.bind(ev);
9827
+ defineOwn(ev, "stopPropagation", () => {
9828
+ stopped = true;
9829
+ ownStop();
9830
+ });
9831
+ defineOwn(ev, "stopImmediatePropagation", () => {
9832
+ stopped = true;
9833
+ stoppedNow = true;
9834
+ ownStopNow();
9835
+ });
9836
+ defineOwn(ev, "target", this);
9837
+ const path2 = [];
9838
+ for (let n = this; n; n = n._parent) path2.push(n);
9839
+ const phase = (node, capture) => {
9840
+ const list = node._listeners?.get(ev.type);
9841
+ if (!list) return;
9842
+ defineOwn(ev, "currentTarget", node);
9843
+ for (const l of list.slice()) {
9844
+ if (capture !== null && l.capture !== capture) continue;
9845
+ if (l.once) node.removeEventListener(ev.type, l.fn, l.capture);
9846
+ if (typeof l.fn === "function") l.fn.call(node, event);
9847
+ else l.fn.handleEvent(event);
9848
+ if (stoppedNow) return;
9849
+ }
9850
+ };
9851
+ for (let i2 = path2.length - 1; i2 > 0 && !stopped; i2--) phase(path2[i2], true);
9852
+ if (!stopped) phase(this, null);
9853
+ if (ev.bubbles) for (let i2 = 1; i2 < path2.length && !stopped; i2++) phase(path2[i2], false);
9854
+ defineOwn(ev, "currentTarget", null);
9855
+ return !ev.defaultPrevented;
9856
+ }
9857
+ };
9858
+ _ServerNode.ELEMENT_NODE = ELEMENT_NODE;
9859
+ _ServerNode.ATTRIBUTE_NODE = ATTRIBUTE_NODE;
9860
+ _ServerNode.TEXT_NODE = TEXT_NODE;
9861
+ _ServerNode.COMMENT_NODE = COMMENT_NODE;
9862
+ _ServerNode.DOCUMENT_NODE = DOCUMENT_NODE;
9863
+ _ServerNode.DOCUMENT_FRAGMENT_NODE = DOCUMENT_FRAGMENT_NODE;
9864
+ _ServerNode.DOCUMENT_POSITION_DISCONNECTED = 1;
9865
+ _ServerNode.DOCUMENT_POSITION_PRECEDING = 2;
9866
+ _ServerNode.DOCUMENT_POSITION_FOLLOWING = 4;
9867
+ _ServerNode.DOCUMENT_POSITION_CONTAINS = 8;
9868
+ _ServerNode.DOCUMENT_POSITION_CONTAINED_BY = 16;
9869
+ var ServerNode = _ServerNode;
9870
+ function defineOwn(obj, key, value) {
9871
+ Object.defineProperty(obj, key, { value, configurable: true, writable: true });
9042
9872
  }
9043
- function attributesOf(el) {
9873
+ function toNode(doc, n) {
9874
+ return typeof n === "string" ? new ServerText(doc, n) : n;
9875
+ }
9876
+ function walkElements(root, visit) {
9877
+ for (let n = root._first; n; n = n._next) {
9878
+ if (n.nodeType === ELEMENT_NODE) {
9879
+ if (visit(n)) return true;
9880
+ if (walkElements(n, visit)) return true;
9881
+ } else if (n.nodeType === DOCUMENT_FRAGMENT_NODE && walkElements(n, visit)) return true;
9882
+ }
9883
+ return false;
9884
+ }
9885
+ var ServerCharacterData = class extends ServerNode {
9886
+ constructor(doc, data2) {
9887
+ super(doc);
9888
+ this._data = data2;
9889
+ }
9890
+ get data() {
9891
+ return this._data;
9892
+ }
9893
+ set data(value) {
9894
+ const old = this._data;
9895
+ this._data = value == null ? "" : String(value);
9896
+ if (observations.length > 0) {
9897
+ queueRecord({
9898
+ type: "characterData",
9899
+ target: this,
9900
+ addedNodes: [],
9901
+ removedNodes: [],
9902
+ previousSibling: null,
9903
+ nextSibling: null,
9904
+ attributeName: null,
9905
+ attributeNamespace: null,
9906
+ oldValue: old
9907
+ });
9908
+ }
9909
+ }
9910
+ get length() {
9911
+ return this._data.length;
9912
+ }
9913
+ get nodeValue() {
9914
+ return this._data;
9915
+ }
9916
+ set nodeValue(value) {
9917
+ this.data = value ?? "";
9918
+ }
9919
+ get textContent() {
9920
+ return this._data;
9921
+ }
9922
+ set textContent(value) {
9923
+ this.data = value ?? "";
9924
+ }
9925
+ appendChild(_node) {
9926
+ throw new TypeError("This node type does not support this method.");
9927
+ }
9928
+ insertBefore(_node, _ref) {
9929
+ throw new TypeError("This node type does not support this method.");
9930
+ }
9931
+ };
9932
+ var ServerText = class _ServerText extends ServerCharacterData {
9933
+ get nodeType() {
9934
+ return TEXT_NODE;
9935
+ }
9936
+ get nodeName() {
9937
+ return "#text";
9938
+ }
9939
+ get wholeText() {
9940
+ return this._data;
9941
+ }
9942
+ splitText(offset) {
9943
+ const rest = new _ServerText(this.ownerDocument, this._data.slice(offset));
9944
+ this.data = this._data.slice(0, offset);
9945
+ this._parent?.insertBefore(rest, this._next);
9946
+ return rest;
9947
+ }
9948
+ _shallowClone() {
9949
+ return new _ServerText(this.ownerDocument, this._data);
9950
+ }
9951
+ };
9952
+ var ServerComment = class _ServerComment extends ServerCharacterData {
9953
+ get nodeType() {
9954
+ return COMMENT_NODE;
9955
+ }
9956
+ get nodeName() {
9957
+ return "#comment";
9958
+ }
9959
+ _shallowClone() {
9960
+ return new _ServerComment(this.ownerDocument, this._data);
9961
+ }
9962
+ };
9963
+ var ServerDocumentFragment = class _ServerDocumentFragment extends ServerNode {
9964
+ get nodeType() {
9965
+ return DOCUMENT_FRAGMENT_NODE;
9966
+ }
9967
+ get nodeName() {
9968
+ return "#document-fragment";
9969
+ }
9970
+ getElementById(id) {
9971
+ return this.querySelector(`#${cssEscapeIdent(id)}`);
9972
+ }
9973
+ _shallowClone() {
9974
+ return new _ServerDocumentFragment(this.ownerDocument);
9975
+ }
9976
+ };
9977
+ var ServerAttr = class {
9978
+ constructor(ownerElement, namespaceURI, prefix, localName, value) {
9979
+ this.ownerElement = ownerElement;
9980
+ this.namespaceURI = namespaceURI;
9981
+ this.prefix = prefix;
9982
+ this.localName = localName;
9983
+ this.nodeType = ATTRIBUTE_NODE;
9984
+ this.specified = true;
9985
+ this._value = value;
9986
+ }
9987
+ get name() {
9988
+ return this.prefix ? `${this.prefix}:${this.localName}` : this.localName;
9989
+ }
9990
+ get nodeName() {
9991
+ return this.name;
9992
+ }
9993
+ get value() {
9994
+ return this._value;
9995
+ }
9996
+ set value(v) {
9997
+ if (this.ownerElement) this.ownerElement.setAttributeNS(this.namespaceURI, this.name, v);
9998
+ else this._value = String(v);
9999
+ }
10000
+ get nodeValue() {
10001
+ return this._value;
10002
+ }
10003
+ get textContent() {
10004
+ return this._value;
10005
+ }
10006
+ };
10007
+ var ServerNamedNodeMap = class extends Array {
10008
+ static get [Symbol.species]() {
10009
+ return Array;
10010
+ }
10011
+ item(index) {
10012
+ return this[index] ?? null;
10013
+ }
10014
+ getNamedItem(name) {
10015
+ return this.find((a2) => a2.name === name) ?? null;
10016
+ }
10017
+ getNamedItemNS(ns, localName) {
10018
+ return this.find((a2) => a2.namespaceURI === (ns || null) && a2.localName === localName) ?? null;
10019
+ }
10020
+ };
10021
+ function splitDeclarations(text2) {
10022
+ const out = [];
10023
+ let depth = 0;
10024
+ let quote2 = "";
10025
+ let start = 0;
10026
+ for (let i2 = 0; i2 < text2.length; i2++) {
10027
+ const c = text2[i2];
10028
+ if (quote2) {
10029
+ if (c === "\\") i2++;
10030
+ else if (c === quote2) quote2 = "";
10031
+ } else if (c === '"' || c === "'") quote2 = c;
10032
+ else if (c === "(") depth++;
10033
+ else if (c === ")") depth = Math.max(0, depth - 1);
10034
+ else if (c === ";" && depth === 0) {
10035
+ out.push(text2.slice(start, i2));
10036
+ start = i2 + 1;
10037
+ }
10038
+ }
10039
+ out.push(text2.slice(start));
10040
+ return out;
10041
+ }
10042
+ var CAMEL_EXCEPTIONS = { cssFloat: "float" };
10043
+ function toKebab(prop) {
10044
+ if (prop.startsWith("--")) return prop;
10045
+ if (Object.hasOwn(CAMEL_EXCEPTIONS, prop)) return CAMEL_EXCEPTIONS[prop];
10046
+ return prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`).replace(/^(webkit|moz|ms)-/, "-$1-");
10047
+ }
10048
+ var ServerStyle = class {
10049
+ constructor(el) {
10050
+ this.el = el;
10051
+ /** @internal */
10052
+ this._decls = /* @__PURE__ */ new Map();
10053
+ /** @internal */
10054
+ this._parsedFrom = null;
10055
+ }
10056
+ /** @internal */
10057
+ _sync() {
10058
+ const attr = this.el.getAttribute("style");
10059
+ if (attr === this._parsedFrom) return;
10060
+ this._decls = /* @__PURE__ */ new Map();
10061
+ this._parsedFrom = attr;
10062
+ if (!attr) return;
10063
+ for (const decl of splitDeclarations(attr)) {
10064
+ const colon = decl.indexOf(":");
10065
+ if (colon === -1) continue;
10066
+ const name = decl.slice(0, colon).trim();
10067
+ let value = decl.slice(colon + 1).trim();
10068
+ if (!name || !value) continue;
10069
+ let priority = "";
10070
+ const bang = value.lastIndexOf("!");
10071
+ if (bang !== -1 && /^!\s*important$/i.test(value.slice(bang))) {
10072
+ priority = "important";
10073
+ value = value.slice(0, bang).trim();
10074
+ }
10075
+ this._decls.set(name.startsWith("--") ? name : name.toLowerCase(), { value, priority });
10076
+ }
10077
+ }
10078
+ /** @internal */
10079
+ _commit() {
10080
+ const text2 = this.cssText;
10081
+ this._parsedFrom = text2 === "" ? null : text2;
10082
+ if (text2 === "") this.el.removeAttribute("style");
10083
+ else this.el.setAttribute("style", text2);
10084
+ this._parsedFrom = this.el.getAttribute("style");
10085
+ }
10086
+ get cssText() {
10087
+ this._sync();
10088
+ const parts = [];
10089
+ for (const [name, d] of this._decls) parts.push(`${name}: ${d.value}${d.priority ? " !important" : ""};`);
10090
+ return parts.join(" ");
10091
+ }
10092
+ set cssText(text2) {
10093
+ this.el.setAttribute("style", String(text2 ?? ""));
10094
+ this._sync();
10095
+ if (this._decls.size === 0) this.el.removeAttribute("style");
10096
+ else this._commit();
10097
+ }
10098
+ get length() {
10099
+ this._sync();
10100
+ return this._decls.size;
10101
+ }
10102
+ item(index) {
10103
+ this._sync();
10104
+ return Array.from(this._decls.keys())[index] ?? "";
10105
+ }
10106
+ getPropertyValue(name) {
10107
+ this._sync();
10108
+ return this._decls.get(name.startsWith("--") ? name : name.toLowerCase())?.value ?? "";
10109
+ }
10110
+ getPropertyPriority(name) {
10111
+ this._sync();
10112
+ return this._decls.get(name.startsWith("--") ? name : name.toLowerCase())?.priority ?? "";
10113
+ }
10114
+ setProperty(name, value, priority = "") {
10115
+ this._sync();
10116
+ const key = name.startsWith("--") ? name : name.toLowerCase();
10117
+ const v = value == null ? "" : String(value).trim();
10118
+ if (v === "") {
10119
+ this.removeProperty(key);
10120
+ return;
10121
+ }
10122
+ this._decls.set(key, { value: v, priority: priority === "important" ? "important" : "" });
10123
+ this._commit();
10124
+ }
10125
+ removeProperty(name) {
10126
+ this._sync();
10127
+ const key = name.startsWith("--") ? name : name.toLowerCase();
10128
+ const old = this._decls.get(key)?.value ?? "";
10129
+ if (this._decls.delete(key)) this._commit();
10130
+ return old;
10131
+ }
10132
+ *[Symbol.iterator]() {
10133
+ this._sync();
10134
+ yield* this._decls.keys();
10135
+ }
10136
+ };
10137
+ function styleProxy(style2) {
10138
+ return new Proxy(style2, {
10139
+ get(target, key, receiver) {
10140
+ if (typeof key === "string" && !(key in target)) {
10141
+ if (/^\d+$/.test(key)) return target.item(Number(key));
10142
+ return target.getPropertyValue(toKebab(key));
10143
+ }
10144
+ return Reflect.get(target, key, receiver);
10145
+ },
10146
+ set(target, key, value, receiver) {
10147
+ if (typeof key === "string" && !(key in target)) {
10148
+ target.setProperty(toKebab(key), value == null ? "" : String(value));
10149
+ return true;
10150
+ }
10151
+ return Reflect.set(target, key, value, receiver);
10152
+ }
10153
+ });
10154
+ }
10155
+ var ServerTokenList = class {
10156
+ constructor(el, attr) {
10157
+ this.el = el;
10158
+ this.attr = attr;
10159
+ }
10160
+ tokens() {
10161
+ return (this.el.getAttribute(this.attr) ?? "").split(/\s+/).filter(Boolean);
10162
+ }
10163
+ write(tokens) {
10164
+ this.el.setAttribute(this.attr, Array.from(new Set(tokens)).join(" "));
10165
+ }
10166
+ get length() {
10167
+ return new Set(this.tokens()).size;
10168
+ }
10169
+ get value() {
10170
+ return this.el.getAttribute(this.attr) ?? "";
10171
+ }
10172
+ set value(v) {
10173
+ this.el.setAttribute(this.attr, v);
10174
+ }
10175
+ item(i2) {
10176
+ return Array.from(new Set(this.tokens()))[i2] ?? null;
10177
+ }
10178
+ contains(token) {
10179
+ return this.tokens().includes(token);
10180
+ }
10181
+ add(...tokens) {
10182
+ this.write([...this.tokens(), ...tokens]);
10183
+ }
10184
+ remove(...tokens) {
10185
+ this.write(this.tokens().filter((t) => !tokens.includes(t)));
10186
+ }
10187
+ toggle(token, force) {
10188
+ const has = this.contains(token);
10189
+ const want = force === void 0 ? !has : force;
10190
+ if (want && !has) this.add(token);
10191
+ else if (!want && has) this.remove(token);
10192
+ return want;
10193
+ }
10194
+ replace(oldToken, newToken) {
10195
+ const tokens = this.tokens();
10196
+ const i2 = tokens.indexOf(oldToken);
10197
+ if (i2 === -1) return false;
10198
+ tokens[i2] = newToken;
10199
+ this.write(tokens);
10200
+ return true;
10201
+ }
10202
+ forEach(fn) {
10203
+ Array.from(new Set(this.tokens())).forEach(fn);
10204
+ }
10205
+ [Symbol.iterator]() {
10206
+ return new Set(this.tokens()).values();
10207
+ }
10208
+ toString() {
10209
+ return this.value;
10210
+ }
10211
+ };
10212
+ function datasetKeyToAttr(key) {
10213
+ return `data-${key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)}`;
10214
+ }
10215
+ var ServerElement = class _ServerElement extends ServerNode {
10216
+ constructor(doc, localName, namespaceURI, prefix = null) {
10217
+ super(doc);
10218
+ this.localName = localName;
10219
+ this.namespaceURI = namespaceURI;
10220
+ this.prefix = prefix;
10221
+ /** @internal */
10222
+ this._attrs = new ServerNamedNodeMap();
10223
+ /** @internal */
10224
+ this._style = null;
10225
+ /** @internal */
10226
+ this._classList = null;
10227
+ this.scrollTop = 0;
10228
+ this.scrollLeft = 0;
10229
+ }
10230
+ get nodeType() {
10231
+ return ELEMENT_NODE;
10232
+ }
10233
+ get isHtml() {
10234
+ return this.namespaceURI === HTML_NS3;
10235
+ }
10236
+ get tagName() {
10237
+ const q2 = this.prefix ? `${this.prefix}:${this.localName}` : this.localName;
10238
+ return this.isHtml ? q2.toUpperCase() : q2;
10239
+ }
10240
+ get nodeName() {
10241
+ return this.tagName;
10242
+ }
10243
+ get attributes() {
10244
+ return this._attrs;
10245
+ }
10246
+ findAttr(name) {
10247
+ const n = this.isHtml ? name.toLowerCase() : name;
10248
+ return this._attrs.find((a2) => a2.name === n);
10249
+ }
10250
+ getAttribute(name) {
10251
+ return this.findAttr(String(name))?.value ?? null;
10252
+ }
10253
+ getAttributeNames() {
10254
+ return this._attrs.map((a2) => a2.name);
10255
+ }
10256
+ hasAttribute(name) {
10257
+ return this.findAttr(String(name)) !== void 0;
10258
+ }
10259
+ hasAttributes() {
10260
+ return this._attrs.length > 0;
10261
+ }
10262
+ setAttribute(name, value) {
10263
+ name = String(name);
10264
+ if (!NAME_RE.test(name)) invalidCharacter(name);
10265
+ const v = String(value);
10266
+ const existing = this.findAttr(name);
10267
+ const old = existing ? existing._value : null;
10268
+ if (existing) existing._value = v;
10269
+ else this._attrs.push(new ServerAttr(this, null, null, this.isHtml ? name.toLowerCase() : name, v));
10270
+ this._recordAttr(this.isHtml ? name.toLowerCase() : name, null, old);
10271
+ }
10272
+ removeAttribute(name) {
10273
+ const attr = this.findAttr(String(name));
10274
+ if (!attr) return;
10275
+ this._attrs.splice(this._attrs.indexOf(attr), 1);
10276
+ this._recordAttr(attr.name, attr.namespaceURI, attr._value);
10277
+ }
10278
+ toggleAttribute(name, force) {
10279
+ const has = this.hasAttribute(name);
10280
+ const want = force === void 0 ? !has : force;
10281
+ if (want && !has) this.setAttribute(name, "");
10282
+ else if (!want && has) this.removeAttribute(name);
10283
+ return want;
10284
+ }
10285
+ getAttributeNS(ns, localName) {
10286
+ return this._attrs.getNamedItemNS(ns, localName)?.value ?? null;
10287
+ }
10288
+ hasAttributeNS(ns, localName) {
10289
+ return this._attrs.getNamedItemNS(ns, localName) !== null;
10290
+ }
10291
+ setAttributeNS(ns, qualifiedName, value) {
10292
+ if (!NAME_RE.test(qualifiedName)) invalidCharacter(qualifiedName);
10293
+ const colon = qualifiedName.indexOf(":");
10294
+ const prefix = colon === -1 ? null : qualifiedName.slice(0, colon);
10295
+ const localName = colon === -1 ? qualifiedName : qualifiedName.slice(colon + 1);
10296
+ const namespace = ns || null;
10297
+ if (namespace === null) {
10298
+ this.setAttribute(qualifiedName, value);
10299
+ return;
10300
+ }
10301
+ const existing = this._attrs.getNamedItemNS(namespace, localName);
10302
+ const old = existing ? existing._value : null;
10303
+ if (existing) existing._value = String(value);
10304
+ else this._attrs.push(new ServerAttr(this, namespace, prefix, localName, String(value)));
10305
+ this._recordAttr(localName, namespace, old);
10306
+ }
10307
+ removeAttributeNS(ns, localName) {
10308
+ const attr = this._attrs.getNamedItemNS(ns, localName);
10309
+ if (!attr) return;
10310
+ this._attrs.splice(this._attrs.indexOf(attr), 1);
10311
+ this._recordAttr(localName, attr.namespaceURI, attr._value);
10312
+ }
10313
+ getAttributeNode(name) {
10314
+ return this.findAttr(name) ?? null;
10315
+ }
10316
+ /** @internal */
10317
+ _recordAttr(name, ns, oldValue) {
10318
+ if (observations.length === 0) return;
10319
+ queueRecord({
10320
+ type: "attributes",
10321
+ target: this,
10322
+ addedNodes: [],
10323
+ removedNodes: [],
10324
+ previousSibling: null,
10325
+ nextSibling: null,
10326
+ attributeName: name,
10327
+ attributeNamespace: ns,
10328
+ oldValue
10329
+ });
10330
+ }
10331
+ get id() {
10332
+ return this.getAttribute("id") ?? "";
10333
+ }
10334
+ set id(v) {
10335
+ this.setAttribute("id", v);
10336
+ }
10337
+ get className() {
10338
+ return this.getAttribute("class") ?? "";
10339
+ }
10340
+ set className(v) {
10341
+ this.setAttribute("class", v);
10342
+ }
10343
+ get classList() {
10344
+ this._classList ?? (this._classList = new ServerTokenList(this, "class"));
10345
+ return this._classList;
10346
+ }
10347
+ get style() {
10348
+ this._style ?? (this._style = styleProxy(new ServerStyle(this)));
10349
+ return this._style;
10350
+ }
10351
+ set style(v) {
10352
+ this.style.cssText = v;
10353
+ }
10354
+ get dataset() {
10355
+ return new Proxy(
10356
+ {},
10357
+ {
10358
+ get: (_t, key) => typeof key === "string" ? this.getAttribute(datasetKeyToAttr(key)) ?? void 0 : void 0,
10359
+ set: (_t, key, value) => {
10360
+ if (typeof key === "string") this.setAttribute(datasetKeyToAttr(key), String(value));
10361
+ return true;
10362
+ },
10363
+ deleteProperty: (_t, key) => {
10364
+ if (typeof key === "string") this.removeAttribute(datasetKeyToAttr(key));
10365
+ return true;
10366
+ },
10367
+ has: (_t, key) => typeof key === "string" && this.hasAttribute(datasetKeyToAttr(key)),
10368
+ ownKeys: () => this._attrs.filter((a2) => a2.name.startsWith("data-")).map((a2) => a2.name.slice(5).replace(/-([a-z])/g, (_m, c) => c.toUpperCase())),
10369
+ getOwnPropertyDescriptor: (_t, key) => typeof key === "string" && this.hasAttribute(datasetKeyToAttr(key)) ? { enumerable: true, configurable: true, value: this.getAttribute(datasetKeyToAttr(key)) } : void 0
10370
+ }
10371
+ );
10372
+ }
10373
+ get innerHTML() {
10374
+ let out = "";
10375
+ for (let n = this._first; n; n = n._next) out += serializeForDebug(n);
10376
+ return out;
10377
+ }
10378
+ set innerHTML(_value) {
10379
+ unavailable("Element.innerHTML assignment (the server DOM has no HTML parser)");
10380
+ }
10381
+ get outerHTML() {
10382
+ return serializeForDebug(this);
10383
+ }
10384
+ insertAdjacentHTML() {
10385
+ unavailable("Element.insertAdjacentHTML()");
10386
+ }
10387
+ matches(selector) {
10388
+ return matchesCompiled(this, compileSelector(selector), null);
10389
+ }
10390
+ closest(selector) {
10391
+ const sel = compileSelector(selector);
10392
+ for (let n = this; n; n = n._parent) {
10393
+ if (n instanceof _ServerElement && matchesCompiled(n, sel, null)) return n;
10394
+ }
10395
+ return null;
10396
+ }
10397
+ // ── Layout and focus: no-ops on a server ──
10398
+ focus() {
10399
+ }
10400
+ blur() {
10401
+ }
10402
+ click() {
10403
+ const Ctor = globalThis.Event;
10404
+ if (Ctor) this.dispatchEvent(new Ctor("click", { bubbles: true, cancelable: true }));
10405
+ }
10406
+ scrollIntoView() {
10407
+ }
10408
+ scrollTo() {
10409
+ }
10410
+ scrollBy() {
10411
+ }
10412
+ getBoundingClientRect() {
10413
+ return { x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0, toJSON: () => ({}) };
10414
+ }
10415
+ getClientRects() {
10416
+ return [];
10417
+ }
10418
+ get offsetWidth() {
10419
+ return 0;
10420
+ }
10421
+ get offsetHeight() {
10422
+ return 0;
10423
+ }
10424
+ get offsetTop() {
10425
+ return 0;
10426
+ }
10427
+ get offsetLeft() {
10428
+ return 0;
10429
+ }
10430
+ get offsetParent() {
10431
+ return null;
10432
+ }
10433
+ get clientWidth() {
10434
+ return 0;
10435
+ }
10436
+ get clientHeight() {
10437
+ return 0;
10438
+ }
10439
+ get scrollWidth() {
10440
+ return 0;
10441
+ }
10442
+ get scrollHeight() {
10443
+ return 0;
10444
+ }
10445
+ // ── Browser-only APIs: a clear error instead of "is not a function" ──
10446
+ animate() {
10447
+ return unavailable("Element.animate()");
10448
+ }
10449
+ getAnimations() {
10450
+ return unavailable("Element.getAnimations()");
10451
+ }
10452
+ attachShadow() {
10453
+ return unavailable("Element.attachShadow()");
10454
+ }
10455
+ requestFullscreen() {
10456
+ return unavailable("Element.requestFullscreen()");
10457
+ }
10458
+ requestPointerLock() {
10459
+ return unavailable("Element.requestPointerLock()");
10460
+ }
10461
+ setPointerCapture() {
10462
+ return unavailable("Element.setPointerCapture()");
10463
+ }
10464
+ _shallowClone() {
10465
+ const copy = this.ownerDocument ? this.ownerDocument.createElementNS(
10466
+ this.namespaceURI,
10467
+ this.prefix ? `${this.prefix}:${this.localName}` : this.localName
10468
+ ) : new _ServerElement(null, this.localName, this.namespaceURI, this.prefix);
10469
+ for (const a2 of this._attrs)
10470
+ copy._attrs.push(new ServerAttr(copy, a2.namespaceURI, a2.prefix, a2.localName, a2._value));
10471
+ return copy;
10472
+ }
10473
+ };
10474
+ var ServerHTMLElement = class extends ServerElement {
10475
+ get hidden() {
10476
+ return this.hasAttribute("hidden");
10477
+ }
10478
+ set hidden(v) {
10479
+ this.toggleAttribute("hidden", !!v);
10480
+ }
10481
+ get title() {
10482
+ return this.getAttribute("title") ?? "";
10483
+ }
10484
+ set title(v) {
10485
+ this.setAttribute("title", v);
10486
+ }
10487
+ get lang() {
10488
+ return this.getAttribute("lang") ?? "";
10489
+ }
10490
+ set lang(v) {
10491
+ this.setAttribute("lang", v);
10492
+ }
10493
+ get dir() {
10494
+ return this.getAttribute("dir") ?? "";
10495
+ }
10496
+ set dir(v) {
10497
+ this.setAttribute("dir", v);
10498
+ }
10499
+ get tabIndex() {
10500
+ const v = Number.parseInt(this.getAttribute("tabindex") ?? "", 10);
10501
+ return Number.isNaN(v) ? -1 : v;
10502
+ }
10503
+ set tabIndex(v) {
10504
+ this.setAttribute("tabindex", String(v));
10505
+ }
10506
+ get innerText() {
10507
+ return this.textContent ?? "";
10508
+ }
10509
+ set innerText(v) {
10510
+ this.textContent = v;
10511
+ }
10512
+ };
10513
+ function reflectDisabled(proto) {
10514
+ Object.defineProperty(proto, "disabled", {
10515
+ get() {
10516
+ return this.hasAttribute("disabled");
10517
+ },
10518
+ set(v) {
10519
+ this.toggleAttribute("disabled", !!v);
10520
+ },
10521
+ configurable: true
10522
+ });
10523
+ }
10524
+ var ServerInputElement = class extends ServerHTMLElement {
10525
+ constructor() {
10526
+ super(...arguments);
10527
+ /** @internal */
10528
+ this._value = null;
10529
+ /** @internal */
10530
+ this._checked = null;
10531
+ }
10532
+ get value() {
10533
+ return this._value ?? this.getAttribute("value") ?? "";
10534
+ }
10535
+ set value(v) {
10536
+ this._value = v == null ? "" : String(v);
10537
+ }
10538
+ get defaultValue() {
10539
+ return this.getAttribute("value") ?? "";
10540
+ }
10541
+ set defaultValue(v) {
10542
+ this.setAttribute("value", v);
10543
+ }
10544
+ get checked() {
10545
+ return this._checked ?? this.hasAttribute("checked");
10546
+ }
10547
+ set checked(v) {
10548
+ this._checked = !!v;
10549
+ }
10550
+ get defaultChecked() {
10551
+ return this.hasAttribute("checked");
10552
+ }
10553
+ get type() {
10554
+ return (this.getAttribute("type") ?? "text").toLowerCase();
10555
+ }
10556
+ set type(v) {
10557
+ this.setAttribute("type", v);
10558
+ }
10559
+ get name() {
10560
+ return this.getAttribute("name") ?? "";
10561
+ }
10562
+ set name(v) {
10563
+ this.setAttribute("name", v);
10564
+ }
10565
+ select() {
10566
+ }
10567
+ setSelectionRange() {
10568
+ }
10569
+ checkValidity() {
10570
+ return true;
10571
+ }
10572
+ reportValidity() {
10573
+ return true;
10574
+ }
10575
+ };
10576
+ reflectDisabled(ServerInputElement.prototype);
10577
+ var ServerTextAreaElement = class extends ServerHTMLElement {
10578
+ constructor() {
10579
+ super(...arguments);
10580
+ /** @internal */
10581
+ this._value = null;
10582
+ }
10583
+ get value() {
10584
+ return this._value ?? this.textContent ?? "";
10585
+ }
10586
+ set value(v) {
10587
+ this._value = v == null ? "" : String(v);
10588
+ }
10589
+ get defaultValue() {
10590
+ return this.textContent ?? "";
10591
+ }
10592
+ set defaultValue(v) {
10593
+ this.textContent = v;
10594
+ }
10595
+ get name() {
10596
+ return this.getAttribute("name") ?? "";
10597
+ }
10598
+ set name(v) {
10599
+ this.setAttribute("name", v);
10600
+ }
10601
+ select() {
10602
+ }
10603
+ setSelectionRange() {
10604
+ }
10605
+ };
10606
+ reflectDisabled(ServerTextAreaElement.prototype);
10607
+ var ServerOptionElement = class extends ServerHTMLElement {
10608
+ constructor() {
10609
+ super(...arguments);
10610
+ /** @internal */
10611
+ this._selected = null;
10612
+ }
10613
+ get value() {
10614
+ return this.getAttribute("value") ?? this.text;
10615
+ }
10616
+ set value(v) {
10617
+ this.setAttribute("value", v);
10618
+ }
10619
+ get text() {
10620
+ return (this.textContent ?? "").replace(/\s+/g, " ").trim();
10621
+ }
10622
+ set text(v) {
10623
+ this.textContent = v;
10624
+ }
10625
+ get label() {
10626
+ return this.getAttribute("label") ?? this.text;
10627
+ }
10628
+ get selected() {
10629
+ return this._selected ?? this.hasAttribute("selected");
10630
+ }
10631
+ set selected(v) {
10632
+ this._selected = !!v;
10633
+ }
10634
+ get defaultSelected() {
10635
+ return this.hasAttribute("selected");
10636
+ }
10637
+ };
10638
+ reflectDisabled(ServerOptionElement.prototype);
10639
+ var ServerSelectElement = class extends ServerHTMLElement {
10640
+ get options() {
10641
+ return this.querySelectorAll("option");
10642
+ }
10643
+ get selectedIndex() {
10644
+ const opts = this.options;
10645
+ for (let i2 = 0; i2 < opts.length; i2++) if (opts[i2].selected) return i2;
10646
+ return opts.length > 0 && !this.hasAttribute("multiple") ? 0 : -1;
10647
+ }
10648
+ set selectedIndex(i2) {
10649
+ this.options.forEach((o, j) => {
10650
+ o.selected = j === i2;
10651
+ });
10652
+ }
10653
+ get value() {
10654
+ const i2 = this.selectedIndex;
10655
+ return i2 === -1 ? "" : this.options[i2].value;
10656
+ }
10657
+ set value(v) {
10658
+ this.options.forEach((o) => {
10659
+ o.selected = o.value === String(v);
10660
+ });
10661
+ }
10662
+ get name() {
10663
+ return this.getAttribute("name") ?? "";
10664
+ }
10665
+ set name(v) {
10666
+ this.setAttribute("name", v);
10667
+ }
10668
+ };
10669
+ reflectDisabled(ServerSelectElement.prototype);
10670
+ var ServerButtonElement = class extends ServerHTMLElement {
10671
+ get type() {
10672
+ return (this.getAttribute("type") ?? "submit").toLowerCase();
10673
+ }
10674
+ set type(v) {
10675
+ this.setAttribute("type", v);
10676
+ }
10677
+ get value() {
10678
+ return this.getAttribute("value") ?? "";
10679
+ }
10680
+ set value(v) {
10681
+ this.setAttribute("value", v);
10682
+ }
10683
+ };
10684
+ reflectDisabled(ServerButtonElement.prototype);
10685
+ var ServerDisableableElement = class extends ServerHTMLElement {
10686
+ };
10687
+ reflectDisabled(ServerDisableableElement.prototype);
10688
+ var ServerCanvasElement = class extends ServerHTMLElement {
10689
+ get width() {
10690
+ return Number(this.getAttribute("width") ?? 300);
10691
+ }
10692
+ set width(v) {
10693
+ this.setAttribute("width", String(v));
10694
+ }
10695
+ get height() {
10696
+ return Number(this.getAttribute("height") ?? 150);
10697
+ }
10698
+ set height(v) {
10699
+ this.setAttribute("height", String(v));
10700
+ }
10701
+ /** No drawing context on a server: warns and returns `null`, as a browser does for an unsupported context. */
10702
+ getContext() {
10703
+ reportBrowserApi("HTMLCanvasElement.getContext()");
10704
+ return null;
10705
+ }
10706
+ toDataURL() {
10707
+ return unavailable("HTMLCanvasElement.toDataURL()");
10708
+ }
10709
+ toBlob() {
10710
+ return unavailable("HTMLCanvasElement.toBlob()");
10711
+ }
10712
+ };
10713
+ var ServerDialogElement = class extends ServerHTMLElement {
10714
+ get open() {
10715
+ return this.hasAttribute("open");
10716
+ }
10717
+ set open(v) {
10718
+ this.toggleAttribute("open", !!v);
10719
+ }
10720
+ showModal() {
10721
+ return unavailable("HTMLDialogElement.showModal()");
10722
+ }
10723
+ show() {
10724
+ this.open = true;
10725
+ }
10726
+ close() {
10727
+ this.open = false;
10728
+ }
10729
+ };
10730
+ var ServerMediaElement = class extends ServerHTMLElement {
10731
+ play() {
10732
+ return unavailable("HTMLMediaElement.play()");
10733
+ }
10734
+ pause() {
10735
+ }
10736
+ load() {
10737
+ }
10738
+ };
10739
+ var ServerTemplateElement = class extends ServerHTMLElement {
10740
+ constructor() {
10741
+ super(...arguments);
10742
+ /** @internal */
10743
+ this._content = null;
10744
+ }
10745
+ get content() {
10746
+ this._content ?? (this._content = new ServerDocumentFragment(this.ownerDocument));
10747
+ return this._content;
10748
+ }
10749
+ };
10750
+ var ServerSVGElement = class extends ServerElement {
10751
+ };
10752
+ var ServerMathMLElement = class extends ServerElement {
10753
+ };
10754
+ var HTML_CLASSES = {
10755
+ input: ServerInputElement,
10756
+ textarea: ServerTextAreaElement,
10757
+ select: ServerSelectElement,
10758
+ option: ServerOptionElement,
10759
+ button: ServerButtonElement,
10760
+ fieldset: ServerDisableableElement,
10761
+ optgroup: ServerDisableableElement,
10762
+ canvas: ServerCanvasElement,
10763
+ dialog: ServerDialogElement,
10764
+ video: ServerMediaElement,
10765
+ audio: ServerMediaElement,
10766
+ template: ServerTemplateElement
10767
+ };
10768
+ var NODE_FILTER = {
10769
+ FILTER_ACCEPT: 1,
10770
+ FILTER_REJECT: 2,
10771
+ FILTER_SKIP: 3,
10772
+ SHOW_ALL: 4294967295,
10773
+ SHOW_ELEMENT: 1,
10774
+ SHOW_ATTRIBUTE: 2,
10775
+ SHOW_TEXT: 4,
10776
+ SHOW_COMMENT: 128,
10777
+ SHOW_DOCUMENT: 256,
10778
+ SHOW_DOCUMENT_FRAGMENT: 1024
10779
+ };
10780
+ var ServerTreeWalker = class {
10781
+ constructor(root, whatToShow, filter) {
10782
+ this.root = root;
10783
+ this.whatToShow = whatToShow;
10784
+ this.filter = filter;
10785
+ this.currentNode = root;
10786
+ }
10787
+ accept(node) {
10788
+ if (!(1 << node.nodeType - 1 & this.whatToShow)) return NODE_FILTER.FILTER_SKIP;
10789
+ if (!this.filter) return NODE_FILTER.FILTER_ACCEPT;
10790
+ return typeof this.filter === "function" ? this.filter(node) : this.filter.acceptNode(node);
10791
+ }
10792
+ nextNode() {
10793
+ let node = this.currentNode;
10794
+ for (; ; ) {
10795
+ let next = null;
10796
+ if (node._first) next = node._first;
10797
+ else {
10798
+ let n = node;
10799
+ while (n && n !== this.root && !n._next) n = n._parent;
10800
+ next = n && n !== this.root ? n._next : null;
10801
+ }
10802
+ if (!next) return null;
10803
+ node = next;
10804
+ if (this.accept(node) === NODE_FILTER.FILTER_ACCEPT) {
10805
+ this.currentNode = node;
10806
+ return node;
10807
+ }
10808
+ }
10809
+ }
10810
+ firstChild() {
10811
+ for (let n = this.currentNode._first; n; n = n._next) {
10812
+ if (this.accept(n) === NODE_FILTER.FILTER_ACCEPT) {
10813
+ this.currentNode = n;
10814
+ return n;
10815
+ }
10816
+ }
10817
+ return null;
10818
+ }
10819
+ nextSibling() {
10820
+ for (let n = this.currentNode._next; n; n = n._next) {
10821
+ if (this.accept(n) === NODE_FILTER.FILTER_ACCEPT) {
10822
+ this.currentNode = n;
10823
+ return n;
10824
+ }
10825
+ }
10826
+ return null;
10827
+ }
10828
+ parentNode() {
10829
+ const p2 = this.currentNode === this.root ? null : this.currentNode._parent;
10830
+ if (p2) this.currentNode = p2;
10831
+ return p2;
10832
+ }
10833
+ };
10834
+ var ServerDocument = class extends ServerNode {
10835
+ constructor() {
10836
+ super(null);
10837
+ this.defaultView = null;
10838
+ this.readyState = "complete";
10839
+ this.contentType = "text/html";
10840
+ this.characterSet = "UTF-8";
10841
+ this.compatMode = "CSS1Compat";
10842
+ this.visibilityState = "visible";
10843
+ this.hidden = false;
10844
+ this.cookie = "";
10845
+ this.ownerDocument = null;
10846
+ this.documentElement = this.createElement("html");
10847
+ this.head = this.createElement("head");
10848
+ this.body = this.createElement("body");
10849
+ this.documentElement.appendChild(this.head);
10850
+ this.documentElement.appendChild(this.body);
10851
+ this.appendChild(this.documentElement);
10852
+ }
10853
+ get nodeType() {
10854
+ return DOCUMENT_NODE;
10855
+ }
10856
+ get nodeName() {
10857
+ return "#document";
10858
+ }
10859
+ get activeElement() {
10860
+ return this.body;
10861
+ }
10862
+ get title() {
10863
+ return this.head.querySelector("title")?.textContent ?? "";
10864
+ }
10865
+ set title(v) {
10866
+ let el = this.head.querySelector("title");
10867
+ if (!el) {
10868
+ el = this.createElement("title");
10869
+ this.head.appendChild(el);
10870
+ }
10871
+ el.textContent = v;
10872
+ }
10873
+ /** Font loading does not exist on a server: recorded as a browser-only read, answers `undefined`. */
10874
+ get fonts() {
10875
+ reportBrowserApi("document.fonts");
10876
+ return void 0;
10877
+ }
10878
+ createElement(name) {
10879
+ name = String(name);
10880
+ if (!NAME_RE.test(name)) invalidCharacter(name);
10881
+ const local = name.toLowerCase();
10882
+ const Ctor = Object.hasOwn(HTML_CLASSES, local) ? HTML_CLASSES[local] : ServerHTMLElement;
10883
+ return new Ctor(this, local, HTML_NS3);
10884
+ }
10885
+ createElementNS(ns, qualifiedName) {
10886
+ if (!NAME_RE.test(qualifiedName)) invalidCharacter(qualifiedName);
10887
+ const namespace = ns || null;
10888
+ if (namespace === HTML_NS3) return this.createElement(qualifiedName);
10889
+ const colon = qualifiedName.indexOf(":");
10890
+ const prefix = colon === -1 ? null : qualifiedName.slice(0, colon);
10891
+ const local = colon === -1 ? qualifiedName : qualifiedName.slice(colon + 1);
10892
+ if (namespace === SVG_NS3) return new ServerSVGElement(this, local, namespace, prefix);
10893
+ if (namespace === MATHML_NS) return new ServerMathMLElement(this, local, namespace, prefix);
10894
+ return new ServerElement(this, local, namespace, prefix);
10895
+ }
10896
+ createTextNode(data2) {
10897
+ return new ServerText(this, String(data2));
10898
+ }
10899
+ createComment(data2) {
10900
+ return new ServerComment(this, String(data2));
10901
+ }
10902
+ createDocumentFragment() {
10903
+ return new ServerDocumentFragment(this);
10904
+ }
10905
+ createTreeWalker(root, whatToShow = NODE_FILTER.SHOW_ALL, filter = null) {
10906
+ return new ServerTreeWalker(root, whatToShow, filter);
10907
+ }
10908
+ createEvent() {
10909
+ return unavailable("document.createEvent() (construct `new Event(type)` instead)");
10910
+ }
10911
+ getElementById(id) {
10912
+ return this.querySelector(`#${cssEscapeIdent(id)}`);
10913
+ }
10914
+ hasFocus() {
10915
+ return false;
10916
+ }
10917
+ getSelection() {
10918
+ return null;
10919
+ }
10920
+ elementFromPoint() {
10921
+ return null;
10922
+ }
10923
+ execCommand() {
10924
+ return unavailable("document.execCommand()");
10925
+ }
10926
+ };
10927
+ var selectorCache = /* @__PURE__ */ new Map();
10928
+ function cssEscapeIdent(value) {
10929
+ return value.replace(/([^A-Za-z0-9_-])/g, "\\$1");
10930
+ }
10931
+ function unescapeIdent(value) {
10932
+ return value.replace(/\\(.)/g, "$1");
10933
+ }
10934
+ function compileSelector(selector) {
10935
+ const cached = selectorCache.get(selector);
10936
+ if (cached) return cached;
10937
+ const groups = [];
10938
+ for (const part of splitTopLevel(selector, ",")) {
10939
+ const text2 = part.trim();
10940
+ if (!text2) throw syntaxError(selector);
10941
+ const tokens = text2.match(/(?:\\.|\[[^\]]*\]|[^\s>])+|>/g) ?? [];
10942
+ const compounds = [];
10943
+ const combinators = [];
10944
+ let pending = " ";
10945
+ let scoped = false;
10946
+ for (const token of tokens) {
10947
+ if (token === ">") {
10948
+ pending = ">";
10949
+ continue;
10950
+ }
10951
+ if (token === ":scope") {
10952
+ scoped = true;
10953
+ pending = " ";
10954
+ continue;
10955
+ }
10956
+ if (compounds.length > 0) combinators.unshift(pending);
10957
+ compounds.unshift(parseCompound(token, selector));
10958
+ pending = " ";
10959
+ }
10960
+ if (compounds.length === 0) throw syntaxError(selector);
10961
+ groups.push({ compounds, combinators, scoped });
10962
+ }
10963
+ if (selectorCache.size > 500) selectorCache.clear();
10964
+ selectorCache.set(selector, groups);
10965
+ return groups;
10966
+ }
10967
+ function splitTopLevel(text2, sep) {
10968
+ const out = [];
10969
+ let depth = 0;
10970
+ let quote2 = "";
10971
+ let start = 0;
10972
+ for (let i2 = 0; i2 < text2.length; i2++) {
10973
+ const c = text2[i2];
10974
+ if (quote2) {
10975
+ if (c === "\\") i2++;
10976
+ else if (c === quote2) quote2 = "";
10977
+ } else if (c === '"' || c === "'") quote2 = c;
10978
+ else if (c === "\\") i2++;
10979
+ else if (c === "[" || c === "(") depth++;
10980
+ else if (c === "]" || c === ")") depth--;
10981
+ else if (c === sep && depth === 0) {
10982
+ out.push(text2.slice(start, i2));
10983
+ start = i2 + 1;
10984
+ }
10985
+ }
10986
+ out.push(text2.slice(start));
10987
+ return out;
10988
+ }
10989
+ function syntaxError(selector) {
10990
+ const Ctor = globalThis.DOMException;
10991
+ const message = `'${selector}' is not a valid selector (the SibuJS server DOM supports tag, #id, .class, [attr], [attr=value], descendant and > combinators)`;
10992
+ return Ctor ? new Ctor(message, "SyntaxError") : new Error(message);
10993
+ }
10994
+ function parseCompound(token, selector) {
10995
+ const c = { tag: null, id: null, classes: [], attrs: [] };
10996
+ const re = /(\\.|[^#.[\\])+|#((?:\\.|[^#.[\\])+)|\.((?:\\.|[^#.[\\])+)|\[([^\]]*)\]/gy;
10997
+ let consumed = 0;
10998
+ for (let m = re.exec(token); m; m = re.exec(token)) {
10999
+ consumed = re.lastIndex;
11000
+ if (m[2] !== void 0) c.id = unescapeIdent(m[2]);
11001
+ else if (m[3] !== void 0) c.classes.push(unescapeIdent(m[3]));
11002
+ else if (m[4] !== void 0) {
11003
+ const am = /^\s*([^\s~|^$*=]+)\s*(?:([~|^$*]?=)\s*(?:"((?:\\.|[^"])*)"|'((?:\\.|[^'])*)'|([^\s"']+)))?\s*$/.exec(
11004
+ m[4]
11005
+ );
11006
+ if (!am) throw syntaxError(selector);
11007
+ c.attrs.push({
11008
+ name: am[1].toLowerCase(),
11009
+ op: am[2] ?? null,
11010
+ value: unescapeIdent(am[3] ?? am[4] ?? am[5] ?? "")
11011
+ });
11012
+ } else {
11013
+ const t = m[0];
11014
+ if (t.startsWith(":")) throw syntaxError(selector);
11015
+ c.tag = t === "*" ? null : unescapeIdent(t);
11016
+ }
11017
+ if (re.lastIndex === token.length) break;
11018
+ }
11019
+ if (consumed !== token.length) throw syntaxError(selector);
11020
+ return c;
11021
+ }
11022
+ function matchesCompound(el, c) {
11023
+ if (c.tag !== null) {
11024
+ const isHtml = el.namespaceURI === HTML_NS3;
11025
+ if (isHtml ? el.localName !== c.tag.toLowerCase() : el.localName !== c.tag) return false;
11026
+ }
11027
+ if (c.id !== null && el.getAttribute("id") !== c.id) return false;
11028
+ if (c.classes.length > 0) {
11029
+ const tokens = (el.getAttribute("class") ?? "").split(/\s+/);
11030
+ for (const cls of c.classes) if (!tokens.includes(cls)) return false;
11031
+ }
11032
+ for (const a2 of c.attrs) {
11033
+ const v = el.getAttribute(a2.name);
11034
+ if (v === null) return false;
11035
+ if (a2.op === null) continue;
11036
+ if (a2.op === "=" && v !== a2.value) return false;
11037
+ if (a2.op === "~=" && !v.split(/\s+/).includes(a2.value)) return false;
11038
+ if (a2.op === "|=" && v !== a2.value && !v.startsWith(`${a2.value}-`)) return false;
11039
+ if (a2.op === "^=" && (!a2.value || !v.startsWith(a2.value))) return false;
11040
+ if (a2.op === "$=" && (!a2.value || !v.endsWith(a2.value))) return false;
11041
+ if (a2.op === "*=" && (!a2.value || !v.includes(a2.value))) return false;
11042
+ }
11043
+ return true;
11044
+ }
11045
+ function matchesCompiled(el, groups, scope) {
11046
+ for (const g2 of groups) if (matchesComplex(el, g2, 0, scope)) return true;
11047
+ return false;
11048
+ }
11049
+ function matchesComplex(el, g2, i2, scope) {
11050
+ if (!matchesCompound(el, g2.compounds[i2])) return false;
11051
+ if (i2 === g2.compounds.length - 1) {
11052
+ if (!g2.scoped || !scope) return true;
11053
+ return el._parent === scope || (g2.combinators.length === 0 ? false : scope.contains(el));
11054
+ }
11055
+ const comb = g2.combinators[i2];
11056
+ for (let p2 = el._parent; p2 && p2 instanceof ServerElement; p2 = p2._parent) {
11057
+ if (scope && p2 === scope && g2.scoped) return false;
11058
+ if (matchesComplex(p2, g2, i2 + 1, scope)) return true;
11059
+ if (comb === ">") return false;
11060
+ }
11061
+ return false;
11062
+ }
11063
+ var VOID = /* @__PURE__ */ new Set([
11064
+ "area",
11065
+ "base",
11066
+ "br",
11067
+ "col",
11068
+ "embed",
11069
+ "hr",
11070
+ "img",
11071
+ "input",
11072
+ "link",
11073
+ "meta",
11074
+ "source",
11075
+ "track",
11076
+ "wbr"
11077
+ ]);
11078
+ function escapeText(s2) {
11079
+ return s2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
11080
+ }
11081
+ function serializeForDebug(node) {
11082
+ if (node.nodeType === TEXT_NODE) return escapeText(node.data);
11083
+ if (node.nodeType === COMMENT_NODE) return `<!--${node.data}-->`;
11084
+ if (node.nodeType !== ELEMENT_NODE) {
11085
+ let out2 = "";
11086
+ for (let n = node._first; n; n = n._next) out2 += serializeForDebug(n);
11087
+ return out2;
11088
+ }
11089
+ const el = node;
11090
+ const tag = el.prefix ? `${el.prefix}:${el.localName}` : el.localName;
11091
+ let out = `<${tag}`;
11092
+ for (const a2 of el._attrs) out += ` ${a2.name}="${escapeText(a2._value).replace(/"/g, "&quot;")}"`;
11093
+ out += ">";
11094
+ if (el.namespaceURI === HTML_NS3 && VOID.has(el.localName)) return out;
11095
+ for (let n = el._first; n; n = n._next) out += serializeForDebug(n);
11096
+ return `${out}</${tag}>`;
11097
+ }
11098
+ var INSTALLED = /* @__PURE__ */ Symbol.for("sibujs.serverDom.v1");
11099
+ function isServerDom() {
11100
+ return typeof document !== "undefined" && document instanceof ServerDocument;
11101
+ }
11102
+ function installServerDom(options = {}) {
11103
+ const g2 = globalThis;
11104
+ if (typeof g2.document !== "undefined" && !options.force) return () => {
11105
+ };
11106
+ const globals = {
11107
+ document: new ServerDocument(),
11108
+ Node: ServerNode,
11109
+ Element: ServerElement,
11110
+ HTMLElement: ServerHTMLElement,
11111
+ SVGElement: ServerSVGElement,
11112
+ MathMLElement: ServerMathMLElement,
11113
+ HTMLInputElement: ServerInputElement,
11114
+ HTMLTextAreaElement: ServerTextAreaElement,
11115
+ HTMLSelectElement: ServerSelectElement,
11116
+ HTMLOptionElement: ServerOptionElement,
11117
+ HTMLButtonElement: ServerButtonElement,
11118
+ HTMLCanvasElement: ServerCanvasElement,
11119
+ HTMLDialogElement: ServerDialogElement,
11120
+ HTMLTemplateElement: ServerTemplateElement,
11121
+ Text: ServerText,
11122
+ Comment: ServerComment,
11123
+ CharacterData: ServerCharacterData,
11124
+ DocumentFragment: ServerDocumentFragment,
11125
+ Document: ServerDocument,
11126
+ Attr: ServerAttr,
11127
+ MutationObserver: ServerMutationObserver,
11128
+ NodeFilter: NODE_FILTER
11129
+ };
11130
+ const previous2 = /* @__PURE__ */ new Map();
11131
+ for (const [key, value] of Object.entries(globals)) {
11132
+ previous2.set(key, Object.getOwnPropertyDescriptor(g2, key));
11133
+ Object.defineProperty(g2, key, { value, configurable: true, writable: true, enumerable: false });
11134
+ }
11135
+ g2[INSTALLED] = true;
11136
+ return () => {
11137
+ for (const [key, desc] of previous2) {
11138
+ if (desc) Object.defineProperty(g2, key, desc);
11139
+ else delete g2[key];
11140
+ }
11141
+ delete g2[INSTALLED];
11142
+ };
11143
+ }
11144
+ var BROWSER_GLOBALS = [
11145
+ "matchMedia",
11146
+ "requestAnimationFrame",
11147
+ "localStorage",
11148
+ "sessionStorage",
11149
+ "IntersectionObserver",
11150
+ "ResizeObserver"
11151
+ ];
11152
+ var WATCHED = /* @__PURE__ */ Symbol.for("sibujs.serverDom.watched.v1");
11153
+ function inServerRender() {
11154
+ const shared = globalThis[/* @__PURE__ */ Symbol.for("sibujs.ssr.v1")];
11155
+ return !!shared?.als?.getStore()?.ssr;
11156
+ }
11157
+ function watchProperty(target, key, api) {
11158
+ const desc = Object.getOwnPropertyDescriptor(target, key);
11159
+ if (!desc || !desc.configurable) return;
11160
+ const read = desc.get ? () => desc.get?.call(target) : () => desc.value;
11161
+ let value = desc.value;
11162
+ Object.defineProperty(target, key, {
11163
+ configurable: true,
11164
+ enumerable: desc.enumerable,
11165
+ get() {
11166
+ if (inServerRender()) reportBrowserApi(api);
11167
+ return desc.get ? read() : value;
11168
+ },
11169
+ set(v) {
11170
+ if (desc.set) desc.set.call(target, v);
11171
+ else value = v;
11172
+ }
11173
+ });
11174
+ }
11175
+ function watchBrowserApis() {
11176
+ if (!DEV || isServerDom()) return;
11177
+ const g2 = globalThis;
11178
+ if (g2[WATCHED]) return;
11179
+ g2[WATCHED] = true;
11180
+ const win = g2.window;
11181
+ for (const key of BROWSER_GLOBALS) {
11182
+ if (Object.hasOwn(g2, key)) watchProperty(g2, key, key);
11183
+ if (win && win !== g2 && Object.hasOwn(win, key)) watchProperty(win, key, `window.${key}`);
11184
+ }
11185
+ const Doc = g2.Document;
11186
+ if (Doc && "fonts" in Doc.prototype) watchProperty(Doc.prototype, "fonts", "document.fonts");
11187
+ const Canvas = g2.HTMLCanvasElement;
11188
+ const getContext = Canvas?.prototype.getContext;
11189
+ if (Canvas && getContext) {
11190
+ Canvas.prototype.getContext = function(...args) {
11191
+ if (inServerRender()) reportBrowserApi("HTMLCanvasElement.getContext()");
11192
+ return getContext.apply(this, args);
11193
+ };
11194
+ }
11195
+ }
11196
+ var BROWSER_ONLY_NAMES = /^(window|self|localStorage|sessionStorage|requestAnimationFrame|cancelAnimationFrame|matchMedia|IntersectionObserver|ResizeObserver|getComputedStyle|location|history|screen|innerWidth|innerHeight|scrollY|scrollX|devicePixelRatio) is not defined$/;
11197
+ function explainServerError(err) {
11198
+ if (!(err instanceof ReferenceError)) return err;
11199
+ const m = BROWSER_ONLY_NAMES.exec(err.message);
11200
+ if (!m) return err;
11201
+ const site = (err.stack ?? "").split("\n")[1]?.trim().replace(/^at\s+/, "") ?? "(unknown site)";
11202
+ return new Error(
11203
+ `[SibuJS SSR] browser-only API \`${m[1]}\` used during a server render (${site}). Move the code into onMount() or an effect, or render the component with ClientOnly().`,
11204
+ { cause: err }
11205
+ );
11206
+ }
11207
+ function ensureServerDom() {
11208
+ if (typeof document === "undefined") installServerDom();
11209
+ }
11210
+
11211
+ // src/platform/serverHead.ts
11212
+ function headSlot() {
11213
+ return requestSlot("head", () => ({ layers: [] }));
11214
+ }
11215
+ function recordServerHead(source2) {
11216
+ const slot4 = headSlot();
11217
+ if (!slot4) return null;
11218
+ const entry = { source: source2 };
11219
+ slot4.layers.push(entry);
11220
+ return () => {
11221
+ if (entry.source === null) return;
11222
+ entry.source = null;
11223
+ const index = slot4.layers.indexOf(entry);
11224
+ if (index !== -1) slot4.layers.splice(index, 1);
11225
+ };
11226
+ }
11227
+ function collectServerHead() {
11228
+ const slot4 = headSlot();
11229
+ if (!slot4 || slot4.layers.length === 0) return "";
11230
+ let title3;
11231
+ const order = [];
11232
+ const byKey = /* @__PURE__ */ new Map();
11233
+ for (const entry of slot4.layers.slice()) {
11234
+ const source2 = entry.source;
11235
+ if (source2 === null) continue;
11236
+ let layer;
11237
+ try {
11238
+ layer = typeof source2 === "function" ? untracked2(source2) : source2;
11239
+ } catch (err) {
11240
+ const message = err instanceof Error ? err.message : String(err);
11241
+ throw new Error(`[SibuJS SSR] a head value threw while the page head was collected: ${message}`, {
11242
+ cause: err
11243
+ });
11244
+ }
11245
+ if (!layer) continue;
11246
+ if (layer.title !== void 0) title3 = layer.title;
11247
+ for (const tag of layer.tags) {
11248
+ if (!byKey.has(tag.key)) order.push(tag.key);
11249
+ byKey.set(tag.key, tag.html);
11250
+ }
11251
+ }
11252
+ const out = [];
11253
+ if (title3 != null) out.push(`<title>${escapeText2(title3)}</title>`);
11254
+ for (const key of order) out.push(byKey.get(key));
11255
+ return out.join("\n ");
11256
+ }
11257
+ function escapeText2(str) {
11258
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
11259
+ }
11260
+
11261
+ // src/platform/ssrAsync.ts
11262
+ var DEFAULT_TRANSFER_MAX_BYTES = 1024 * 1024;
11263
+ function describeNodePath(node) {
11264
+ const parts = [];
11265
+ let current2 = node;
11266
+ while (current2 && parts.length < 8) {
11267
+ if (current2.nodeType === 1) {
11268
+ const el = current2;
11269
+ let part = el.localName;
11270
+ const id = el.getAttribute("id");
11271
+ if (id) part += `#${id}`;
11272
+ const cls = el.getAttribute("class")?.trim().split(/\s+/)[0];
11273
+ if (cls) part += `.${cls}`;
11274
+ parts.unshift(part);
11275
+ }
11276
+ current2 = current2.parentNode;
11277
+ }
11278
+ return parts.length > 0 ? parts.join(" > ") : "(detached)";
11279
+ }
11280
+ function renderFailure(entry) {
11281
+ const error = explainServerError(entry.error);
11282
+ const message = error instanceof Error ? error.message : String(error);
11283
+ const where = entry.context.node ? describeNodePath(entry.context.node) : "(unknown position)";
11284
+ const label2 = entry.context.name ? ` in ${entry.context.name}` : "";
11285
+ return new Error(`[SibuJS SSR] render failed${label2} at ${where}: ${message}`, { cause: error });
11286
+ }
11287
+
11288
+ // src/platform/hydrateAdopt.ts
11289
+ var ADOPT_ID_ATTR = "data-sibu-h";
11290
+ function createServerAdoptScope(ids) {
11291
+ const sink = {
11292
+ on: true,
11293
+ el(tag, ns, id) {
11294
+ const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
11295
+ ids.set(el, id);
11296
+ return el;
11297
+ }
11298
+ };
11299
+ return { p: "", n: 0, s: sink };
11300
+ }
11301
+ var STICKY = {
11302
+ img: ["src", "srcset", "sizes"],
11303
+ source: ["src", "srcset", "sizes"],
11304
+ video: ["src", "poster"],
11305
+ audio: ["src"],
11306
+ track: ["src"],
11307
+ iframe: ["src"],
11308
+ embed: ["src"],
11309
+ object: ["data"],
11310
+ input: ["value", "checked", "type"],
11311
+ textarea: [],
11312
+ select: [],
11313
+ option: ["value", "selected"],
11314
+ details: ["open"],
11315
+ dialog: ["open"]
11316
+ };
11317
+ function snapshotSelect(select3) {
11318
+ const options = Array.from(select3.options);
11319
+ const seen = /* @__PURE__ */ new Map();
11320
+ const chosen = [];
11321
+ for (const node of options) {
11322
+ const occurrence = seen.get(node.value) ?? 0;
11323
+ seen.set(node.value, occurrence + 1);
11324
+ if (node.selected) chosen.push({ node, value: node.value, occurrence });
11325
+ }
11326
+ return { chosen, server: new Set(options) };
11327
+ }
11328
+ var nativeAppend = (parent, child) => Node.prototype.appendChild.call(parent, child);
11329
+ var nativeInsert = (parent, child, ref) => Node.prototype.insertBefore.call(parent, child, ref);
11330
+ var nativeReplace = (parent, child, old) => Node.prototype.replaceChild.call(parent, child, old);
11331
+ function sameKind(a2, b2) {
11332
+ return a2.nodeType === b2.nodeType && (a2.nodeType === 3 || a2.nodeType === 8);
11333
+ }
11334
+ function isOptionDisabled(option2) {
11335
+ const parent = option2.parentElement;
11336
+ return option2.disabled || parent?.localName === "optgroup" && parent.hasAttribute("disabled");
11337
+ }
11338
+ function defaultSelection(select3) {
11339
+ const options = Array.from(select3.options);
11340
+ const parsed = reparsedSelection(select3, options);
11341
+ if (parsed) return parsed;
11342
+ const marked = options.filter((o) => o.hasAttribute("selected"));
11343
+ if (select3.multiple) return new Set(marked);
11344
+ if (marked.length > 0) return /* @__PURE__ */ new Set([marked[marked.length - 1]]);
11345
+ if (select3.size > 1) return /* @__PURE__ */ new Set();
11346
+ const first = options.find((o) => !isOptionDisabled(o));
11347
+ return new Set(first ? [first] : []);
11348
+ }
11349
+ function reparsedSelection(select3, options) {
11350
+ if (typeof DOMParser !== "function") return null;
11351
+ try {
11352
+ const doc = new DOMParser().parseFromString(`<!doctype html><body>${select3.outerHTML}`, "text/html");
11353
+ const copy = doc.querySelector("select");
11354
+ if (!copy || copy.options.length !== options.length) return null;
11355
+ const chosen = /* @__PURE__ */ new Set();
11356
+ Array.from(copy.options).forEach((o, i2) => {
11357
+ if (o.selected) chosen.add(options[i2]);
11358
+ });
11359
+ return chosen;
11360
+ } catch {
11361
+ return null;
11362
+ }
11363
+ }
11364
+ function isDirty(el) {
11365
+ const tag = el.localName;
11366
+ if (tag === "input") {
11367
+ const input2 = el;
11368
+ if (input2.type === "checkbox" || input2.type === "radio") return input2.checked !== input2.hasAttribute("checked");
11369
+ return input2.value !== (input2.getAttribute("value") ?? "");
11370
+ }
11371
+ if (tag === "textarea") return el.value !== (el.textContent ?? "");
11372
+ if (tag === "select") {
11373
+ const select3 = el;
11374
+ const initial = defaultSelection(select3);
11375
+ return Array.from(select3.options).some((o) => o.selected !== initial.has(o));
11376
+ }
11377
+ return false;
11378
+ }
11379
+ var AdoptSession = class {
11380
+ constructor(root, options) {
11381
+ this.root = root;
11382
+ this.options = options;
11383
+ this.byId = /* @__PURE__ */ new Map();
11384
+ this.server = /* @__PURE__ */ new WeakSet();
11385
+ this.claimed = /* @__PURE__ */ new Map();
11386
+ this.cursors = /* @__PURE__ */ new WeakMap();
11387
+ this.patched = [];
11388
+ this.touched = /* @__PURE__ */ new Set();
11389
+ this.mismatches = [];
11390
+ /**
11391
+ * The selection of each `<select>` the user changed before takeover. Taken
11392
+ * before any client code runs: the client builds a select's options BEFORE
11393
+ * the select, and an option's `selected` write changes the selection long
11394
+ * before the select itself is claimed. Session-scoped: the references go
11395
+ * with the session.
11396
+ */
11397
+ this.selections = /* @__PURE__ */ new Map();
11398
+ /**
11399
+ * Checkboxes and radios the user changed before takeover, and their state —
11400
+ * for the same reason: checking a radio unchecks its group, so the client
11401
+ * writing a sibling (or a sibling joining the group) changes this one first.
11402
+ */
11403
+ this.checks = /* @__PURE__ */ new Map();
11404
+ /** Form controls whose state differed from their markup when the session started: the user's. */
11405
+ this.dirty = /* @__PURE__ */ new Set();
11406
+ this.created = 0;
11407
+ this.removed = 0;
11408
+ /** AdoptSink: numbering and claiming are on for the length of the session. */
11409
+ this.on = true;
11410
+ /** AdoptSink: the hydration session work built in this sink's scopes belongs to. */
11411
+ this.h = null;
11412
+ this.restored = false;
11413
+ const walk = (node) => {
11414
+ for (let child = node.firstChild; child; child = child.nextSibling) {
11415
+ this.server.add(child);
11416
+ if (child.nodeType === 1) {
11417
+ const id = child.getAttribute(ADOPT_ID_ATTR);
11418
+ if (id !== null && !this.byId.has(id)) this.byId.set(id, child);
11419
+ const tag = child.localName;
11420
+ if ((tag === "select" || tag === "input" || tag === "textarea") && isDirty(child)) {
11421
+ this.dirty.add(child);
11422
+ if (tag === "select") {
11423
+ this.selections.set(child, snapshotSelect(child));
11424
+ } else if (tag === "input") {
11425
+ const input2 = child;
11426
+ if (input2.type === "checkbox" || input2.type === "radio") this.checks.set(input2, input2.checked);
11427
+ }
11428
+ }
11429
+ walk(child);
11430
+ }
11431
+ }
11432
+ };
11433
+ walk(root);
11434
+ this.patchParent(root);
11435
+ }
11436
+ report(m) {
11437
+ const message = m.kind === "tag" ? `server rendered <${m.serverValue}>, the client built <${m.clientValue}> \u2014 the subtree is replaced` : m.kind === "missing" ? `the client built <${m.clientValue}>, which the server did not render` : m.kind === "extra" ? `the server rendered ${m.serverValue}, which the client did not build \u2014 removed` : `text differs: server "${m.serverValue}", client "${m.clientValue}"`;
11438
+ const report = { ...m, message };
11439
+ this.mismatches.push(report);
11440
+ if (this.options.onMismatch) this.options.onMismatch(report);
11441
+ else if (DEV && this.mismatches.length <= 10) {
11442
+ console.warn(
11443
+ `[SibuJS hydration] adopt mismatch at ${m.path}${m.id ? ` (id ${m.id})` : ""}: ${message}.
11444
+ Likely cause: ${m.cause}`
11445
+ );
11446
+ }
11447
+ }
11448
+ // ── AdoptSink: claim the server element with this id ──
11449
+ el(tag, ns, id) {
11450
+ if (!this.on) return null;
11451
+ const candidate = this.byId.get(id);
11452
+ const want = ns ?? "http://www.w3.org/1999/xhtml";
11453
+ if (candidate && candidate.localName === tag && (candidate.namespaceURI ?? want) === want && !this.claimed.has(candidate)) {
11454
+ this.byId.delete(id);
11455
+ this.claim(candidate);
11456
+ return candidate;
11457
+ }
11458
+ this.created++;
11459
+ if (candidate) {
11460
+ this.report({
11461
+ kind: "tag",
11462
+ path: describeNodePath(candidate),
11463
+ id,
11464
+ serverValue: candidate.localName,
11465
+ clientValue: tag,
11466
+ cause: "the server and the client took different branches: a browser-only read (window, matchMedia, storage) during render, data that differs between them, or a non-deterministic render (Date.now(), Math.random()). Render browser-only content with ClientOnly()."
11467
+ });
11468
+ } else {
11469
+ this.report({
11470
+ kind: "missing",
11471
+ path: "(new element)",
11472
+ id,
11473
+ serverValue: "(none)",
11474
+ clientValue: tag,
11475
+ cause: "the client built more than the server: data the server did not have (a query with ssr: false, a timed-out fetch), or a branch that depends on the browser. ClientOnly() renders it after takeover."
11476
+ });
11477
+ }
11478
+ return null;
11479
+ }
11480
+ claim(el) {
11481
+ el.removeAttribute(ADOPT_ID_ATTR);
11482
+ const keep = STICKY[el.localName] ?? [];
11483
+ const sticky = /* @__PURE__ */ new Set();
11484
+ for (const attr of Array.from(el.attributes)) {
11485
+ if (keep.includes(attr.name)) {
11486
+ const safe = resolveAttributeValue(attr.name, attr.value, { element: el });
11487
+ if (safe === null) el.removeAttribute(attr.name);
11488
+ else {
11489
+ if (safe !== attr.value) el.setAttribute(attr.name, safe);
11490
+ sticky.add(attr.name);
11491
+ }
11492
+ } else el.removeAttribute(attr.name);
11493
+ }
11494
+ this.claimed.set(el, { sticky });
11495
+ if (this.dirty.has(el)) this.touched.add(el);
11496
+ this.patchParent(el);
11497
+ }
11498
+ /**
11499
+ * Instance overrides on an adopted parent for the length of the session —
11500
+ * the core's own `appendChild` / `insertBefore` calls then place children
11501
+ * on the server nodes instead of moving them. Removed when the session ends.
11502
+ */
11503
+ patchParent(parent) {
11504
+ const session = this;
11505
+ const record = this.claimed.get(parent);
11506
+ this.cursors.set(parent, parent.firstChild);
11507
+ this.patched.push(parent);
11508
+ const own = parent;
11509
+ own.appendChild = function(child) {
11510
+ if (inAdoptScope() || child.nodeType === 11) return session.place(this, child);
11511
+ return nativeAppend(this, child);
11512
+ };
11513
+ own.insertBefore = function(child, ref) {
11514
+ return session.insertAt(this, child, ref);
11515
+ };
11516
+ own.replaceChildren = function(...nodes) {
11517
+ session.cursors.set(this, this.firstChild);
11518
+ for (const n of nodes) session.place(this, typeof n === "string" ? document.createTextNode(n) : n);
11519
+ let rest = session.cursors.get(this) ?? null;
11520
+ while (rest) {
11521
+ const next = rest.nextSibling;
11522
+ this.removeChild(rest);
11523
+ rest = next;
11524
+ }
11525
+ };
11526
+ const textDesc = Object.getOwnPropertyDescriptor(Node.prototype, "textContent");
11527
+ if (textDesc?.set && textDesc.get) {
11528
+ Object.defineProperty(parent, "textContent", {
11529
+ configurable: true,
11530
+ get() {
11531
+ return textDesc.get?.call(this);
11532
+ },
11533
+ set(value) {
11534
+ const text2 = value == null ? "" : String(value);
11535
+ const only = this.firstChild;
11536
+ if (only && only === this.lastChild && only.nodeType === 3 && only.data === text2) {
11537
+ session.server.delete(only);
11538
+ return;
11539
+ }
11540
+ textDesc.set?.call(this, value);
11541
+ }
11542
+ });
11543
+ }
11544
+ if (record) {
11545
+ const note = (name) => record.sticky.delete(String(name).toLowerCase());
11546
+ const { getAttribute, setAttribute, removeAttribute } = Element.prototype;
11547
+ own.getAttribute = function(name) {
11548
+ note(name);
11549
+ return getAttribute.call(this, name);
11550
+ };
11551
+ own.setAttribute = function(name, value) {
11552
+ note(name);
11553
+ return setAttribute.call(this, name, value);
11554
+ };
11555
+ own.removeAttribute = function(name) {
11556
+ note(name);
11557
+ return removeAttribute.call(this, name);
11558
+ };
11559
+ if (this.touched.has(parent) && parent.localName !== "select") {
11560
+ for (const prop of ["value", "checked"]) {
11561
+ if (prop in parent) {
11562
+ Object.defineProperty(parent, prop, {
11563
+ configurable: true,
11564
+ get() {
11565
+ const desc = findDescriptor(Object.getPrototypeOf(this), prop);
11566
+ return desc?.get?.call(this);
11567
+ },
11568
+ set() {
11569
+ }
11570
+ });
11571
+ }
11572
+ }
11573
+ }
11574
+ }
11575
+ }
11576
+ /** Put `child` at the cursor of `parent`. */
11577
+ place(parent, child) {
11578
+ if (child.nodeType === 11) {
11579
+ for (const n of Array.from(child.childNodes)) this.place(parent, n);
11580
+ return child;
11581
+ }
11582
+ let cur = this.cursors.has(parent) ? this.cursors.get(parent) ?? null : null;
11583
+ if (child === cur) {
11584
+ this.cursors.set(parent, child.nextSibling);
11585
+ return child;
11586
+ }
11587
+ if (child.parentNode === parent && this.claimed.has(child) && this.follows(cur, child)) {
11588
+ this.cursors.set(parent, child.nextSibling);
11589
+ return child;
11590
+ }
11591
+ if (!child.parentNode && (child.nodeType === 3 || child.nodeType === 8)) {
11592
+ const match = this.findCounterpart(cur, child);
11593
+ if (match) cur = match;
11594
+ }
11595
+ if (cur && this.server.has(cur) && !this.claimed.has(cur) && sameKind(cur, child) && !child.parentNode) {
11596
+ if (child.nodeType === 3) {
11597
+ const serverText = cur;
11598
+ const clientText = child.data;
11599
+ if (clientText !== "" && serverText.data !== clientText && serverText.data.startsWith(clientText)) {
11600
+ serverText.data = serverText.data.slice(clientText.length);
11601
+ nativeInsert(parent, child, serverText);
11602
+ return child;
11603
+ }
11604
+ if (serverText.data !== clientText) {
11605
+ this.report({
11606
+ kind: "text",
11607
+ path: describeNodePath(parent),
11608
+ id: null,
11609
+ serverValue: serverText.data.slice(0, 80),
11610
+ clientValue: clientText.slice(0, 80),
11611
+ cause: "the text was computed differently: a non-deterministic value (Date.now(), Math.random(), a locale-dependent format) or data that changed between render and takeover. The client text is kept."
11612
+ });
11613
+ }
11614
+ }
11615
+ this.server.delete(cur);
11616
+ this.cursors.set(parent, cur.nextSibling);
11617
+ nativeReplace(parent, child, cur);
11618
+ return child;
11619
+ }
11620
+ nativeInsert(parent, child, cur);
11621
+ return child;
11622
+ }
11623
+ /** Is `node` at or after `from` among its siblings? */
11624
+ follows(from, node) {
11625
+ for (let n = from; n; n = n.nextSibling) if (n === node) return true;
11626
+ return false;
11627
+ }
11628
+ /**
11629
+ * The server node a fresh text / comment child stands for: the first
11630
+ * unconsumed server node of the same kind from `from` on (a comment must
11631
+ * carry the same text), skipping unclaimed server nodes in between — a
11632
+ * preceding directive's branch content — but never an adopted element.
11633
+ */
11634
+ findCounterpart(from, child) {
11635
+ for (let n = from; n; n = n.nextSibling) {
11636
+ if (!this.server.has(n)) return null;
11637
+ if (n.nodeType === 1 && this.claimed.has(n)) return null;
11638
+ if (n.nodeType !== child.nodeType) continue;
11639
+ if (n.nodeType === 8 && n.data !== child.data) continue;
11640
+ return n;
11641
+ }
11642
+ return null;
11643
+ }
11644
+ /** `insertBefore` on an adopted parent: no-op when already in place; a fresh text/comment takes the server one's place. */
11645
+ insertAt(parent, child, ref) {
11646
+ if (child === ref || child.parentNode === parent && child.nextSibling === ref) return child;
11647
+ if (child.nodeType === 11) {
11648
+ for (const n of Array.from(child.childNodes)) this.insertAt(parent, n, ref);
11649
+ return child;
11650
+ }
11651
+ if (ref && !child.parentNode && this.server.has(ref) && sameKind(ref, child)) {
11652
+ if (child.nodeType === 3 && ref.data !== child.data) {
11653
+ this.report({
11654
+ kind: "text",
11655
+ path: describeNodePath(parent),
11656
+ id: null,
11657
+ serverValue: ref.data.slice(0, 80),
11658
+ clientValue: child.data.slice(0, 80),
11659
+ cause: "the text was computed differently: a non-deterministic value (Date.now(), Math.random(), a locale-dependent format) or data that changed between render and takeover. The client text is kept."
11660
+ });
11661
+ }
11662
+ this.server.delete(ref);
11663
+ if (this.cursors.get(parent) === ref) this.cursors.set(parent, ref.nextSibling);
11664
+ nativeReplace(parent, child, ref);
11665
+ return child;
11666
+ }
11667
+ return nativeInsert(parent, child, ref);
11668
+ }
11669
+ /** Remove every instance override; idempotent, and also run when the build throws. */
11670
+ restore() {
11671
+ this.on = false;
11672
+ if (this.restored) return;
11673
+ this.restored = true;
11674
+ for (const node of this.patched) {
11675
+ const own = node;
11676
+ for (const key of [
11677
+ "appendChild",
11678
+ "insertBefore",
11679
+ "replaceChildren",
11680
+ "textContent",
11681
+ "getAttribute",
11682
+ "setAttribute",
11683
+ "removeAttribute",
11684
+ "value",
11685
+ "checked"
11686
+ ]) {
11687
+ if (Object.hasOwn(own, key)) delete own[key];
11688
+ }
11689
+ }
11690
+ }
11691
+ /** End of the session: restore the instances, release unclaimed server nodes, replay input. */
11692
+ finish() {
11693
+ this.restore();
11694
+ const sweep = (node) => {
11695
+ for (let child = node.firstChild; child; ) {
11696
+ const next = child.nextSibling;
11697
+ if (this.server.has(child) && !this.claimed.has(child)) {
11698
+ if (child.nodeType === 1 && child.hasAttribute(ADOPT_ID_ATTR)) {
11699
+ this.report({
11700
+ kind: "extra",
11701
+ path: describeNodePath(child),
11702
+ id: child.getAttribute(ADOPT_ID_ATTR),
11703
+ serverValue: `<${child.localName}>`,
11704
+ clientValue: "(none)",
11705
+ cause: "the client built less than the server, or built it under another scope: a branch that renders differently in the browser, or a component whose structure depends on timing."
11706
+ });
11707
+ }
11708
+ child.parentNode?.removeChild(child);
11709
+ this.removed++;
11710
+ } else if (child.nodeType === 1) sweep(child);
11711
+ child = next;
11712
+ }
11713
+ };
11714
+ sweep(this.root);
11715
+ for (const [el, record] of this.claimed) {
11716
+ for (const name of record.sticky) el.removeAttribute(name);
11717
+ }
11718
+ reselect(this);
11719
+ for (const el of this.touched) {
11720
+ el.dispatchEvent(new Event("input", { bubbles: true }));
11721
+ el.dispatchEvent(new Event("change", { bubbles: true }));
11722
+ }
11723
+ }
11724
+ };
11725
+ function survivingSelection(select3, snapshot) {
11726
+ const options = Array.from(select3.options);
11727
+ const present = new Set(options);
11728
+ const result = /* @__PURE__ */ new Set();
11729
+ const rebuilt = /* @__PURE__ */ new Map();
11730
+ for (const o of options) {
11731
+ if (snapshot.server.has(o)) continue;
11732
+ const list = rebuilt.get(o.value);
11733
+ if (list) list.push(o);
11734
+ else rebuilt.set(o.value, [o]);
11735
+ }
11736
+ const lost = [];
11737
+ for (const entry of snapshot.chosen) {
11738
+ if (present.has(entry.node) && entry.node.value === entry.value) result.add(entry.node);
11739
+ else lost.push(entry);
11740
+ }
11741
+ for (const entry of lost) {
11742
+ const candidates = rebuilt.get(entry.value);
11743
+ if (!candidates) continue;
11744
+ const atOccurrence = candidates[entry.occurrence];
11745
+ const match = atOccurrence && !result.has(atOccurrence) ? atOccurrence : candidates.find((o) => !result.has(o));
11746
+ if (match) result.add(match);
11747
+ }
11748
+ return result;
11749
+ }
11750
+ function reselect(session) {
11751
+ for (const [select3, snapshot] of session.selections) {
11752
+ if (!session.claimed.has(select3) || !session.root.contains(select3)) {
11753
+ session.touched.delete(select3);
11754
+ continue;
11755
+ }
11756
+ if (snapshot.chosen.length === 0) {
11757
+ select3.selectedIndex = -1;
11758
+ continue;
11759
+ }
11760
+ const keep = survivingSelection(select3, snapshot);
11761
+ if (keep.size === 0) {
11762
+ session.touched.delete(select3);
11763
+ continue;
11764
+ }
11765
+ if (select3.multiple) for (const o of Array.from(select3.options)) o.selected = keep.has(o);
11766
+ else keep.values().next().value.selected = true;
11767
+ }
11768
+ const live = Array.from(session.checks).filter(([el]) => session.claimed.has(el) && session.root.contains(el));
11769
+ for (const [el, checked] of live) if (!checked) el.checked = false;
11770
+ for (const [el, checked] of live) if (checked) el.checked = true;
11771
+ }
11772
+ function findDescriptor(proto, key) {
11773
+ for (let p2 = proto; p2; p2 = Object.getPrototypeOf(p2)) {
11774
+ const d = Object.getOwnPropertyDescriptor(p2, key);
11775
+ if (d) return d;
11776
+ }
11777
+ return void 0;
11778
+ }
11779
+ var macrotask = () => new Promise((resolve) => {
11780
+ if (typeof MessageChannel === "function") {
11781
+ const channel = new MessageChannel();
11782
+ channel.port1.onmessage = () => {
11783
+ channel.port1.close();
11784
+ resolve();
11785
+ };
11786
+ channel.port2.postMessage(null);
11787
+ } else setTimeout(resolve, 0);
11788
+ });
11789
+ async function hydrateAdopt(component, container, options = {}) {
11790
+ const hydration = beginHydration();
11791
+ const session = new AdoptSession(container, options);
11792
+ session.h = hydration;
11793
+ const rootScope = { p: "", n: 0, s: session };
11794
+ let replacedRoot = false;
11795
+ try {
11796
+ const tree = inHydration(hydration, () => inScope(rootScope, component));
11797
+ if (tree.parentNode !== container) {
11798
+ if (tree.nodeType === 1 && !session.claimed.has(tree)) {
11799
+ replacedRoot = true;
11800
+ if (DEV && !options.onMismatch) {
11801
+ console.warn(
11802
+ '[SibuJS hydration] adopt: the root element did not match the server markup, so the whole tree is replaced. Was the server render made with { hydration: "adopt" } and the same root component?'
11803
+ );
11804
+ }
11805
+ }
11806
+ inScope(rootScope, () => session.place(container, tree));
11807
+ }
11808
+ const deadline = Date.now() + (options.timeout ?? 1e4);
11809
+ const { pending, wake } = hydration;
11810
+ for (; ; ) {
11811
+ await macrotask();
11812
+ if (pending.size === 0) {
11813
+ await macrotask();
11814
+ if (pending.size === 0) break;
11815
+ continue;
11816
+ }
11817
+ const remaining = deadline - Date.now();
11818
+ if (remaining <= 0) break;
11819
+ await new Promise((resolve) => {
11820
+ const done = () => {
11821
+ clearTimeout(timer);
11822
+ wake.delete(done);
11823
+ resolve();
11824
+ };
11825
+ const timer = setTimeout(done, remaining);
11826
+ wake.add(done);
11827
+ });
11828
+ }
11829
+ session.finish();
11830
+ } finally {
11831
+ session.restore();
11832
+ hydration.end();
11833
+ }
11834
+ container.setAttribute("data-sibu-hydrated", "adopt");
11835
+ return {
11836
+ adopted: session.claimed.size,
11837
+ created: session.created,
11838
+ removed: session.removed,
11839
+ mismatches: session.mismatches,
11840
+ replacedRoot
11841
+ };
11842
+ }
11843
+
11844
+ // src/platform/componentIsland.ts
11845
+ var ISLAND_PROPS_ATTR = "data-sibu-props";
11846
+ var SAFE_NAME = /^[A-Za-z0-9_-]+$/;
11847
+ function componentIsland(name, component, props, options = {}) {
11848
+ if (!SAFE_NAME.test(name)) {
11849
+ throw new Error(`[SibuJS SSR] island: name must match [A-Za-z0-9_-]+ (got: ${JSON.stringify(name.slice(0, 32))})`);
11850
+ }
11851
+ const wrapper = document.createElement("div");
11852
+ wrapper.setAttribute("data-sibu-island", name);
11853
+ if (options.load) wrapper.setAttribute("data-sibu-load", options.load);
11854
+ if (options.media) wrapper.setAttribute("data-sibu-media", options.media);
11855
+ wrapper.setAttribute("style", "display: contents");
11856
+ let json;
11857
+ try {
11858
+ json = JSON.stringify(props ?? null);
11859
+ } catch (err) {
11860
+ throw new Error(`[SibuJS SSR] island "${name}": props must be JSON-serializable`, { cause: err });
11861
+ }
11862
+ wrapper.setAttribute(ISLAND_PROPS_ATTR, json);
11863
+ const scope = isServer() ? {
11864
+ p: "",
11865
+ n: 0,
11866
+ s: {
11867
+ on: true,
11868
+ el(tag, ns, id) {
11869
+ const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
11870
+ el.setAttribute(ADOPT_ID_ATTR, id);
11871
+ return el;
11872
+ }
11873
+ }
11874
+ } : null;
11875
+ wrapper.appendChild(inScope(scope, () => component(props)));
11876
+ return wrapper;
11877
+ }
11878
+
11879
+ // src/platform/ssrStream.ts
11880
+ var hookInstalled = false;
11881
+ function installHook() {
11882
+ if (hookInstalled) return;
11883
+ hookInstalled = true;
11884
+ setBoundaryHook((container) => {
11885
+ const state3 = requestSlot("stream");
11886
+ const store = getRequestStore();
11887
+ if (!state3 || !store) return null;
11888
+ const id = `sibu-sus-${store.suspenseIdCounter++}`;
11889
+ container.setAttribute("data-sibu-suspense-id", id);
11890
+ const record = {
11891
+ id,
11892
+ container,
11893
+ done: false,
11894
+ emitted: false,
11895
+ fallbackHtml: null,
11896
+ api: {
11897
+ enter: (fn) => {
11898
+ if (record.fallbackHtml === null && state3.serialize) {
11899
+ record.fallbackHtml = Array.from(container.childNodes, (n) => state3.serialize?.(n) ?? "").join("");
11900
+ }
11901
+ return runInBoundary(record.api, fn);
11902
+ },
11903
+ done: () => {
11904
+ record.done = true;
11905
+ store.wake?.();
11906
+ }
11907
+ }
11908
+ };
11909
+ state3.boundaries.push(record);
11910
+ return record.api;
11911
+ });
11912
+ }
11913
+ function createChannel() {
11914
+ const chunks = [];
11915
+ let taken = null;
11916
+ let arrived = null;
11917
+ let ended = false;
11918
+ let cancelled = false;
11919
+ let error;
11920
+ return {
11921
+ get cancelled() {
11922
+ return cancelled;
11923
+ },
11924
+ async push(chunk) {
11925
+ if (cancelled || chunk === "") return;
11926
+ chunks.push(chunk);
11927
+ arrived?.();
11928
+ arrived = null;
11929
+ await new Promise((resolve) => {
11930
+ taken = resolve;
11931
+ });
11932
+ },
11933
+ end() {
11934
+ ended = true;
11935
+ arrived?.();
11936
+ },
11937
+ fail(err) {
11938
+ error = err;
11939
+ ended = true;
11940
+ arrived?.();
11941
+ },
11942
+ /** Called on cancel, so a renderer waiting for a boundary stops at once. */
11943
+ onCancel: null,
11944
+ cancel() {
11945
+ cancelled = true;
11946
+ taken?.();
11947
+ this.onCancel?.();
11948
+ },
11949
+ async take() {
11950
+ for (; ; ) {
11951
+ if (chunks.length > 0) {
11952
+ const value = chunks.shift();
11953
+ const release = taken;
11954
+ taken = null;
11955
+ release?.();
11956
+ return { value, done: false };
11957
+ }
11958
+ if (error !== void 0) throw error;
11959
+ if (ended) return { done: true };
11960
+ await new Promise((resolve) => {
11961
+ arrived = resolve;
11962
+ });
11963
+ }
11964
+ }
11965
+ };
11966
+ }
11967
+ var macrotask2 = () => new Promise((resolve) => {
11968
+ if (typeof setImmediate === "function") setImmediate(resolve);
11969
+ else setTimeout(resolve, 0);
11970
+ });
11971
+ async function waitFor(ready, deadline, stop2) {
11972
+ const store = getRequestStore();
11973
+ for (; ; ) {
11974
+ await macrotask2();
11975
+ if (stop2()) return false;
11976
+ if (ready()) {
11977
+ await macrotask2();
11978
+ if (ready()) return true;
11979
+ continue;
11980
+ }
11981
+ const remaining = deadline - Date.now();
11982
+ if (remaining <= 0) return false;
11983
+ await new Promise((resolve) => {
11984
+ const done = () => {
11985
+ clearTimeout(timer);
11986
+ if (store && store.wake === done) store.wake = null;
11987
+ resolve();
11988
+ };
11989
+ const timer = setTimeout(done, Math.min(remaining, 50));
11990
+ if (store) store.wake = done;
11991
+ });
11992
+ }
11993
+ }
11994
+ function pendingFor(pending, boundary) {
11995
+ if (!pending) return false;
11996
+ for (const work of pending) if (work.boundary === boundary) return true;
11997
+ return false;
11998
+ }
11999
+ function streamPage(input2, options = {}) {
12000
+ assertRequestIsolation("renderToReadableStream()");
12001
+ installHook();
12002
+ const channel = createChannel();
12003
+ const nonce = options.nonce;
12004
+ const doc = options.document === false ? null : options.document ?? {};
12005
+ const MARK_BODY = "<sibu-stream-body>";
12006
+ const MARK_END = "<sibu-stream-end>";
12007
+ void runInSSRContext(async () => {
12008
+ const store = getRequestStore();
12009
+ const state3 = { boundaries: [], serialize: null };
12010
+ requestSlot("stream", () => state3);
12011
+ const errors = [];
12012
+ if (store) store.errors = errors;
12013
+ let holder = null;
12014
+ channel.onCancel = () => store?.wake?.();
12015
+ const failIfErrored = () => {
12016
+ if (errors.length > 0) throw renderFailure(errors[0]);
12017
+ };
12018
+ const stopWaiting = () => errors.length > 0 || channel.cancelled;
12019
+ try {
12020
+ ensureServerDom();
12021
+ watchBrowserApis();
12022
+ const ids = options.hydration === "adopt" ? /* @__PURE__ */ new WeakMap() : null;
12023
+ const scope = ids ? createServerAdoptScope(ids) : null;
12024
+ let root;
12025
+ try {
12026
+ root = inScope(scope, input2);
12027
+ } catch (err) {
12028
+ throw explainServerError(err);
12029
+ }
12030
+ const serialize = (node) => renderToStringWith(node, { marker: options.marker ?? "root", ids });
12031
+ state3.serialize = serialize;
12032
+ holder = document.createDocumentFragment();
12033
+ holder.appendChild(root);
12034
+ const ready = (b2) => b2.done && !pendingFor(store?.pending, b2.api);
12035
+ const serializeWithFallbacks = (node) => {
12036
+ const held = [];
12037
+ for (const b2 of state3.boundaries) {
12038
+ if (ready(b2) || b2.container === node || !node.contains(b2.container)) continue;
12039
+ if (held.some((h) => h.b.container.contains(b2.container))) continue;
12040
+ const nodes = Array.from(b2.container.childNodes);
12041
+ for (const n of nodes) b2.container.removeChild(n);
12042
+ const mark2 = document.createComment(`sibu-fallback:${b2.id}`);
12043
+ b2.container.appendChild(mark2);
12044
+ held.push({ b: b2, nodes, mark: mark2 });
12045
+ }
12046
+ let html2 = serialize(node);
12047
+ for (const { b: b2, nodes, mark: mark2 } of held) {
12048
+ b2.container.removeChild(mark2);
12049
+ for (const n of nodes) b2.container.appendChild(n);
12050
+ const fallback = b2.fallbackHtml ?? "";
12051
+ html2 = html2.replace(`<!--sibu-fallback:${b2.id}-->`, () => fallback);
12052
+ }
12053
+ return html2;
12054
+ };
12055
+ const shellDeadline = Date.now() + (options.shellTimeout ?? 5e3);
12056
+ await waitFor(() => !pendingFor(store?.pending, void 0), shellDeadline, stopWaiting);
12057
+ failIfErrored();
12058
+ if (channel.cancelled) return;
12059
+ for (const b2 of state3.boundaries) {
12060
+ const inline = (x) => x.done && !pendingFor(store?.pending, x.api);
12061
+ const enclosing = state3.boundaries.filter((a2) => a2 !== b2 && a2.container.contains(b2.container));
12062
+ if (inline(b2) && enclosing.every(inline)) b2.emitted = true;
12063
+ }
12064
+ const shell = serializeWithFallbacks(holder);
12065
+ const head2 = collectServerHead();
12066
+ let after = "";
12067
+ let between = "";
12068
+ if (doc) {
12069
+ const page = assembleDocument(MARK_BODY, doc, head2, MARK_END);
12070
+ const bodyAt = page.indexOf(MARK_BODY);
12071
+ const endAt = page.indexOf(MARK_END, bodyAt + MARK_BODY.length);
12072
+ const start = page.slice(0, bodyAt);
12073
+ between = page.slice(bodyAt + MARK_BODY.length, endAt);
12074
+ after = page.slice(endAt + MARK_END.length);
12075
+ await channel.push(start + shell);
12076
+ } else {
12077
+ await channel.push(shell);
12078
+ }
12079
+ if (channel.cancelled) return;
12080
+ failIfErrored();
12081
+ const deadline = Date.now() + (options.timeout ?? 1e4);
12082
+ const outstanding = () => state3.boundaries.filter((b2) => !b2.emitted);
12083
+ const ancestorsOf = (b2) => state3.boundaries.filter((a2) => a2 !== b2 && a2.container.contains(b2.container));
12084
+ const emittable = (b2) => ready(b2) && ancestorsOf(b2).every((a2) => a2.emitted);
12085
+ let bodyClosed = false;
12086
+ for (; ; ) {
12087
+ if (outstanding().length === 0) break;
12088
+ const next = outstanding().find(emittable);
12089
+ if (!next) {
12090
+ const progressed = await waitFor(
12091
+ () => outstanding().some(emittable) || outstanding().length === 0,
12092
+ deadline,
12093
+ stopWaiting
12094
+ );
12095
+ if (channel.cancelled) return;
12096
+ failIfErrored();
12097
+ if (!progressed) break;
12098
+ continue;
12099
+ }
12100
+ failIfErrored();
12101
+ if (!bodyClosed && doc) {
12102
+ await channel.push(between);
12103
+ bodyClosed = true;
12104
+ if (channel.cancelled) return;
12105
+ failIfErrored();
12106
+ }
12107
+ for (const b2 of state3.boundaries) {
12108
+ if (b2 === next || !next.container.contains(b2.container) || !ready(b2)) continue;
12109
+ const between2 = ancestorsOf(b2).filter((a2) => a2 !== next && next.container.contains(a2.container));
12110
+ if (between2.every(ready)) b2.emitted = true;
12111
+ }
12112
+ next.emitted = true;
12113
+ if (!next.container.isConnected && !holder.contains(next.container)) continue;
12114
+ let html2 = "";
12115
+ for (const child of Array.from(next.container.childNodes)) html2 += serializeWithFallbacks(child);
12116
+ await channel.push(
12117
+ `<div hidden id="sibu-resolved-${next.id}">${html2}</div>${suspenseSwapScript(next.id, nonce)}`
12118
+ );
12119
+ if (channel.cancelled) return;
12120
+ failIfErrored();
12121
+ }
12122
+ if (DEV && outstanding().length > 0) {
12123
+ console.warn(
12124
+ `[SibuJS SSR] streaming: ${outstanding().length} Suspense boundar${outstanding().length === 1 ? "y" : "ies"} did not resolve within ${options.timeout ?? 1e4} ms and kept the fallback.`
12125
+ );
12126
+ }
12127
+ failIfErrored();
12128
+ let stateScript = "";
12129
+ if (options.transfer !== false) {
12130
+ const data2 = collectTransfer();
12131
+ if (data2) {
12132
+ try {
12133
+ stateScript = serializeState(data2, nonce, {
12134
+ maxBytes: options.maxStateBytes ?? DEFAULT_TRANSFER_MAX_BYTES,
12135
+ global: "__SIBU_TRANSFER__"
12136
+ });
12137
+ } catch (err) {
12138
+ if (DEV) console.warn("[SibuJS SSR] streaming: transferred state left out:", err);
12139
+ }
12140
+ }
12141
+ }
12142
+ if (doc) {
12143
+ await channel.push((bodyClosed ? "" : between) + stateScript + after);
12144
+ } else if (stateScript) {
12145
+ await channel.push(stateScript);
12146
+ }
12147
+ channel.end();
12148
+ } catch (err) {
12149
+ channel.fail(err);
12150
+ } finally {
12151
+ if (store) store.errors = void 0;
12152
+ if (holder) for (const child of Array.from(holder.childNodes)) dispose(child);
12153
+ }
12154
+ });
12155
+ return new ReadableStream({
12156
+ async pull(controller) {
12157
+ const { value, done } = await channel.take();
12158
+ if (done) controller.close();
12159
+ else controller.enqueue(value);
12160
+ },
12161
+ cancel() {
12162
+ channel.cancel();
12163
+ }
12164
+ });
12165
+ }
12166
+
12167
+ // src/platform/ssr.ts
12168
+ function isForbiddenSsrAttr(lowerName) {
12169
+ return isHtmlContentAttribute(lowerName);
12170
+ }
12171
+ var SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
12172
+ function isSafeAttrName(name) {
12173
+ return SAFE_ATTR_NAME.test(name);
12174
+ }
12175
+ function ssrErrorComment(err) {
12176
+ if (DEV) {
12177
+ const msg = escapeHtml(err instanceof Error ? err.message : String(err));
12178
+ return `<!--SSR error: ${safeCommentText(msg)}-->`;
12179
+ }
12180
+ return "<!--SSR error-->";
12181
+ }
12182
+ function safeCommentText(text2) {
12183
+ return text2.replace(/-->/g, "--&gt;").replace(/--!>/g, "--!&gt;").replace(/<!--/g, "&lt;!--").replace(/^(-?)>/, "$1&gt;").replace(/<!-$/, "&lt;!-").replace(/--$/g, "--&#45;");
12184
+ }
12185
+ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
12186
+ "area",
12187
+ "base",
12188
+ "br",
12189
+ "col",
12190
+ "embed",
12191
+ "hr",
12192
+ "img",
12193
+ "input",
12194
+ "link",
12195
+ "meta",
12196
+ "param",
12197
+ "source",
12198
+ "track",
12199
+ "wbr"
12200
+ ]);
12201
+ function findNativeGetter(proto, name) {
12202
+ for (let p2 = proto; p2; p2 = Object.getPrototypeOf(p2)) {
12203
+ const get = Object.getOwnPropertyDescriptor(p2, name)?.get;
12204
+ if (get) return get;
12205
+ }
12206
+ return null;
12207
+ }
12208
+ var nativeAccessorsByRealm = /* @__PURE__ */ new WeakMap();
12209
+ function nativeAccessors() {
12210
+ const realm = Element;
12211
+ let accessors = nativeAccessorsByRealm.get(realm);
12212
+ if (!accessors) {
12213
+ accessors = {
12214
+ attributes: findNativeGetter(Element.prototype, "attributes"),
12215
+ tagName: findNativeGetter(Element.prototype, "tagName"),
12216
+ childNodes: findNativeGetter(Node.prototype, "childNodes"),
12217
+ getAttribute: Element.prototype.getAttribute
12218
+ };
12219
+ nativeAccessorsByRealm.set(realm, accessors);
12220
+ }
12221
+ return accessors;
12222
+ }
12223
+ function attributesOf(el) {
9044
12224
  const get = nativeAccessors().attributes;
9045
12225
  return get ? get.call(el) : el.attributes;
9046
12226
  }
@@ -9055,8 +12235,8 @@ function childNodesOf(node) {
9055
12235
  function getAttributeOf(el, name) {
9056
12236
  return nativeAccessors().getAttribute.call(el, name);
9057
12237
  }
9058
- var SVG_NS3 = "http://www.w3.org/2000/svg";
9059
- var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
12238
+ var SVG_NS4 = "http://www.w3.org/2000/svg";
12239
+ var MATHML_NS2 = "http://www.w3.org/1998/Math/MathML";
9060
12240
  var XLINK_NS2 = "http://www.w3.org/1999/xlink";
9061
12241
  var XML_NS2 = "http://www.w3.org/XML/1998/namespace";
9062
12242
  var XMLNS_NS = "http://www.w3.org/2000/xmlns/";
@@ -9111,21 +12291,21 @@ function isBreakout(lowerName, element) {
9111
12291
  return lowerName === "font" && (element.hasAttribute("color") || element.hasAttribute("face") || element.hasAttribute("size"));
9112
12292
  }
9113
12293
  function fitsParseContext(ns, lowerName, element, context) {
9114
- if (ns === SVG_NS3) {
12294
+ if (ns === SVG_NS4) {
9115
12295
  if (context === 1 /* Svg */) return !isBreakout(lowerName, element);
9116
12296
  return lowerName === "svg" && (context === 0 /* Html */ || context === 3 /* Annotation */);
9117
12297
  }
9118
- if (ns === MATHML_NS) {
12298
+ if (ns === MATHML_NS2) {
9119
12299
  if (context === 2 /* Math */ || context === 3 /* Annotation */) return !isBreakout(lowerName, element);
9120
12300
  return lowerName === "math" && context === 0 /* Html */;
9121
12301
  }
9122
12302
  return context === 0 /* Html */;
9123
12303
  }
9124
12304
  function childParseContext(ns, lowerName, element) {
9125
- if (ns === SVG_NS3) {
12305
+ if (ns === SVG_NS4) {
9126
12306
  return lowerName === "foreignobject" || lowerName === "desc" || lowerName === "title" ? 0 /* Html */ : 1 /* Svg */;
9127
12307
  }
9128
- if (ns === MATHML_NS) {
12308
+ if (ns === MATHML_NS2) {
9129
12309
  if (lowerName === "mi" || lowerName === "mo" || lowerName === "mn" || lowerName === "ms" || lowerName === "mtext") {
9130
12310
  return 0 /* Html */;
9131
12311
  }
@@ -9144,7 +12324,8 @@ function foreignAttrName(attr) {
9144
12324
  if (ns === XMLNS_NS) return attr.localName === "xmlns" ? "xmlns" : `xmlns:${attr.localName}`;
9145
12325
  return attr.name;
9146
12326
  }
9147
- function serializeOpenTag(element, tag, foreign) {
12327
+ var LEGACY_SERIALIZE = { marker: "all", ids: null };
12328
+ function serializeOpenTag(element, tag, foreign, opts, depth) {
9148
12329
  let html2 = `<${tag}`;
9149
12330
  const meta2 = tag === "meta" && !foreign ? /* @__PURE__ */ new Map() : null;
9150
12331
  const embed2 = tag === "iframe" && !foreign ? getEmbedRecord(element) : void 0;
@@ -9173,18 +12354,20 @@ function serializeOpenTag(element, tag, foreign) {
9173
12354
  if (tail === null) return null;
9174
12355
  html2 += tail;
9175
12356
  }
9176
- if (!getAttributeOf(element, "data-sibu-hydrate")) {
12357
+ const hid = opts.ids?.get(element);
12358
+ if (hid !== void 0) html2 += ` data-sibu-h="${hid}"`;
12359
+ if ((opts.marker === "all" || opts.marker === "root" && depth === 0) && !getAttributeOf(element, "data-sibu-hydrate")) {
9177
12360
  html2 += ` data-sibu-ssr="true"`;
9178
12361
  }
9179
12362
  return html2;
9180
12363
  }
9181
- function serializeNode(node, context) {
12364
+ function serializeNode(node, context, opts = LEGACY_SERIALIZE, depth = 0) {
9182
12365
  if (node.nodeType === 3) return escapeHtml(node.textContent || "");
9183
12366
  if (node.nodeType === 8) return `<!--${safeCommentText(node.textContent || "")}-->`;
9184
12367
  let foreign = false;
9185
12368
  if (!(node instanceof HTMLElement)) {
9186
12369
  const ns2 = node.nodeType === 1 ? node.namespaceURI : null;
9187
- if (ns2 !== SVG_NS3 && ns2 !== MATHML_NS) return escapeHtml(node.textContent || "");
12370
+ if (ns2 !== SVG_NS4 && ns2 !== MATHML_NS2) return escapeHtml(node.textContent || "");
9188
12371
  foreign = true;
9189
12372
  }
9190
12373
  const element = node;
@@ -9194,7 +12377,7 @@ function serializeNode(node, context) {
9194
12377
  const ns = foreign ? element.namespaceURI : null;
9195
12378
  const lowerName = tag.toLowerCase();
9196
12379
  if (!fitsParseContext(ns, lowerName, element, context)) return DEV ? `<!--ssr:${tag}-misplaced-->` : "";
9197
- const openTag = serializeOpenTag(element, tag, foreign);
12380
+ const openTag = serializeOpenTag(element, tag, foreign, opts, depth);
9198
12381
  if (openTag === null) return DEV ? `<!--ssr:${tag}-stripped-->` : "";
9199
12382
  const children = childNodesOf(element);
9200
12383
  if (foreign ? children.length === 0 : VOID_ELEMENTS.has(tag)) return `${openTag} />`;
@@ -9206,31 +12389,45 @@ function serializeNode(node, context) {
9206
12389
  };
9207
12390
  }
9208
12391
  function renderToString(element) {
9209
- return renderNodeToString(element, 0 /* Html */);
12392
+ return renderNodeToString(element, 0 /* Html */, LEGACY_SERIALIZE, 0);
9210
12393
  }
9211
- function renderNodeToString(element, context) {
12394
+ function renderToStringWith(element, opts) {
12395
+ return renderNodeToString(element, 0 /* Html */, opts, 0);
12396
+ }
12397
+ function renderNodeToString(element, context, opts, depth) {
9212
12398
  if (element instanceof DocumentFragment) {
12399
+ let prevText2 = false;
9213
12400
  return Array.from(element.childNodes).map((child) => {
12401
+ const isText = child.nodeType === 3;
12402
+ const sep = opts.ids && isText && prevText2 ? "<!--|-->" : "";
12403
+ prevText2 = isText;
9214
12404
  try {
9215
- return renderNodeToString(child, context);
12405
+ return sep + renderNodeToString(child, context, opts, depth);
9216
12406
  } catch (err) {
9217
12407
  return ssrErrorComment(err);
9218
12408
  }
9219
12409
  }).join("");
9220
12410
  }
9221
- const frame = serializeNode(element, context);
12411
+ const frame = serializeNode(element, context, opts, depth);
9222
12412
  if (typeof frame === "string") return frame;
9223
12413
  let html2 = frame.open;
12414
+ let prevText = false;
9224
12415
  for (const child of frame.children) {
12416
+ const isText = child.nodeType === 3;
12417
+ if (opts.ids && isText && prevText) html2 += "<!--|-->";
12418
+ prevText = isText;
9225
12419
  try {
9226
- html2 += renderNodeToString(child, frame.context);
12420
+ html2 += renderNodeToString(child, frame.context, opts, depth + 1);
9227
12421
  } catch (err) {
9228
12422
  html2 += ssrErrorComment(err);
9229
12423
  }
9230
12424
  }
9231
12425
  return html2 + frame.close;
9232
12426
  }
9233
- function hydrate(component, container, options = {}) {
12427
+ function hydrate(component, target, input2 = {}) {
12428
+ if (input2.strategy === "adopt") return hydrateAdopt(component, target, input2);
12429
+ const options = input2;
12430
+ const container = target;
9234
12431
  const clientTree = component();
9235
12432
  if (options.diagnostics) {
9236
12433
  const mismatches = [];
@@ -9386,6 +12583,9 @@ function renderToDocument(component, options = {}) {
9386
12583
  } catch (err) {
9387
12584
  content = ssrErrorComment(err);
9388
12585
  }
12586
+ return assembleDocument(content, options, "", "");
12587
+ }
12588
+ function assembleDocument(content, options, head2, bodyEnd) {
9389
12589
  const metaTags = (options.meta || []).map((attrs) => serializeHeadEntry("meta", attrs)).filter(Boolean).join("\n ");
9390
12590
  const linkTags = (options.links || []).map((attrs) => serializeHeadEntry("link", attrs)).filter(Boolean).join("\n ");
9391
12591
  const scriptTags = (options.scripts || []).map((src) => {
@@ -9403,10 +12603,12 @@ function renderToDocument(component, options = {}) {
9403
12603
  ${options.title != null ? `<title>${escapeHtml(options.title)}</title>` : ""}
9404
12604
  ${metaTags}
9405
12605
  ${linkTags}
9406
- ${options.headExtra || ""}
12606
+ ${options.headExtra || ""}${head2 ? `
12607
+ ${head2}` : ""}
9407
12608
  </head>
9408
12609
  <body${bodyAttrs}>
9409
- <div id="app">${content}</div>
12610
+ <div id="app">${content}</div>${bodyEnd ? `
12611
+ ${bodyEnd}` : ""}
9410
12612
  ${scriptTags}
9411
12613
  </body>
9412
12614
  </html>`;
@@ -9447,7 +12649,8 @@ async function collectStream(stream2) {
9447
12649
  }
9448
12650
  return result;
9449
12651
  }
9450
- function renderToReadableStream(element) {
12652
+ function renderToReadableStream(element, options) {
12653
+ if (typeof element === "function") return streamPage(element, options);
9451
12654
  const generator = renderToStream(element);
9452
12655
  return new ReadableStream({
9453
12656
  async pull(controller) {
@@ -9464,7 +12667,8 @@ function renderToReadableStream(element) {
9464
12667
  });
9465
12668
  }
9466
12669
  var SAFE_ID = /^[A-Za-z0-9_-]+$/;
9467
- function island(id, component) {
12670
+ function island(id, component, ...rest) {
12671
+ if (rest.length > 0) return componentIsland(id, component, rest[0], rest[1]);
9468
12672
  if (!SAFE_ID.test(id)) {
9469
12673
  throw new Error(`[SibuJS SSR] island: id must match [A-Za-z0-9_-]+ (got: ${JSON.stringify(id.slice(0, 32))})`);
9470
12674
  }
@@ -9598,16 +12802,22 @@ function escapeScriptJson(json) {
9598
12802
  return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
9599
12803
  }
9600
12804
  var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
12805
+ var SAFE_GLOBAL_NAME = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
9601
12806
  function serializeState(state3, nonce, options) {
12807
+ const globalName = options?.global ?? SSR_DATA_ATTR;
12808
+ if (!SAFE_GLOBAL_NAME.test(globalName)) {
12809
+ throw new Error(`[SibuJS SSR] serializeState: global must be an identifier (got: ${JSON.stringify(globalName)})`);
12810
+ }
9602
12811
  const rawJson = JSON.stringify(state3);
9603
12812
  const maxBytes = options?.maxBytes ?? DEFAULT_MAX_SSR_BYTES;
9604
12813
  const byteLen = typeof TextEncoder !== "undefined" ? new TextEncoder().encode(rawJson).byteLength : Buffer.byteLength(rawJson, "utf8");
9605
12814
  if (byteLen > maxBytes) {
9606
12815
  throw new Error(`[SibuJS SSR] serializeState: payload (${byteLen} bytes) exceeds maxBytes (${maxBytes})`);
9607
12816
  }
9608
- const json = escapeScriptJson(rawJson);
12817
+ const value = rawJson.includes('"__proto__":') ? `JSON.parse(${JSON.stringify(rawJson)})` : rawJson;
12818
+ const json = escapeScriptJson(value);
9609
12819
  const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : "";
9610
- return `<script${nonceAttr}>window.${SSR_DATA_ATTR}=${json}</script>`;
12820
+ return `<script${nonceAttr}>window.${globalName}=${json}</script>`;
9611
12821
  }
9612
12822
  function deserializeState(validate) {
9613
12823
  if (typeof window === "undefined") return void 0;
@@ -9657,14 +12867,14 @@ function block(factory) {
9657
12867
  function dict(source2) {
9658
12868
  const out = /* @__PURE__ */ Object.create(null);
9659
12869
  if (source2) {
9660
- for (const key of Object.keys(source2)) defineOwn(out, key, source2[key]);
12870
+ for (const key of Object.keys(source2)) defineOwn2(out, key, source2[key]);
9661
12871
  }
9662
12872
  return out;
9663
12873
  }
9664
12874
  function ownGet(obj, key) {
9665
12875
  return obj !== void 0 && Object.hasOwn(obj, key) ? obj[key] : void 0;
9666
12876
  }
9667
- function defineOwn(obj, key, value) {
12877
+ function defineOwn2(obj, key, value) {
9668
12878
  Object.defineProperty(obj, key, { value, writable: true, enumerable: true, configurable: true });
9669
12879
  }
9670
12880
  function readEntityId(entity, idKey, typeName) {
@@ -9687,7 +12897,7 @@ function normalizedStore(schema) {
9687
12897
  setState((prev) => {
9688
12898
  const ids = Object.hasOwn(prev.entities, id) ? prev.ids : [...prev.ids, id];
9689
12899
  const entities = dict(prev.entities);
9690
- defineOwn(entities, id, entity);
12900
+ defineOwn2(entities, id, entity);
9691
12901
  return { ids, entities };
9692
12902
  });
9693
12903
  }
@@ -9701,7 +12911,7 @@ function normalizedStore(schema) {
9701
12911
  if (!Object.hasOwn(nextEntities, id)) {
9702
12912
  nextIds.push(id);
9703
12913
  }
9704
- defineOwn(nextEntities, id, entity);
12914
+ defineOwn2(nextEntities, id, entity);
9705
12915
  });
9706
12916
  return { ids: nextIds, entities: nextEntities };
9707
12917
  });
@@ -9724,12 +12934,12 @@ function normalizedStore(schema) {
9724
12934
  );
9725
12935
  }
9726
12936
  }
9727
- setState((current) => {
9728
- const existing = ownGet(current.entities, id);
9729
- if (!existing) return current;
9730
- const entities = dict(current.entities);
9731
- defineOwn(entities, id, { ...existing, ...partial });
9732
- return { ids: current.ids, entities };
12937
+ setState((current2) => {
12938
+ const existing = ownGet(current2.entities, id);
12939
+ if (!existing) return current2;
12940
+ const entities = dict(current2.entities);
12941
+ defineOwn2(entities, id, { ...existing, ...partial });
12942
+ return { ids: current2.ids, entities };
9733
12943
  });
9734
12944
  }
9735
12945
  function remove(id) {
@@ -9755,7 +12965,7 @@ function normalize(data2, schema) {
9755
12965
  let table2 = ownGet(entities, name);
9756
12966
  if (!table2) {
9757
12967
  table2 = dict();
9758
- defineOwn(entities, name, table2);
12968
+ defineOwn2(entities, name, table2);
9759
12969
  }
9760
12970
  return table2;
9761
12971
  }
@@ -9770,17 +12980,17 @@ function normalize(data2, schema) {
9770
12980
  if (value == null) continue;
9771
12981
  const relSchema = { name: relationType };
9772
12982
  if (Array.isArray(value)) {
9773
- defineOwn(
12983
+ defineOwn2(
9774
12984
  flat,
9775
12985
  field,
9776
12986
  value.map((item) => normalizeEntity(item, relSchema))
9777
12987
  );
9778
12988
  } else if (typeof value === "object") {
9779
- defineOwn(flat, field, normalizeEntity(value, relSchema));
12989
+ defineOwn2(flat, field, normalizeEntity(value, relSchema));
9780
12990
  }
9781
12991
  }
9782
12992
  }
9783
- defineOwn(table2, id, flat);
12993
+ defineOwn2(table2, id, flat);
9784
12994
  return id;
9785
12995
  }
9786
12996
  if (Array.isArray(data2)) {
@@ -9802,13 +13012,13 @@ function denormalize(id, entities, schema) {
9802
13012
  if (value == null) continue;
9803
13013
  const relSchema = { name: relationType };
9804
13014
  if (Array.isArray(value)) {
9805
- defineOwn(
13015
+ defineOwn2(
9806
13016
  result,
9807
13017
  field,
9808
13018
  value.map((relId) => denormalize(relId, entities, relSchema))
9809
13019
  );
9810
13020
  } else if (typeof value === "string") {
9811
- defineOwn(result, field, denormalize(value, entities, relSchema));
13021
+ defineOwn2(result, field, denormalize(value, entities, relSchema));
9812
13022
  }
9813
13023
  }
9814
13024
  }
@@ -9836,7 +13046,7 @@ function createChunkRegistry(config = {}) {
9836
13046
  const cache = /* @__PURE__ */ new Map();
9837
13047
  const pending = /* @__PURE__ */ new Map();
9838
13048
  const preloaded = /* @__PURE__ */ new Map();
9839
- function notify(name, run) {
13049
+ function notify2(name, run) {
9840
13050
  try {
9841
13051
  run();
9842
13052
  } catch (err) {
@@ -9908,7 +13118,7 @@ function createChunkRegistry(config = {}) {
9908
13118
  const entry = { promise: outcome };
9909
13119
  pending.set(id, entry);
9910
13120
  const owns = () => pending.get(id) === entry;
9911
- notify("onLoadStart", () => onLoadStart?.(id));
13121
+ notify2("onLoadStart", () => onLoadStart?.(id));
9912
13122
  void loadWithRetry(id, loader).then(
9913
13123
  (value) => {
9914
13124
  if (owns()) {
@@ -9917,13 +13127,13 @@ function createChunkRegistry(config = {}) {
9917
13127
  const now = Date.now();
9918
13128
  cache.set(id, { value, timestamp: now, lastAccess: now, accessCount: 1 });
9919
13129
  }
9920
- notify("onLoadEnd", () => onLoadEnd?.(id));
13130
+ notify2("onLoadEnd", () => onLoadEnd?.(id));
9921
13131
  resolveOuter(value);
9922
13132
  },
9923
13133
  (err) => {
9924
13134
  if (owns()) pending.delete(id);
9925
13135
  const error = err instanceof Error ? err : new Error(String(err));
9926
- notify("onLoadError", () => onLoadError?.(id, error));
13136
+ notify2("onLoadError", () => onLoadError?.(id, error));
9927
13137
  rejectOuter(error);
9928
13138
  }
9929
13139
  ).catch((internal) => {
@@ -10009,9 +13219,9 @@ function createChunkRegistry(config = {}) {
10009
13219
  }
10010
13220
  };
10011
13221
  }
10012
- function lazyChunk(id, loader, registry, fallback) {
13222
+ function lazyChunk(id, loader, registry2, fallback) {
10013
13223
  return () => {
10014
- const cached = registry.get(id);
13224
+ const cached = registry2.get(id);
10015
13225
  if (cached) return cached();
10016
13226
  const container = document.createElement("div");
10017
13227
  container.setAttribute("data-chunk", id);
@@ -10022,7 +13232,7 @@ function lazyChunk(id, loader, registry, fallback) {
10022
13232
  registerDisposer(container, () => {
10023
13233
  disposed = true;
10024
13234
  });
10025
- registry.load(id, async () => {
13235
+ registry2.load(id, async () => {
10026
13236
  const mod = await loader();
10027
13237
  return typeof mod === "function" ? mod : mod.default;
10028
13238
  }).then(
@@ -10073,18 +13283,18 @@ var CLIENT_RESOLVER = {
10073
13283
  isReactiveValue: (value) => typeof value === "function"
10074
13284
  };
10075
13285
  function applyMetaEntry(metaProps, managedElements) {
10076
- let current = null;
13286
+ let current2 = null;
10077
13287
  const retract = () => {
10078
- if (!current) return;
10079
- const index = managedElements.indexOf(current);
13288
+ if (!current2) return;
13289
+ const index = managedElements.indexOf(current2);
10080
13290
  if (index !== -1) managedElements.splice(index, 1);
10081
- current.remove();
10082
- current = null;
13291
+ current2.remove();
13292
+ current2 = null;
10083
13293
  };
10084
13294
  const alreadyPublished = (attributes) => {
10085
- if (!current || current.attributes.length !== attributes.size) return false;
13295
+ if (!current2 || current2.attributes.length !== attributes.size) return false;
10086
13296
  for (const [name, value] of attributes) {
10087
- if (current.getAttribute(name) !== value) return false;
13297
+ if (current2.getAttribute(name) !== value) return false;
10088
13298
  }
10089
13299
  return true;
10090
13300
  };
@@ -10092,16 +13302,16 @@ function applyMetaEntry(metaProps, managedElements) {
10092
13302
  if (alreadyPublished(attributes)) return;
10093
13303
  const next = document.createElement("meta");
10094
13304
  for (const [name, value] of attributes) next.setAttribute(name, value);
10095
- const index = current ? managedElements.indexOf(current) : -1;
10096
- if (current?.parentNode) {
10097
- current.replaceWith(next);
13305
+ const index = current2 ? managedElements.indexOf(current2) : -1;
13306
+ if (current2?.parentNode) {
13307
+ current2.replaceWith(next);
10098
13308
  } else {
10099
- current?.remove();
13309
+ current2?.remove();
10100
13310
  document.head.appendChild(next);
10101
13311
  }
10102
13312
  if (index !== -1) managedElements[index] = next;
10103
13313
  else managedElements.push(next);
10104
- current = next;
13314
+ current2 = next;
10105
13315
  };
10106
13316
  const stopEffect = effect(() => {
10107
13317
  const plan = planMetaEntry(metaProps, CLIENT_RESOLVER);
@@ -10116,8 +13326,43 @@ function applyMetaEntry(metaProps, managedElements) {
10116
13326
  retract();
10117
13327
  };
10118
13328
  }
13329
+ function headEntryKey(tag, attrs) {
13330
+ const lower = (v) => (v ?? "").toLowerCase();
13331
+ if (tag === "meta") {
13332
+ if (attrs.name) return `meta:name:${lower(attrs.name)}`;
13333
+ if (attrs.property) return `meta:property:${lower(attrs.property)}`;
13334
+ if (attrs["http-equiv"]) return `meta:http-equiv:${lower(attrs["http-equiv"])}`;
13335
+ return `meta:${JSON.stringify(attrs)}`;
13336
+ }
13337
+ const rel = lower(attrs.rel);
13338
+ if (rel === "canonical") return "link:rel:canonical";
13339
+ if (rel === "alternate" && attrs.hreflang) return `link:hreflang:${lower(attrs.hreflang)}`;
13340
+ return `link:${rel}:${attrs.href ?? ""}`;
13341
+ }
13342
+ function resolveHeadForServer(props) {
13343
+ const layer = { tags: [] };
13344
+ if (props.title != null) layer.title = CLIENT_RESOLVER.resolveValue("title", props.title);
13345
+ for (const entry of props.meta ?? []) {
13346
+ const plan = planMetaEntry(entry, CLIENT_RESOLVER);
13347
+ if (plan.kind === "drop") continue;
13348
+ const attrs = Object.fromEntries(plan.attributes);
13349
+ layer.tags.push({ key: headEntryKey("meta", attrs), html: serializePlannedHeadEntry("meta", plan.attributes) });
13350
+ }
13351
+ for (const attrs of props.link ?? []) {
13352
+ const html2 = serializeHeadEntry("link", attrs);
13353
+ if (html2) layer.tags.push({ key: headEntryKey("link", attrs), html: html2 });
13354
+ }
13355
+ return layer;
13356
+ }
13357
+ function recordHeadForServer(props, anchor) {
13358
+ const withdraw = recordServerHead(() => resolveHeadForServer(props));
13359
+ if (!withdraw) return false;
13360
+ registerDisposer(anchor, withdraw);
13361
+ return true;
13362
+ }
10119
13363
  function Head(props) {
10120
13364
  const anchor = document.createComment("sibu-head");
13365
+ if (getRequestStore()?.ssr && recordHeadForServer(props, anchor)) return anchor;
10121
13366
  const managedElements = [];
10122
13367
  const effectCleanups = [];
10123
13368
  const cleanup3 = () => {
@@ -10207,7 +13452,7 @@ function setCanonical(url) {
10207
13452
  }
10208
13453
 
10209
13454
  // src/platform/customElement.ts
10210
- var SVG_NS4 = "http://www.w3.org/2000/svg";
13455
+ var SVG_NS5 = "http://www.w3.org/2000/svg";
10211
13456
  var MAX_RENDER_PASSES = 10;
10212
13457
  var ABANDONED_RENDER = /* @__PURE__ */ Symbol("sibujs.defineElement.abandonedRender");
10213
13458
  function defineElement(name, component, options = {}) {
@@ -10359,7 +13604,7 @@ function svgElement(tag, props = {}, ...nodes) {
10359
13604
  if (isBlockedElement(tag)) {
10360
13605
  throw new Error(`svgElement: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
10361
13606
  }
10362
- const el = document.createElementNS(SVG_NS4, tag);
13607
+ const el = document.createElementNS(SVG_NS5, tag);
10363
13608
  for (const [key, value] of Object.entries(props)) {
10364
13609
  if (key === "nodes") continue;
10365
13610
  if (typeof value === "function" && isEventHandlerAttr(key)) {
@@ -10553,7 +13798,7 @@ function createWorkerPool(workerFn2, poolSize) {
10553
13798
  }
10554
13799
  function dispatchOne(idx) {
10555
13800
  const w = workers[idx];
10556
- const slot2 = queues[idx].shift();
13801
+ const slot4 = queues[idx].shift();
10557
13802
  const onMsg = (e) => {
10558
13803
  if (!firedOnce) {
10559
13804
  firedOnce = true;
@@ -10562,7 +13807,7 @@ function createWorkerPool(workerFn2, poolSize) {
10562
13807
  w.removeEventListener("message", onMsg);
10563
13808
  w.removeEventListener("error", onErr);
10564
13809
  inflight[idx] = null;
10565
- slot2.resolve(e.data);
13810
+ slot4.resolve(e.data);
10566
13811
  dispatchNext(idx);
10567
13812
  };
10568
13813
  const onErr = (e) => {
@@ -10573,16 +13818,16 @@ function createWorkerPool(workerFn2, poolSize) {
10573
13818
  w.removeEventListener("message", onMsg);
10574
13819
  w.removeEventListener("error", onErr);
10575
13820
  inflight[idx] = null;
10576
- slot2.reject(new Error(e.message || "Worker error"));
13821
+ slot4.reject(new Error(e.message || "Worker error"));
10577
13822
  dispatchNext(idx);
10578
13823
  };
10579
13824
  try {
10580
- w.postMessage(slot2.data);
13825
+ w.postMessage(slot4.data);
10581
13826
  } catch (err) {
10582
- slot2.reject(toError(err));
13827
+ slot4.reject(toError(err));
10583
13828
  return;
10584
13829
  }
10585
- inflight[idx] = { ...slot2, onMsg, onErr };
13830
+ inflight[idx] = { ...slot4, onMsg, onErr };
10586
13831
  w.addEventListener("message", onMsg);
10587
13832
  w.addEventListener("error", onErr);
10588
13833
  }
@@ -10922,10 +14167,11 @@ function restoreFocusWithin(snapshot, nodes, where, policy) {
10922
14167
  // src/reactivity/bindChildNode.ts
10923
14168
  function bindChildNode(placeholder, getter) {
10924
14169
  let lastNodes = [];
14170
+ const scope = captureScope();
10925
14171
  function commit() {
10926
14172
  let result;
10927
14173
  try {
10928
- result = getter();
14174
+ result = inScope(scope, getter);
10929
14175
  } catch (err) {
10930
14176
  reportError(err, { phase: "binding", name: "bindChildNode", node: placeholder });
10931
14177
  return;
@@ -11001,7 +14247,7 @@ function noDocument() {
11001
14247
  }
11002
14248
 
11003
14249
  // src/core/rendering/tagFactory.ts
11004
- var SVG_NS5 = "http://www.w3.org/2000/svg";
14250
+ var SVG_NS6 = "http://www.w3.org/2000/svg";
11005
14251
  var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
11006
14252
  "config",
11007
14253
  "location",
@@ -11019,7 +14265,7 @@ var warnedLoneStrings = /* @__PURE__ */ new Set();
11019
14265
  var MAX_WARNED_LONE_STRINGS = 100;
11020
14266
  var loneStringCapAnnounced = false;
11021
14267
  var kebabCache = /* @__PURE__ */ new Map();
11022
- function toKebab(prop) {
14268
+ function toKebab2(prop) {
11023
14269
  let cached = kebabCache.get(prop);
11024
14270
  if (cached !== void 0) return cached;
11025
14271
  cached = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
@@ -11049,7 +14295,7 @@ function applyStyle(el, style2) {
11049
14295
  if (!Object.hasOwn(value, prop)) continue;
11050
14296
  const val = value[prop];
11051
14297
  if (val == null) continue;
11052
- const name = toKebab(prop);
14298
+ const name = toKebab2(prop);
11053
14299
  next.push(name);
11054
14300
  decl.setProperty(name, sanitizeCSSDeclaration(name, String(val), { element: el }));
11055
14301
  }
@@ -11069,7 +14315,7 @@ function applyStyle(el, style2) {
11069
14315
  for (const prop in style2) {
11070
14316
  if (!Object.hasOwn(style2, prop)) continue;
11071
14317
  const val = style2[prop];
11072
- const name = toKebab(prop);
14318
+ const name = toKebab2(prop);
11073
14319
  if (typeof val === "function") {
11074
14320
  const getter = val;
11075
14321
  const teardown = reactiveBinding2(() => {
@@ -11181,7 +14427,7 @@ function tagFactory(tag, ns) {
11181
14427
  throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
11182
14428
  }
11183
14429
  if (typeof document === "undefined") noDocument();
11184
- const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
14430
+ const el = createScopedElement(tag, ns);
11185
14431
  if (first === void 0) return el;
11186
14432
  if (typeof first === "string") {
11187
14433
  if (second !== void 0) {
@@ -11356,7 +14602,7 @@ var param = tagFactory("param");
11356
14602
  var picture = tagFactory("picture");
11357
14603
  var portal = tagFactory("portal");
11358
14604
  var source = tagFactory("source");
11359
- var svg = tagFactory("svg", SVG_NS5);
14605
+ var svg = tagFactory("svg", SVG_NS6);
11360
14606
  var math = tagFactory("math");
11361
14607
  var canvas = tagFactory("canvas");
11362
14608
  var noscript = tagFactory("noscript");
@@ -11391,32 +14637,32 @@ var details = tagFactory("details");
11391
14637
  var dialog2 = tagFactory("dialog");
11392
14638
  var menu = tagFactory("menu");
11393
14639
  var summary = tagFactory("summary");
11394
- var slot = tagFactory("slot");
14640
+ var slot3 = tagFactory("slot");
11395
14641
  var template = tagFactory("template");
11396
14642
  var base = tagFactory("base");
11397
14643
  var link = tagFactory("link");
11398
14644
  var meta = tagFactory("meta");
11399
14645
  var style = tagFactory("style");
11400
- var circle = tagFactory("circle", SVG_NS5);
11401
- var ellipse = tagFactory("ellipse", SVG_NS5);
11402
- var g = tagFactory("g", SVG_NS5);
11403
- var line = tagFactory("line", SVG_NS5);
11404
- var path = tagFactory("path", SVG_NS5);
11405
- var polygon = tagFactory("polygon", SVG_NS5);
11406
- var polyline = tagFactory("polyline", SVG_NS5);
11407
- var rect = tagFactory("rect", SVG_NS5);
11408
- var text = tagFactory("text", SVG_NS5);
11409
- var tspan = tagFactory("tspan", SVG_NS5);
11410
- var defs = tagFactory("defs", SVG_NS5);
11411
- var clipPath = tagFactory("clipPath", SVG_NS5);
11412
- var mask = tagFactory("mask", SVG_NS5);
11413
- var pattern = tagFactory("pattern", SVG_NS5);
11414
- var linearGradient = tagFactory("linearGradient", SVG_NS5);
11415
- var radialGradient = tagFactory("radialGradient", SVG_NS5);
11416
- var stop = tagFactory("stop", SVG_NS5);
11417
- var use = tagFactory("use", SVG_NS5);
11418
- var symbol = tagFactory("symbol", SVG_NS5);
11419
- var marker = tagFactory("marker", SVG_NS5);
14646
+ var circle = tagFactory("circle", SVG_NS6);
14647
+ var ellipse = tagFactory("ellipse", SVG_NS6);
14648
+ var g = tagFactory("g", SVG_NS6);
14649
+ var line = tagFactory("line", SVG_NS6);
14650
+ var path = tagFactory("path", SVG_NS6);
14651
+ var polygon = tagFactory("polygon", SVG_NS6);
14652
+ var polyline = tagFactory("polyline", SVG_NS6);
14653
+ var rect = tagFactory("rect", SVG_NS6);
14654
+ var text = tagFactory("text", SVG_NS6);
14655
+ var tspan = tagFactory("tspan", SVG_NS6);
14656
+ var defs = tagFactory("defs", SVG_NS6);
14657
+ var clipPath = tagFactory("clipPath", SVG_NS6);
14658
+ var mask = tagFactory("mask", SVG_NS6);
14659
+ var pattern = tagFactory("pattern", SVG_NS6);
14660
+ var linearGradient = tagFactory("linearGradient", SVG_NS6);
14661
+ var radialGradient = tagFactory("radialGradient", SVG_NS6);
14662
+ var stop = tagFactory("stop", SVG_NS6);
14663
+ var use = tagFactory("use", SVG_NS6);
14664
+ var symbol = tagFactory("symbol", SVG_NS6);
14665
+ var marker = tagFactory("marker", SVG_NS6);
11420
14666
  var center = tagFactory("center");
11421
14667
  var font = tagFactory("font");
11422
14668
  var marquee = tagFactory("marquee");
@@ -11762,13 +15008,13 @@ function createISR(options) {
11762
15008
  if (inFlight) return inFlight;
11763
15009
  let resolve;
11764
15010
  let reject;
11765
- const current = new Promise((res, rej) => {
15011
+ const current2 = new Promise((res, rej) => {
11766
15012
  resolve = res;
11767
15013
  reject = rej;
11768
15014
  });
11769
- inFlight = current;
15015
+ inFlight = current2;
11770
15016
  const release = () => {
11771
- if (inFlight === current) inFlight = null;
15017
+ if (inFlight === current2) inFlight = null;
11772
15018
  };
11773
15019
  run().then(
11774
15020
  () => {
@@ -11780,7 +15026,7 @@ function createISR(options) {
11780
15026
  reject(err);
11781
15027
  }
11782
15028
  );
11783
- return current;
15029
+ return current2;
11784
15030
  };
11785
15031
  if (initialData === void 0) {
11786
15032
  revalidate().catch((err) => {
@@ -11951,7 +15197,7 @@ function createMiddlewareChain() {
11951
15197
 
11952
15198
  // src/plugins/plugin.ts
11953
15199
  var CANCELLED_BRAND = /* @__PURE__ */ Symbol.for("sibujs.plugins.installCancelled.v1");
11954
- var _a;
15200
+ var _a3;
11955
15201
  var PluginInstallCancelledError = class extends Error {
11956
15202
  constructor(pluginName) {
11957
15203
  super(`[Plugin] Installation of "${pluginName}" was cancelled before it was committed (registry reset).`);
@@ -11960,11 +15206,11 @@ var PluginInstallCancelledError = class extends Error {
11960
15206
  * of this module, so the error a caller receives may come from another copy's
11961
15207
  * constructor. `instanceof` is taught to recognise the brand instead.
11962
15208
  */
11963
- this[_a] = true;
15209
+ this[_a3] = true;
11964
15210
  this.name = "PluginInstallCancelledError";
11965
15211
  this.pluginName = pluginName;
11966
15212
  }
11967
- static [(_a = CANCELLED_BRAND, Symbol.hasInstance)](value) {
15213
+ static [(_a3 = CANCELLED_BRAND, Symbol.hasInstance)](value) {
11968
15214
  return isPluginInstallCancelledError(value);
11969
15215
  }
11970
15216
  };
@@ -11978,7 +15224,7 @@ function createPluginRegistry() {
11978
15224
  const installStack = /* @__PURE__ */ new Set();
11979
15225
  const pendingInstalls = /* @__PURE__ */ new Map();
11980
15226
  let generation = 0;
11981
- const registry = {
15227
+ const registry2 = {
11982
15228
  installedPlugins,
11983
15229
  hooks,
11984
15230
  provided,
@@ -12118,7 +15364,7 @@ function createPluginRegistry() {
12118
15364
  provided.clear();
12119
15365
  }
12120
15366
  };
12121
- return registry;
15367
+ return registry2;
12122
15368
  }
12123
15369
  var _defaults = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.plugins.defaultRegistry.v1"), () => ({
12124
15370
  registry: createPluginRegistry(),
@@ -12147,13 +15393,13 @@ function resetPlugins() {
12147
15393
  _defaults.registry.reset();
12148
15394
  _defaults.touched = false;
12149
15395
  }
12150
- function setDefaultPluginRegistry(registry) {
15396
+ function setDefaultPluginRegistry(registry2) {
12151
15397
  if (_defaults.touched && _defaults.registry.installedPlugins.size > 0) {
12152
15398
  console.warn(
12153
15399
  "[Plugin] Replacing default plugin registry while plugins are already installed on the singleton. This may indicate mixed singleton/registry usage."
12154
15400
  );
12155
15401
  }
12156
- _defaults.registry = registry;
15402
+ _defaults.registry = registry2;
12157
15403
  _defaults.touched = true;
12158
15404
  }
12159
15405
 
@@ -12300,6 +15546,7 @@ var MODULE_ENTRY_POINTS = {
12300
15546
  ui: "./ui.ts",
12301
15547
  widgets: "./widgets.ts",
12302
15548
  ssr: "./ssr.ts",
15549
+ "ssr/dom": "./ssr-dom.ts",
12303
15550
  devtools: "./devtools.ts",
12304
15551
  performance: "./performance.ts",
12305
15552
  ecosystem: "./ecosystem.ts",
@@ -12316,7 +15563,7 @@ var CDN_ENTRY_POINTS = {
12316
15563
  };
12317
15564
  var packageInfo = {
12318
15565
  name: "sibujs",
12319
- version: true ? "4.13.0" : "dev",
15566
+ version: true ? "4.14.0" : "dev",
12320
15567
  entryPoints: MODULE_ENTRY_POINTS,
12321
15568
  /**
12322
15569
  * Generate the package.json `exports` map. Module entries resolve to the
@@ -12461,7 +15708,7 @@ var env = {
12461
15708
  };
12462
15709
 
12463
15710
  // src/plugins/versioning.ts
12464
- var VERSION = true ? "4.13.0" : "dev";
15711
+ var VERSION = true ? "4.14.0" : "dev";
12465
15712
  var NUM = "(?:0|[1-9]\\d*)";
12466
15713
  var PRE_ID = `(?:${NUM}|\\d*[a-zA-Z-][0-9a-zA-Z-]*)`;
12467
15714
  var BUILD_ID = "[0-9a-zA-Z-]+";
@@ -15873,9 +19120,9 @@ function componentAdapter(config) {
15873
19120
  components[name] = (props = {}, children) => {
15874
19121
  const { variant, size, class: userClass, ...rest } = props;
15875
19122
  const themeClasses = () => {
15876
- const current = theme.config();
15877
- const overrides = current.classOverrides ?? {};
15878
- const pick = (key, fallback) => Object.hasOwn(overrides, key) ? overrides[key] : reprefix(fallback, current.prefix);
19123
+ const current2 = theme.config();
19124
+ const overrides = current2.classOverrides ?? {};
19125
+ const pick = (key, fallback) => Object.hasOwn(overrides, key) ? overrides[key] : reprefix(fallback, current2.prefix);
15879
19126
  const classes = [pick(name, mapping.baseClass)];
15880
19127
  const variantClass = ownString(mapping.variants, variant);
15881
19128
  if (variant && variantClass) {
@@ -16129,6 +19376,7 @@ var materialAdapter = componentAdapter(materialConfig);
16129
19376
  announce,
16130
19377
  antdAdapter,
16131
19378
  aria,
19379
+ assembleDocument,
16132
19380
  assertType,
16133
19381
  battery,
16134
19382
  bindAttrs,
@@ -16325,6 +19573,7 @@ var materialAdapter = componentAdapter(materialConfig);
16325
19573
  renderToReadableStream,
16326
19574
  renderToStream,
16327
19575
  renderToString,
19576
+ renderToStringWith,
16328
19577
  renderToSuspenseStream,
16329
19578
  renderWithLoader,
16330
19579
  required,
@@ -16403,6 +19652,7 @@ var materialAdapter = componentAdapter(materialConfig);
16403
19652
  withRetry,
16404
19653
  withScopedStyle,
16405
19654
  withWrapper,
19655
+ withholdTransfer,
16406
19656
  worker,
16407
19657
  workerFn,
16408
19658
  yieldToMain,