hadars 0.1.40 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -107,7 +107,11 @@ var parseCookies = (cookieString) => {
107
107
  if (index > -1) {
108
108
  const key = pair.slice(0, index).trim();
109
109
  const value = pair.slice(index + 1).trim();
110
- cookies[key] = decodeURIComponent(value);
110
+ try {
111
+ cookies[key] = decodeURIComponent(value);
112
+ } catch {
113
+ cookies[key] = value;
114
+ }
111
115
  }
112
116
  }
113
117
  return cookies;
@@ -171,6 +175,13 @@ function swapContextMap(map) {
171
175
  function captureMap() {
172
176
  return _g[MAP_KEY];
173
177
  }
178
+ var UNSUSPEND_KEY = "__hadarsUnsuspend";
179
+ function captureUnsuspend() {
180
+ return _g[UNSUSPEND_KEY];
181
+ }
182
+ function restoreUnsuspend(u) {
183
+ _g[UNSUSPEND_KEY] = u;
184
+ }
174
185
  function getContextValue(context) {
175
186
  const map = _g[MAP_KEY];
176
187
  if (map && map.has(context)) return map.get(context);
@@ -178,10 +189,14 @@ function getContextValue(context) {
178
189
  return "_defaultValue" in c ? c._defaultValue : c._currentValue;
179
190
  }
180
191
  function pushContextValue(context, value) {
181
- const map = _g[MAP_KEY];
192
+ let map = _g[MAP_KEY];
193
+ if (map === null) {
194
+ map = /* @__PURE__ */ new Map();
195
+ _g[MAP_KEY] = map;
196
+ }
182
197
  const c = context;
183
- const prev = map && map.has(context) ? map.get(context) : "_defaultValue" in c ? c._defaultValue : c._currentValue;
184
- map?.set(context, value);
198
+ const prev = map.has(context) ? map.get(context) : "_defaultValue" in c ? c._defaultValue : c._currentValue;
199
+ map.set(context, value);
185
200
  return prev;
186
201
  }
187
202
  function popContextValue(context, prev) {
@@ -189,48 +204,57 @@ function popContextValue(context, prev) {
189
204
  }
190
205
  var GLOBAL_KEY = "__slimReactRenderState";
191
206
  var EMPTY = { id: 1, overflow: "" };
207
+ var _stateCache = null;
192
208
  function s() {
193
- const g = globalThis;
194
- if (!g[GLOBAL_KEY]) {
195
- g[GLOBAL_KEY] = { currentTreeContext: { ...EMPTY }, localIdCounter: 0, idPrefix: "" };
209
+ if (_stateCache !== null) return _stateCache;
210
+ if (!_g[GLOBAL_KEY]) {
211
+ _g[GLOBAL_KEY] = { currentTreeContext: { ...EMPTY }, localIdCounter: 0, idPrefix: "" };
196
212
  }
197
- return g[GLOBAL_KEY];
213
+ _stateCache = _g[GLOBAL_KEY];
214
+ return _stateCache;
198
215
  }
216
+ var _treeIdStack = [];
217
+ var _treeOvStack = [];
218
+ var _treeDepth = 0;
199
219
  function resetRenderState(idPrefix = "") {
200
220
  const st = s();
201
- st.currentTreeContext = { ...EMPTY };
221
+ st.currentTreeContext.id = EMPTY.id;
222
+ st.currentTreeContext.overflow = EMPTY.overflow;
202
223
  st.localIdCounter = 0;
203
224
  st.idPrefix = idPrefix;
225
+ _treeDepth = 0;
204
226
  }
205
227
  function pushTreeContext(totalChildren, index) {
206
228
  const st = s();
207
- const saved = { ...st.currentTreeContext };
208
- const baseIdWithLeadingBit = st.currentTreeContext.id;
209
- const baseOverflow = st.currentTreeContext.overflow;
229
+ const ctx = st.currentTreeContext;
230
+ const depth = _treeDepth++;
231
+ _treeIdStack[depth] = ctx.id;
232
+ _treeOvStack[depth] = ctx.overflow;
233
+ const baseIdWithLeadingBit = ctx.id;
234
+ const baseOverflow = ctx.overflow;
210
235
  const baseLength = 31 - Math.clz32(baseIdWithLeadingBit);
211
236
  let baseId = baseIdWithLeadingBit & ~(1 << baseLength);
212
237
  const slot = index + 1;
213
238
  const newBits = 32 - Math.clz32(totalChildren);
214
239
  const length = newBits + baseLength;
215
240
  if (30 < length) {
216
- const numberOfOverflowBits = baseLength - baseLength % 5;
217
- const overflowStr = (baseId & (1 << numberOfOverflowBits) - 1).toString(32);
218
- baseId >>= numberOfOverflowBits;
219
- const newBaseLength = baseLength - numberOfOverflowBits;
220
- st.currentTreeContext = {
221
- id: 1 << newBits + newBaseLength | slot << newBaseLength | baseId,
222
- overflow: overflowStr + baseOverflow
223
- };
241
+ const overflowBits = baseLength - baseLength % 5;
242
+ const overflowStr = (baseId & (1 << overflowBits) - 1).toString(32);
243
+ baseId >>= overflowBits;
244
+ const newBaseLength = baseLength - overflowBits;
245
+ ctx.id = 1 << newBits + newBaseLength | slot << newBaseLength | baseId;
246
+ ctx.overflow = overflowStr + baseOverflow;
224
247
  } else {
225
- st.currentTreeContext = {
226
- id: 1 << length | slot << baseLength | baseId,
227
- overflow: baseOverflow
228
- };
248
+ ctx.id = 1 << length | slot << baseLength | baseId;
249
+ ctx.overflow = baseOverflow;
229
250
  }
230
- return saved;
251
+ return depth;
231
252
  }
232
- function popTreeContext(saved) {
233
- s().currentTreeContext = saved;
253
+ function popTreeContext(depth) {
254
+ const ctx = s().currentTreeContext;
255
+ ctx.id = _treeIdStack[depth];
256
+ ctx.overflow = _treeOvStack[depth];
257
+ _treeDepth = depth;
234
258
  }
235
259
  function pushComponentScope() {
236
260
  const st = s();
@@ -246,12 +270,16 @@ function componentCalledUseId() {
246
270
  }
247
271
  function snapshotContext() {
248
272
  const st = s();
249
- return { tree: { ...st.currentTreeContext }, localId: st.localIdCounter };
273
+ const ctx = st.currentTreeContext;
274
+ return { tree: { id: ctx.id, overflow: ctx.overflow }, localId: st.localIdCounter, treeDepth: _treeDepth };
250
275
  }
251
276
  function restoreContext(snap) {
252
277
  const st = s();
253
- st.currentTreeContext = { ...snap.tree };
278
+ const ctx = st.currentTreeContext;
279
+ ctx.id = snap.tree.id;
280
+ ctx.overflow = snap.tree.overflow;
254
281
  st.localIdCounter = snap.localId;
282
+ _treeDepth = snap.treeDepth;
255
283
  }
256
284
  function getTreeId() {
257
285
  const { id, overflow } = s().currentTreeContext;
@@ -382,19 +410,80 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
382
410
  "wbr"
383
411
  ]);
384
412
  var HTML_ESC = { "&": "&amp;", "<": "&lt;", ">": "&gt;", "'": "&#x27;" };
413
+ var HTML_ESC_RE = /[&<>']/;
385
414
  function escapeHtml(str) {
415
+ if (!HTML_ESC_RE.test(str)) return str;
386
416
  return str.replace(/[&<>']/g, (c) => HTML_ESC[c]);
387
417
  }
388
418
  var ATTR_ESC = { "&": "&amp;", '"': "&quot;", "<": "&lt;", ">": "&gt;" };
419
+ var ATTR_ESC_RE = /[&"<>]/;
389
420
  function escapeAttr(str) {
421
+ if (!ATTR_ESC_RE.test(str)) return str;
390
422
  return str.replace(/[&"<>]/g, (c) => ATTR_ESC[c]);
391
423
  }
424
+ var UNITLESS_CSS = /* @__PURE__ */ new Set([
425
+ "animationIterationCount",
426
+ "aspectRatio",
427
+ "borderImageOutset",
428
+ "borderImageSlice",
429
+ "borderImageWidth",
430
+ "boxFlex",
431
+ "boxFlexGroup",
432
+ "boxOrdinalGroup",
433
+ "columnCount",
434
+ "columns",
435
+ "flex",
436
+ "flexGrow",
437
+ "flexPositive",
438
+ "flexShrink",
439
+ "flexNegative",
440
+ "flexOrder",
441
+ "gridArea",
442
+ "gridRow",
443
+ "gridRowEnd",
444
+ "gridRowSpan",
445
+ "gridRowStart",
446
+ "gridColumn",
447
+ "gridColumnEnd",
448
+ "gridColumnSpan",
449
+ "gridColumnStart",
450
+ "fontWeight",
451
+ "lineClamp",
452
+ "lineHeight",
453
+ "opacity",
454
+ "order",
455
+ "orphans",
456
+ "scale",
457
+ "tabSize",
458
+ "widows",
459
+ "zIndex",
460
+ "zoom",
461
+ "fillOpacity",
462
+ "floodOpacity",
463
+ "stopOpacity",
464
+ "strokeDasharray",
465
+ "strokeDashoffset",
466
+ "strokeMiterlimit",
467
+ "strokeOpacity",
468
+ "strokeWidth"
469
+ ]);
470
+ var _cssKeyCache = /* @__PURE__ */ new Map();
392
471
  function styleObjectToString(style) {
393
472
  let result = "";
394
473
  for (const key in style) {
474
+ const value = style[key];
475
+ if (value == null || typeof value === "boolean") continue;
395
476
  if (result) result += ";";
396
- const cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
397
- result += cssKey + ":" + style[key];
477
+ let cssKey = _cssKeyCache.get(key);
478
+ if (cssKey === void 0) {
479
+ cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
480
+ _cssKeyCache.set(key, cssKey);
481
+ }
482
+ if (typeof value === "number" && value !== 0 && !UNITLESS_CSS.has(key)) {
483
+ result += cssKey + ":" + value + "px";
484
+ } else {
485
+ result += cssKey + ":" + value;
486
+ }
398
487
  }
399
488
  return result;
400
489
  }
@@ -529,14 +618,22 @@ var SVG_ATTR_MAP = {
529
618
  xChannelSelector: "xChannelSelector",
530
619
  yChannelSelector: "yChannelSelector"
531
620
  };
532
- function renderAttributes(props, isSvg) {
533
- let attrs = "";
621
+ var TEXTAREA_SKIP_PROPS = /* @__PURE__ */ new Set(["value", "defaultValue", "children"]);
622
+ var SELECT_SKIP_PROPS = /* @__PURE__ */ new Set(["value", "defaultValue"]);
623
+ var INTERNAL_PROPS = /* @__PURE__ */ new Set([
624
+ "children",
625
+ "key",
626
+ "ref",
627
+ "dangerouslySetInnerHTML",
628
+ "suppressHydrationWarning",
629
+ "suppressContentEditableWarning"
630
+ ]);
631
+ function writeAttributes(writer, props, isSvg, skip) {
534
632
  for (const key in props) {
633
+ if (skip !== void 0 && skip.has(key)) continue;
535
634
  const value = props[key];
536
- if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || key === "suppressHydrationWarning" || key === "suppressContentEditableWarning")
537
- continue;
538
- if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase())
539
- continue;
635
+ if (INTERNAL_PROPS.has(key)) continue;
636
+ if (key.length > 2 && key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && key.charCodeAt(2) >= 65 && key.charCodeAt(2) <= 90) continue;
540
637
  let attrName;
541
638
  if (isSvg && key in SVG_ATTR_MAP) {
542
639
  attrName = SVG_ATTR_MAP[key];
@@ -544,41 +641,46 @@ function renderAttributes(props, isSvg) {
544
641
  attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "tabIndex" ? "tabindex" : key === "defaultValue" ? "value" : key === "defaultChecked" ? "checked" : key;
545
642
  }
546
643
  if (value === false || value == null) {
547
- if (value === false && (attrName.startsWith("aria-") || attrName.startsWith("data-"))) {
548
- attrs += ` ${attrName}="false"`;
644
+ if (value === false && (attrName.charCodeAt(0) === 97 && attrName.startsWith("aria-") || attrName.charCodeAt(0) === 100 && attrName.startsWith("data-"))) {
645
+ writer.write(` ${attrName}="false"`);
549
646
  }
550
647
  continue;
551
648
  }
552
649
  if (value === true) {
553
- if (attrName.startsWith("aria-") || attrName.startsWith("data-")) {
554
- attrs += ` ${attrName}="true"`;
650
+ if (attrName.charCodeAt(0) === 97 && attrName.startsWith("aria-") || attrName.charCodeAt(0) === 100 && attrName.startsWith("data-")) {
651
+ writer.write(` ${attrName}="true"`);
555
652
  } else {
556
- attrs += ` ${attrName}=""`;
653
+ writer.write(` ${attrName}=""`);
557
654
  }
558
655
  continue;
559
656
  }
560
657
  if (key === "style" && typeof value === "object") {
561
658
  const styleStr = styleObjectToString(value);
562
- if (styleStr) attrs += ` style="${escapeAttr(styleStr)}"`;
659
+ if (styleStr) writer.write(` style="${escapeAttr(styleStr)}"`);
563
660
  continue;
564
661
  }
565
- attrs += ` ${attrName}="${escapeAttr(String(value))}"`;
662
+ writer.write(` ${attrName}="${escapeAttr(typeof value === "string" ? value : String(value))}"`);
566
663
  }
567
- return attrs;
568
664
  }
569
- var BufferWriter = class {
570
- chunks = [];
665
+ var BufferWriter = class _BufferWriter {
666
+ data = "";
571
667
  lastWasText = false;
572
668
  write(chunk) {
573
- this.chunks.push(chunk);
669
+ this.data += chunk;
574
670
  this.lastWasText = false;
575
671
  }
576
672
  text(s2) {
577
- this.chunks.push(s2);
673
+ this.data += s2;
578
674
  this.lastWasText = true;
579
675
  }
580
- flush(target) {
581
- for (const c of this.chunks) target.write(c);
676
+ /** Flush accumulated output into a parent writer and reset. */
677
+ flushTo(target) {
678
+ if (!this.data) return;
679
+ if (target instanceof _BufferWriter) {
680
+ target.data += this.data;
681
+ } else {
682
+ target.write(this.data);
683
+ }
582
684
  target.lastWasText = this.lastWasText;
583
685
  }
584
686
  };
@@ -595,15 +697,12 @@ function renderNode(node, writer, isSvg = false) {
595
697
  if (Array.isArray(node)) {
596
698
  return renderChildArray(node, writer, isSvg);
597
699
  }
598
- if (typeof node === "object" && node !== null && Symbol.iterator in node && !("$$typeof" in node)) {
599
- return renderChildArray(
600
- Array.from(node),
601
- writer,
602
- isSvg
603
- );
700
+ const obj = node;
701
+ if (Symbol.iterator in obj && !("$$typeof" in obj)) {
702
+ return renderChildArray(Array.from(obj), writer, isSvg);
604
703
  }
605
- if (typeof node === "object" && node !== null && "$$typeof" in node) {
606
- const elType = node["$$typeof"];
704
+ if ("$$typeof" in obj) {
705
+ const elType = obj["$$typeof"];
607
706
  if (elType !== SLIM_ELEMENT && elType !== REACT19_ELEMENT) return;
608
707
  const element = node;
609
708
  const { type, props } = element;
@@ -613,15 +712,15 @@ function renderNode(node, writer, isSvg = false) {
613
712
  if (type === SUSPENSE_TYPE) {
614
713
  return renderSuspense(props, writer, isSvg);
615
714
  }
715
+ if (typeof type === "string") {
716
+ return renderHostElement(type, props, writer, isSvg);
717
+ }
616
718
  if (typeof type === "function") {
617
719
  return renderComponent(type, props, writer, isSvg);
618
720
  }
619
721
  if (typeof type === "object" && type !== null) {
620
722
  return renderComponent(type, props, writer, isSvg);
621
723
  }
622
- if (typeof type === "string") {
623
- return renderHostElement(type, props, writer, isSvg);
624
- }
625
724
  }
626
725
  }
627
726
  function markSelectedOptionsMulti(children, selectedValues) {
@@ -647,26 +746,21 @@ function markSelectedOptionsMulti(children, selectedValues) {
647
746
  return children;
648
747
  }
649
748
  function renderHostElement(tag, props, writer, isSvg) {
650
- const enteringSvg = tag === "svg";
651
- const childSvg = isSvg || enteringSvg;
749
+ const childSvg = isSvg || tag === "svg";
652
750
  if (tag === "textarea") {
653
751
  const textContent = props.value ?? props.defaultValue ?? props.children ?? "";
654
- const filteredProps = {};
655
- for (const k of Object.keys(props)) {
656
- if (k !== "value" && k !== "defaultValue" && k !== "children") filteredProps[k] = props[k];
657
- }
658
- writer.write(`<textarea${renderAttributes(filteredProps, false)}>`);
752
+ writer.write("<textarea");
753
+ writeAttributes(writer, props, false, TEXTAREA_SKIP_PROPS);
754
+ writer.write(">");
659
755
  writer.text(escapeHtml(String(textContent)));
660
756
  writer.write("</textarea>");
661
757
  return;
662
758
  }
663
759
  if (tag === "select") {
664
760
  const selectedValue = props.value ?? props.defaultValue;
665
- const filteredProps = {};
666
- for (const k of Object.keys(props)) {
667
- if (k !== "value" && k !== "defaultValue") filteredProps[k] = props[k];
668
- }
669
- writer.write(`<select${renderAttributes(filteredProps, false)}>`);
761
+ writer.write("<select");
762
+ writeAttributes(writer, props, false, SELECT_SKIP_PROPS);
763
+ writer.write(">");
670
764
  const selectedSet = selectedValue == null ? null : Array.isArray(selectedValue) ? new Set(selectedValue.map(String)) : /* @__PURE__ */ new Set([String(selectedValue)]);
671
765
  const patchedChildren = selectedSet != null ? markSelectedOptionsMulti(props.children, selectedSet) : props.children;
672
766
  const inner2 = renderChildren(patchedChildren, writer, false);
@@ -678,7 +772,8 @@ function renderHostElement(tag, props, writer, isSvg) {
678
772
  writer.write("</select>");
679
773
  return;
680
774
  }
681
- writer.write(`<${tag}${renderAttributes(props, childSvg)}`);
775
+ writer.write(`<${tag}`);
776
+ writeAttributes(writer, props, childSvg);
682
777
  if (VOID_ELEMENTS.has(tag)) {
683
778
  writer.write("/>");
684
779
  return;
@@ -704,8 +799,25 @@ var REACT_PROVIDER = /* @__PURE__ */ Symbol.for("react.provider");
704
799
  var REACT_CONTEXT = /* @__PURE__ */ Symbol.for("react.context");
705
800
  var REACT_CONSUMER = /* @__PURE__ */ Symbol.for("react.consumer");
706
801
  var REACT_LAZY = /* @__PURE__ */ Symbol.for("react.lazy");
707
- function renderComponent(type, props, writer, isSvg) {
708
- const typeOf = type?.$$typeof;
802
+ var SUSPENSE_RETRY_LIMIT = /* @__PURE__ */ Symbol("SuspenseRetryLimit");
803
+ var MAX_COMPONENT_SUSPENSE_RETRIES = 25;
804
+ function patchPromiseStatus(p) {
805
+ const w = p;
806
+ if (w.status) return;
807
+ w.status = "pending";
808
+ w.then(
809
+ (v) => {
810
+ w.status = "fulfilled";
811
+ w.value = v;
812
+ },
813
+ (r) => {
814
+ w.status = "rejected";
815
+ w.reason = r;
816
+ }
817
+ );
818
+ }
819
+ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
820
+ const typeOf = type.$$typeof;
709
821
  if (typeOf === REACT_MEMO) {
710
822
  return renderNode(
711
823
  { $$typeof: SLIM_ELEMENT, type: type.type, props, key: null },
@@ -717,7 +829,23 @@ function renderComponent(type, props, writer, isSvg) {
717
829
  return renderComponent(type.render, props, writer, isSvg);
718
830
  }
719
831
  if (typeOf === REACT_LAZY) {
720
- const resolved = type._init(type._payload);
832
+ let resolved;
833
+ try {
834
+ resolved = type._init(type._payload);
835
+ } catch (e) {
836
+ if (e && typeof e.then === "function") {
837
+ if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
838
+ patchPromiseStatus(e);
839
+ const m = captureMap();
840
+ const u = captureUnsuspend();
841
+ return e.then(() => {
842
+ swapContextMap(m);
843
+ restoreUnsuspend(u);
844
+ return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
845
+ });
846
+ }
847
+ throw e;
848
+ }
721
849
  const LazyComp = resolved?.default ?? resolved;
722
850
  return renderComponent(LazyComp, props, writer, isSvg);
723
851
  }
@@ -726,12 +854,12 @@ function renderComponent(type, props, writer, isSvg) {
726
854
  const value = ctx2 ? getContextValue(ctx2) : void 0;
727
855
  const result2 = typeof props.children === "function" ? props.children(value) : null;
728
856
  const savedScope2 = pushComponentScope();
729
- const finish2 = () => popComponentScope(savedScope2);
857
+ const finish = () => popComponentScope(savedScope2);
730
858
  const r2 = renderNode(result2, writer, isSvg);
731
859
  if (r2 && typeof r2.then === "function") {
732
- return r2.then(finish2);
860
+ return r2.then(finish);
733
861
  }
734
- finish2();
862
+ finish();
735
863
  return;
736
864
  }
737
865
  const isProvider = "_context" in type || typeOf === REACT_PROVIDER || typeOf === REACT_CONTEXT && "value" in props;
@@ -743,26 +871,29 @@ function renderComponent(type, props, writer, isSvg) {
743
871
  }
744
872
  const savedScope = pushComponentScope();
745
873
  if (isProvider && typeof type !== "function") {
746
- const finish2 = () => {
874
+ const finish = () => {
747
875
  popComponentScope(savedScope);
748
876
  popContextValue(ctx, prevCtxValue);
749
877
  };
750
878
  const r2 = renderChildren(props.children, writer, isSvg);
751
879
  if (r2 && typeof r2.then === "function") {
752
880
  const m = captureMap();
881
+ const u = captureUnsuspend();
753
882
  return r2.then(
754
883
  () => {
755
884
  swapContextMap(m);
756
- finish2();
885
+ restoreUnsuspend(u);
886
+ finish();
757
887
  },
758
888
  (e) => {
759
889
  swapContextMap(m);
760
- finish2();
890
+ restoreUnsuspend(u);
891
+ finish();
761
892
  throw e;
762
893
  }
763
894
  );
764
895
  }
765
- finish2();
896
+ finish();
766
897
  return;
767
898
  }
768
899
  let result;
@@ -782,6 +913,17 @@ function renderComponent(type, props, writer, isSvg) {
782
913
  restoreDispatcher(prevDispatcher);
783
914
  popComponentScope(savedScope);
784
915
  if (isProvider) popContextValue(ctx, prevCtxValue);
916
+ if (e && typeof e.then === "function") {
917
+ if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
918
+ patchPromiseStatus(e);
919
+ const m = captureMap();
920
+ const u = captureUnsuspend();
921
+ return e.then(() => {
922
+ swapContextMap(m);
923
+ restoreUnsuspend(u);
924
+ return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
925
+ });
926
+ }
785
927
  throw e;
786
928
  }
787
929
  restoreDispatcher(prevDispatcher);
@@ -789,97 +931,93 @@ function renderComponent(type, props, writer, isSvg) {
789
931
  if (!(result instanceof Promise) && componentCalledUseId()) {
790
932
  savedIdTree = pushTreeContext(1, 0);
791
933
  }
792
- const finish = () => {
793
- if (savedIdTree !== void 0) popTreeContext(savedIdTree);
794
- popComponentScope(savedScope);
795
- if (isProvider) popContextValue(ctx, prevCtxValue);
796
- };
797
934
  if (result instanceof Promise) {
798
935
  const m = captureMap();
936
+ const u = captureUnsuspend();
799
937
  return result.then((resolved) => {
800
938
  swapContextMap(m);
939
+ restoreUnsuspend(u);
801
940
  let asyncSavedIdTree;
802
941
  if (componentCalledUseId()) {
803
942
  asyncSavedIdTree = pushTreeContext(1, 0);
804
943
  }
805
- const asyncFinish = () => {
806
- if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
807
- popComponentScope(savedScope);
808
- if (isProvider) popContextValue(ctx, prevCtxValue);
809
- };
810
944
  const r2 = renderNode(resolved, writer, isSvg);
811
945
  if (r2 && typeof r2.then === "function") {
812
946
  const m2 = captureMap();
947
+ const u2 = captureUnsuspend();
813
948
  return r2.then(
814
949
  () => {
815
950
  swapContextMap(m2);
816
- asyncFinish();
951
+ restoreUnsuspend(u2);
952
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
953
+ popComponentScope(savedScope);
954
+ if (isProvider) popContextValue(ctx, prevCtxValue);
817
955
  },
818
956
  (e) => {
819
957
  swapContextMap(m2);
820
- asyncFinish();
958
+ restoreUnsuspend(u2);
959
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
960
+ popComponentScope(savedScope);
961
+ if (isProvider) popContextValue(ctx, prevCtxValue);
821
962
  throw e;
822
963
  }
823
964
  );
824
965
  }
825
- asyncFinish();
966
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
967
+ popComponentScope(savedScope);
968
+ if (isProvider) popContextValue(ctx, prevCtxValue);
826
969
  }, (e) => {
827
970
  swapContextMap(m);
828
- finish();
971
+ restoreUnsuspend(u);
972
+ popComponentScope(savedScope);
973
+ if (isProvider) popContextValue(ctx, prevCtxValue);
829
974
  throw e;
830
975
  });
831
976
  }
832
977
  const r = renderNode(result, writer, isSvg);
833
978
  if (r && typeof r.then === "function") {
834
979
  const m = captureMap();
980
+ const u = captureUnsuspend();
835
981
  return r.then(
836
982
  () => {
837
983
  swapContextMap(m);
838
- finish();
984
+ restoreUnsuspend(u);
985
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
986
+ popComponentScope(savedScope);
987
+ if (isProvider) popContextValue(ctx, prevCtxValue);
839
988
  },
840
989
  (e) => {
841
990
  swapContextMap(m);
842
- finish();
991
+ restoreUnsuspend(u);
992
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
993
+ popComponentScope(savedScope);
994
+ if (isProvider) popContextValue(ctx, prevCtxValue);
843
995
  throw e;
844
996
  }
845
997
  );
846
998
  }
847
- finish();
848
- }
849
- function isTextLike(node) {
850
- return typeof node === "string" || typeof node === "number";
999
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
1000
+ popComponentScope(savedScope);
1001
+ if (isProvider) popContextValue(ctx, prevCtxValue);
851
1002
  }
852
1003
  function renderChildArray(children, writer, isSvg) {
853
- const totalChildren = children.length;
854
- for (let i = 0; i < totalChildren; i++) {
855
- if (isTextLike(children[i]) && writer.lastWasText) {
856
- writer.write("<!-- -->");
857
- }
858
- const savedTree = pushTreeContext(totalChildren, i);
859
- const r = renderNode(children[i], writer, isSvg);
860
- if (r && typeof r.then === "function") {
861
- const m = captureMap();
862
- return r.then(() => {
863
- swapContextMap(m);
864
- popTreeContext(savedTree);
865
- return renderChildArrayFrom(children, i + 1, writer, isSvg);
866
- });
867
- }
868
- popTreeContext(savedTree);
869
- }
1004
+ return renderChildArrayFrom(children, 0, writer, isSvg);
870
1005
  }
871
1006
  function renderChildArrayFrom(children, startIndex, writer, isSvg) {
872
1007
  const totalChildren = children.length;
873
1008
  for (let i = startIndex; i < totalChildren; i++) {
874
- if (isTextLike(children[i]) && writer.lastWasText) {
1009
+ const child = children[i];
1010
+ if ((typeof child === "string" || typeof child === "number") && writer.lastWasText) {
875
1011
  writer.write("<!-- -->");
876
1012
  }
877
1013
  const savedTree = pushTreeContext(totalChildren, i);
878
- const r = renderNode(children[i], writer, isSvg);
1014
+ const r = renderNode(child, writer, isSvg);
879
1015
  if (r && typeof r.then === "function") {
880
1016
  const m = captureMap();
1017
+ const u = captureUnsuspend();
881
1018
  return r.then(() => {
882
1019
  swapContextMap(m);
1020
+ restoreUnsuspend(u);
883
1021
  popTreeContext(savedTree);
884
1022
  return renderChildArrayFrom(children, i + 1, writer, isSvg);
885
1023
  });
@@ -894,87 +1032,94 @@ function renderChildren(children, writer, isSvg = false) {
894
1032
  }
895
1033
  return renderNode(children, writer, isSvg);
896
1034
  }
897
- var MAX_SUSPENSE_RETRIES = 25;
898
1035
  async function renderSuspense(props, writer, isSvg = false) {
899
1036
  const { children, fallback } = props;
900
- let attempts = 0;
901
1037
  const snap = snapshotContext();
902
- while (attempts < MAX_SUSPENSE_RETRIES) {
903
- restoreContext(snap);
904
- let buffer = new BufferWriter();
905
- try {
906
- const r = renderNode(children, buffer, isSvg);
907
- if (r && typeof r.then === "function") {
908
- const m = captureMap();
909
- await r;
910
- swapContextMap(m);
1038
+ const savedMap = captureMap();
1039
+ const savedMapClone = savedMap ? new Map(savedMap) : null;
1040
+ const buffer = new BufferWriter();
1041
+ try {
1042
+ const r = renderNode(children, buffer, isSvg);
1043
+ if (r && typeof r.then === "function") {
1044
+ const m = captureMap();
1045
+ const u = captureUnsuspend();
1046
+ await r;
1047
+ swapContextMap(m);
1048
+ restoreUnsuspend(u);
1049
+ }
1050
+ writer.write("<!--$-->");
1051
+ buffer.flushTo(writer);
1052
+ writer.write("<!--/$-->");
1053
+ writer.flush?.();
1054
+ } catch (error) {
1055
+ if (error === SUSPENSE_RETRY_LIMIT) {
1056
+ restoreContext(snap);
1057
+ swapContextMap(savedMapClone);
1058
+ writer.write("<!--$?-->");
1059
+ if (fallback) {
1060
+ const r = renderNode(fallback, writer, isSvg);
1061
+ if (r && typeof r.then === "function") {
1062
+ const m = captureMap();
1063
+ const u = captureUnsuspend();
1064
+ await r;
1065
+ swapContextMap(m);
1066
+ restoreUnsuspend(u);
1067
+ }
911
1068
  }
912
- writer.write("<!--$-->");
913
- buffer.flush(writer);
914
1069
  writer.write("<!--/$-->");
915
- return;
916
- } catch (error) {
917
- if (error && typeof error.then === "function") {
918
- const m = captureMap();
919
- await error;
920
- swapContextMap(m);
921
- attempts++;
922
- } else {
923
- throw error;
924
- }
1070
+ } else {
1071
+ throw error;
925
1072
  }
926
1073
  }
927
- restoreContext(snap);
928
- writer.write("<!--$?-->");
929
- if (fallback) {
930
- const r = renderNode(fallback, writer, isSvg);
1074
+ }
1075
+ var _streamEncoder = new TextEncoder();
1076
+ var NULL_WRITER = {
1077
+ lastWasText: false,
1078
+ write(_c) {
1079
+ },
1080
+ text(_s) {
1081
+ }
1082
+ };
1083
+ async function renderPreflight(element, options) {
1084
+ const idPrefix = options?.identifierPrefix ?? "";
1085
+ const prev = swapContextMap(null);
1086
+ try {
1087
+ resetRenderState(idPrefix);
1088
+ NULL_WRITER.lastWasText = false;
1089
+ const r = renderNode(element, NULL_WRITER);
931
1090
  if (r && typeof r.then === "function") {
932
1091
  const m = captureMap();
933
1092
  await r;
934
1093
  swapContextMap(m);
935
1094
  }
1095
+ } finally {
1096
+ swapContextMap(prev);
936
1097
  }
937
- writer.write("<!--/$-->");
938
1098
  }
939
1099
  async function renderToString(element, options) {
940
1100
  const idPrefix = options?.identifierPrefix ?? "";
941
- const contextMap = /* @__PURE__ */ new Map();
942
- const prev = swapContextMap(contextMap);
1101
+ const prev = swapContextMap(null);
1102
+ let output = "";
1103
+ const writer = {
1104
+ lastWasText: false,
1105
+ write(c) {
1106
+ output += c;
1107
+ this.lastWasText = false;
1108
+ },
1109
+ text(s2) {
1110
+ output += s2;
1111
+ this.lastWasText = true;
1112
+ }
1113
+ };
943
1114
  try {
944
- for (let attempt = 0; attempt < MAX_SUSPENSE_RETRIES; attempt++) {
945
- resetRenderState(idPrefix);
946
- swapContextMap(contextMap);
947
- const chunks = [];
948
- const writer = {
949
- lastWasText: false,
950
- write(c) {
951
- chunks.push(c);
952
- this.lastWasText = false;
953
- },
954
- text(s2) {
955
- chunks.push(s2);
956
- this.lastWasText = true;
957
- }
958
- };
959
- try {
960
- const r = renderNode(element, writer);
961
- if (r && typeof r.then === "function") {
962
- const m = captureMap();
963
- await r;
964
- swapContextMap(m);
965
- }
966
- return chunks.join("");
967
- } catch (error) {
968
- if (error && typeof error.then === "function") {
969
- const m = captureMap();
970
- await error;
971
- swapContextMap(m);
972
- continue;
973
- }
974
- throw error;
975
- }
1115
+ resetRenderState(idPrefix);
1116
+ const r = renderNode(element, writer);
1117
+ if (r && typeof r.then === "function") {
1118
+ const m = captureMap();
1119
+ await r;
1120
+ swapContextMap(m);
976
1121
  }
977
- throw new Error("[slim-react] renderToString exceeded maximum retries");
1122
+ return output;
978
1123
  } finally {
979
1124
  swapContextMap(prev);
980
1125
  }
@@ -995,8 +1140,8 @@ var ATTR = {
995
1140
  fetchPriority: "fetchpriority",
996
1141
  hrefLang: "hreflang"
997
1142
  };
998
- function renderHeadTag(tag, opts, selfClose = false) {
999
- let attrs = "";
1143
+ function renderHeadTag(tag, id, opts, selfClose = false) {
1144
+ let attrs = ` id="${escAttr(id)}"`;
1000
1145
  let inner = "";
1001
1146
  for (const [k, v] of Object.entries(opts)) {
1002
1147
  if (k === "key" || k === "children") continue;
@@ -1010,18 +1155,18 @@ function renderHeadTag(tag, opts, selfClose = false) {
1010
1155
  }
1011
1156
  return selfClose ? `<${tag}${attrs}>` : `<${tag}${attrs}>${inner}</${tag}>`;
1012
1157
  }
1013
- var getHeadHtml = (seoData) => {
1158
+ function buildHeadHtml(seoData) {
1014
1159
  let html = `<title>${escText(seoData.title ?? "")}</title>`;
1015
- for (const opts of Object.values(seoData.meta))
1016
- html += renderHeadTag("meta", opts, true);
1017
- for (const opts of Object.values(seoData.link))
1018
- html += renderHeadTag("link", opts, true);
1019
- for (const opts of Object.values(seoData.style))
1020
- html += renderHeadTag("style", opts);
1021
- for (const opts of Object.values(seoData.script))
1022
- html += renderHeadTag("script", opts);
1160
+ for (const [id, opts] of Object.entries(seoData.meta))
1161
+ html += renderHeadTag("meta", id, opts, true);
1162
+ for (const [id, opts] of Object.entries(seoData.link))
1163
+ html += renderHeadTag("link", id, opts, true);
1164
+ for (const [id, opts] of Object.entries(seoData.style))
1165
+ html += renderHeadTag("style", id, opts);
1166
+ for (const [id, opts] of Object.entries(seoData.script))
1167
+ html += renderHeadTag("script", id, opts);
1023
1168
  return html;
1024
- };
1169
+ }
1025
1170
  var getReactResponse = async (req, opts) => {
1026
1171
  const App = opts.document.body;
1027
1172
  const { getInitProps, getFinalProps } = opts.document;
@@ -1035,28 +1180,40 @@ var getReactResponse = async (req, opts) => {
1035
1180
  };
1036
1181
  const unsuspend = { cache: /* @__PURE__ */ new Map() };
1037
1182
  globalThis.__hadarsUnsuspend = unsuspend;
1038
- let bodyHtml;
1183
+ const element = createElement(App, props);
1039
1184
  try {
1040
- bodyHtml = await renderToString(createElement(App, props));
1185
+ await renderPreflight(element);
1041
1186
  } finally {
1042
1187
  globalThis.__hadarsUnsuspend = null;
1043
1188
  }
1044
- const { context: _, ...restProps } = getFinalProps ? await getFinalProps(props) : props;
1045
- const serverData = {};
1046
- for (const [key, entry] of unsuspend.cache) {
1047
- if (entry.status === "fulfilled") serverData[key] = entry.value;
1048
- }
1049
- const clientProps = {
1050
- ...restProps,
1051
- location: req.location,
1052
- ...Object.keys(serverData).length > 0 ? { __serverData: serverData } : {}
1189
+ const status = context.head.status;
1190
+ const getAppBody = async () => {
1191
+ globalThis.__hadarsUnsuspend = unsuspend;
1192
+ try {
1193
+ return await renderToString(element);
1194
+ } finally {
1195
+ globalThis.__hadarsUnsuspend = null;
1196
+ }
1053
1197
  };
1054
- return {
1055
- bodyHtml,
1056
- clientProps,
1057
- status: context.head.status,
1058
- headHtml: getHeadHtml(context.head)
1198
+ const finalize = async () => {
1199
+ const { context: _, ...restProps } = getFinalProps ? await getFinalProps(props) : props;
1200
+ const serverData = {};
1201
+ let hasServerData = false;
1202
+ for (const [key, entry] of unsuspend.cache) {
1203
+ if (entry.status === "fulfilled") {
1204
+ serverData[key] = entry.value;
1205
+ hasServerData = true;
1206
+ }
1207
+ }
1208
+ return {
1209
+ clientProps: {
1210
+ ...restProps,
1211
+ location: req.location,
1212
+ ...hasServerData ? { __serverData: serverData } : {}
1213
+ }
1214
+ };
1059
1215
  };
1216
+ return { head: context.head, status, getAppBody, finalize };
1060
1217
  };
1061
1218
 
1062
1219
  // src/utils/rspack.ts
@@ -1454,27 +1611,6 @@ function nodeReadableToWebStream(readable) {
1454
1611
  });
1455
1612
  }
1456
1613
  var noopCtx = { upgrade: () => false };
1457
- var COMPRESSIBLE_RE = /\b(?:text\/|application\/(?:json|javascript|xml)|image\/svg\+xml)/;
1458
- function withCompression(handler) {
1459
- return async (req, ctx) => {
1460
- const res = await handler(req, ctx);
1461
- if (!res?.body) return res;
1462
- if (!COMPRESSIBLE_RE.test(res.headers.get("Content-Type") ?? "")) return res;
1463
- if (res.headers.has("Content-Encoding")) return res;
1464
- const accept = req.headers.get("Accept-Encoding") ?? "";
1465
- const encoding = accept.includes("br") ? "br" : accept.includes("gzip") ? "gzip" : null;
1466
- if (!encoding) return res;
1467
- try {
1468
- const compressed = res.body.pipeThrough(new globalThis.CompressionStream(encoding));
1469
- const headers = new Headers(res.headers);
1470
- headers.set("Content-Encoding", encoding);
1471
- headers.delete("Content-Length");
1472
- return new Response(compressed, { status: res.status, statusText: res.statusText, headers });
1473
- } catch {
1474
- return res;
1475
- }
1476
- };
1477
- }
1478
1614
  function withRequestLogging(handler) {
1479
1615
  return async (req, ctx) => {
1480
1616
  const start = performance.now();
@@ -1486,9 +1622,27 @@ function withRequestLogging(handler) {
1486
1622
  return res;
1487
1623
  };
1488
1624
  }
1625
+ var COMPRESSIBLE_RE = /^text\/|\/json|\/javascript|\/xml|\/wasm/;
1626
+ function withCompression(handler) {
1627
+ return async (req, ctx) => {
1628
+ const res = await handler(req, ctx);
1629
+ if (!res || !res.body) return res;
1630
+ const accept = req.headers.get("Accept-Encoding") ?? "";
1631
+ if (!accept.includes("gzip")) return res;
1632
+ if (res.headers.has("content-encoding")) return res;
1633
+ const ct = res.headers.get("content-type") ?? "";
1634
+ if (!COMPRESSIBLE_RE.test(ct)) return res;
1635
+ const compressed = res.body.pipeThrough(
1636
+ new globalThis.CompressionStream("gzip")
1637
+ );
1638
+ const headers = new Headers(res.headers);
1639
+ headers.set("content-encoding", "gzip");
1640
+ headers.delete("content-length");
1641
+ return new Response(compressed, { status: res.status, headers });
1642
+ };
1643
+ }
1489
1644
  async function serve(port, fetchHandler, websocket) {
1490
- fetchHandler = withCompression(fetchHandler);
1491
- fetchHandler = withRequestLogging(fetchHandler);
1645
+ fetchHandler = withCompression(withRequestLogging(fetchHandler));
1492
1646
  if (isBun) {
1493
1647
  globalThis.Bun.serve({
1494
1648
  port,
@@ -1561,7 +1715,7 @@ async function serve(port, fetchHandler, websocket) {
1561
1715
  }
1562
1716
 
1563
1717
  // src/utils/staticFile.ts
1564
- import { readFile, stat } from "node:fs/promises";
1718
+ import { readFile } from "node:fs/promises";
1565
1719
  var MIME = {
1566
1720
  html: "text/html; charset=utf-8",
1567
1721
  htm: "text/html; charset=utf-8",
@@ -1587,16 +1741,11 @@ var MIME = {
1587
1741
  pdf: "application/pdf"
1588
1742
  };
1589
1743
  async function tryServeFile(filePath) {
1590
- try {
1591
- await stat(filePath);
1592
- } catch {
1593
- return null;
1594
- }
1595
1744
  try {
1596
1745
  const data = await readFile(filePath);
1597
1746
  const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
1598
1747
  const contentType = MIME[ext] ?? "application/octet-stream";
1599
- return new Response(data.buffer, { headers: { "Content-Type": contentType } });
1748
+ return new Response(data, { headers: { "Content-Type": contentType } });
1600
1749
  } catch {
1601
1750
  return null;
1602
1751
  }
@@ -1617,16 +1766,25 @@ import cluster from "node:cluster";
1617
1766
  var HEAD_MARKER = '<meta name="HADARS_HEAD">';
1618
1767
  var BODY_MARKER = '<meta name="HADARS_BODY">';
1619
1768
  var encoder = new TextEncoder();
1620
- async function buildSsrResponse(bodyHtml, clientProps, headHtml, status, getPrecontentHtml) {
1769
+ function buildSsrResponse(head, status, getAppBody, finalize, getPrecontentHtml) {
1770
+ const headHtml = buildHeadHtml(head);
1771
+ const precontentResult = getPrecontentHtml(headHtml);
1621
1772
  const responseStream = new ReadableStream({
1622
1773
  async start(controller) {
1623
- const [precontentHtml, postContent] = await getPrecontentHtml(headHtml);
1624
- controller.enqueue(encoder.encode(precontentHtml));
1625
- const scriptContent = JSON.stringify({ hadars: { props: clientProps } }).replace(/</g, "\\u003c");
1626
- controller.enqueue(encoder.encode(
1627
- `<div id="app">${bodyHtml}</div><script id="hadars" type="application/json">${scriptContent}</script>` + postContent
1628
- ));
1629
- controller.close();
1774
+ try {
1775
+ const [precontentHtml, postContent] = precontentResult instanceof Promise ? await precontentResult : precontentResult;
1776
+ controller.enqueue(encoder.encode(precontentHtml));
1777
+ const bodyHtml = await getAppBody();
1778
+ controller.enqueue(encoder.encode(`<div id="app">${bodyHtml}</div>`));
1779
+ const { clientProps } = await finalize();
1780
+ const scriptContent = JSON.stringify({ hadars: { props: clientProps } }).replace(/</g, "\\u003c");
1781
+ controller.enqueue(encoder.encode(
1782
+ `<script id="hadars" type="application/json">${scriptContent}</script>` + postContent
1783
+ ));
1784
+ controller.close();
1785
+ } catch (err) {
1786
+ controller.error(err);
1787
+ }
1630
1788
  }
1631
1789
  });
1632
1790
  return new Response(responseStream, {
@@ -1638,16 +1796,18 @@ var makePrecontentHtmlGetter = (htmlFilePromise) => {
1638
1796
  let preHead = null;
1639
1797
  let postHead = null;
1640
1798
  let postContent = null;
1641
- return async (headHtml) => {
1642
- if (preHead === null || postHead === null || postContent === null) {
1643
- const html = await htmlFilePromise;
1799
+ return (headHtml) => {
1800
+ if (preHead !== null) {
1801
+ return [preHead + headHtml + postHead, postContent];
1802
+ }
1803
+ return htmlFilePromise.then((html) => {
1644
1804
  const headEnd = html.indexOf(HEAD_MARKER);
1645
1805
  const contentStart = html.indexOf(BODY_MARKER);
1646
1806
  preHead = html.slice(0, headEnd);
1647
1807
  postHead = html.slice(headEnd + HEAD_MARKER.length, contentStart);
1648
1808
  postContent = html.slice(contentStart + BODY_MARKER.length);
1649
- }
1650
- return [preHead + headHtml + postHead, postContent];
1809
+ return [preHead + headHtml + postHead, postContent];
1810
+ });
1651
1811
  };
1652
1812
  };
1653
1813
  async function transformStream(data, stream) {
@@ -2117,7 +2277,7 @@ var dev = async (options) => {
2117
2277
  getInitProps,
2118
2278
  getFinalProps
2119
2279
  } = await import(importPath);
2120
- const { bodyHtml, clientProps, status, headHtml } = await getReactResponse(request, {
2280
+ const { head, status, getAppBody, finalize } = await getReactResponse(request, {
2121
2281
  document: {
2122
2282
  body: Component,
2123
2283
  lang: "en",
@@ -2126,13 +2286,14 @@ var dev = async (options) => {
2126
2286
  }
2127
2287
  });
2128
2288
  if (request.headers.get("Accept") === "application/json") {
2289
+ const { clientProps } = await finalize();
2129
2290
  const serverData = clientProps.__serverData ?? {};
2130
2291
  return new Response(JSON.stringify({ serverData }), {
2131
2292
  status,
2132
2293
  headers: { "Content-Type": "application/json; charset=utf-8" }
2133
2294
  });
2134
2295
  }
2135
- return buildSsrResponse(bodyHtml, clientProps, headHtml, status, getPrecontentHtml);
2296
+ return buildSsrResponse(head, status, getAppBody, finalize, getPrecontentHtml);
2136
2297
  } catch (err) {
2137
2298
  console.error("[hadars] SSR render error:", err);
2138
2299
  const msg = (err?.stack ?? err?.message ?? String(err)).replace(/</g, "&lt;");
@@ -2274,7 +2435,7 @@ var run = async (options) => {
2274
2435
  status: wStatus
2275
2436
  });
2276
2437
  }
2277
- const { bodyHtml, clientProps, status, headHtml } = await getReactResponse(request, {
2438
+ const { head, status, getAppBody, finalize } = await getReactResponse(request, {
2278
2439
  document: {
2279
2440
  body: Component,
2280
2441
  lang: "en",
@@ -2283,13 +2444,14 @@ var run = async (options) => {
2283
2444
  }
2284
2445
  });
2285
2446
  if (request.headers.get("Accept") === "application/json") {
2447
+ const { clientProps } = await finalize();
2286
2448
  const serverData = clientProps.__serverData ?? {};
2287
2449
  return new Response(JSON.stringify({ serverData }), {
2288
2450
  status,
2289
2451
  headers: { "Content-Type": "application/json; charset=utf-8" }
2290
2452
  });
2291
2453
  }
2292
- return buildSsrResponse(bodyHtml, clientProps, headHtml, status, getPrecontentHtml);
2454
+ return buildSsrResponse(head, status, getAppBody, finalize, getPrecontentHtml);
2293
2455
  } catch (err) {
2294
2456
  console.error("[hadars] SSR render error:", err);
2295
2457
  return new Response("Internal Server Error", { status: 500 });