sibujs 4.13.1 → 4.14.1

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-J6FW5TV6.js → chunk-3HEX6QJQ.js} +5 -3
  13. package/dist/chunk-3HZOSMPX.js +90 -0
  14. package/dist/{chunk-K4LNUT5L.js → chunk-3T7TWMSD.js} +8 -6
  15. package/dist/{chunk-ADZHPN2B.js → chunk-4XCWNGRY.js} +3 -3
  16. package/dist/{chunk-2NC56RGY.js → chunk-55TAOW5M.js} +2 -2
  17. package/dist/{chunk-G3Z2FEBR.js → chunk-B2NLNZ3E.js} +119 -26
  18. package/dist/{chunk-EXXSN3BW.js → chunk-B3HOT4TK.js} +1 -1
  19. package/dist/{chunk-QKFVMIAV.js → chunk-FCWOMATN.js} +11 -3
  20. package/dist/{chunk-QC3NP47A.js → chunk-FFXZ6ELZ.js} +10 -6
  21. package/dist/{chunk-TUCPL2HB.js → chunk-GIJ33UJZ.js} +1 -1
  22. package/dist/chunk-KTJC7QPA.js +195 -0
  23. package/dist/chunk-L2IPKGUJ.js +2596 -0
  24. package/dist/{chunk-4UTGDVSA.js → chunk-LAHX7XFG.js} +7 -14
  25. package/dist/{chunk-PBJYCE2Z.js → chunk-LJ2LR5P4.js} +5 -5
  26. package/dist/{chunk-AM6DZLBM.js → chunk-LJMX4SQ7.js} +2 -2
  27. package/dist/{chunk-5RIBLY2N.js → chunk-LUZXFMKH.js} +6 -6
  28. package/dist/{chunk-VFPLWUT7.js → chunk-LZKKMDQF.js} +151 -86
  29. package/dist/{chunk-J4X7ICH4.js → chunk-NIHGSXOX.js} +8 -6
  30. package/dist/chunk-NT3ZYB5S.js +167 -0
  31. package/dist/{chunk-2O6JJCUR.js → chunk-OLMZF4RU.js} +49 -8
  32. package/dist/{chunk-22OPSWMF.js → chunk-OPRQW4LI.js} +2 -2
  33. package/dist/chunk-R5U7XKVJ.js +16 -0
  34. package/dist/{chunk-KC62VURU.js → chunk-RBRITLFL.js} +10 -8
  35. package/dist/{chunk-F2UWOZ6J.js → chunk-RVWJGWCL.js} +2 -2
  36. package/dist/{chunk-NYNYSPK7.js → chunk-S37PZD6I.js} +30 -45
  37. package/dist/chunk-TOV4PN3P.js +2015 -0
  38. package/dist/{chunk-C73VBPEF.js → chunk-TS6JDK7Y.js} +8 -8
  39. package/dist/{chunk-EU7T7EB3.js → chunk-TZNR6E6D.js} +4 -4
  40. package/dist/chunk-UYTYNCMZ.js +199 -0
  41. package/dist/{chunk-OIKD7YDY.js → chunk-VIAVYBNQ.js} +6 -5
  42. package/dist/{chunk-QZ47OZ25.js → chunk-WFMMSMA5.js} +8 -6
  43. package/dist/chunk-YIXMS546.js +1901 -0
  44. package/dist/{chunk-5XUGJM3J.js → chunk-YPLQQTWS.js} +1 -1
  45. package/dist/{chunk-CPQKWCJ2.js → chunk-ZKI4SDZ2.js} +16 -10
  46. package/dist/{chunk-YFTBCCVH.js → chunk-ZYK4NZZA.js} +5 -3
  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 +3562 -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 +5267 -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-VBM6J5SJ.js → ssr-HHU3DAD2.js} +15 -6
  84. package/dist/ssr-JpGpHnpC.d.cts +841 -0
  85. package/dist/ssr-JpGpHnpC.d.ts +841 -0
  86. package/dist/ssr-dom.cjs +1904 -0
  87. package/dist/ssr-dom.d.cts +343 -0
  88. package/dist/ssr-dom.d.ts +343 -0
  89. package/dist/ssr-dom.js +19 -0
  90. package/dist/ssr.cjs +7677 -2069
  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 +6585 -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.1" : "dev";
1289
+ var _runtimeVersion = true ? "4.14.1" : "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,2906 @@ 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
+ set nodeValue(v) {
10004
+ this.value = v;
10005
+ }
10006
+ get textContent() {
10007
+ return this._value;
10008
+ }
10009
+ set textContent(v) {
10010
+ this.value = v;
10011
+ }
10012
+ };
10013
+ var ServerNamedNodeMap = class extends Array {
10014
+ static get [Symbol.species]() {
10015
+ return Array;
10016
+ }
10017
+ item(index) {
10018
+ return this[index] ?? null;
10019
+ }
10020
+ getNamedItem(name) {
10021
+ return this.find((a2) => a2.name === name) ?? null;
10022
+ }
10023
+ getNamedItemNS(ns, localName) {
10024
+ return this.find((a2) => a2.namespaceURI === (ns || null) && a2.localName === localName) ?? null;
10025
+ }
10026
+ };
10027
+ function splitDeclarations(text2) {
10028
+ const out = [];
10029
+ let depth = 0;
10030
+ let quote2 = "";
10031
+ let start = 0;
10032
+ for (let i2 = 0; i2 < text2.length; i2++) {
10033
+ const c = text2[i2];
10034
+ if (quote2) {
10035
+ if (c === "\\") i2++;
10036
+ else if (c === quote2) quote2 = "";
10037
+ } else if (c === '"' || c === "'") quote2 = c;
10038
+ else if (c === "(") depth++;
10039
+ else if (c === ")") depth = Math.max(0, depth - 1);
10040
+ else if (c === ";" && depth === 0) {
10041
+ out.push(text2.slice(start, i2));
10042
+ start = i2 + 1;
10043
+ }
10044
+ }
10045
+ out.push(text2.slice(start));
10046
+ return out;
10047
+ }
10048
+ var CAMEL_EXCEPTIONS = { cssFloat: "float" };
10049
+ function toKebab(prop) {
10050
+ if (prop.startsWith("--")) return prop;
10051
+ if (Object.hasOwn(CAMEL_EXCEPTIONS, prop)) return CAMEL_EXCEPTIONS[prop];
10052
+ return prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`).replace(/^(webkit|moz|ms)-/, "-$1-");
10053
+ }
10054
+ var ServerStyle = class {
10055
+ constructor(el) {
10056
+ this.el = el;
10057
+ /** @internal */
10058
+ this._decls = /* @__PURE__ */ new Map();
10059
+ /** @internal */
10060
+ this._parsedFrom = null;
10061
+ }
10062
+ /** @internal */
10063
+ _sync() {
10064
+ const attr = this.el.getAttribute("style");
10065
+ if (attr === this._parsedFrom) return;
10066
+ this._decls = /* @__PURE__ */ new Map();
10067
+ this._parsedFrom = attr;
10068
+ if (!attr) return;
10069
+ for (const decl of splitDeclarations(attr)) {
10070
+ const colon = decl.indexOf(":");
10071
+ if (colon === -1) continue;
10072
+ const name = decl.slice(0, colon).trim();
10073
+ let value = decl.slice(colon + 1).trim();
10074
+ if (!name || !value) continue;
10075
+ let priority = "";
10076
+ const bang = value.lastIndexOf("!");
10077
+ if (bang !== -1 && /^!\s*important$/i.test(value.slice(bang))) {
10078
+ priority = "important";
10079
+ value = value.slice(0, bang).trim();
10080
+ }
10081
+ this._decls.set(name.startsWith("--") ? name : name.toLowerCase(), { value, priority });
10082
+ }
10083
+ }
10084
+ /** @internal */
10085
+ _commit() {
10086
+ const text2 = this.cssText;
10087
+ this._parsedFrom = text2 === "" ? null : text2;
10088
+ if (text2 === "") this.el.removeAttribute("style");
10089
+ else this.el.setAttribute("style", text2);
10090
+ this._parsedFrom = this.el.getAttribute("style");
10091
+ }
10092
+ get cssText() {
10093
+ this._sync();
10094
+ const parts = [];
10095
+ for (const [name, d] of this._decls) parts.push(`${name}: ${d.value}${d.priority ? " !important" : ""};`);
10096
+ return parts.join(" ");
10097
+ }
10098
+ set cssText(text2) {
10099
+ this.el.setAttribute("style", String(text2 ?? ""));
10100
+ this._sync();
10101
+ if (this._decls.size === 0) this.el.removeAttribute("style");
10102
+ else this._commit();
10103
+ }
10104
+ get length() {
10105
+ this._sync();
10106
+ return this._decls.size;
10107
+ }
10108
+ item(index) {
10109
+ this._sync();
10110
+ return Array.from(this._decls.keys())[index] ?? "";
10111
+ }
10112
+ getPropertyValue(name) {
10113
+ this._sync();
10114
+ return this._decls.get(name.startsWith("--") ? name : name.toLowerCase())?.value ?? "";
10115
+ }
10116
+ getPropertyPriority(name) {
10117
+ this._sync();
10118
+ return this._decls.get(name.startsWith("--") ? name : name.toLowerCase())?.priority ?? "";
10119
+ }
10120
+ setProperty(name, value, priority = "") {
10121
+ this._sync();
10122
+ const key = name.startsWith("--") ? name : name.toLowerCase();
10123
+ const v = value == null ? "" : String(value).trim();
10124
+ if (v === "") {
10125
+ this.removeProperty(key);
10126
+ return;
10127
+ }
10128
+ this._decls.set(key, { value: v, priority: priority === "important" ? "important" : "" });
10129
+ this._commit();
10130
+ }
10131
+ removeProperty(name) {
10132
+ this._sync();
10133
+ const key = name.startsWith("--") ? name : name.toLowerCase();
10134
+ const old = this._decls.get(key)?.value ?? "";
10135
+ if (this._decls.delete(key)) this._commit();
10136
+ return old;
10137
+ }
10138
+ *[Symbol.iterator]() {
10139
+ this._sync();
10140
+ yield* this._decls.keys();
10141
+ }
10142
+ };
10143
+ function styleProxy(style2) {
10144
+ return new Proxy(style2, {
10145
+ get(target, key, receiver) {
10146
+ if (typeof key === "string" && !(key in target)) {
10147
+ if (/^\d+$/.test(key)) return target.item(Number(key));
10148
+ return target.getPropertyValue(toKebab(key));
10149
+ }
10150
+ return Reflect.get(target, key, receiver);
10151
+ },
10152
+ set(target, key, value, receiver) {
10153
+ if (typeof key === "string" && !(key in target)) {
10154
+ target.setProperty(toKebab(key), value == null ? "" : String(value));
10155
+ return true;
10156
+ }
10157
+ return Reflect.set(target, key, value, receiver);
10158
+ }
10159
+ });
10160
+ }
10161
+ var ServerTokenList = class {
10162
+ constructor(el, attr) {
10163
+ this.el = el;
10164
+ this.attr = attr;
10165
+ }
10166
+ tokens() {
10167
+ return (this.el.getAttribute(this.attr) ?? "").split(/\s+/).filter(Boolean);
10168
+ }
10169
+ write(tokens) {
10170
+ this.el.setAttribute(this.attr, Array.from(new Set(tokens)).join(" "));
10171
+ }
10172
+ get length() {
10173
+ return new Set(this.tokens()).size;
10174
+ }
10175
+ get value() {
10176
+ return this.el.getAttribute(this.attr) ?? "";
10177
+ }
10178
+ set value(v) {
10179
+ this.el.setAttribute(this.attr, v);
10180
+ }
10181
+ item(i2) {
10182
+ return Array.from(new Set(this.tokens()))[i2] ?? null;
10183
+ }
10184
+ contains(token) {
10185
+ return this.tokens().includes(token);
10186
+ }
10187
+ add(...tokens) {
10188
+ this.write([...this.tokens(), ...tokens]);
10189
+ }
10190
+ remove(...tokens) {
10191
+ this.write(this.tokens().filter((t) => !tokens.includes(t)));
10192
+ }
10193
+ toggle(token, force) {
10194
+ const has = this.contains(token);
10195
+ const want = force === void 0 ? !has : force;
10196
+ if (want && !has) this.add(token);
10197
+ else if (!want && has) this.remove(token);
10198
+ return want;
10199
+ }
10200
+ replace(oldToken, newToken) {
10201
+ const tokens = this.tokens();
10202
+ const i2 = tokens.indexOf(oldToken);
10203
+ if (i2 === -1) return false;
10204
+ tokens[i2] = newToken;
10205
+ this.write(tokens);
10206
+ return true;
10207
+ }
10208
+ forEach(fn) {
10209
+ Array.from(new Set(this.tokens())).forEach(fn);
10210
+ }
10211
+ [Symbol.iterator]() {
10212
+ return new Set(this.tokens()).values();
10213
+ }
10214
+ toString() {
10215
+ return this.value;
10216
+ }
10217
+ };
10218
+ function datasetKeyToAttr(key) {
10219
+ return `data-${key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)}`;
10220
+ }
10221
+ var ServerElement = class _ServerElement extends ServerNode {
10222
+ constructor(doc, localName, namespaceURI, prefix = null) {
10223
+ super(doc);
10224
+ this.localName = localName;
10225
+ this.namespaceURI = namespaceURI;
10226
+ this.prefix = prefix;
10227
+ /** @internal */
10228
+ this._attrs = new ServerNamedNodeMap();
10229
+ /** @internal */
10230
+ this._style = null;
10231
+ /** @internal */
10232
+ this._classList = null;
10233
+ this.scrollTop = 0;
10234
+ this.scrollLeft = 0;
10235
+ }
10236
+ get nodeType() {
10237
+ return ELEMENT_NODE;
10238
+ }
10239
+ get isHtml() {
10240
+ return this.namespaceURI === HTML_NS3;
10241
+ }
10242
+ get tagName() {
10243
+ const q2 = this.prefix ? `${this.prefix}:${this.localName}` : this.localName;
10244
+ return this.isHtml ? q2.toUpperCase() : q2;
10245
+ }
10246
+ get nodeName() {
10247
+ return this.tagName;
10248
+ }
10249
+ get attributes() {
10250
+ return this._attrs;
10251
+ }
10252
+ findAttr(name) {
10253
+ const n = this.isHtml ? name.toLowerCase() : name;
10254
+ return this._attrs.find((a2) => a2.name === n);
10255
+ }
10256
+ getAttribute(name) {
10257
+ return this.findAttr(String(name))?.value ?? null;
10258
+ }
10259
+ getAttributeNames() {
10260
+ return this._attrs.map((a2) => a2.name);
10261
+ }
10262
+ hasAttribute(name) {
10263
+ return this.findAttr(String(name)) !== void 0;
10264
+ }
10265
+ hasAttributes() {
10266
+ return this._attrs.length > 0;
10267
+ }
10268
+ setAttribute(name, value) {
10269
+ name = String(name);
10270
+ if (!NAME_RE.test(name)) invalidCharacter(name);
10271
+ const v = String(value);
10272
+ const existing = this.findAttr(name);
10273
+ const old = existing ? existing._value : null;
10274
+ if (existing) existing._value = v;
10275
+ else this._attrs.push(new ServerAttr(this, null, null, this.isHtml ? name.toLowerCase() : name, v));
10276
+ this._recordAttr(this.isHtml ? name.toLowerCase() : name, null, old);
10277
+ }
10278
+ removeAttribute(name) {
10279
+ const attr = this.findAttr(String(name));
10280
+ if (!attr) return;
10281
+ this._attrs.splice(this._attrs.indexOf(attr), 1);
10282
+ this._recordAttr(attr.name, attr.namespaceURI, attr._value);
10283
+ }
10284
+ toggleAttribute(name, force) {
10285
+ const has = this.hasAttribute(name);
10286
+ const want = force === void 0 ? !has : force;
10287
+ if (want && !has) this.setAttribute(name, "");
10288
+ else if (!want && has) this.removeAttribute(name);
10289
+ return want;
10290
+ }
10291
+ getAttributeNS(ns, localName) {
10292
+ return this._attrs.getNamedItemNS(ns, localName)?.value ?? null;
10293
+ }
10294
+ hasAttributeNS(ns, localName) {
10295
+ return this._attrs.getNamedItemNS(ns, localName) !== null;
10296
+ }
10297
+ setAttributeNS(ns, qualifiedName, value) {
10298
+ if (!NAME_RE.test(qualifiedName)) invalidCharacter(qualifiedName);
10299
+ const colon = qualifiedName.indexOf(":");
10300
+ const prefix = colon === -1 ? null : qualifiedName.slice(0, colon);
10301
+ const localName = colon === -1 ? qualifiedName : qualifiedName.slice(colon + 1);
10302
+ const namespace = ns || null;
10303
+ if (namespace === null) {
10304
+ this.setAttribute(qualifiedName, value);
10305
+ return;
10306
+ }
10307
+ const existing = this._attrs.getNamedItemNS(namespace, localName);
10308
+ const old = existing ? existing._value : null;
10309
+ if (existing) existing._value = String(value);
10310
+ else this._attrs.push(new ServerAttr(this, namespace, prefix, localName, String(value)));
10311
+ this._recordAttr(localName, namespace, old);
10312
+ }
10313
+ removeAttributeNS(ns, localName) {
10314
+ const attr = this._attrs.getNamedItemNS(ns, localName);
10315
+ if (!attr) return;
10316
+ this._attrs.splice(this._attrs.indexOf(attr), 1);
10317
+ this._recordAttr(localName, attr.namespaceURI, attr._value);
10318
+ }
10319
+ getAttributeNode(name) {
10320
+ return this.findAttr(name) ?? null;
10321
+ }
10322
+ /** @internal */
10323
+ _recordAttr(name, ns, oldValue) {
10324
+ if (observations.length === 0) return;
10325
+ queueRecord({
10326
+ type: "attributes",
10327
+ target: this,
10328
+ addedNodes: [],
10329
+ removedNodes: [],
10330
+ previousSibling: null,
10331
+ nextSibling: null,
10332
+ attributeName: name,
10333
+ attributeNamespace: ns,
10334
+ oldValue
10335
+ });
10336
+ }
10337
+ get id() {
10338
+ return this.getAttribute("id") ?? "";
10339
+ }
10340
+ set id(v) {
10341
+ this.setAttribute("id", v);
10342
+ }
10343
+ get className() {
10344
+ return this.getAttribute("class") ?? "";
10345
+ }
10346
+ set className(v) {
10347
+ this.setAttribute("class", v);
10348
+ }
10349
+ get classList() {
10350
+ this._classList ?? (this._classList = new ServerTokenList(this, "class"));
10351
+ return this._classList;
10352
+ }
10353
+ get style() {
10354
+ this._style ?? (this._style = styleProxy(new ServerStyle(this)));
10355
+ return this._style;
10356
+ }
10357
+ set style(v) {
10358
+ this.style.cssText = v;
10359
+ }
10360
+ get dataset() {
10361
+ return new Proxy(
10362
+ {},
10363
+ {
10364
+ get: (_t, key) => typeof key === "string" ? this.getAttribute(datasetKeyToAttr(key)) ?? void 0 : void 0,
10365
+ set: (_t, key, value) => {
10366
+ if (typeof key === "string") this.setAttribute(datasetKeyToAttr(key), String(value));
10367
+ return true;
10368
+ },
10369
+ deleteProperty: (_t, key) => {
10370
+ if (typeof key === "string") this.removeAttribute(datasetKeyToAttr(key));
10371
+ return true;
10372
+ },
10373
+ has: (_t, key) => typeof key === "string" && this.hasAttribute(datasetKeyToAttr(key)),
10374
+ ownKeys: () => this._attrs.filter((a2) => a2.name.startsWith("data-")).map((a2) => a2.name.slice(5).replace(/-([a-z])/g, (_m, c) => c.toUpperCase())),
10375
+ getOwnPropertyDescriptor: (_t, key) => typeof key === "string" && this.hasAttribute(datasetKeyToAttr(key)) ? { enumerable: true, configurable: true, value: this.getAttribute(datasetKeyToAttr(key)) } : void 0
10376
+ }
10377
+ );
10378
+ }
10379
+ get innerHTML() {
10380
+ let out = "";
10381
+ for (let n = this._first; n; n = n._next) out += serializeForDebug(n);
10382
+ return out;
10383
+ }
10384
+ set innerHTML(_value) {
10385
+ unavailable("Element.innerHTML assignment (the server DOM has no HTML parser)");
10386
+ }
10387
+ get outerHTML() {
10388
+ return serializeForDebug(this);
10389
+ }
10390
+ insertAdjacentHTML() {
10391
+ unavailable("Element.insertAdjacentHTML()");
10392
+ }
10393
+ matches(selector) {
10394
+ return matchesCompiled(this, compileSelector(selector), null);
10395
+ }
10396
+ closest(selector) {
10397
+ const sel = compileSelector(selector);
10398
+ for (let n = this; n; n = n._parent) {
10399
+ if (n instanceof _ServerElement && matchesCompiled(n, sel, null)) return n;
10400
+ }
10401
+ return null;
10402
+ }
10403
+ // ── Layout and focus: no-ops on a server ──
10404
+ focus() {
10405
+ }
10406
+ blur() {
10407
+ }
10408
+ click() {
10409
+ const Ctor = globalThis.Event;
10410
+ if (Ctor) this.dispatchEvent(new Ctor("click", { bubbles: true, cancelable: true }));
10411
+ }
10412
+ scrollIntoView() {
10413
+ }
10414
+ scrollTo() {
10415
+ }
10416
+ scrollBy() {
10417
+ }
10418
+ getBoundingClientRect() {
10419
+ return { x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0, toJSON: () => ({}) };
10420
+ }
10421
+ getClientRects() {
10422
+ return [];
10423
+ }
10424
+ get offsetWidth() {
10425
+ return 0;
10426
+ }
10427
+ get offsetHeight() {
10428
+ return 0;
10429
+ }
10430
+ get offsetTop() {
10431
+ return 0;
10432
+ }
10433
+ get offsetLeft() {
10434
+ return 0;
10435
+ }
10436
+ get offsetParent() {
10437
+ return null;
10438
+ }
10439
+ get clientWidth() {
10440
+ return 0;
10441
+ }
10442
+ get clientHeight() {
10443
+ return 0;
10444
+ }
10445
+ get scrollWidth() {
10446
+ return 0;
10447
+ }
10448
+ get scrollHeight() {
10449
+ return 0;
10450
+ }
10451
+ // ── Browser-only APIs: a clear error instead of "is not a function" ──
10452
+ animate() {
10453
+ return unavailable("Element.animate()");
10454
+ }
10455
+ getAnimations() {
10456
+ return unavailable("Element.getAnimations()");
10457
+ }
10458
+ attachShadow() {
10459
+ return unavailable("Element.attachShadow()");
10460
+ }
10461
+ requestFullscreen() {
10462
+ return unavailable("Element.requestFullscreen()");
10463
+ }
10464
+ requestPointerLock() {
10465
+ return unavailable("Element.requestPointerLock()");
10466
+ }
10467
+ setPointerCapture() {
10468
+ return unavailable("Element.setPointerCapture()");
10469
+ }
10470
+ _shallowClone() {
10471
+ const copy = this.ownerDocument ? this.ownerDocument.createElementNS(
10472
+ this.namespaceURI,
10473
+ this.prefix ? `${this.prefix}:${this.localName}` : this.localName
10474
+ ) : new _ServerElement(null, this.localName, this.namespaceURI, this.prefix);
10475
+ for (const a2 of this._attrs)
10476
+ copy._attrs.push(new ServerAttr(copy, a2.namespaceURI, a2.prefix, a2.localName, a2._value));
10477
+ return copy;
10478
+ }
10479
+ };
10480
+ var ServerHTMLElement = class extends ServerElement {
10481
+ get hidden() {
10482
+ return this.hasAttribute("hidden");
10483
+ }
10484
+ set hidden(v) {
10485
+ this.toggleAttribute("hidden", !!v);
10486
+ }
10487
+ get title() {
10488
+ return this.getAttribute("title") ?? "";
10489
+ }
10490
+ set title(v) {
10491
+ this.setAttribute("title", v);
10492
+ }
10493
+ get lang() {
10494
+ return this.getAttribute("lang") ?? "";
10495
+ }
10496
+ set lang(v) {
10497
+ this.setAttribute("lang", v);
10498
+ }
10499
+ get dir() {
10500
+ return this.getAttribute("dir") ?? "";
10501
+ }
10502
+ set dir(v) {
10503
+ this.setAttribute("dir", v);
10504
+ }
10505
+ get tabIndex() {
10506
+ const v = Number.parseInt(this.getAttribute("tabindex") ?? "", 10);
10507
+ return Number.isNaN(v) ? -1 : v;
10508
+ }
10509
+ set tabIndex(v) {
10510
+ this.setAttribute("tabindex", String(v));
10511
+ }
10512
+ get innerText() {
10513
+ return this.textContent ?? "";
10514
+ }
10515
+ set innerText(v) {
10516
+ this.textContent = v;
10517
+ }
10518
+ };
10519
+ function reflectDisabled(proto) {
10520
+ Object.defineProperty(proto, "disabled", {
10521
+ get() {
10522
+ return this.hasAttribute("disabled");
10523
+ },
10524
+ set(v) {
10525
+ this.toggleAttribute("disabled", !!v);
10526
+ },
10527
+ configurable: true
10528
+ });
10529
+ }
10530
+ var ServerInputElement = class extends ServerHTMLElement {
10531
+ constructor() {
10532
+ super(...arguments);
10533
+ /** @internal */
10534
+ this._value = null;
10535
+ /** @internal */
10536
+ this._checked = null;
10537
+ }
10538
+ get value() {
10539
+ return this._value ?? this.getAttribute("value") ?? "";
10540
+ }
10541
+ set value(v) {
10542
+ this._value = v == null ? "" : String(v);
10543
+ }
10544
+ get defaultValue() {
10545
+ return this.getAttribute("value") ?? "";
10546
+ }
10547
+ set defaultValue(v) {
10548
+ this.setAttribute("value", v);
10549
+ }
10550
+ get checked() {
10551
+ return this._checked ?? this.hasAttribute("checked");
10552
+ }
10553
+ set checked(v) {
10554
+ this._checked = !!v;
10555
+ }
10556
+ get defaultChecked() {
10557
+ return this.hasAttribute("checked");
10558
+ }
10559
+ /** Reflects to the `checked` attribute; `checked` follows it until written (dirty checkedness). */
10560
+ set defaultChecked(v) {
10561
+ this.toggleAttribute("checked", !!v);
10562
+ }
10563
+ get type() {
10564
+ return (this.getAttribute("type") ?? "text").toLowerCase();
10565
+ }
10566
+ set type(v) {
10567
+ this.setAttribute("type", v);
10568
+ }
10569
+ get name() {
10570
+ return this.getAttribute("name") ?? "";
10571
+ }
10572
+ set name(v) {
10573
+ this.setAttribute("name", v);
10574
+ }
10575
+ select() {
10576
+ }
10577
+ setSelectionRange() {
10578
+ }
10579
+ checkValidity() {
10580
+ return true;
10581
+ }
10582
+ reportValidity() {
10583
+ return true;
10584
+ }
10585
+ };
10586
+ reflectDisabled(ServerInputElement.prototype);
10587
+ var ServerTextAreaElement = class extends ServerHTMLElement {
10588
+ constructor() {
10589
+ super(...arguments);
10590
+ /** @internal */
10591
+ this._value = null;
10592
+ }
10593
+ get value() {
10594
+ return this._value ?? this.textContent ?? "";
10595
+ }
10596
+ set value(v) {
10597
+ this._value = v == null ? "" : String(v);
10598
+ }
10599
+ get defaultValue() {
10600
+ return this.textContent ?? "";
10601
+ }
10602
+ set defaultValue(v) {
10603
+ this.textContent = v;
10604
+ }
10605
+ get name() {
10606
+ return this.getAttribute("name") ?? "";
10607
+ }
10608
+ set name(v) {
10609
+ this.setAttribute("name", v);
10610
+ }
10611
+ select() {
10612
+ }
10613
+ setSelectionRange() {
10614
+ }
10615
+ };
10616
+ reflectDisabled(ServerTextAreaElement.prototype);
10617
+ var ServerOptionElement = class extends ServerHTMLElement {
10618
+ constructor() {
10619
+ super(...arguments);
10620
+ /** Selectedness; `null` while it follows the `selected` attribute. @internal */
10621
+ this._selected = null;
10622
+ /** Set by a `selected` write: the attribute no longer decides selectedness. @internal */
10623
+ this._dirty = false;
10624
+ }
10625
+ get value() {
10626
+ return this.getAttribute("value") ?? this.text;
10627
+ }
10628
+ set value(v) {
10629
+ this.setAttribute("value", v);
10630
+ }
10631
+ get text() {
10632
+ return (this.textContent ?? "").replace(/\s+/g, " ").trim();
10633
+ }
10634
+ set text(v) {
10635
+ this.textContent = v;
10636
+ }
10637
+ get label() {
10638
+ return this.getAttribute("label") ?? this.text;
10639
+ }
10640
+ set label(v) {
10641
+ this.setAttribute("label", v);
10642
+ }
10643
+ get selected() {
10644
+ return this._selected ?? this.hasAttribute("selected");
10645
+ }
10646
+ set selected(v) {
10647
+ this._selected = !!v;
10648
+ this._dirty = true;
10649
+ const select3 = singleSelectOf(this);
10650
+ if (select3 && v) {
10651
+ for (const o of select3.options) if (o !== this) o._selected = false;
10652
+ }
10653
+ }
10654
+ get defaultSelected() {
10655
+ return this.hasAttribute("selected");
10656
+ }
10657
+ /** Reflects to the `selected` attribute; `selected` follows it unless written. */
10658
+ set defaultSelected(v) {
10659
+ this.toggleAttribute("selected", !!v);
10660
+ if (this._dirty) return;
10661
+ this._selected = null;
10662
+ const select3 = singleSelectOf(this);
10663
+ if (!select3) return;
10664
+ let last = null;
10665
+ for (const o of select3.options) if (o.selected) last = o;
10666
+ for (const o of select3.options) if (o !== last && o.selected) o._selected = false;
10667
+ }
10668
+ };
10669
+ function singleSelectOf(option2) {
10670
+ let parent = option2.parentNode;
10671
+ if (parent instanceof ServerElement && parent.localName === "optgroup") parent = parent.parentNode;
10672
+ return parent instanceof ServerSelectElement && !parent.hasAttribute("multiple") ? parent : null;
10673
+ }
10674
+ reflectDisabled(ServerOptionElement.prototype);
10675
+ var ServerSelectElement = class extends ServerHTMLElement {
10676
+ get multiple() {
10677
+ return this.hasAttribute("multiple");
10678
+ }
10679
+ set multiple(v) {
10680
+ this.toggleAttribute("multiple", !!v);
10681
+ }
10682
+ get options() {
10683
+ return this.querySelectorAll("option");
10684
+ }
10685
+ get selectedIndex() {
10686
+ const opts = this.options;
10687
+ for (let i2 = 0; i2 < opts.length; i2++) if (opts[i2].selected) return i2;
10688
+ return opts.length > 0 && !this.hasAttribute("multiple") ? 0 : -1;
10689
+ }
10690
+ set selectedIndex(i2) {
10691
+ this.options.forEach((o, j) => {
10692
+ o.selected = j === i2;
10693
+ });
10694
+ }
10695
+ get value() {
10696
+ const i2 = this.selectedIndex;
10697
+ return i2 === -1 ? "" : this.options[i2].value;
10698
+ }
10699
+ set value(v) {
10700
+ this.options.forEach((o) => {
10701
+ o.selected = o.value === String(v);
10702
+ });
10703
+ }
10704
+ get name() {
10705
+ return this.getAttribute("name") ?? "";
10706
+ }
10707
+ set name(v) {
10708
+ this.setAttribute("name", v);
10709
+ }
10710
+ };
10711
+ reflectDisabled(ServerSelectElement.prototype);
10712
+ var ServerButtonElement = class extends ServerHTMLElement {
10713
+ get type() {
10714
+ return (this.getAttribute("type") ?? "submit").toLowerCase();
10715
+ }
10716
+ set type(v) {
10717
+ this.setAttribute("type", v);
10718
+ }
10719
+ get value() {
10720
+ return this.getAttribute("value") ?? "";
10721
+ }
10722
+ set value(v) {
10723
+ this.setAttribute("value", v);
10724
+ }
10725
+ };
10726
+ reflectDisabled(ServerButtonElement.prototype);
10727
+ var ServerDisableableElement = class extends ServerHTMLElement {
10728
+ };
10729
+ reflectDisabled(ServerDisableableElement.prototype);
10730
+ var ServerCanvasElement = class extends ServerHTMLElement {
10731
+ get width() {
10732
+ return Number(this.getAttribute("width") ?? 300);
10733
+ }
10734
+ set width(v) {
10735
+ this.setAttribute("width", String(v));
10736
+ }
10737
+ get height() {
10738
+ return Number(this.getAttribute("height") ?? 150);
10739
+ }
10740
+ set height(v) {
10741
+ this.setAttribute("height", String(v));
10742
+ }
10743
+ /** No drawing context on a server: warns and returns `null`, as a browser does for an unsupported context. */
10744
+ getContext() {
10745
+ reportBrowserApi("HTMLCanvasElement.getContext()");
10746
+ return null;
10747
+ }
10748
+ toDataURL() {
10749
+ return unavailable("HTMLCanvasElement.toDataURL()");
10750
+ }
10751
+ toBlob() {
10752
+ return unavailable("HTMLCanvasElement.toBlob()");
10753
+ }
10754
+ };
10755
+ var ServerDialogElement = class extends ServerHTMLElement {
10756
+ get open() {
10757
+ return this.hasAttribute("open");
10758
+ }
10759
+ set open(v) {
10760
+ this.toggleAttribute("open", !!v);
10761
+ }
10762
+ showModal() {
10763
+ return unavailable("HTMLDialogElement.showModal()");
10764
+ }
10765
+ show() {
10766
+ this.open = true;
10767
+ }
10768
+ close() {
10769
+ this.open = false;
10770
+ }
10771
+ };
10772
+ var ServerMediaElement = class extends ServerHTMLElement {
10773
+ play() {
10774
+ return unavailable("HTMLMediaElement.play()");
10775
+ }
10776
+ pause() {
10777
+ }
10778
+ load() {
10779
+ }
10780
+ };
10781
+ var ServerTemplateElement = class extends ServerHTMLElement {
10782
+ constructor() {
10783
+ super(...arguments);
10784
+ /** @internal */
10785
+ this._content = null;
10786
+ }
10787
+ get content() {
10788
+ this._content ?? (this._content = new ServerDocumentFragment(this.ownerDocument));
10789
+ return this._content;
10790
+ }
10791
+ };
10792
+ var ServerSVGElement = class extends ServerElement {
10793
+ };
10794
+ var ServerMathMLElement = class extends ServerElement {
10795
+ };
10796
+ var HTML_CLASSES = {
10797
+ input: ServerInputElement,
10798
+ textarea: ServerTextAreaElement,
10799
+ select: ServerSelectElement,
10800
+ option: ServerOptionElement,
10801
+ button: ServerButtonElement,
10802
+ fieldset: ServerDisableableElement,
10803
+ optgroup: ServerDisableableElement,
10804
+ canvas: ServerCanvasElement,
10805
+ dialog: ServerDialogElement,
10806
+ video: ServerMediaElement,
10807
+ audio: ServerMediaElement,
10808
+ template: ServerTemplateElement
10809
+ };
10810
+ var NODE_FILTER = {
10811
+ FILTER_ACCEPT: 1,
10812
+ FILTER_REJECT: 2,
10813
+ FILTER_SKIP: 3,
10814
+ SHOW_ALL: 4294967295,
10815
+ SHOW_ELEMENT: 1,
10816
+ SHOW_ATTRIBUTE: 2,
10817
+ SHOW_TEXT: 4,
10818
+ SHOW_COMMENT: 128,
10819
+ SHOW_DOCUMENT: 256,
10820
+ SHOW_DOCUMENT_FRAGMENT: 1024
10821
+ };
10822
+ var ServerTreeWalker = class {
10823
+ constructor(root, whatToShow, filter) {
10824
+ this.root = root;
10825
+ this.whatToShow = whatToShow;
10826
+ this.filter = filter;
10827
+ this.currentNode = root;
10828
+ }
10829
+ accept(node) {
10830
+ if (!(1 << node.nodeType - 1 & this.whatToShow)) return NODE_FILTER.FILTER_SKIP;
10831
+ if (!this.filter) return NODE_FILTER.FILTER_ACCEPT;
10832
+ return typeof this.filter === "function" ? this.filter(node) : this.filter.acceptNode(node);
10833
+ }
10834
+ nextNode() {
10835
+ let node = this.currentNode;
10836
+ for (; ; ) {
10837
+ let next = null;
10838
+ if (node._first) next = node._first;
10839
+ else {
10840
+ let n = node;
10841
+ while (n && n !== this.root && !n._next) n = n._parent;
10842
+ next = n && n !== this.root ? n._next : null;
10843
+ }
10844
+ if (!next) return null;
10845
+ node = next;
10846
+ if (this.accept(node) === NODE_FILTER.FILTER_ACCEPT) {
10847
+ this.currentNode = node;
10848
+ return node;
10849
+ }
10850
+ }
10851
+ }
10852
+ firstChild() {
10853
+ for (let n = this.currentNode._first; n; n = n._next) {
10854
+ if (this.accept(n) === NODE_FILTER.FILTER_ACCEPT) {
10855
+ this.currentNode = n;
10856
+ return n;
10857
+ }
10858
+ }
10859
+ return null;
10860
+ }
10861
+ nextSibling() {
10862
+ for (let n = this.currentNode._next; n; n = n._next) {
10863
+ if (this.accept(n) === NODE_FILTER.FILTER_ACCEPT) {
10864
+ this.currentNode = n;
10865
+ return n;
10866
+ }
10867
+ }
10868
+ return null;
10869
+ }
10870
+ parentNode() {
10871
+ const p2 = this.currentNode === this.root ? null : this.currentNode._parent;
10872
+ if (p2) this.currentNode = p2;
10873
+ return p2;
10874
+ }
10875
+ };
10876
+ var ServerDocument = class extends ServerNode {
10877
+ constructor() {
10878
+ super(null);
10879
+ this.defaultView = null;
10880
+ this.readyState = "complete";
10881
+ this.contentType = "text/html";
10882
+ this.characterSet = "UTF-8";
10883
+ this.compatMode = "CSS1Compat";
10884
+ this.visibilityState = "visible";
10885
+ this.hidden = false;
10886
+ this.cookie = "";
10887
+ this.ownerDocument = null;
10888
+ this.documentElement = this.createElement("html");
10889
+ this.head = this.createElement("head");
10890
+ this.body = this.createElement("body");
10891
+ this.documentElement.appendChild(this.head);
10892
+ this.documentElement.appendChild(this.body);
10893
+ this.appendChild(this.documentElement);
10894
+ }
10895
+ get nodeType() {
10896
+ return DOCUMENT_NODE;
10897
+ }
10898
+ get nodeName() {
10899
+ return "#document";
10900
+ }
10901
+ get activeElement() {
10902
+ return this.body;
10903
+ }
10904
+ get title() {
10905
+ return this.head.querySelector("title")?.textContent ?? "";
10906
+ }
10907
+ set title(v) {
10908
+ let el = this.head.querySelector("title");
10909
+ if (!el) {
10910
+ el = this.createElement("title");
10911
+ this.head.appendChild(el);
10912
+ }
10913
+ el.textContent = v;
10914
+ }
10915
+ /** Font loading does not exist on a server: recorded as a browser-only read, answers `undefined`. */
10916
+ get fonts() {
10917
+ reportBrowserApi("document.fonts");
10918
+ return void 0;
10919
+ }
10920
+ createElement(name) {
10921
+ name = String(name);
10922
+ if (!NAME_RE.test(name)) invalidCharacter(name);
10923
+ const local = name.toLowerCase();
10924
+ const Ctor = Object.hasOwn(HTML_CLASSES, local) ? HTML_CLASSES[local] : ServerHTMLElement;
10925
+ return new Ctor(this, local, HTML_NS3);
10926
+ }
10927
+ createElementNS(ns, qualifiedName) {
10928
+ if (!NAME_RE.test(qualifiedName)) invalidCharacter(qualifiedName);
10929
+ const namespace = ns || null;
10930
+ if (namespace === HTML_NS3) return this.createElement(qualifiedName);
10931
+ const colon = qualifiedName.indexOf(":");
10932
+ const prefix = colon === -1 ? null : qualifiedName.slice(0, colon);
10933
+ const local = colon === -1 ? qualifiedName : qualifiedName.slice(colon + 1);
10934
+ if (namespace === SVG_NS3) return new ServerSVGElement(this, local, namespace, prefix);
10935
+ if (namespace === MATHML_NS) return new ServerMathMLElement(this, local, namespace, prefix);
10936
+ return new ServerElement(this, local, namespace, prefix);
10937
+ }
10938
+ createTextNode(data2) {
10939
+ return new ServerText(this, String(data2));
10940
+ }
10941
+ createComment(data2) {
10942
+ return new ServerComment(this, String(data2));
10943
+ }
10944
+ createDocumentFragment() {
10945
+ return new ServerDocumentFragment(this);
10946
+ }
10947
+ createTreeWalker(root, whatToShow = NODE_FILTER.SHOW_ALL, filter = null) {
10948
+ return new ServerTreeWalker(root, whatToShow, filter);
10949
+ }
10950
+ createEvent() {
10951
+ return unavailable("document.createEvent() (construct `new Event(type)` instead)");
10952
+ }
10953
+ getElementById(id) {
10954
+ return this.querySelector(`#${cssEscapeIdent(id)}`);
10955
+ }
10956
+ hasFocus() {
10957
+ return false;
10958
+ }
10959
+ getSelection() {
10960
+ return null;
10961
+ }
10962
+ elementFromPoint() {
10963
+ return null;
10964
+ }
10965
+ execCommand() {
10966
+ return unavailable("document.execCommand()");
10967
+ }
10968
+ };
10969
+ var selectorCache = /* @__PURE__ */ new Map();
10970
+ function cssEscapeIdent(value) {
10971
+ return value.replace(/([^A-Za-z0-9_-])/g, "\\$1");
10972
+ }
10973
+ function unescapeIdent(value) {
10974
+ return value.replace(/\\(.)/g, "$1");
10975
+ }
10976
+ function compileSelector(selector) {
10977
+ const cached = selectorCache.get(selector);
10978
+ if (cached) return cached;
10979
+ const groups = [];
10980
+ for (const part of splitTopLevel(selector, ",")) {
10981
+ const text2 = part.trim();
10982
+ if (!text2) throw syntaxError(selector);
10983
+ const tokens = text2.match(/(?:\\.|\[[^\]]*\]|[^\s>])+|>/g) ?? [];
10984
+ const compounds = [];
10985
+ const combinators = [];
10986
+ let pending = " ";
10987
+ let scoped = false;
10988
+ for (const token of tokens) {
10989
+ if (token === ">") {
10990
+ pending = ">";
10991
+ continue;
10992
+ }
10993
+ if (token === ":scope") {
10994
+ scoped = true;
10995
+ pending = " ";
10996
+ continue;
10997
+ }
10998
+ if (compounds.length > 0) combinators.unshift(pending);
10999
+ compounds.unshift(parseCompound(token, selector));
11000
+ pending = " ";
11001
+ }
11002
+ if (compounds.length === 0) throw syntaxError(selector);
11003
+ groups.push({ compounds, combinators, scoped });
11004
+ }
11005
+ if (selectorCache.size > 500) selectorCache.clear();
11006
+ selectorCache.set(selector, groups);
11007
+ return groups;
11008
+ }
11009
+ function splitTopLevel(text2, sep) {
11010
+ const out = [];
11011
+ let depth = 0;
11012
+ let quote2 = "";
11013
+ let start = 0;
11014
+ for (let i2 = 0; i2 < text2.length; i2++) {
11015
+ const c = text2[i2];
11016
+ if (quote2) {
11017
+ if (c === "\\") i2++;
11018
+ else if (c === quote2) quote2 = "";
11019
+ } else if (c === '"' || c === "'") quote2 = c;
11020
+ else if (c === "\\") i2++;
11021
+ else if (c === "[" || c === "(") depth++;
11022
+ else if (c === "]" || c === ")") depth--;
11023
+ else if (c === sep && depth === 0) {
11024
+ out.push(text2.slice(start, i2));
11025
+ start = i2 + 1;
11026
+ }
11027
+ }
11028
+ out.push(text2.slice(start));
11029
+ return out;
11030
+ }
11031
+ function syntaxError(selector) {
11032
+ const Ctor = globalThis.DOMException;
11033
+ const message = `'${selector}' is not a valid selector (the SibuJS server DOM supports tag, #id, .class, [attr], [attr=value], descendant and > combinators)`;
11034
+ return Ctor ? new Ctor(message, "SyntaxError") : new Error(message);
11035
+ }
11036
+ function parseCompound(token, selector) {
11037
+ const c = { tag: null, id: null, classes: [], attrs: [] };
11038
+ const re = /(\\.|[^#.[\\])+|#((?:\\.|[^#.[\\])+)|\.((?:\\.|[^#.[\\])+)|\[([^\]]*)\]/gy;
11039
+ let consumed = 0;
11040
+ for (let m = re.exec(token); m; m = re.exec(token)) {
11041
+ consumed = re.lastIndex;
11042
+ if (m[2] !== void 0) c.id = unescapeIdent(m[2]);
11043
+ else if (m[3] !== void 0) c.classes.push(unescapeIdent(m[3]));
11044
+ else if (m[4] !== void 0) {
11045
+ const am = /^\s*([^\s~|^$*=]+)\s*(?:([~|^$*]?=)\s*(?:"((?:\\.|[^"])*)"|'((?:\\.|[^'])*)'|([^\s"']+)))?\s*$/.exec(
11046
+ m[4]
11047
+ );
11048
+ if (!am) throw syntaxError(selector);
11049
+ c.attrs.push({
11050
+ name: am[1].toLowerCase(),
11051
+ op: am[2] ?? null,
11052
+ value: unescapeIdent(am[3] ?? am[4] ?? am[5] ?? "")
11053
+ });
11054
+ } else {
11055
+ const t = m[0];
11056
+ if (t.startsWith(":")) throw syntaxError(selector);
11057
+ c.tag = t === "*" ? null : unescapeIdent(t);
11058
+ }
11059
+ if (re.lastIndex === token.length) break;
11060
+ }
11061
+ if (consumed !== token.length) throw syntaxError(selector);
11062
+ return c;
11063
+ }
11064
+ function matchesCompound(el, c) {
11065
+ if (c.tag !== null) {
11066
+ const isHtml = el.namespaceURI === HTML_NS3;
11067
+ if (isHtml ? el.localName !== c.tag.toLowerCase() : el.localName !== c.tag) return false;
11068
+ }
11069
+ if (c.id !== null && el.getAttribute("id") !== c.id) return false;
11070
+ if (c.classes.length > 0) {
11071
+ const tokens = (el.getAttribute("class") ?? "").split(/\s+/);
11072
+ for (const cls of c.classes) if (!tokens.includes(cls)) return false;
11073
+ }
11074
+ for (const a2 of c.attrs) {
11075
+ const v = el.getAttribute(a2.name);
11076
+ if (v === null) return false;
11077
+ if (a2.op === null) continue;
11078
+ if (a2.op === "=" && v !== a2.value) return false;
11079
+ if (a2.op === "~=" && !v.split(/\s+/).includes(a2.value)) return false;
11080
+ if (a2.op === "|=" && v !== a2.value && !v.startsWith(`${a2.value}-`)) return false;
11081
+ if (a2.op === "^=" && (!a2.value || !v.startsWith(a2.value))) return false;
11082
+ if (a2.op === "$=" && (!a2.value || !v.endsWith(a2.value))) return false;
11083
+ if (a2.op === "*=" && (!a2.value || !v.includes(a2.value))) return false;
11084
+ }
11085
+ return true;
11086
+ }
11087
+ function matchesCompiled(el, groups, scope) {
11088
+ for (const g2 of groups) if (matchesComplex(el, g2, 0, scope)) return true;
11089
+ return false;
11090
+ }
11091
+ function matchesComplex(el, g2, i2, scope) {
11092
+ if (!matchesCompound(el, g2.compounds[i2])) return false;
11093
+ if (i2 === g2.compounds.length - 1) {
11094
+ if (!g2.scoped || !scope) return true;
11095
+ return el._parent === scope || (g2.combinators.length === 0 ? false : scope.contains(el));
11096
+ }
11097
+ const comb = g2.combinators[i2];
11098
+ for (let p2 = el._parent; p2 && p2 instanceof ServerElement; p2 = p2._parent) {
11099
+ if (scope && p2 === scope && g2.scoped) return false;
11100
+ if (matchesComplex(p2, g2, i2 + 1, scope)) return true;
11101
+ if (comb === ">") return false;
11102
+ }
11103
+ return false;
11104
+ }
11105
+ var VOID = /* @__PURE__ */ new Set([
11106
+ "area",
11107
+ "base",
11108
+ "br",
11109
+ "col",
11110
+ "embed",
11111
+ "hr",
11112
+ "img",
11113
+ "input",
11114
+ "link",
11115
+ "meta",
11116
+ "source",
11117
+ "track",
11118
+ "wbr"
11119
+ ]);
11120
+ function escapeText(s2) {
11121
+ return s2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
11122
+ }
11123
+ function serializeForDebug(node) {
11124
+ if (node.nodeType === TEXT_NODE) return escapeText(node.data);
11125
+ if (node.nodeType === COMMENT_NODE) return `<!--${node.data}-->`;
11126
+ if (node.nodeType !== ELEMENT_NODE) {
11127
+ let out2 = "";
11128
+ for (let n = node._first; n; n = n._next) out2 += serializeForDebug(n);
11129
+ return out2;
11130
+ }
11131
+ const el = node;
11132
+ const tag = el.prefix ? `${el.prefix}:${el.localName}` : el.localName;
11133
+ let out = `<${tag}`;
11134
+ for (const a2 of el._attrs) out += ` ${a2.name}="${escapeText(a2._value).replace(/"/g, "&quot;")}"`;
11135
+ out += ">";
11136
+ if (el.namespaceURI === HTML_NS3 && VOID.has(el.localName)) return out;
11137
+ for (let n = el._first; n; n = n._next) out += serializeForDebug(n);
11138
+ return `${out}</${tag}>`;
11139
+ }
11140
+ var INSTALLED = /* @__PURE__ */ Symbol.for("sibujs.serverDom.v1");
11141
+ function isServerDom() {
11142
+ return typeof document !== "undefined" && document instanceof ServerDocument;
11143
+ }
11144
+ function installServerDom(options = {}) {
11145
+ const g2 = globalThis;
11146
+ if (typeof g2.document !== "undefined" && !options.force) return () => {
11147
+ };
11148
+ const globals = {
11149
+ document: new ServerDocument(),
11150
+ Node: ServerNode,
11151
+ Element: ServerElement,
11152
+ HTMLElement: ServerHTMLElement,
11153
+ SVGElement: ServerSVGElement,
11154
+ MathMLElement: ServerMathMLElement,
11155
+ HTMLInputElement: ServerInputElement,
11156
+ HTMLTextAreaElement: ServerTextAreaElement,
11157
+ HTMLSelectElement: ServerSelectElement,
11158
+ HTMLOptionElement: ServerOptionElement,
11159
+ HTMLButtonElement: ServerButtonElement,
11160
+ HTMLCanvasElement: ServerCanvasElement,
11161
+ HTMLDialogElement: ServerDialogElement,
11162
+ HTMLTemplateElement: ServerTemplateElement,
11163
+ Text: ServerText,
11164
+ Comment: ServerComment,
11165
+ CharacterData: ServerCharacterData,
11166
+ DocumentFragment: ServerDocumentFragment,
11167
+ Document: ServerDocument,
11168
+ Attr: ServerAttr,
11169
+ MutationObserver: ServerMutationObserver,
11170
+ NodeFilter: NODE_FILTER
11171
+ };
11172
+ const previous2 = /* @__PURE__ */ new Map();
11173
+ for (const [key, value] of Object.entries(globals)) {
11174
+ previous2.set(key, Object.getOwnPropertyDescriptor(g2, key));
11175
+ Object.defineProperty(g2, key, { value, configurable: true, writable: true, enumerable: false });
11176
+ }
11177
+ g2[INSTALLED] = true;
11178
+ return () => {
11179
+ for (const [key, desc] of previous2) {
11180
+ if (desc) Object.defineProperty(g2, key, desc);
11181
+ else delete g2[key];
11182
+ }
11183
+ delete g2[INSTALLED];
11184
+ };
11185
+ }
11186
+ var BROWSER_GLOBALS = [
11187
+ "matchMedia",
11188
+ "requestAnimationFrame",
11189
+ "localStorage",
11190
+ "sessionStorage",
11191
+ "IntersectionObserver",
11192
+ "ResizeObserver"
11193
+ ];
11194
+ var WATCHED = /* @__PURE__ */ Symbol.for("sibujs.serverDom.watched.v1");
11195
+ function inServerRender() {
11196
+ const shared = globalThis[/* @__PURE__ */ Symbol.for("sibujs.ssr.v1")];
11197
+ return !!shared?.als?.getStore()?.ssr;
11198
+ }
11199
+ function watchProperty(target, key, api) {
11200
+ const desc = Object.getOwnPropertyDescriptor(target, key);
11201
+ if (!desc || !desc.configurable) return;
11202
+ const read = desc.get ? () => desc.get?.call(target) : () => desc.value;
11203
+ let value = desc.value;
11204
+ Object.defineProperty(target, key, {
11205
+ configurable: true,
11206
+ enumerable: desc.enumerable,
11207
+ get() {
11208
+ if (inServerRender()) reportBrowserApi(api);
11209
+ return desc.get ? read() : value;
11210
+ },
11211
+ set(v) {
11212
+ if (desc.set) desc.set.call(target, v);
11213
+ else value = v;
11214
+ }
11215
+ });
11216
+ }
11217
+ function watchBrowserApis() {
11218
+ if (!DEV || isServerDom()) return;
11219
+ const g2 = globalThis;
11220
+ if (g2[WATCHED]) return;
11221
+ g2[WATCHED] = true;
11222
+ const win = g2.window;
11223
+ for (const key of BROWSER_GLOBALS) {
11224
+ if (Object.hasOwn(g2, key)) watchProperty(g2, key, key);
11225
+ if (win && win !== g2 && Object.hasOwn(win, key)) watchProperty(win, key, `window.${key}`);
11226
+ }
11227
+ const Doc = g2.Document;
11228
+ if (Doc && "fonts" in Doc.prototype) watchProperty(Doc.prototype, "fonts", "document.fonts");
11229
+ const Canvas = g2.HTMLCanvasElement;
11230
+ const getContext = Canvas?.prototype.getContext;
11231
+ if (Canvas && getContext) {
11232
+ Canvas.prototype.getContext = function(...args) {
11233
+ if (inServerRender()) reportBrowserApi("HTMLCanvasElement.getContext()");
11234
+ return getContext.apply(this, args);
11235
+ };
11236
+ }
11237
+ }
11238
+ 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$/;
11239
+ function explainServerError(err) {
11240
+ if (!(err instanceof ReferenceError)) return err;
11241
+ const m = BROWSER_ONLY_NAMES.exec(err.message);
11242
+ if (!m) return err;
11243
+ const site = (err.stack ?? "").split("\n")[1]?.trim().replace(/^at\s+/, "") ?? "(unknown site)";
11244
+ return new Error(
11245
+ `[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().`,
11246
+ { cause: err }
11247
+ );
11248
+ }
11249
+ function ensureServerDom() {
11250
+ if (typeof document === "undefined") installServerDom();
11251
+ }
11252
+
11253
+ // src/platform/serverHead.ts
11254
+ function headSlot() {
11255
+ return requestSlot("head", () => ({ layers: [] }));
11256
+ }
11257
+ function recordServerHead(source2) {
11258
+ const slot4 = headSlot();
11259
+ if (!slot4) return null;
11260
+ const entry = { source: source2 };
11261
+ slot4.layers.push(entry);
11262
+ return () => {
11263
+ if (entry.source === null) return;
11264
+ entry.source = null;
11265
+ const index = slot4.layers.indexOf(entry);
11266
+ if (index !== -1) slot4.layers.splice(index, 1);
11267
+ };
11268
+ }
11269
+ function collectServerHead() {
11270
+ const slot4 = headSlot();
11271
+ if (!slot4 || slot4.layers.length === 0) return "";
11272
+ let title3;
11273
+ const order = [];
11274
+ const byKey = /* @__PURE__ */ new Map();
11275
+ for (const entry of slot4.layers.slice()) {
11276
+ const source2 = entry.source;
11277
+ if (source2 === null) continue;
11278
+ let layer;
11279
+ try {
11280
+ layer = typeof source2 === "function" ? untracked2(source2) : source2;
11281
+ } catch (err) {
11282
+ const message = err instanceof Error ? err.message : String(err);
11283
+ throw new Error(`[SibuJS SSR] a head value threw while the page head was collected: ${message}`, {
11284
+ cause: err
11285
+ });
11286
+ }
11287
+ if (!layer) continue;
11288
+ if (layer.title !== void 0) title3 = layer.title;
11289
+ for (const tag of layer.tags) {
11290
+ if (!byKey.has(tag.key)) order.push(tag.key);
11291
+ byKey.set(tag.key, tag.html);
11292
+ }
11293
+ }
11294
+ const out = [];
11295
+ if (title3 != null) out.push(`<title>${escapeText2(title3)}</title>`);
11296
+ for (const key of order) out.push(byKey.get(key));
11297
+ return out.join("\n ");
11298
+ }
11299
+ function escapeText2(str) {
11300
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
11301
+ }
11302
+
11303
+ // src/platform/ssrAsync.ts
11304
+ var DEFAULT_TRANSFER_MAX_BYTES = 1024 * 1024;
11305
+ function describeNodePath(node) {
11306
+ const parts = [];
11307
+ let current2 = node;
11308
+ while (current2 && parts.length < 8) {
11309
+ if (current2.nodeType === 1) {
11310
+ const el = current2;
11311
+ let part = el.localName;
11312
+ const id = el.getAttribute("id");
11313
+ if (id) part += `#${id}`;
11314
+ const cls = el.getAttribute("class")?.trim().split(/\s+/)[0];
11315
+ if (cls) part += `.${cls}`;
11316
+ parts.unshift(part);
11317
+ }
11318
+ current2 = current2.parentNode;
11319
+ }
11320
+ return parts.length > 0 ? parts.join(" > ") : "(detached)";
11321
+ }
11322
+ function renderFailure(entry) {
11323
+ const error = explainServerError(entry.error);
11324
+ const message = error instanceof Error ? error.message : String(error);
11325
+ const where = entry.context.node ? describeNodePath(entry.context.node) : "(unknown position)";
11326
+ const label2 = entry.context.name ? ` in ${entry.context.name}` : "";
11327
+ return new Error(`[SibuJS SSR] render failed${label2} at ${where}: ${message}`, { cause: error });
11328
+ }
11329
+
11330
+ // src/platform/hydrateAdopt.ts
11331
+ var ADOPT_ID_ATTR = "data-sibu-h";
11332
+ function createServerAdoptScope(ids) {
11333
+ const sink = {
11334
+ on: true,
11335
+ el(tag, ns, id) {
11336
+ const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
11337
+ ids.set(el, id);
11338
+ return el;
11339
+ }
11340
+ };
11341
+ return { p: "", n: 0, s: sink };
11342
+ }
11343
+ var STICKY = {
11344
+ img: ["src", "srcset", "sizes"],
11345
+ source: ["src", "srcset", "sizes"],
11346
+ video: ["src", "poster"],
11347
+ audio: ["src"],
11348
+ track: ["src"],
11349
+ iframe: ["src"],
11350
+ embed: ["src"],
11351
+ object: ["data"],
11352
+ input: ["value", "checked", "type"],
11353
+ textarea: [],
11354
+ select: [],
11355
+ option: ["value", "selected"],
11356
+ details: ["open"],
11357
+ dialog: ["open"]
11358
+ };
11359
+ function snapshotSelect(select3) {
11360
+ const options = Array.from(select3.options);
11361
+ const seen = /* @__PURE__ */ new Map();
11362
+ const chosen = [];
11363
+ for (const node of options) {
11364
+ const occurrence = seen.get(node.value) ?? 0;
11365
+ seen.set(node.value, occurrence + 1);
11366
+ if (node.selected) chosen.push({ node, value: node.value, occurrence });
11367
+ }
11368
+ return { chosen, server: new Set(options) };
11369
+ }
11370
+ var nativeAppend = (parent, child) => Node.prototype.appendChild.call(parent, child);
11371
+ var nativeInsert = (parent, child, ref) => Node.prototype.insertBefore.call(parent, child, ref);
11372
+ var nativeReplace = (parent, child, old) => Node.prototype.replaceChild.call(parent, child, old);
11373
+ function sameKind(a2, b2) {
11374
+ return a2.nodeType === b2.nodeType && (a2.nodeType === 3 || a2.nodeType === 8);
11375
+ }
11376
+ function isOptionDisabled(option2) {
11377
+ const parent = option2.parentElement;
11378
+ return option2.disabled || parent?.localName === "optgroup" && parent.hasAttribute("disabled");
11379
+ }
11380
+ function defaultSelection(select3) {
11381
+ const options = Array.from(select3.options);
11382
+ const parsed = reparsedSelection(select3, options);
11383
+ if (parsed) return parsed;
11384
+ const marked = options.filter((o) => o.hasAttribute("selected"));
11385
+ if (select3.multiple) return new Set(marked);
11386
+ if (marked.length > 0) return /* @__PURE__ */ new Set([marked[marked.length - 1]]);
11387
+ if (select3.size > 1) return /* @__PURE__ */ new Set();
11388
+ const first = options.find((o) => !isOptionDisabled(o));
11389
+ return new Set(first ? [first] : []);
11390
+ }
11391
+ function reparsedSelection(select3, options) {
11392
+ if (typeof DOMParser !== "function") return null;
11393
+ try {
11394
+ const doc = new DOMParser().parseFromString(`<!doctype html><body>${select3.outerHTML}`, "text/html");
11395
+ const copy = doc.querySelector("select");
11396
+ if (!copy || copy.options.length !== options.length) return null;
11397
+ const chosen = /* @__PURE__ */ new Set();
11398
+ Array.from(copy.options).forEach((o, i2) => {
11399
+ if (o.selected) chosen.add(options[i2]);
11400
+ });
11401
+ return chosen;
11402
+ } catch {
11403
+ return null;
11404
+ }
11405
+ }
11406
+ function isDirty(el) {
11407
+ const tag = el.localName;
11408
+ if (tag === "input") {
11409
+ const input2 = el;
11410
+ if (input2.type === "checkbox" || input2.type === "radio") return input2.checked !== input2.hasAttribute("checked");
11411
+ return input2.value !== (input2.getAttribute("value") ?? "");
11412
+ }
11413
+ if (tag === "textarea") return el.value !== (el.textContent ?? "");
11414
+ if (tag === "select") {
11415
+ const select3 = el;
11416
+ const initial = defaultSelection(select3);
11417
+ return Array.from(select3.options).some((o) => o.selected !== initial.has(o));
11418
+ }
11419
+ return false;
11420
+ }
11421
+ var AdoptSession = class {
11422
+ constructor(root, options) {
11423
+ this.root = root;
11424
+ this.options = options;
11425
+ this.byId = /* @__PURE__ */ new Map();
11426
+ this.server = /* @__PURE__ */ new WeakSet();
11427
+ this.claimed = /* @__PURE__ */ new Map();
11428
+ this.cursors = /* @__PURE__ */ new WeakMap();
11429
+ this.patched = [];
11430
+ this.touched = /* @__PURE__ */ new Set();
11431
+ this.mismatches = [];
11432
+ /**
11433
+ * The selection of each `<select>` the user changed before takeover. Taken
11434
+ * before any client code runs: the client builds a select's options BEFORE
11435
+ * the select, and an option's `selected` write changes the selection long
11436
+ * before the select itself is claimed. Session-scoped: the references go
11437
+ * with the session.
11438
+ */
11439
+ this.selections = /* @__PURE__ */ new Map();
11440
+ /**
11441
+ * Checkboxes and radios the user changed before takeover, and their state —
11442
+ * for the same reason: checking a radio unchecks its group, so the client
11443
+ * writing a sibling (or a sibling joining the group) changes this one first.
11444
+ */
11445
+ this.checks = /* @__PURE__ */ new Map();
11446
+ /** Form controls whose state differed from their markup when the session started: the user's. */
11447
+ this.dirty = /* @__PURE__ */ new Set();
11448
+ this.created = 0;
11449
+ this.removed = 0;
11450
+ /** AdoptSink: numbering and claiming are on for the length of the session. */
11451
+ this.on = true;
11452
+ /** AdoptSink: the hydration session work built in this sink's scopes belongs to. */
11453
+ this.h = null;
11454
+ this.restored = false;
11455
+ const walk = (node) => {
11456
+ for (let child = node.firstChild; child; child = child.nextSibling) {
11457
+ this.server.add(child);
11458
+ if (child.nodeType === 1) {
11459
+ const id = child.getAttribute(ADOPT_ID_ATTR);
11460
+ if (id !== null && !this.byId.has(id)) this.byId.set(id, child);
11461
+ const tag = child.localName;
11462
+ if ((tag === "select" || tag === "input" || tag === "textarea") && isDirty(child)) {
11463
+ this.dirty.add(child);
11464
+ if (tag === "select") {
11465
+ this.selections.set(child, snapshotSelect(child));
11466
+ } else if (tag === "input") {
11467
+ const input2 = child;
11468
+ if (input2.type === "checkbox" || input2.type === "radio") this.checks.set(input2, input2.checked);
11469
+ }
11470
+ }
11471
+ walk(child);
11472
+ }
11473
+ }
11474
+ };
11475
+ walk(root);
11476
+ this.patchParent(root);
11477
+ }
11478
+ report(m) {
11479
+ 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}"`;
11480
+ const report = { ...m, message };
11481
+ this.mismatches.push(report);
11482
+ if (this.options.onMismatch) this.options.onMismatch(report);
11483
+ else if (DEV && this.mismatches.length <= 10) {
11484
+ console.warn(
11485
+ `[SibuJS hydration] adopt mismatch at ${m.path}${m.id ? ` (id ${m.id})` : ""}: ${message}.
11486
+ Likely cause: ${m.cause}`
11487
+ );
11488
+ }
11489
+ }
11490
+ // ── AdoptSink: claim the server element with this id ──
11491
+ el(tag, ns, id) {
11492
+ if (!this.on) return null;
11493
+ const candidate = this.byId.get(id);
11494
+ const want = ns ?? "http://www.w3.org/1999/xhtml";
11495
+ if (candidate && candidate.localName === tag && (candidate.namespaceURI ?? want) === want && !this.claimed.has(candidate)) {
11496
+ this.byId.delete(id);
11497
+ this.claim(candidate);
11498
+ return candidate;
11499
+ }
11500
+ this.created++;
11501
+ if (candidate) {
11502
+ this.report({
11503
+ kind: "tag",
11504
+ path: describeNodePath(candidate),
11505
+ id,
11506
+ serverValue: candidate.localName,
11507
+ clientValue: tag,
11508
+ 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()."
11509
+ });
11510
+ } else {
11511
+ this.report({
11512
+ kind: "missing",
11513
+ path: "(new element)",
11514
+ id,
11515
+ serverValue: "(none)",
11516
+ clientValue: tag,
11517
+ 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."
11518
+ });
11519
+ }
11520
+ return null;
11521
+ }
11522
+ claim(el) {
11523
+ el.removeAttribute(ADOPT_ID_ATTR);
11524
+ const keep = STICKY[el.localName] ?? [];
11525
+ const sticky = /* @__PURE__ */ new Set();
11526
+ for (const attr of Array.from(el.attributes)) {
11527
+ if (keep.includes(attr.name)) {
11528
+ const safe = resolveAttributeValue(attr.name, attr.value, { element: el });
11529
+ if (safe === null) el.removeAttribute(attr.name);
11530
+ else {
11531
+ if (safe !== attr.value) el.setAttribute(attr.name, safe);
11532
+ sticky.add(attr.name);
11533
+ }
11534
+ } else el.removeAttribute(attr.name);
11535
+ }
11536
+ this.claimed.set(el, { sticky });
11537
+ if (this.dirty.has(el)) this.touched.add(el);
11538
+ this.patchParent(el);
11539
+ }
11540
+ /**
11541
+ * Instance overrides on an adopted parent for the length of the session —
11542
+ * the core's own `appendChild` / `insertBefore` calls then place children
11543
+ * on the server nodes instead of moving them. Removed when the session ends.
11544
+ */
11545
+ patchParent(parent) {
11546
+ const session = this;
11547
+ const record = this.claimed.get(parent);
11548
+ this.cursors.set(parent, parent.firstChild);
11549
+ this.patched.push(parent);
11550
+ const own = parent;
11551
+ own.appendChild = function(child) {
11552
+ if (inAdoptScope() || child.nodeType === 11) return session.place(this, child);
11553
+ return nativeAppend(this, child);
11554
+ };
11555
+ own.insertBefore = function(child, ref) {
11556
+ return session.insertAt(this, child, ref);
11557
+ };
11558
+ own.replaceChildren = function(...nodes) {
11559
+ session.cursors.set(this, this.firstChild);
11560
+ for (const n of nodes) session.place(this, typeof n === "string" ? document.createTextNode(n) : n);
11561
+ let rest = session.cursors.get(this) ?? null;
11562
+ while (rest) {
11563
+ const next = rest.nextSibling;
11564
+ this.removeChild(rest);
11565
+ rest = next;
11566
+ }
11567
+ };
11568
+ const textDesc = Object.getOwnPropertyDescriptor(Node.prototype, "textContent");
11569
+ if (textDesc?.set && textDesc.get) {
11570
+ Object.defineProperty(parent, "textContent", {
11571
+ configurable: true,
11572
+ get() {
11573
+ return textDesc.get?.call(this);
11574
+ },
11575
+ set(value) {
11576
+ const text2 = value == null ? "" : String(value);
11577
+ const only = this.firstChild;
11578
+ if (only && only === this.lastChild && only.nodeType === 3 && only.data === text2) {
11579
+ session.server.delete(only);
11580
+ return;
11581
+ }
11582
+ textDesc.set?.call(this, value);
11583
+ }
11584
+ });
11585
+ }
11586
+ if (record) {
11587
+ const note = (name) => record.sticky.delete(String(name).toLowerCase());
11588
+ const { getAttribute, setAttribute, removeAttribute } = Element.prototype;
11589
+ own.getAttribute = function(name) {
11590
+ note(name);
11591
+ return getAttribute.call(this, name);
11592
+ };
11593
+ own.setAttribute = function(name, value) {
11594
+ note(name);
11595
+ return setAttribute.call(this, name, value);
11596
+ };
11597
+ own.removeAttribute = function(name) {
11598
+ note(name);
11599
+ return removeAttribute.call(this, name);
11600
+ };
11601
+ if (this.touched.has(parent) && parent.localName !== "select") {
11602
+ for (const prop of ["value", "checked"]) {
11603
+ if (prop in parent) {
11604
+ Object.defineProperty(parent, prop, {
11605
+ configurable: true,
11606
+ get() {
11607
+ const desc = findDescriptor(Object.getPrototypeOf(this), prop);
11608
+ return desc?.get?.call(this);
11609
+ },
11610
+ set() {
11611
+ }
11612
+ });
11613
+ }
11614
+ }
11615
+ }
11616
+ }
11617
+ }
11618
+ /** Put `child` at the cursor of `parent`. */
11619
+ place(parent, child) {
11620
+ if (child.nodeType === 11) {
11621
+ for (const n of Array.from(child.childNodes)) this.place(parent, n);
11622
+ return child;
11623
+ }
11624
+ let cur = this.cursors.has(parent) ? this.cursors.get(parent) ?? null : null;
11625
+ if (child === cur) {
11626
+ this.cursors.set(parent, child.nextSibling);
11627
+ return child;
11628
+ }
11629
+ if (child.parentNode === parent && this.claimed.has(child) && this.follows(cur, child)) {
11630
+ this.cursors.set(parent, child.nextSibling);
11631
+ return child;
11632
+ }
11633
+ if (!child.parentNode && (child.nodeType === 3 || child.nodeType === 8)) {
11634
+ const match = this.findCounterpart(cur, child);
11635
+ if (match) cur = match;
11636
+ }
11637
+ if (cur && this.server.has(cur) && !this.claimed.has(cur) && sameKind(cur, child) && !child.parentNode) {
11638
+ if (child.nodeType === 3) {
11639
+ const serverText = cur;
11640
+ const clientText = child.data;
11641
+ if (clientText !== "" && serverText.data !== clientText && serverText.data.startsWith(clientText)) {
11642
+ serverText.data = serverText.data.slice(clientText.length);
11643
+ nativeInsert(parent, child, serverText);
11644
+ return child;
11645
+ }
11646
+ if (serverText.data !== clientText) {
11647
+ this.report({
11648
+ kind: "text",
11649
+ path: describeNodePath(parent),
11650
+ id: null,
11651
+ serverValue: serverText.data.slice(0, 80),
11652
+ clientValue: clientText.slice(0, 80),
11653
+ 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."
11654
+ });
11655
+ }
11656
+ }
11657
+ this.server.delete(cur);
11658
+ this.cursors.set(parent, cur.nextSibling);
11659
+ nativeReplace(parent, child, cur);
11660
+ return child;
11661
+ }
11662
+ nativeInsert(parent, child, cur);
11663
+ return child;
11664
+ }
11665
+ /** Is `node` at or after `from` among its siblings? */
11666
+ follows(from, node) {
11667
+ for (let n = from; n; n = n.nextSibling) if (n === node) return true;
11668
+ return false;
11669
+ }
11670
+ /**
11671
+ * The server node a fresh text / comment child stands for: the first
11672
+ * unconsumed server node of the same kind from `from` on (a comment must
11673
+ * carry the same text), skipping unclaimed server nodes in between — a
11674
+ * preceding directive's branch content — but never an adopted element.
11675
+ */
11676
+ findCounterpart(from, child) {
11677
+ for (let n = from; n; n = n.nextSibling) {
11678
+ if (!this.server.has(n)) return null;
11679
+ if (n.nodeType === 1 && this.claimed.has(n)) return null;
11680
+ if (n.nodeType !== child.nodeType) continue;
11681
+ if (n.nodeType === 8 && n.data !== child.data) continue;
11682
+ return n;
11683
+ }
11684
+ return null;
11685
+ }
11686
+ /** `insertBefore` on an adopted parent: no-op when already in place; a fresh text/comment takes the server one's place. */
11687
+ insertAt(parent, child, ref) {
11688
+ if (child === ref || child.parentNode === parent && child.nextSibling === ref) return child;
11689
+ if (child.nodeType === 11) {
11690
+ for (const n of Array.from(child.childNodes)) this.insertAt(parent, n, ref);
11691
+ return child;
11692
+ }
11693
+ if (ref && !child.parentNode && this.server.has(ref) && sameKind(ref, child)) {
11694
+ if (child.nodeType === 3 && ref.data !== child.data) {
11695
+ this.report({
11696
+ kind: "text",
11697
+ path: describeNodePath(parent),
11698
+ id: null,
11699
+ serverValue: ref.data.slice(0, 80),
11700
+ clientValue: child.data.slice(0, 80),
11701
+ 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."
11702
+ });
11703
+ }
11704
+ this.server.delete(ref);
11705
+ if (this.cursors.get(parent) === ref) this.cursors.set(parent, ref.nextSibling);
11706
+ nativeReplace(parent, child, ref);
11707
+ return child;
11708
+ }
11709
+ return nativeInsert(parent, child, ref);
11710
+ }
11711
+ /** Remove every instance override; idempotent, and also run when the build throws. */
11712
+ restore() {
11713
+ this.on = false;
11714
+ if (this.restored) return;
11715
+ this.restored = true;
11716
+ for (const node of this.patched) {
11717
+ const own = node;
11718
+ for (const key of [
11719
+ "appendChild",
11720
+ "insertBefore",
11721
+ "replaceChildren",
11722
+ "textContent",
11723
+ "getAttribute",
11724
+ "setAttribute",
11725
+ "removeAttribute",
11726
+ "value",
11727
+ "checked"
11728
+ ]) {
11729
+ if (Object.hasOwn(own, key)) delete own[key];
11730
+ }
11731
+ }
11732
+ }
11733
+ /** End of the session: restore the instances, release unclaimed server nodes, replay input. */
11734
+ finish() {
11735
+ this.restore();
11736
+ const sweep = (node) => {
11737
+ for (let child = node.firstChild; child; ) {
11738
+ const next = child.nextSibling;
11739
+ if (this.server.has(child) && !this.claimed.has(child)) {
11740
+ if (child.nodeType === 1 && child.hasAttribute(ADOPT_ID_ATTR)) {
11741
+ this.report({
11742
+ kind: "extra",
11743
+ path: describeNodePath(child),
11744
+ id: child.getAttribute(ADOPT_ID_ATTR),
11745
+ serverValue: `<${child.localName}>`,
11746
+ clientValue: "(none)",
11747
+ 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."
11748
+ });
11749
+ }
11750
+ child.parentNode?.removeChild(child);
11751
+ this.removed++;
11752
+ } else if (child.nodeType === 1) sweep(child);
11753
+ child = next;
11754
+ }
11755
+ };
11756
+ sweep(this.root);
11757
+ for (const [el, record] of this.claimed) {
11758
+ for (const name of record.sticky) el.removeAttribute(name);
11759
+ }
11760
+ reselect(this);
11761
+ for (const el of this.touched) {
11762
+ el.dispatchEvent(new Event("input", { bubbles: true }));
11763
+ el.dispatchEvent(new Event("change", { bubbles: true }));
11764
+ }
11765
+ }
11766
+ };
11767
+ function survivingSelection(select3, snapshot) {
11768
+ const options = Array.from(select3.options);
11769
+ const present = new Set(options);
11770
+ const result = /* @__PURE__ */ new Set();
11771
+ const rebuilt = /* @__PURE__ */ new Map();
11772
+ for (const o of options) {
11773
+ if (snapshot.server.has(o)) continue;
11774
+ const list = rebuilt.get(o.value);
11775
+ if (list) list.push(o);
11776
+ else rebuilt.set(o.value, [o]);
11777
+ }
11778
+ const lost = [];
11779
+ for (const entry of snapshot.chosen) {
11780
+ if (present.has(entry.node) && entry.node.value === entry.value) result.add(entry.node);
11781
+ else lost.push(entry);
11782
+ }
11783
+ for (const entry of lost) {
11784
+ const candidates = rebuilt.get(entry.value);
11785
+ if (!candidates) continue;
11786
+ const atOccurrence = candidates[entry.occurrence];
11787
+ const match = atOccurrence && !result.has(atOccurrence) ? atOccurrence : candidates.find((o) => !result.has(o));
11788
+ if (match) result.add(match);
11789
+ }
11790
+ return result;
11791
+ }
11792
+ function reselect(session) {
11793
+ for (const [select3, snapshot] of session.selections) {
11794
+ if (!session.claimed.has(select3) || !session.root.contains(select3)) {
11795
+ session.touched.delete(select3);
11796
+ continue;
11797
+ }
11798
+ if (snapshot.chosen.length === 0) {
11799
+ select3.selectedIndex = -1;
11800
+ continue;
11801
+ }
11802
+ const keep = survivingSelection(select3, snapshot);
11803
+ if (keep.size === 0) {
11804
+ session.touched.delete(select3);
11805
+ continue;
11806
+ }
11807
+ if (select3.multiple) for (const o of Array.from(select3.options)) o.selected = keep.has(o);
11808
+ else keep.values().next().value.selected = true;
11809
+ }
11810
+ const live = Array.from(session.checks).filter(([el]) => session.claimed.has(el) && session.root.contains(el));
11811
+ for (const [el, checked] of live) if (!checked) el.checked = false;
11812
+ for (const [el, checked] of live) if (checked) el.checked = true;
11813
+ }
11814
+ function findDescriptor(proto, key) {
11815
+ for (let p2 = proto; p2; p2 = Object.getPrototypeOf(p2)) {
11816
+ const d = Object.getOwnPropertyDescriptor(p2, key);
11817
+ if (d) return d;
11818
+ }
11819
+ return void 0;
11820
+ }
11821
+ var macrotask = () => new Promise((resolve) => {
11822
+ if (typeof MessageChannel === "function") {
11823
+ const channel = new MessageChannel();
11824
+ channel.port1.onmessage = () => {
11825
+ channel.port1.close();
11826
+ resolve();
11827
+ };
11828
+ channel.port2.postMessage(null);
11829
+ } else setTimeout(resolve, 0);
11830
+ });
11831
+ async function hydrateAdopt(component, container, options = {}) {
11832
+ const hydration = beginHydration();
11833
+ const session = new AdoptSession(container, options);
11834
+ session.h = hydration;
11835
+ const rootScope = { p: "", n: 0, s: session };
11836
+ let replacedRoot = false;
11837
+ try {
11838
+ const tree = inHydration(hydration, () => inScope(rootScope, component));
11839
+ if (tree.parentNode !== container) {
11840
+ if (tree.nodeType === 1 && !session.claimed.has(tree)) {
11841
+ replacedRoot = true;
11842
+ if (DEV && !options.onMismatch) {
11843
+ console.warn(
11844
+ '[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?'
11845
+ );
11846
+ }
11847
+ }
11848
+ inScope(rootScope, () => session.place(container, tree));
11849
+ }
11850
+ const deadline = Date.now() + (options.timeout ?? 1e4);
11851
+ const { pending, wake } = hydration;
11852
+ for (; ; ) {
11853
+ await macrotask();
11854
+ if (pending.size === 0) {
11855
+ await macrotask();
11856
+ if (pending.size === 0) break;
11857
+ continue;
11858
+ }
11859
+ const remaining = deadline - Date.now();
11860
+ if (remaining <= 0) break;
11861
+ await new Promise((resolve) => {
11862
+ const done = () => {
11863
+ clearTimeout(timer);
11864
+ wake.delete(done);
11865
+ resolve();
11866
+ };
11867
+ const timer = setTimeout(done, remaining);
11868
+ wake.add(done);
11869
+ });
11870
+ }
11871
+ session.finish();
11872
+ } finally {
11873
+ session.restore();
11874
+ hydration.end();
11875
+ }
11876
+ container.setAttribute("data-sibu-hydrated", "adopt");
11877
+ return {
11878
+ adopted: session.claimed.size,
11879
+ created: session.created,
11880
+ removed: session.removed,
11881
+ mismatches: session.mismatches,
11882
+ replacedRoot
11883
+ };
11884
+ }
11885
+
11886
+ // src/platform/componentIsland.ts
11887
+ var ISLAND_PROPS_ATTR = "data-sibu-props";
11888
+ var SAFE_NAME = /^[A-Za-z0-9_-]+$/;
11889
+ function componentIsland(name, component, props, options = {}) {
11890
+ if (!SAFE_NAME.test(name)) {
11891
+ throw new Error(`[SibuJS SSR] island: name must match [A-Za-z0-9_-]+ (got: ${JSON.stringify(name.slice(0, 32))})`);
11892
+ }
11893
+ const wrapper = document.createElement("div");
11894
+ wrapper.setAttribute("data-sibu-island", name);
11895
+ if (options.load) wrapper.setAttribute("data-sibu-load", options.load);
11896
+ if (options.media) wrapper.setAttribute("data-sibu-media", options.media);
11897
+ wrapper.setAttribute("style", "display: contents");
11898
+ let json;
11899
+ try {
11900
+ json = JSON.stringify(props ?? null);
11901
+ } catch (err) {
11902
+ throw new Error(`[SibuJS SSR] island "${name}": props must be JSON-serializable`, { cause: err });
11903
+ }
11904
+ wrapper.setAttribute(ISLAND_PROPS_ATTR, json);
11905
+ const scope = isServer() ? {
11906
+ p: "",
11907
+ n: 0,
11908
+ s: {
11909
+ on: true,
11910
+ el(tag, ns, id) {
11911
+ const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
11912
+ el.setAttribute(ADOPT_ID_ATTR, id);
11913
+ return el;
11914
+ }
11915
+ }
11916
+ } : null;
11917
+ wrapper.appendChild(inScope(scope, () => component(props)));
11918
+ return wrapper;
11919
+ }
11920
+
11921
+ // src/platform/ssrStream.ts
11922
+ var hookInstalled = false;
11923
+ function installHook() {
11924
+ if (hookInstalled) return;
11925
+ hookInstalled = true;
11926
+ setBoundaryHook((container) => {
11927
+ const state3 = requestSlot("stream");
11928
+ const store = getRequestStore();
11929
+ if (!state3 || !store) return null;
11930
+ const id = `sibu-sus-${store.suspenseIdCounter++}`;
11931
+ container.setAttribute("data-sibu-suspense-id", id);
11932
+ const record = {
11933
+ id,
11934
+ container,
11935
+ done: false,
11936
+ emitted: false,
11937
+ fallbackHtml: null,
11938
+ api: {
11939
+ enter: (fn) => {
11940
+ if (record.fallbackHtml === null && state3.serialize) {
11941
+ record.fallbackHtml = Array.from(container.childNodes, (n) => state3.serialize?.(n) ?? "").join("");
11942
+ }
11943
+ return runInBoundary(record.api, fn);
11944
+ },
11945
+ done: () => {
11946
+ record.done = true;
11947
+ store.wake?.();
11948
+ }
11949
+ }
11950
+ };
11951
+ state3.boundaries.push(record);
11952
+ return record.api;
11953
+ });
11954
+ }
11955
+ function createChannel() {
11956
+ const chunks = [];
11957
+ let taken = null;
11958
+ let arrived = null;
11959
+ let ended = false;
11960
+ let cancelled = false;
11961
+ let error;
11962
+ return {
11963
+ get cancelled() {
11964
+ return cancelled;
11965
+ },
11966
+ async push(chunk) {
11967
+ if (cancelled || chunk === "") return;
11968
+ chunks.push(chunk);
11969
+ arrived?.();
11970
+ arrived = null;
11971
+ await new Promise((resolve) => {
11972
+ taken = resolve;
11973
+ });
11974
+ },
11975
+ end() {
11976
+ ended = true;
11977
+ arrived?.();
11978
+ },
11979
+ fail(err) {
11980
+ error = err;
11981
+ ended = true;
11982
+ arrived?.();
11983
+ },
11984
+ /** Called on cancel, so a renderer waiting for a boundary stops at once. */
11985
+ onCancel: null,
11986
+ cancel() {
11987
+ cancelled = true;
11988
+ taken?.();
11989
+ this.onCancel?.();
11990
+ },
11991
+ async take() {
11992
+ for (; ; ) {
11993
+ if (chunks.length > 0) {
11994
+ const value = chunks.shift();
11995
+ const release = taken;
11996
+ taken = null;
11997
+ release?.();
11998
+ return { value, done: false };
11999
+ }
12000
+ if (error !== void 0) throw error;
12001
+ if (ended) return { done: true };
12002
+ await new Promise((resolve) => {
12003
+ arrived = resolve;
12004
+ });
12005
+ }
12006
+ }
12007
+ };
12008
+ }
12009
+ var macrotask2 = () => new Promise((resolve) => {
12010
+ if (typeof setImmediate === "function") setImmediate(resolve);
12011
+ else setTimeout(resolve, 0);
12012
+ });
12013
+ async function waitFor(ready, deadline, stop2) {
12014
+ const store = getRequestStore();
12015
+ for (; ; ) {
12016
+ await macrotask2();
12017
+ if (stop2()) return false;
12018
+ if (ready()) {
12019
+ await macrotask2();
12020
+ if (ready()) return true;
12021
+ continue;
12022
+ }
12023
+ const remaining = deadline - Date.now();
12024
+ if (remaining <= 0) return false;
12025
+ await new Promise((resolve) => {
12026
+ const done = () => {
12027
+ clearTimeout(timer);
12028
+ if (store && store.wake === done) store.wake = null;
12029
+ resolve();
12030
+ };
12031
+ const timer = setTimeout(done, Math.min(remaining, 50));
12032
+ if (store) store.wake = done;
12033
+ });
12034
+ }
12035
+ }
12036
+ function pendingFor(pending, boundary) {
12037
+ if (!pending) return false;
12038
+ for (const work of pending) if (work.boundary === boundary) return true;
12039
+ return false;
12040
+ }
12041
+ function streamPage(input2, options = {}) {
12042
+ assertRequestIsolation("renderToReadableStream()");
12043
+ installHook();
12044
+ const channel = createChannel();
12045
+ const nonce = options.nonce;
12046
+ const doc = options.document === false ? null : options.document ?? {};
12047
+ const MARK_BODY = "<sibu-stream-body>";
12048
+ const MARK_END = "<sibu-stream-end>";
12049
+ void runInSSRContext(async () => {
12050
+ const store = getRequestStore();
12051
+ const state3 = { boundaries: [], serialize: null };
12052
+ requestSlot("stream", () => state3);
12053
+ const errors = [];
12054
+ if (store) store.errors = errors;
12055
+ let holder = null;
12056
+ channel.onCancel = () => store?.wake?.();
12057
+ const failIfErrored = () => {
12058
+ if (errors.length > 0) throw renderFailure(errors[0]);
12059
+ };
12060
+ const stopWaiting = () => errors.length > 0 || channel.cancelled;
12061
+ try {
12062
+ ensureServerDom();
12063
+ watchBrowserApis();
12064
+ const ids = options.hydration === "adopt" ? /* @__PURE__ */ new WeakMap() : null;
12065
+ const scope = ids ? createServerAdoptScope(ids) : null;
12066
+ let root;
12067
+ try {
12068
+ root = inScope(scope, input2);
12069
+ } catch (err) {
12070
+ throw explainServerError(err);
12071
+ }
12072
+ const serialize = (node) => renderToStringWith(node, { marker: options.marker ?? "root", ids });
12073
+ state3.serialize = serialize;
12074
+ holder = document.createDocumentFragment();
12075
+ holder.appendChild(root);
12076
+ const ready = (b2) => b2.done && !pendingFor(store?.pending, b2.api);
12077
+ const serializeWithFallbacks = (node) => {
12078
+ const held = [];
12079
+ for (const b2 of state3.boundaries) {
12080
+ if (ready(b2) || b2.container === node || !node.contains(b2.container)) continue;
12081
+ if (held.some((h) => h.b.container.contains(b2.container))) continue;
12082
+ const nodes = Array.from(b2.container.childNodes);
12083
+ for (const n of nodes) b2.container.removeChild(n);
12084
+ const mark2 = document.createComment(`sibu-fallback:${b2.id}`);
12085
+ b2.container.appendChild(mark2);
12086
+ held.push({ b: b2, nodes, mark: mark2 });
12087
+ }
12088
+ let html2 = serialize(node);
12089
+ for (const { b: b2, nodes, mark: mark2 } of held) {
12090
+ b2.container.removeChild(mark2);
12091
+ for (const n of nodes) b2.container.appendChild(n);
12092
+ const fallback = b2.fallbackHtml ?? "";
12093
+ html2 = html2.replace(`<!--sibu-fallback:${b2.id}-->`, () => fallback);
12094
+ }
12095
+ return html2;
12096
+ };
12097
+ const shellDeadline = Date.now() + (options.shellTimeout ?? 5e3);
12098
+ await waitFor(() => !pendingFor(store?.pending, void 0), shellDeadline, stopWaiting);
12099
+ failIfErrored();
12100
+ if (channel.cancelled) return;
12101
+ for (const b2 of state3.boundaries) {
12102
+ const inline = (x) => x.done && !pendingFor(store?.pending, x.api);
12103
+ const enclosing = state3.boundaries.filter((a2) => a2 !== b2 && a2.container.contains(b2.container));
12104
+ if (inline(b2) && enclosing.every(inline)) b2.emitted = true;
12105
+ }
12106
+ const shell = serializeWithFallbacks(holder);
12107
+ const head2 = collectServerHead();
12108
+ let after = "";
12109
+ let between = "";
12110
+ if (doc) {
12111
+ const page = assembleDocument(MARK_BODY, doc, head2, MARK_END);
12112
+ const bodyAt = page.indexOf(MARK_BODY);
12113
+ const endAt = page.indexOf(MARK_END, bodyAt + MARK_BODY.length);
12114
+ const start = page.slice(0, bodyAt);
12115
+ between = page.slice(bodyAt + MARK_BODY.length, endAt);
12116
+ after = page.slice(endAt + MARK_END.length);
12117
+ await channel.push(start + shell);
12118
+ } else {
12119
+ await channel.push(shell);
12120
+ }
12121
+ if (channel.cancelled) return;
12122
+ failIfErrored();
12123
+ const deadline = Date.now() + (options.timeout ?? 1e4);
12124
+ const outstanding = () => state3.boundaries.filter((b2) => !b2.emitted);
12125
+ const ancestorsOf = (b2) => state3.boundaries.filter((a2) => a2 !== b2 && a2.container.contains(b2.container));
12126
+ const emittable = (b2) => ready(b2) && ancestorsOf(b2).every((a2) => a2.emitted);
12127
+ let bodyClosed = false;
12128
+ for (; ; ) {
12129
+ if (outstanding().length === 0) break;
12130
+ const next = outstanding().find(emittable);
12131
+ if (!next) {
12132
+ const progressed = await waitFor(
12133
+ () => outstanding().some(emittable) || outstanding().length === 0,
12134
+ deadline,
12135
+ stopWaiting
12136
+ );
12137
+ if (channel.cancelled) return;
12138
+ failIfErrored();
12139
+ if (!progressed) break;
12140
+ continue;
12141
+ }
12142
+ failIfErrored();
12143
+ if (!bodyClosed && doc) {
12144
+ await channel.push(between);
12145
+ bodyClosed = true;
12146
+ if (channel.cancelled) return;
12147
+ failIfErrored();
12148
+ }
12149
+ for (const b2 of state3.boundaries) {
12150
+ if (b2 === next || !next.container.contains(b2.container) || !ready(b2)) continue;
12151
+ const between2 = ancestorsOf(b2).filter((a2) => a2 !== next && next.container.contains(a2.container));
12152
+ if (between2.every(ready)) b2.emitted = true;
12153
+ }
12154
+ next.emitted = true;
12155
+ if (!next.container.isConnected && !holder.contains(next.container)) continue;
12156
+ let html2 = "";
12157
+ for (const child of Array.from(next.container.childNodes)) html2 += serializeWithFallbacks(child);
12158
+ await channel.push(
12159
+ `<div hidden id="sibu-resolved-${next.id}">${html2}</div>${suspenseSwapScript(next.id, nonce)}`
12160
+ );
12161
+ if (channel.cancelled) return;
12162
+ failIfErrored();
12163
+ }
12164
+ if (DEV && outstanding().length > 0) {
12165
+ console.warn(
12166
+ `[SibuJS SSR] streaming: ${outstanding().length} Suspense boundar${outstanding().length === 1 ? "y" : "ies"} did not resolve within ${options.timeout ?? 1e4} ms and kept the fallback.`
12167
+ );
12168
+ }
12169
+ failIfErrored();
12170
+ let stateScript = "";
12171
+ if (options.transfer !== false) {
12172
+ const data2 = collectTransfer();
12173
+ if (data2) {
12174
+ try {
12175
+ stateScript = serializeState(data2, nonce, {
12176
+ maxBytes: options.maxStateBytes ?? DEFAULT_TRANSFER_MAX_BYTES,
12177
+ global: "__SIBU_TRANSFER__"
12178
+ });
12179
+ } catch (err) {
12180
+ if (DEV) console.warn("[SibuJS SSR] streaming: transferred state left out:", err);
12181
+ }
12182
+ }
12183
+ }
12184
+ if (doc) {
12185
+ await channel.push((bodyClosed ? "" : between) + stateScript + after);
12186
+ } else if (stateScript) {
12187
+ await channel.push(stateScript);
12188
+ }
12189
+ channel.end();
12190
+ } catch (err) {
12191
+ channel.fail(err);
12192
+ } finally {
12193
+ if (store) store.errors = void 0;
12194
+ if (holder) for (const child of Array.from(holder.childNodes)) dispose(child);
12195
+ }
12196
+ });
12197
+ return new ReadableStream({
12198
+ async pull(controller) {
12199
+ const { value, done } = await channel.take();
12200
+ if (done) controller.close();
12201
+ else controller.enqueue(value);
12202
+ },
12203
+ cancel() {
12204
+ channel.cancel();
12205
+ }
12206
+ });
12207
+ }
12208
+
12209
+ // src/platform/ssr.ts
12210
+ function isForbiddenSsrAttr(lowerName) {
12211
+ return isHtmlContentAttribute(lowerName);
12212
+ }
12213
+ var SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
12214
+ function isSafeAttrName(name) {
12215
+ return SAFE_ATTR_NAME.test(name);
12216
+ }
12217
+ function ssrErrorComment(err) {
12218
+ if (DEV) {
12219
+ const msg = escapeHtml(err instanceof Error ? err.message : String(err));
12220
+ return `<!--SSR error: ${safeCommentText(msg)}-->`;
12221
+ }
12222
+ return "<!--SSR error-->";
12223
+ }
12224
+ function safeCommentText(text2) {
12225
+ return text2.replace(/-->/g, "--&gt;").replace(/--!>/g, "--!&gt;").replace(/<!--/g, "&lt;!--").replace(/^(-?)>/, "$1&gt;").replace(/<!-$/, "&lt;!-").replace(/--$/g, "--&#45;");
12226
+ }
12227
+ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
12228
+ "area",
12229
+ "base",
12230
+ "br",
12231
+ "col",
12232
+ "embed",
12233
+ "hr",
12234
+ "img",
12235
+ "input",
12236
+ "link",
12237
+ "meta",
12238
+ "param",
12239
+ "source",
12240
+ "track",
12241
+ "wbr"
12242
+ ]);
12243
+ function findNativeGetter(proto, name) {
12244
+ for (let p2 = proto; p2; p2 = Object.getPrototypeOf(p2)) {
12245
+ const get = Object.getOwnPropertyDescriptor(p2, name)?.get;
12246
+ if (get) return get;
12247
+ }
12248
+ return null;
12249
+ }
12250
+ var nativeAccessorsByRealm = /* @__PURE__ */ new WeakMap();
12251
+ function nativeAccessors() {
12252
+ const realm = Element;
12253
+ let accessors = nativeAccessorsByRealm.get(realm);
12254
+ if (!accessors) {
12255
+ accessors = {
12256
+ attributes: findNativeGetter(Element.prototype, "attributes"),
12257
+ tagName: findNativeGetter(Element.prototype, "tagName"),
12258
+ childNodes: findNativeGetter(Node.prototype, "childNodes"),
12259
+ getAttribute: Element.prototype.getAttribute
12260
+ };
12261
+ nativeAccessorsByRealm.set(realm, accessors);
12262
+ }
12263
+ return accessors;
12264
+ }
12265
+ function attributesOf(el) {
9044
12266
  const get = nativeAccessors().attributes;
9045
12267
  return get ? get.call(el) : el.attributes;
9046
12268
  }
@@ -9055,8 +12277,8 @@ function childNodesOf(node) {
9055
12277
  function getAttributeOf(el, name) {
9056
12278
  return nativeAccessors().getAttribute.call(el, name);
9057
12279
  }
9058
- var SVG_NS3 = "http://www.w3.org/2000/svg";
9059
- var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
12280
+ var SVG_NS4 = "http://www.w3.org/2000/svg";
12281
+ var MATHML_NS2 = "http://www.w3.org/1998/Math/MathML";
9060
12282
  var XLINK_NS2 = "http://www.w3.org/1999/xlink";
9061
12283
  var XML_NS2 = "http://www.w3.org/XML/1998/namespace";
9062
12284
  var XMLNS_NS = "http://www.w3.org/2000/xmlns/";
@@ -9111,21 +12333,21 @@ function isBreakout(lowerName, element) {
9111
12333
  return lowerName === "font" && (element.hasAttribute("color") || element.hasAttribute("face") || element.hasAttribute("size"));
9112
12334
  }
9113
12335
  function fitsParseContext(ns, lowerName, element, context) {
9114
- if (ns === SVG_NS3) {
12336
+ if (ns === SVG_NS4) {
9115
12337
  if (context === 1 /* Svg */) return !isBreakout(lowerName, element);
9116
12338
  return lowerName === "svg" && (context === 0 /* Html */ || context === 3 /* Annotation */);
9117
12339
  }
9118
- if (ns === MATHML_NS) {
12340
+ if (ns === MATHML_NS2) {
9119
12341
  if (context === 2 /* Math */ || context === 3 /* Annotation */) return !isBreakout(lowerName, element);
9120
12342
  return lowerName === "math" && context === 0 /* Html */;
9121
12343
  }
9122
12344
  return context === 0 /* Html */;
9123
12345
  }
9124
12346
  function childParseContext(ns, lowerName, element) {
9125
- if (ns === SVG_NS3) {
12347
+ if (ns === SVG_NS4) {
9126
12348
  return lowerName === "foreignobject" || lowerName === "desc" || lowerName === "title" ? 0 /* Html */ : 1 /* Svg */;
9127
12349
  }
9128
- if (ns === MATHML_NS) {
12350
+ if (ns === MATHML_NS2) {
9129
12351
  if (lowerName === "mi" || lowerName === "mo" || lowerName === "mn" || lowerName === "ms" || lowerName === "mtext") {
9130
12352
  return 0 /* Html */;
9131
12353
  }
@@ -9144,7 +12366,8 @@ function foreignAttrName(attr) {
9144
12366
  if (ns === XMLNS_NS) return attr.localName === "xmlns" ? "xmlns" : `xmlns:${attr.localName}`;
9145
12367
  return attr.name;
9146
12368
  }
9147
- function serializeOpenTag(element, tag, foreign) {
12369
+ var LEGACY_SERIALIZE = { marker: "all", ids: null };
12370
+ function serializeOpenTag(element, tag, foreign, opts, depth) {
9148
12371
  let html2 = `<${tag}`;
9149
12372
  const meta2 = tag === "meta" && !foreign ? /* @__PURE__ */ new Map() : null;
9150
12373
  const embed2 = tag === "iframe" && !foreign ? getEmbedRecord(element) : void 0;
@@ -9173,18 +12396,20 @@ function serializeOpenTag(element, tag, foreign) {
9173
12396
  if (tail === null) return null;
9174
12397
  html2 += tail;
9175
12398
  }
9176
- if (!getAttributeOf(element, "data-sibu-hydrate")) {
12399
+ const hid = opts.ids?.get(element);
12400
+ if (hid !== void 0) html2 += ` data-sibu-h="${hid}"`;
12401
+ if ((opts.marker === "all" || opts.marker === "root" && depth === 0) && !getAttributeOf(element, "data-sibu-hydrate")) {
9177
12402
  html2 += ` data-sibu-ssr="true"`;
9178
12403
  }
9179
12404
  return html2;
9180
12405
  }
9181
- function serializeNode(node, context) {
12406
+ function serializeNode(node, context, opts = LEGACY_SERIALIZE, depth = 0) {
9182
12407
  if (node.nodeType === 3) return escapeHtml(node.textContent || "");
9183
12408
  if (node.nodeType === 8) return `<!--${safeCommentText(node.textContent || "")}-->`;
9184
12409
  let foreign = false;
9185
12410
  if (!(node instanceof HTMLElement)) {
9186
12411
  const ns2 = node.nodeType === 1 ? node.namespaceURI : null;
9187
- if (ns2 !== SVG_NS3 && ns2 !== MATHML_NS) return escapeHtml(node.textContent || "");
12412
+ if (ns2 !== SVG_NS4 && ns2 !== MATHML_NS2) return escapeHtml(node.textContent || "");
9188
12413
  foreign = true;
9189
12414
  }
9190
12415
  const element = node;
@@ -9194,7 +12419,7 @@ function serializeNode(node, context) {
9194
12419
  const ns = foreign ? element.namespaceURI : null;
9195
12420
  const lowerName = tag.toLowerCase();
9196
12421
  if (!fitsParseContext(ns, lowerName, element, context)) return DEV ? `<!--ssr:${tag}-misplaced-->` : "";
9197
- const openTag = serializeOpenTag(element, tag, foreign);
12422
+ const openTag = serializeOpenTag(element, tag, foreign, opts, depth);
9198
12423
  if (openTag === null) return DEV ? `<!--ssr:${tag}-stripped-->` : "";
9199
12424
  const children = childNodesOf(element);
9200
12425
  if (foreign ? children.length === 0 : VOID_ELEMENTS.has(tag)) return `${openTag} />`;
@@ -9206,31 +12431,45 @@ function serializeNode(node, context) {
9206
12431
  };
9207
12432
  }
9208
12433
  function renderToString(element) {
9209
- return renderNodeToString(element, 0 /* Html */);
12434
+ return renderNodeToString(element, 0 /* Html */, LEGACY_SERIALIZE, 0);
9210
12435
  }
9211
- function renderNodeToString(element, context) {
12436
+ function renderToStringWith(element, opts) {
12437
+ return renderNodeToString(element, 0 /* Html */, opts, 0);
12438
+ }
12439
+ function renderNodeToString(element, context, opts, depth) {
9212
12440
  if (element instanceof DocumentFragment) {
12441
+ let prevText2 = false;
9213
12442
  return Array.from(element.childNodes).map((child) => {
12443
+ const isText = child.nodeType === 3;
12444
+ const sep = opts.ids && isText && prevText2 ? "<!--|-->" : "";
12445
+ prevText2 = isText;
9214
12446
  try {
9215
- return renderNodeToString(child, context);
12447
+ return sep + renderNodeToString(child, context, opts, depth);
9216
12448
  } catch (err) {
9217
12449
  return ssrErrorComment(err);
9218
12450
  }
9219
12451
  }).join("");
9220
12452
  }
9221
- const frame = serializeNode(element, context);
12453
+ const frame = serializeNode(element, context, opts, depth);
9222
12454
  if (typeof frame === "string") return frame;
9223
12455
  let html2 = frame.open;
12456
+ let prevText = false;
9224
12457
  for (const child of frame.children) {
12458
+ const isText = child.nodeType === 3;
12459
+ if (opts.ids && isText && prevText) html2 += "<!--|-->";
12460
+ prevText = isText;
9225
12461
  try {
9226
- html2 += renderNodeToString(child, frame.context);
12462
+ html2 += renderNodeToString(child, frame.context, opts, depth + 1);
9227
12463
  } catch (err) {
9228
12464
  html2 += ssrErrorComment(err);
9229
12465
  }
9230
12466
  }
9231
12467
  return html2 + frame.close;
9232
12468
  }
9233
- function hydrate(component, container, options = {}) {
12469
+ function hydrate(component, target, input2 = {}) {
12470
+ if (input2.strategy === "adopt") return hydrateAdopt(component, target, input2);
12471
+ const options = input2;
12472
+ const container = target;
9234
12473
  const clientTree = component();
9235
12474
  if (options.diagnostics) {
9236
12475
  const mismatches = [];
@@ -9386,6 +12625,9 @@ function renderToDocument(component, options = {}) {
9386
12625
  } catch (err) {
9387
12626
  content = ssrErrorComment(err);
9388
12627
  }
12628
+ return assembleDocument(content, options, "", "");
12629
+ }
12630
+ function assembleDocument(content, options, head2, bodyEnd) {
9389
12631
  const metaTags = (options.meta || []).map((attrs) => serializeHeadEntry("meta", attrs)).filter(Boolean).join("\n ");
9390
12632
  const linkTags = (options.links || []).map((attrs) => serializeHeadEntry("link", attrs)).filter(Boolean).join("\n ");
9391
12633
  const scriptTags = (options.scripts || []).map((src) => {
@@ -9403,10 +12645,12 @@ function renderToDocument(component, options = {}) {
9403
12645
  ${options.title != null ? `<title>${escapeHtml(options.title)}</title>` : ""}
9404
12646
  ${metaTags}
9405
12647
  ${linkTags}
9406
- ${options.headExtra || ""}
12648
+ ${options.headExtra || ""}${head2 ? `
12649
+ ${head2}` : ""}
9407
12650
  </head>
9408
12651
  <body${bodyAttrs}>
9409
- <div id="app">${content}</div>
12652
+ <div id="app">${content}</div>${bodyEnd ? `
12653
+ ${bodyEnd}` : ""}
9410
12654
  ${scriptTags}
9411
12655
  </body>
9412
12656
  </html>`;
@@ -9447,7 +12691,8 @@ async function collectStream(stream2) {
9447
12691
  }
9448
12692
  return result;
9449
12693
  }
9450
- function renderToReadableStream(element) {
12694
+ function renderToReadableStream(element, options) {
12695
+ if (typeof element === "function") return streamPage(element, options);
9451
12696
  const generator = renderToStream(element);
9452
12697
  return new ReadableStream({
9453
12698
  async pull(controller) {
@@ -9464,7 +12709,8 @@ function renderToReadableStream(element) {
9464
12709
  });
9465
12710
  }
9466
12711
  var SAFE_ID = /^[A-Za-z0-9_-]+$/;
9467
- function island(id, component) {
12712
+ function island(id, component, ...rest) {
12713
+ if (rest.length > 0) return componentIsland(id, component, rest[0], rest[1]);
9468
12714
  if (!SAFE_ID.test(id)) {
9469
12715
  throw new Error(`[SibuJS SSR] island: id must match [A-Za-z0-9_-]+ (got: ${JSON.stringify(id.slice(0, 32))})`);
9470
12716
  }
@@ -9598,16 +12844,22 @@ function escapeScriptJson(json) {
9598
12844
  return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
9599
12845
  }
9600
12846
  var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
12847
+ var SAFE_GLOBAL_NAME = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
9601
12848
  function serializeState(state3, nonce, options) {
12849
+ const globalName = options?.global ?? SSR_DATA_ATTR;
12850
+ if (!SAFE_GLOBAL_NAME.test(globalName)) {
12851
+ throw new Error(`[SibuJS SSR] serializeState: global must be an identifier (got: ${JSON.stringify(globalName)})`);
12852
+ }
9602
12853
  const rawJson = JSON.stringify(state3);
9603
12854
  const maxBytes = options?.maxBytes ?? DEFAULT_MAX_SSR_BYTES;
9604
12855
  const byteLen = typeof TextEncoder !== "undefined" ? new TextEncoder().encode(rawJson).byteLength : Buffer.byteLength(rawJson, "utf8");
9605
12856
  if (byteLen > maxBytes) {
9606
12857
  throw new Error(`[SibuJS SSR] serializeState: payload (${byteLen} bytes) exceeds maxBytes (${maxBytes})`);
9607
12858
  }
9608
- const json = escapeScriptJson(rawJson);
12859
+ const value = rawJson.includes('"__proto__":') ? `JSON.parse(${JSON.stringify(rawJson)})` : rawJson;
12860
+ const json = escapeScriptJson(value);
9609
12861
  const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : "";
9610
- return `<script${nonceAttr}>window.${SSR_DATA_ATTR}=${json}</script>`;
12862
+ return `<script${nonceAttr}>window.${globalName}=${json}</script>`;
9611
12863
  }
9612
12864
  function deserializeState(validate) {
9613
12865
  if (typeof window === "undefined") return void 0;
@@ -9657,14 +12909,14 @@ function block(factory) {
9657
12909
  function dict(source2) {
9658
12910
  const out = /* @__PURE__ */ Object.create(null);
9659
12911
  if (source2) {
9660
- for (const key of Object.keys(source2)) defineOwn(out, key, source2[key]);
12912
+ for (const key of Object.keys(source2)) defineOwn2(out, key, source2[key]);
9661
12913
  }
9662
12914
  return out;
9663
12915
  }
9664
12916
  function ownGet(obj, key) {
9665
12917
  return obj !== void 0 && Object.hasOwn(obj, key) ? obj[key] : void 0;
9666
12918
  }
9667
- function defineOwn(obj, key, value) {
12919
+ function defineOwn2(obj, key, value) {
9668
12920
  Object.defineProperty(obj, key, { value, writable: true, enumerable: true, configurable: true });
9669
12921
  }
9670
12922
  function readEntityId(entity, idKey, typeName) {
@@ -9687,7 +12939,7 @@ function normalizedStore(schema) {
9687
12939
  setState((prev) => {
9688
12940
  const ids = Object.hasOwn(prev.entities, id) ? prev.ids : [...prev.ids, id];
9689
12941
  const entities = dict(prev.entities);
9690
- defineOwn(entities, id, entity);
12942
+ defineOwn2(entities, id, entity);
9691
12943
  return { ids, entities };
9692
12944
  });
9693
12945
  }
@@ -9701,7 +12953,7 @@ function normalizedStore(schema) {
9701
12953
  if (!Object.hasOwn(nextEntities, id)) {
9702
12954
  nextIds.push(id);
9703
12955
  }
9704
- defineOwn(nextEntities, id, entity);
12956
+ defineOwn2(nextEntities, id, entity);
9705
12957
  });
9706
12958
  return { ids: nextIds, entities: nextEntities };
9707
12959
  });
@@ -9724,12 +12976,12 @@ function normalizedStore(schema) {
9724
12976
  );
9725
12977
  }
9726
12978
  }
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 };
12979
+ setState((current2) => {
12980
+ const existing = ownGet(current2.entities, id);
12981
+ if (!existing) return current2;
12982
+ const entities = dict(current2.entities);
12983
+ defineOwn2(entities, id, { ...existing, ...partial });
12984
+ return { ids: current2.ids, entities };
9733
12985
  });
9734
12986
  }
9735
12987
  function remove(id) {
@@ -9755,7 +13007,7 @@ function normalize(data2, schema) {
9755
13007
  let table2 = ownGet(entities, name);
9756
13008
  if (!table2) {
9757
13009
  table2 = dict();
9758
- defineOwn(entities, name, table2);
13010
+ defineOwn2(entities, name, table2);
9759
13011
  }
9760
13012
  return table2;
9761
13013
  }
@@ -9770,17 +13022,17 @@ function normalize(data2, schema) {
9770
13022
  if (value == null) continue;
9771
13023
  const relSchema = { name: relationType };
9772
13024
  if (Array.isArray(value)) {
9773
- defineOwn(
13025
+ defineOwn2(
9774
13026
  flat,
9775
13027
  field,
9776
13028
  value.map((item) => normalizeEntity(item, relSchema))
9777
13029
  );
9778
13030
  } else if (typeof value === "object") {
9779
- defineOwn(flat, field, normalizeEntity(value, relSchema));
13031
+ defineOwn2(flat, field, normalizeEntity(value, relSchema));
9780
13032
  }
9781
13033
  }
9782
13034
  }
9783
- defineOwn(table2, id, flat);
13035
+ defineOwn2(table2, id, flat);
9784
13036
  return id;
9785
13037
  }
9786
13038
  if (Array.isArray(data2)) {
@@ -9802,13 +13054,13 @@ function denormalize(id, entities, schema) {
9802
13054
  if (value == null) continue;
9803
13055
  const relSchema = { name: relationType };
9804
13056
  if (Array.isArray(value)) {
9805
- defineOwn(
13057
+ defineOwn2(
9806
13058
  result,
9807
13059
  field,
9808
13060
  value.map((relId) => denormalize(relId, entities, relSchema))
9809
13061
  );
9810
13062
  } else if (typeof value === "string") {
9811
- defineOwn(result, field, denormalize(value, entities, relSchema));
13063
+ defineOwn2(result, field, denormalize(value, entities, relSchema));
9812
13064
  }
9813
13065
  }
9814
13066
  }
@@ -9836,7 +13088,7 @@ function createChunkRegistry(config = {}) {
9836
13088
  const cache = /* @__PURE__ */ new Map();
9837
13089
  const pending = /* @__PURE__ */ new Map();
9838
13090
  const preloaded = /* @__PURE__ */ new Map();
9839
- function notify(name, run) {
13091
+ function notify2(name, run) {
9840
13092
  try {
9841
13093
  run();
9842
13094
  } catch (err) {
@@ -9908,7 +13160,7 @@ function createChunkRegistry(config = {}) {
9908
13160
  const entry = { promise: outcome };
9909
13161
  pending.set(id, entry);
9910
13162
  const owns = () => pending.get(id) === entry;
9911
- notify("onLoadStart", () => onLoadStart?.(id));
13163
+ notify2("onLoadStart", () => onLoadStart?.(id));
9912
13164
  void loadWithRetry(id, loader).then(
9913
13165
  (value) => {
9914
13166
  if (owns()) {
@@ -9917,13 +13169,13 @@ function createChunkRegistry(config = {}) {
9917
13169
  const now = Date.now();
9918
13170
  cache.set(id, { value, timestamp: now, lastAccess: now, accessCount: 1 });
9919
13171
  }
9920
- notify("onLoadEnd", () => onLoadEnd?.(id));
13172
+ notify2("onLoadEnd", () => onLoadEnd?.(id));
9921
13173
  resolveOuter(value);
9922
13174
  },
9923
13175
  (err) => {
9924
13176
  if (owns()) pending.delete(id);
9925
13177
  const error = err instanceof Error ? err : new Error(String(err));
9926
- notify("onLoadError", () => onLoadError?.(id, error));
13178
+ notify2("onLoadError", () => onLoadError?.(id, error));
9927
13179
  rejectOuter(error);
9928
13180
  }
9929
13181
  ).catch((internal) => {
@@ -10009,9 +13261,9 @@ function createChunkRegistry(config = {}) {
10009
13261
  }
10010
13262
  };
10011
13263
  }
10012
- function lazyChunk(id, loader, registry, fallback) {
13264
+ function lazyChunk(id, loader, registry2, fallback) {
10013
13265
  return () => {
10014
- const cached = registry.get(id);
13266
+ const cached = registry2.get(id);
10015
13267
  if (cached) return cached();
10016
13268
  const container = document.createElement("div");
10017
13269
  container.setAttribute("data-chunk", id);
@@ -10022,7 +13274,7 @@ function lazyChunk(id, loader, registry, fallback) {
10022
13274
  registerDisposer(container, () => {
10023
13275
  disposed = true;
10024
13276
  });
10025
- registry.load(id, async () => {
13277
+ registry2.load(id, async () => {
10026
13278
  const mod = await loader();
10027
13279
  return typeof mod === "function" ? mod : mod.default;
10028
13280
  }).then(
@@ -10073,18 +13325,18 @@ var CLIENT_RESOLVER = {
10073
13325
  isReactiveValue: (value) => typeof value === "function"
10074
13326
  };
10075
13327
  function applyMetaEntry(metaProps, managedElements) {
10076
- let current = null;
13328
+ let current2 = null;
10077
13329
  const retract = () => {
10078
- if (!current) return;
10079
- const index = managedElements.indexOf(current);
13330
+ if (!current2) return;
13331
+ const index = managedElements.indexOf(current2);
10080
13332
  if (index !== -1) managedElements.splice(index, 1);
10081
- current.remove();
10082
- current = null;
13333
+ current2.remove();
13334
+ current2 = null;
10083
13335
  };
10084
13336
  const alreadyPublished = (attributes) => {
10085
- if (!current || current.attributes.length !== attributes.size) return false;
13337
+ if (!current2 || current2.attributes.length !== attributes.size) return false;
10086
13338
  for (const [name, value] of attributes) {
10087
- if (current.getAttribute(name) !== value) return false;
13339
+ if (current2.getAttribute(name) !== value) return false;
10088
13340
  }
10089
13341
  return true;
10090
13342
  };
@@ -10092,16 +13344,16 @@ function applyMetaEntry(metaProps, managedElements) {
10092
13344
  if (alreadyPublished(attributes)) return;
10093
13345
  const next = document.createElement("meta");
10094
13346
  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);
13347
+ const index = current2 ? managedElements.indexOf(current2) : -1;
13348
+ if (current2?.parentNode) {
13349
+ current2.replaceWith(next);
10098
13350
  } else {
10099
- current?.remove();
13351
+ current2?.remove();
10100
13352
  document.head.appendChild(next);
10101
13353
  }
10102
13354
  if (index !== -1) managedElements[index] = next;
10103
13355
  else managedElements.push(next);
10104
- current = next;
13356
+ current2 = next;
10105
13357
  };
10106
13358
  const stopEffect = effect(() => {
10107
13359
  const plan = planMetaEntry(metaProps, CLIENT_RESOLVER);
@@ -10116,8 +13368,43 @@ function applyMetaEntry(metaProps, managedElements) {
10116
13368
  retract();
10117
13369
  };
10118
13370
  }
13371
+ function headEntryKey(tag, attrs) {
13372
+ const lower = (v) => (v ?? "").toLowerCase();
13373
+ if (tag === "meta") {
13374
+ if (attrs.name) return `meta:name:${lower(attrs.name)}`;
13375
+ if (attrs.property) return `meta:property:${lower(attrs.property)}`;
13376
+ if (attrs["http-equiv"]) return `meta:http-equiv:${lower(attrs["http-equiv"])}`;
13377
+ return `meta:${JSON.stringify(attrs)}`;
13378
+ }
13379
+ const rel = lower(attrs.rel);
13380
+ if (rel === "canonical") return "link:rel:canonical";
13381
+ if (rel === "alternate" && attrs.hreflang) return `link:hreflang:${lower(attrs.hreflang)}`;
13382
+ return `link:${rel}:${attrs.href ?? ""}`;
13383
+ }
13384
+ function resolveHeadForServer(props) {
13385
+ const layer = { tags: [] };
13386
+ if (props.title != null) layer.title = CLIENT_RESOLVER.resolveValue("title", props.title);
13387
+ for (const entry of props.meta ?? []) {
13388
+ const plan = planMetaEntry(entry, CLIENT_RESOLVER);
13389
+ if (plan.kind === "drop") continue;
13390
+ const attrs = Object.fromEntries(plan.attributes);
13391
+ layer.tags.push({ key: headEntryKey("meta", attrs), html: serializePlannedHeadEntry("meta", plan.attributes) });
13392
+ }
13393
+ for (const attrs of props.link ?? []) {
13394
+ const html2 = serializeHeadEntry("link", attrs);
13395
+ if (html2) layer.tags.push({ key: headEntryKey("link", attrs), html: html2 });
13396
+ }
13397
+ return layer;
13398
+ }
13399
+ function recordHeadForServer(props, anchor) {
13400
+ const withdraw = recordServerHead(() => resolveHeadForServer(props));
13401
+ if (!withdraw) return false;
13402
+ registerDisposer(anchor, withdraw);
13403
+ return true;
13404
+ }
10119
13405
  function Head(props) {
10120
13406
  const anchor = document.createComment("sibu-head");
13407
+ if (getRequestStore()?.ssr && recordHeadForServer(props, anchor)) return anchor;
10121
13408
  const managedElements = [];
10122
13409
  const effectCleanups = [];
10123
13410
  const cleanup3 = () => {
@@ -10207,7 +13494,7 @@ function setCanonical(url) {
10207
13494
  }
10208
13495
 
10209
13496
  // src/platform/customElement.ts
10210
- var SVG_NS4 = "http://www.w3.org/2000/svg";
13497
+ var SVG_NS5 = "http://www.w3.org/2000/svg";
10211
13498
  var MAX_RENDER_PASSES = 10;
10212
13499
  var ABANDONED_RENDER = /* @__PURE__ */ Symbol("sibujs.defineElement.abandonedRender");
10213
13500
  function defineElement(name, component, options = {}) {
@@ -10359,7 +13646,7 @@ function svgElement(tag, props = {}, ...nodes) {
10359
13646
  if (isBlockedElement(tag)) {
10360
13647
  throw new Error(`svgElement: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
10361
13648
  }
10362
- const el = document.createElementNS(SVG_NS4, tag);
13649
+ const el = document.createElementNS(SVG_NS5, tag);
10363
13650
  for (const [key, value] of Object.entries(props)) {
10364
13651
  if (key === "nodes") continue;
10365
13652
  if (typeof value === "function" && isEventHandlerAttr(key)) {
@@ -10553,7 +13840,7 @@ function createWorkerPool(workerFn2, poolSize) {
10553
13840
  }
10554
13841
  function dispatchOne(idx) {
10555
13842
  const w = workers[idx];
10556
- const slot2 = queues[idx].shift();
13843
+ const slot4 = queues[idx].shift();
10557
13844
  const onMsg = (e) => {
10558
13845
  if (!firedOnce) {
10559
13846
  firedOnce = true;
@@ -10562,7 +13849,7 @@ function createWorkerPool(workerFn2, poolSize) {
10562
13849
  w.removeEventListener("message", onMsg);
10563
13850
  w.removeEventListener("error", onErr);
10564
13851
  inflight[idx] = null;
10565
- slot2.resolve(e.data);
13852
+ slot4.resolve(e.data);
10566
13853
  dispatchNext(idx);
10567
13854
  };
10568
13855
  const onErr = (e) => {
@@ -10573,16 +13860,16 @@ function createWorkerPool(workerFn2, poolSize) {
10573
13860
  w.removeEventListener("message", onMsg);
10574
13861
  w.removeEventListener("error", onErr);
10575
13862
  inflight[idx] = null;
10576
- slot2.reject(new Error(e.message || "Worker error"));
13863
+ slot4.reject(new Error(e.message || "Worker error"));
10577
13864
  dispatchNext(idx);
10578
13865
  };
10579
13866
  try {
10580
- w.postMessage(slot2.data);
13867
+ w.postMessage(slot4.data);
10581
13868
  } catch (err) {
10582
- slot2.reject(toError(err));
13869
+ slot4.reject(toError(err));
10583
13870
  return;
10584
13871
  }
10585
- inflight[idx] = { ...slot2, onMsg, onErr };
13872
+ inflight[idx] = { ...slot4, onMsg, onErr };
10586
13873
  w.addEventListener("message", onMsg);
10587
13874
  w.addEventListener("error", onErr);
10588
13875
  }
@@ -10922,10 +14209,11 @@ function restoreFocusWithin(snapshot, nodes, where, policy) {
10922
14209
  // src/reactivity/bindChildNode.ts
10923
14210
  function bindChildNode(placeholder, getter) {
10924
14211
  let lastNodes = [];
14212
+ const scope = captureScope();
10925
14213
  function commit() {
10926
14214
  let result;
10927
14215
  try {
10928
- result = getter();
14216
+ result = inScope(scope, getter);
10929
14217
  } catch (err) {
10930
14218
  reportError(err, { phase: "binding", name: "bindChildNode", node: placeholder });
10931
14219
  return;
@@ -11001,7 +14289,7 @@ function noDocument() {
11001
14289
  }
11002
14290
 
11003
14291
  // src/core/rendering/tagFactory.ts
11004
- var SVG_NS5 = "http://www.w3.org/2000/svg";
14292
+ var SVG_NS6 = "http://www.w3.org/2000/svg";
11005
14293
  var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
11006
14294
  "config",
11007
14295
  "location",
@@ -11019,7 +14307,7 @@ var warnedLoneStrings = /* @__PURE__ */ new Set();
11019
14307
  var MAX_WARNED_LONE_STRINGS = 100;
11020
14308
  var loneStringCapAnnounced = false;
11021
14309
  var kebabCache = /* @__PURE__ */ new Map();
11022
- function toKebab(prop) {
14310
+ function toKebab2(prop) {
11023
14311
  let cached = kebabCache.get(prop);
11024
14312
  if (cached !== void 0) return cached;
11025
14313
  cached = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
@@ -11049,7 +14337,7 @@ function applyStyle(el, style2) {
11049
14337
  if (!Object.hasOwn(value, prop)) continue;
11050
14338
  const val = value[prop];
11051
14339
  if (val == null) continue;
11052
- const name = toKebab(prop);
14340
+ const name = toKebab2(prop);
11053
14341
  next.push(name);
11054
14342
  decl.setProperty(name, sanitizeCSSDeclaration(name, String(val), { element: el }));
11055
14343
  }
@@ -11069,7 +14357,7 @@ function applyStyle(el, style2) {
11069
14357
  for (const prop in style2) {
11070
14358
  if (!Object.hasOwn(style2, prop)) continue;
11071
14359
  const val = style2[prop];
11072
- const name = toKebab(prop);
14360
+ const name = toKebab2(prop);
11073
14361
  if (typeof val === "function") {
11074
14362
  const getter = val;
11075
14363
  const teardown = reactiveBinding2(() => {
@@ -11181,7 +14469,7 @@ function tagFactory(tag, ns) {
11181
14469
  throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
11182
14470
  }
11183
14471
  if (typeof document === "undefined") noDocument();
11184
- const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
14472
+ const el = createScopedElement(tag, ns);
11185
14473
  if (first === void 0) return el;
11186
14474
  if (typeof first === "string") {
11187
14475
  if (second !== void 0) {
@@ -11356,7 +14644,7 @@ var param = tagFactory("param");
11356
14644
  var picture = tagFactory("picture");
11357
14645
  var portal = tagFactory("portal");
11358
14646
  var source = tagFactory("source");
11359
- var svg = tagFactory("svg", SVG_NS5);
14647
+ var svg = tagFactory("svg", SVG_NS6);
11360
14648
  var math = tagFactory("math");
11361
14649
  var canvas = tagFactory("canvas");
11362
14650
  var noscript = tagFactory("noscript");
@@ -11391,32 +14679,32 @@ var details = tagFactory("details");
11391
14679
  var dialog2 = tagFactory("dialog");
11392
14680
  var menu = tagFactory("menu");
11393
14681
  var summary = tagFactory("summary");
11394
- var slot = tagFactory("slot");
14682
+ var slot3 = tagFactory("slot");
11395
14683
  var template = tagFactory("template");
11396
14684
  var base = tagFactory("base");
11397
14685
  var link = tagFactory("link");
11398
14686
  var meta = tagFactory("meta");
11399
14687
  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);
14688
+ var circle = tagFactory("circle", SVG_NS6);
14689
+ var ellipse = tagFactory("ellipse", SVG_NS6);
14690
+ var g = tagFactory("g", SVG_NS6);
14691
+ var line = tagFactory("line", SVG_NS6);
14692
+ var path = tagFactory("path", SVG_NS6);
14693
+ var polygon = tagFactory("polygon", SVG_NS6);
14694
+ var polyline = tagFactory("polyline", SVG_NS6);
14695
+ var rect = tagFactory("rect", SVG_NS6);
14696
+ var text = tagFactory("text", SVG_NS6);
14697
+ var tspan = tagFactory("tspan", SVG_NS6);
14698
+ var defs = tagFactory("defs", SVG_NS6);
14699
+ var clipPath = tagFactory("clipPath", SVG_NS6);
14700
+ var mask = tagFactory("mask", SVG_NS6);
14701
+ var pattern = tagFactory("pattern", SVG_NS6);
14702
+ var linearGradient = tagFactory("linearGradient", SVG_NS6);
14703
+ var radialGradient = tagFactory("radialGradient", SVG_NS6);
14704
+ var stop = tagFactory("stop", SVG_NS6);
14705
+ var use = tagFactory("use", SVG_NS6);
14706
+ var symbol = tagFactory("symbol", SVG_NS6);
14707
+ var marker = tagFactory("marker", SVG_NS6);
11420
14708
  var center = tagFactory("center");
11421
14709
  var font = tagFactory("font");
11422
14710
  var marquee = tagFactory("marquee");
@@ -11762,13 +15050,13 @@ function createISR(options) {
11762
15050
  if (inFlight) return inFlight;
11763
15051
  let resolve;
11764
15052
  let reject;
11765
- const current = new Promise((res, rej) => {
15053
+ const current2 = new Promise((res, rej) => {
11766
15054
  resolve = res;
11767
15055
  reject = rej;
11768
15056
  });
11769
- inFlight = current;
15057
+ inFlight = current2;
11770
15058
  const release = () => {
11771
- if (inFlight === current) inFlight = null;
15059
+ if (inFlight === current2) inFlight = null;
11772
15060
  };
11773
15061
  run().then(
11774
15062
  () => {
@@ -11780,7 +15068,7 @@ function createISR(options) {
11780
15068
  reject(err);
11781
15069
  }
11782
15070
  );
11783
- return current;
15071
+ return current2;
11784
15072
  };
11785
15073
  if (initialData === void 0) {
11786
15074
  revalidate().catch((err) => {
@@ -11951,7 +15239,7 @@ function createMiddlewareChain() {
11951
15239
 
11952
15240
  // src/plugins/plugin.ts
11953
15241
  var CANCELLED_BRAND = /* @__PURE__ */ Symbol.for("sibujs.plugins.installCancelled.v1");
11954
- var _a;
15242
+ var _a3;
11955
15243
  var PluginInstallCancelledError = class extends Error {
11956
15244
  constructor(pluginName) {
11957
15245
  super(`[Plugin] Installation of "${pluginName}" was cancelled before it was committed (registry reset).`);
@@ -11960,11 +15248,11 @@ var PluginInstallCancelledError = class extends Error {
11960
15248
  * of this module, so the error a caller receives may come from another copy's
11961
15249
  * constructor. `instanceof` is taught to recognise the brand instead.
11962
15250
  */
11963
- this[_a] = true;
15251
+ this[_a3] = true;
11964
15252
  this.name = "PluginInstallCancelledError";
11965
15253
  this.pluginName = pluginName;
11966
15254
  }
11967
- static [(_a = CANCELLED_BRAND, Symbol.hasInstance)](value) {
15255
+ static [(_a3 = CANCELLED_BRAND, Symbol.hasInstance)](value) {
11968
15256
  return isPluginInstallCancelledError(value);
11969
15257
  }
11970
15258
  };
@@ -11978,7 +15266,7 @@ function createPluginRegistry() {
11978
15266
  const installStack = /* @__PURE__ */ new Set();
11979
15267
  const pendingInstalls = /* @__PURE__ */ new Map();
11980
15268
  let generation = 0;
11981
- const registry = {
15269
+ const registry2 = {
11982
15270
  installedPlugins,
11983
15271
  hooks,
11984
15272
  provided,
@@ -12118,7 +15406,7 @@ function createPluginRegistry() {
12118
15406
  provided.clear();
12119
15407
  }
12120
15408
  };
12121
- return registry;
15409
+ return registry2;
12122
15410
  }
12123
15411
  var _defaults = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.plugins.defaultRegistry.v1"), () => ({
12124
15412
  registry: createPluginRegistry(),
@@ -12147,13 +15435,13 @@ function resetPlugins() {
12147
15435
  _defaults.registry.reset();
12148
15436
  _defaults.touched = false;
12149
15437
  }
12150
- function setDefaultPluginRegistry(registry) {
15438
+ function setDefaultPluginRegistry(registry2) {
12151
15439
  if (_defaults.touched && _defaults.registry.installedPlugins.size > 0) {
12152
15440
  console.warn(
12153
15441
  "[Plugin] Replacing default plugin registry while plugins are already installed on the singleton. This may indicate mixed singleton/registry usage."
12154
15442
  );
12155
15443
  }
12156
- _defaults.registry = registry;
15444
+ _defaults.registry = registry2;
12157
15445
  _defaults.touched = true;
12158
15446
  }
12159
15447
 
@@ -12300,6 +15588,7 @@ var MODULE_ENTRY_POINTS = {
12300
15588
  ui: "./ui.ts",
12301
15589
  widgets: "./widgets.ts",
12302
15590
  ssr: "./ssr.ts",
15591
+ "ssr/dom": "./ssr-dom.ts",
12303
15592
  devtools: "./devtools.ts",
12304
15593
  performance: "./performance.ts",
12305
15594
  ecosystem: "./ecosystem.ts",
@@ -12316,7 +15605,7 @@ var CDN_ENTRY_POINTS = {
12316
15605
  };
12317
15606
  var packageInfo = {
12318
15607
  name: "sibujs",
12319
- version: true ? "4.13.1" : "dev",
15608
+ version: true ? "4.14.1" : "dev",
12320
15609
  entryPoints: MODULE_ENTRY_POINTS,
12321
15610
  /**
12322
15611
  * Generate the package.json `exports` map. Module entries resolve to the
@@ -12461,7 +15750,7 @@ var env = {
12461
15750
  };
12462
15751
 
12463
15752
  // src/plugins/versioning.ts
12464
- var VERSION = true ? "4.13.1" : "dev";
15753
+ var VERSION = true ? "4.14.1" : "dev";
12465
15754
  var NUM = "(?:0|[1-9]\\d*)";
12466
15755
  var PRE_ID = `(?:${NUM}|\\d*[a-zA-Z-][0-9a-zA-Z-]*)`;
12467
15756
  var BUILD_ID = "[0-9a-zA-Z-]+";
@@ -15873,9 +19162,9 @@ function componentAdapter(config) {
15873
19162
  components[name] = (props = {}, children) => {
15874
19163
  const { variant, size, class: userClass, ...rest } = props;
15875
19164
  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);
19165
+ const current2 = theme.config();
19166
+ const overrides = current2.classOverrides ?? {};
19167
+ const pick = (key, fallback) => Object.hasOwn(overrides, key) ? overrides[key] : reprefix(fallback, current2.prefix);
15879
19168
  const classes = [pick(name, mapping.baseClass)];
15880
19169
  const variantClass = ownString(mapping.variants, variant);
15881
19170
  if (variant && variantClass) {
@@ -16129,6 +19418,7 @@ var materialAdapter = componentAdapter(materialConfig);
16129
19418
  announce,
16130
19419
  antdAdapter,
16131
19420
  aria,
19421
+ assembleDocument,
16132
19422
  assertType,
16133
19423
  battery,
16134
19424
  bindAttrs,
@@ -16325,6 +19615,7 @@ var materialAdapter = componentAdapter(materialConfig);
16325
19615
  renderToReadableStream,
16326
19616
  renderToStream,
16327
19617
  renderToString,
19618
+ renderToStringWith,
16328
19619
  renderToSuspenseStream,
16329
19620
  renderWithLoader,
16330
19621
  required,
@@ -16403,6 +19694,7 @@ var materialAdapter = componentAdapter(materialConfig);
16403
19694
  withRetry,
16404
19695
  withScopedStyle,
16405
19696
  withWrapper,
19697
+ withholdTransfer,
16406
19698
  worker,
16407
19699
  workerFn,
16408
19700
  yieldToMain,