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/lambda.cjs CHANGED
@@ -136,7 +136,11 @@ var parseCookies = (cookieString) => {
136
136
  if (index > -1) {
137
137
  const key = pair.slice(0, index).trim();
138
138
  const value = pair.slice(index + 1).trim();
139
- cookies[key] = decodeURIComponent(value);
139
+ try {
140
+ cookies[key] = decodeURIComponent(value);
141
+ } catch {
142
+ cookies[key] = value;
143
+ }
140
144
  }
141
145
  }
142
146
  return cookies;
@@ -177,16 +181,11 @@ var MIME = {
177
181
  pdf: "application/pdf"
178
182
  };
179
183
  async function tryServeFile(filePath) {
180
- try {
181
- await (0, import_promises.stat)(filePath);
182
- } catch {
183
- return null;
184
- }
185
184
  try {
186
185
  const data = await (0, import_promises.readFile)(filePath);
187
186
  const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
188
187
  const contentType = MIME[ext] ?? "application/octet-stream";
189
- return new Response(data.buffer, { headers: { "Content-Type": contentType } });
188
+ return new Response(data, { headers: { "Content-Type": contentType } });
190
189
  } catch {
191
190
  return null;
192
191
  }
@@ -228,6 +227,13 @@ function swapContextMap(map) {
228
227
  function captureMap() {
229
228
  return _g[MAP_KEY];
230
229
  }
230
+ var UNSUSPEND_KEY = "__hadarsUnsuspend";
231
+ function captureUnsuspend() {
232
+ return _g[UNSUSPEND_KEY];
233
+ }
234
+ function restoreUnsuspend(u) {
235
+ _g[UNSUSPEND_KEY] = u;
236
+ }
231
237
  function getContextValue(context) {
232
238
  const map = _g[MAP_KEY];
233
239
  if (map && map.has(context)) return map.get(context);
@@ -235,10 +241,14 @@ function getContextValue(context) {
235
241
  return "_defaultValue" in c ? c._defaultValue : c._currentValue;
236
242
  }
237
243
  function pushContextValue(context, value) {
238
- const map = _g[MAP_KEY];
244
+ let map = _g[MAP_KEY];
245
+ if (map === null) {
246
+ map = /* @__PURE__ */ new Map();
247
+ _g[MAP_KEY] = map;
248
+ }
239
249
  const c = context;
240
- const prev = map && map.has(context) ? map.get(context) : "_defaultValue" in c ? c._defaultValue : c._currentValue;
241
- map?.set(context, value);
250
+ const prev = map.has(context) ? map.get(context) : "_defaultValue" in c ? c._defaultValue : c._currentValue;
251
+ map.set(context, value);
242
252
  return prev;
243
253
  }
244
254
  function popContextValue(context, prev) {
@@ -246,48 +256,57 @@ function popContextValue(context, prev) {
246
256
  }
247
257
  var GLOBAL_KEY = "__slimReactRenderState";
248
258
  var EMPTY = { id: 1, overflow: "" };
259
+ var _stateCache = null;
249
260
  function s() {
250
- const g = globalThis;
251
- if (!g[GLOBAL_KEY]) {
252
- g[GLOBAL_KEY] = { currentTreeContext: { ...EMPTY }, localIdCounter: 0, idPrefix: "" };
261
+ if (_stateCache !== null) return _stateCache;
262
+ if (!_g[GLOBAL_KEY]) {
263
+ _g[GLOBAL_KEY] = { currentTreeContext: { ...EMPTY }, localIdCounter: 0, idPrefix: "" };
253
264
  }
254
- return g[GLOBAL_KEY];
265
+ _stateCache = _g[GLOBAL_KEY];
266
+ return _stateCache;
255
267
  }
268
+ var _treeIdStack = [];
269
+ var _treeOvStack = [];
270
+ var _treeDepth = 0;
256
271
  function resetRenderState(idPrefix = "") {
257
272
  const st = s();
258
- st.currentTreeContext = { ...EMPTY };
273
+ st.currentTreeContext.id = EMPTY.id;
274
+ st.currentTreeContext.overflow = EMPTY.overflow;
259
275
  st.localIdCounter = 0;
260
276
  st.idPrefix = idPrefix;
277
+ _treeDepth = 0;
261
278
  }
262
279
  function pushTreeContext(totalChildren, index) {
263
280
  const st = s();
264
- const saved = { ...st.currentTreeContext };
265
- const baseIdWithLeadingBit = st.currentTreeContext.id;
266
- const baseOverflow = st.currentTreeContext.overflow;
281
+ const ctx = st.currentTreeContext;
282
+ const depth = _treeDepth++;
283
+ _treeIdStack[depth] = ctx.id;
284
+ _treeOvStack[depth] = ctx.overflow;
285
+ const baseIdWithLeadingBit = ctx.id;
286
+ const baseOverflow = ctx.overflow;
267
287
  const baseLength = 31 - Math.clz32(baseIdWithLeadingBit);
268
288
  let baseId = baseIdWithLeadingBit & ~(1 << baseLength);
269
289
  const slot = index + 1;
270
290
  const newBits = 32 - Math.clz32(totalChildren);
271
291
  const length = newBits + baseLength;
272
292
  if (30 < length) {
273
- const numberOfOverflowBits = baseLength - baseLength % 5;
274
- const overflowStr = (baseId & (1 << numberOfOverflowBits) - 1).toString(32);
275
- baseId >>= numberOfOverflowBits;
276
- const newBaseLength = baseLength - numberOfOverflowBits;
277
- st.currentTreeContext = {
278
- id: 1 << newBits + newBaseLength | slot << newBaseLength | baseId,
279
- overflow: overflowStr + baseOverflow
280
- };
293
+ const overflowBits = baseLength - baseLength % 5;
294
+ const overflowStr = (baseId & (1 << overflowBits) - 1).toString(32);
295
+ baseId >>= overflowBits;
296
+ const newBaseLength = baseLength - overflowBits;
297
+ ctx.id = 1 << newBits + newBaseLength | slot << newBaseLength | baseId;
298
+ ctx.overflow = overflowStr + baseOverflow;
281
299
  } else {
282
- st.currentTreeContext = {
283
- id: 1 << length | slot << baseLength | baseId,
284
- overflow: baseOverflow
285
- };
300
+ ctx.id = 1 << length | slot << baseLength | baseId;
301
+ ctx.overflow = baseOverflow;
286
302
  }
287
- return saved;
303
+ return depth;
288
304
  }
289
- function popTreeContext(saved) {
290
- s().currentTreeContext = saved;
305
+ function popTreeContext(depth) {
306
+ const ctx = s().currentTreeContext;
307
+ ctx.id = _treeIdStack[depth];
308
+ ctx.overflow = _treeOvStack[depth];
309
+ _treeDepth = depth;
291
310
  }
292
311
  function pushComponentScope() {
293
312
  const st = s();
@@ -303,12 +322,16 @@ function componentCalledUseId() {
303
322
  }
304
323
  function snapshotContext() {
305
324
  const st = s();
306
- return { tree: { ...st.currentTreeContext }, localId: st.localIdCounter };
325
+ const ctx = st.currentTreeContext;
326
+ return { tree: { id: ctx.id, overflow: ctx.overflow }, localId: st.localIdCounter, treeDepth: _treeDepth };
307
327
  }
308
328
  function restoreContext(snap) {
309
329
  const st = s();
310
- st.currentTreeContext = { ...snap.tree };
330
+ const ctx = st.currentTreeContext;
331
+ ctx.id = snap.tree.id;
332
+ ctx.overflow = snap.tree.overflow;
311
333
  st.localIdCounter = snap.localId;
334
+ _treeDepth = snap.treeDepth;
312
335
  }
313
336
  function getTreeId() {
314
337
  const { id, overflow } = s().currentTreeContext;
@@ -439,19 +462,80 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
439
462
  "wbr"
440
463
  ]);
441
464
  var HTML_ESC = { "&": "&amp;", "<": "&lt;", ">": "&gt;", "'": "&#x27;" };
465
+ var HTML_ESC_RE = /[&<>']/;
442
466
  function escapeHtml(str) {
467
+ if (!HTML_ESC_RE.test(str)) return str;
443
468
  return str.replace(/[&<>']/g, (c) => HTML_ESC[c]);
444
469
  }
445
470
  var ATTR_ESC = { "&": "&amp;", '"': "&quot;", "<": "&lt;", ">": "&gt;" };
471
+ var ATTR_ESC_RE = /[&"<>]/;
446
472
  function escapeAttr(str) {
473
+ if (!ATTR_ESC_RE.test(str)) return str;
447
474
  return str.replace(/[&"<>]/g, (c) => ATTR_ESC[c]);
448
475
  }
476
+ var UNITLESS_CSS = /* @__PURE__ */ new Set([
477
+ "animationIterationCount",
478
+ "aspectRatio",
479
+ "borderImageOutset",
480
+ "borderImageSlice",
481
+ "borderImageWidth",
482
+ "boxFlex",
483
+ "boxFlexGroup",
484
+ "boxOrdinalGroup",
485
+ "columnCount",
486
+ "columns",
487
+ "flex",
488
+ "flexGrow",
489
+ "flexPositive",
490
+ "flexShrink",
491
+ "flexNegative",
492
+ "flexOrder",
493
+ "gridArea",
494
+ "gridRow",
495
+ "gridRowEnd",
496
+ "gridRowSpan",
497
+ "gridRowStart",
498
+ "gridColumn",
499
+ "gridColumnEnd",
500
+ "gridColumnSpan",
501
+ "gridColumnStart",
502
+ "fontWeight",
503
+ "lineClamp",
504
+ "lineHeight",
505
+ "opacity",
506
+ "order",
507
+ "orphans",
508
+ "scale",
509
+ "tabSize",
510
+ "widows",
511
+ "zIndex",
512
+ "zoom",
513
+ "fillOpacity",
514
+ "floodOpacity",
515
+ "stopOpacity",
516
+ "strokeDasharray",
517
+ "strokeDashoffset",
518
+ "strokeMiterlimit",
519
+ "strokeOpacity",
520
+ "strokeWidth"
521
+ ]);
522
+ var _cssKeyCache = /* @__PURE__ */ new Map();
449
523
  function styleObjectToString(style) {
450
524
  let result = "";
451
525
  for (const key in style) {
526
+ const value = style[key];
527
+ if (value == null || typeof value === "boolean") continue;
452
528
  if (result) result += ";";
453
- const cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
454
- result += cssKey + ":" + style[key];
529
+ let cssKey = _cssKeyCache.get(key);
530
+ if (cssKey === void 0) {
531
+ cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
532
+ _cssKeyCache.set(key, cssKey);
533
+ }
534
+ if (typeof value === "number" && value !== 0 && !UNITLESS_CSS.has(key)) {
535
+ result += cssKey + ":" + value + "px";
536
+ } else {
537
+ result += cssKey + ":" + value;
538
+ }
455
539
  }
456
540
  return result;
457
541
  }
@@ -586,14 +670,22 @@ var SVG_ATTR_MAP = {
586
670
  xChannelSelector: "xChannelSelector",
587
671
  yChannelSelector: "yChannelSelector"
588
672
  };
589
- function renderAttributes(props, isSvg) {
590
- let attrs = "";
673
+ var TEXTAREA_SKIP_PROPS = /* @__PURE__ */ new Set(["value", "defaultValue", "children"]);
674
+ var SELECT_SKIP_PROPS = /* @__PURE__ */ new Set(["value", "defaultValue"]);
675
+ var INTERNAL_PROPS = /* @__PURE__ */ new Set([
676
+ "children",
677
+ "key",
678
+ "ref",
679
+ "dangerouslySetInnerHTML",
680
+ "suppressHydrationWarning",
681
+ "suppressContentEditableWarning"
682
+ ]);
683
+ function writeAttributes(writer, props, isSvg, skip) {
591
684
  for (const key in props) {
685
+ if (skip !== void 0 && skip.has(key)) continue;
592
686
  const value = props[key];
593
- if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || key === "suppressHydrationWarning" || key === "suppressContentEditableWarning")
594
- continue;
595
- if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase())
596
- continue;
687
+ if (INTERNAL_PROPS.has(key)) continue;
688
+ if (key.length > 2 && key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && key.charCodeAt(2) >= 65 && key.charCodeAt(2) <= 90) continue;
597
689
  let attrName;
598
690
  if (isSvg && key in SVG_ATTR_MAP) {
599
691
  attrName = SVG_ATTR_MAP[key];
@@ -601,41 +693,46 @@ function renderAttributes(props, isSvg) {
601
693
  attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "tabIndex" ? "tabindex" : key === "defaultValue" ? "value" : key === "defaultChecked" ? "checked" : key;
602
694
  }
603
695
  if (value === false || value == null) {
604
- if (value === false && (attrName.startsWith("aria-") || attrName.startsWith("data-"))) {
605
- attrs += ` ${attrName}="false"`;
696
+ if (value === false && (attrName.charCodeAt(0) === 97 && attrName.startsWith("aria-") || attrName.charCodeAt(0) === 100 && attrName.startsWith("data-"))) {
697
+ writer.write(` ${attrName}="false"`);
606
698
  }
607
699
  continue;
608
700
  }
609
701
  if (value === true) {
610
- if (attrName.startsWith("aria-") || attrName.startsWith("data-")) {
611
- attrs += ` ${attrName}="true"`;
702
+ if (attrName.charCodeAt(0) === 97 && attrName.startsWith("aria-") || attrName.charCodeAt(0) === 100 && attrName.startsWith("data-")) {
703
+ writer.write(` ${attrName}="true"`);
612
704
  } else {
613
- attrs += ` ${attrName}=""`;
705
+ writer.write(` ${attrName}=""`);
614
706
  }
615
707
  continue;
616
708
  }
617
709
  if (key === "style" && typeof value === "object") {
618
710
  const styleStr = styleObjectToString(value);
619
- if (styleStr) attrs += ` style="${escapeAttr(styleStr)}"`;
711
+ if (styleStr) writer.write(` style="${escapeAttr(styleStr)}"`);
620
712
  continue;
621
713
  }
622
- attrs += ` ${attrName}="${escapeAttr(String(value))}"`;
714
+ writer.write(` ${attrName}="${escapeAttr(typeof value === "string" ? value : String(value))}"`);
623
715
  }
624
- return attrs;
625
716
  }
626
- var BufferWriter = class {
627
- chunks = [];
717
+ var BufferWriter = class _BufferWriter {
718
+ data = "";
628
719
  lastWasText = false;
629
720
  write(chunk) {
630
- this.chunks.push(chunk);
721
+ this.data += chunk;
631
722
  this.lastWasText = false;
632
723
  }
633
724
  text(s2) {
634
- this.chunks.push(s2);
725
+ this.data += s2;
635
726
  this.lastWasText = true;
636
727
  }
637
- flush(target) {
638
- for (const c of this.chunks) target.write(c);
728
+ /** Flush accumulated output into a parent writer and reset. */
729
+ flushTo(target) {
730
+ if (!this.data) return;
731
+ if (target instanceof _BufferWriter) {
732
+ target.data += this.data;
733
+ } else {
734
+ target.write(this.data);
735
+ }
639
736
  target.lastWasText = this.lastWasText;
640
737
  }
641
738
  };
@@ -652,15 +749,12 @@ function renderNode(node, writer, isSvg = false) {
652
749
  if (Array.isArray(node)) {
653
750
  return renderChildArray(node, writer, isSvg);
654
751
  }
655
- if (typeof node === "object" && node !== null && Symbol.iterator in node && !("$$typeof" in node)) {
656
- return renderChildArray(
657
- Array.from(node),
658
- writer,
659
- isSvg
660
- );
752
+ const obj = node;
753
+ if (Symbol.iterator in obj && !("$$typeof" in obj)) {
754
+ return renderChildArray(Array.from(obj), writer, isSvg);
661
755
  }
662
- if (typeof node === "object" && node !== null && "$$typeof" in node) {
663
- const elType = node["$$typeof"];
756
+ if ("$$typeof" in obj) {
757
+ const elType = obj["$$typeof"];
664
758
  if (elType !== SLIM_ELEMENT && elType !== REACT19_ELEMENT) return;
665
759
  const element = node;
666
760
  const { type, props } = element;
@@ -670,15 +764,15 @@ function renderNode(node, writer, isSvg = false) {
670
764
  if (type === SUSPENSE_TYPE) {
671
765
  return renderSuspense(props, writer, isSvg);
672
766
  }
767
+ if (typeof type === "string") {
768
+ return renderHostElement(type, props, writer, isSvg);
769
+ }
673
770
  if (typeof type === "function") {
674
771
  return renderComponent(type, props, writer, isSvg);
675
772
  }
676
773
  if (typeof type === "object" && type !== null) {
677
774
  return renderComponent(type, props, writer, isSvg);
678
775
  }
679
- if (typeof type === "string") {
680
- return renderHostElement(type, props, writer, isSvg);
681
- }
682
776
  }
683
777
  }
684
778
  function markSelectedOptionsMulti(children, selectedValues) {
@@ -704,26 +798,21 @@ function markSelectedOptionsMulti(children, selectedValues) {
704
798
  return children;
705
799
  }
706
800
  function renderHostElement(tag, props, writer, isSvg) {
707
- const enteringSvg = tag === "svg";
708
- const childSvg = isSvg || enteringSvg;
801
+ const childSvg = isSvg || tag === "svg";
709
802
  if (tag === "textarea") {
710
803
  const textContent = props.value ?? props.defaultValue ?? props.children ?? "";
711
- const filteredProps = {};
712
- for (const k of Object.keys(props)) {
713
- if (k !== "value" && k !== "defaultValue" && k !== "children") filteredProps[k] = props[k];
714
- }
715
- writer.write(`<textarea${renderAttributes(filteredProps, false)}>`);
804
+ writer.write("<textarea");
805
+ writeAttributes(writer, props, false, TEXTAREA_SKIP_PROPS);
806
+ writer.write(">");
716
807
  writer.text(escapeHtml(String(textContent)));
717
808
  writer.write("</textarea>");
718
809
  return;
719
810
  }
720
811
  if (tag === "select") {
721
812
  const selectedValue = props.value ?? props.defaultValue;
722
- const filteredProps = {};
723
- for (const k of Object.keys(props)) {
724
- if (k !== "value" && k !== "defaultValue") filteredProps[k] = props[k];
725
- }
726
- writer.write(`<select${renderAttributes(filteredProps, false)}>`);
813
+ writer.write("<select");
814
+ writeAttributes(writer, props, false, SELECT_SKIP_PROPS);
815
+ writer.write(">");
727
816
  const selectedSet = selectedValue == null ? null : Array.isArray(selectedValue) ? new Set(selectedValue.map(String)) : /* @__PURE__ */ new Set([String(selectedValue)]);
728
817
  const patchedChildren = selectedSet != null ? markSelectedOptionsMulti(props.children, selectedSet) : props.children;
729
818
  const inner2 = renderChildren(patchedChildren, writer, false);
@@ -735,7 +824,8 @@ function renderHostElement(tag, props, writer, isSvg) {
735
824
  writer.write("</select>");
736
825
  return;
737
826
  }
738
- writer.write(`<${tag}${renderAttributes(props, childSvg)}`);
827
+ writer.write(`<${tag}`);
828
+ writeAttributes(writer, props, childSvg);
739
829
  if (VOID_ELEMENTS.has(tag)) {
740
830
  writer.write("/>");
741
831
  return;
@@ -761,8 +851,25 @@ var REACT_PROVIDER = Symbol.for("react.provider");
761
851
  var REACT_CONTEXT = Symbol.for("react.context");
762
852
  var REACT_CONSUMER = Symbol.for("react.consumer");
763
853
  var REACT_LAZY = Symbol.for("react.lazy");
764
- function renderComponent(type, props, writer, isSvg) {
765
- const typeOf = type?.$$typeof;
854
+ var SUSPENSE_RETRY_LIMIT = Symbol("SuspenseRetryLimit");
855
+ var MAX_COMPONENT_SUSPENSE_RETRIES = 25;
856
+ function patchPromiseStatus(p) {
857
+ const w = p;
858
+ if (w.status) return;
859
+ w.status = "pending";
860
+ w.then(
861
+ (v) => {
862
+ w.status = "fulfilled";
863
+ w.value = v;
864
+ },
865
+ (r) => {
866
+ w.status = "rejected";
867
+ w.reason = r;
868
+ }
869
+ );
870
+ }
871
+ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
872
+ const typeOf = type.$$typeof;
766
873
  if (typeOf === REACT_MEMO) {
767
874
  return renderNode(
768
875
  { $$typeof: SLIM_ELEMENT, type: type.type, props, key: null },
@@ -774,7 +881,23 @@ function renderComponent(type, props, writer, isSvg) {
774
881
  return renderComponent(type.render, props, writer, isSvg);
775
882
  }
776
883
  if (typeOf === REACT_LAZY) {
777
- const resolved = type._init(type._payload);
884
+ let resolved;
885
+ try {
886
+ resolved = type._init(type._payload);
887
+ } catch (e) {
888
+ if (e && typeof e.then === "function") {
889
+ if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
890
+ patchPromiseStatus(e);
891
+ const m = captureMap();
892
+ const u = captureUnsuspend();
893
+ return e.then(() => {
894
+ swapContextMap(m);
895
+ restoreUnsuspend(u);
896
+ return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
897
+ });
898
+ }
899
+ throw e;
900
+ }
778
901
  const LazyComp = resolved?.default ?? resolved;
779
902
  return renderComponent(LazyComp, props, writer, isSvg);
780
903
  }
@@ -783,12 +906,12 @@ function renderComponent(type, props, writer, isSvg) {
783
906
  const value = ctx2 ? getContextValue(ctx2) : void 0;
784
907
  const result2 = typeof props.children === "function" ? props.children(value) : null;
785
908
  const savedScope2 = pushComponentScope();
786
- const finish2 = () => popComponentScope(savedScope2);
909
+ const finish = () => popComponentScope(savedScope2);
787
910
  const r2 = renderNode(result2, writer, isSvg);
788
911
  if (r2 && typeof r2.then === "function") {
789
- return r2.then(finish2);
912
+ return r2.then(finish);
790
913
  }
791
- finish2();
914
+ finish();
792
915
  return;
793
916
  }
794
917
  const isProvider = "_context" in type || typeOf === REACT_PROVIDER || typeOf === REACT_CONTEXT && "value" in props;
@@ -800,26 +923,29 @@ function renderComponent(type, props, writer, isSvg) {
800
923
  }
801
924
  const savedScope = pushComponentScope();
802
925
  if (isProvider && typeof type !== "function") {
803
- const finish2 = () => {
926
+ const finish = () => {
804
927
  popComponentScope(savedScope);
805
928
  popContextValue(ctx, prevCtxValue);
806
929
  };
807
930
  const r2 = renderChildren(props.children, writer, isSvg);
808
931
  if (r2 && typeof r2.then === "function") {
809
932
  const m = captureMap();
933
+ const u = captureUnsuspend();
810
934
  return r2.then(
811
935
  () => {
812
936
  swapContextMap(m);
813
- finish2();
937
+ restoreUnsuspend(u);
938
+ finish();
814
939
  },
815
940
  (e) => {
816
941
  swapContextMap(m);
817
- finish2();
942
+ restoreUnsuspend(u);
943
+ finish();
818
944
  throw e;
819
945
  }
820
946
  );
821
947
  }
822
- finish2();
948
+ finish();
823
949
  return;
824
950
  }
825
951
  let result;
@@ -839,6 +965,17 @@ function renderComponent(type, props, writer, isSvg) {
839
965
  restoreDispatcher(prevDispatcher);
840
966
  popComponentScope(savedScope);
841
967
  if (isProvider) popContextValue(ctx, prevCtxValue);
968
+ if (e && typeof e.then === "function") {
969
+ if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
970
+ patchPromiseStatus(e);
971
+ const m = captureMap();
972
+ const u = captureUnsuspend();
973
+ return e.then(() => {
974
+ swapContextMap(m);
975
+ restoreUnsuspend(u);
976
+ return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
977
+ });
978
+ }
842
979
  throw e;
843
980
  }
844
981
  restoreDispatcher(prevDispatcher);
@@ -846,97 +983,93 @@ function renderComponent(type, props, writer, isSvg) {
846
983
  if (!(result instanceof Promise) && componentCalledUseId()) {
847
984
  savedIdTree = pushTreeContext(1, 0);
848
985
  }
849
- const finish = () => {
850
- if (savedIdTree !== void 0) popTreeContext(savedIdTree);
851
- popComponentScope(savedScope);
852
- if (isProvider) popContextValue(ctx, prevCtxValue);
853
- };
854
986
  if (result instanceof Promise) {
855
987
  const m = captureMap();
988
+ const u = captureUnsuspend();
856
989
  return result.then((resolved) => {
857
990
  swapContextMap(m);
991
+ restoreUnsuspend(u);
858
992
  let asyncSavedIdTree;
859
993
  if (componentCalledUseId()) {
860
994
  asyncSavedIdTree = pushTreeContext(1, 0);
861
995
  }
862
- const asyncFinish = () => {
863
- if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
864
- popComponentScope(savedScope);
865
- if (isProvider) popContextValue(ctx, prevCtxValue);
866
- };
867
996
  const r2 = renderNode(resolved, writer, isSvg);
868
997
  if (r2 && typeof r2.then === "function") {
869
998
  const m2 = captureMap();
999
+ const u2 = captureUnsuspend();
870
1000
  return r2.then(
871
1001
  () => {
872
1002
  swapContextMap(m2);
873
- asyncFinish();
1003
+ restoreUnsuspend(u2);
1004
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
1005
+ popComponentScope(savedScope);
1006
+ if (isProvider) popContextValue(ctx, prevCtxValue);
874
1007
  },
875
1008
  (e) => {
876
1009
  swapContextMap(m2);
877
- asyncFinish();
1010
+ restoreUnsuspend(u2);
1011
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
1012
+ popComponentScope(savedScope);
1013
+ if (isProvider) popContextValue(ctx, prevCtxValue);
878
1014
  throw e;
879
1015
  }
880
1016
  );
881
1017
  }
882
- asyncFinish();
1018
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
1019
+ popComponentScope(savedScope);
1020
+ if (isProvider) popContextValue(ctx, prevCtxValue);
883
1021
  }, (e) => {
884
1022
  swapContextMap(m);
885
- finish();
1023
+ restoreUnsuspend(u);
1024
+ popComponentScope(savedScope);
1025
+ if (isProvider) popContextValue(ctx, prevCtxValue);
886
1026
  throw e;
887
1027
  });
888
1028
  }
889
1029
  const r = renderNode(result, writer, isSvg);
890
1030
  if (r && typeof r.then === "function") {
891
1031
  const m = captureMap();
1032
+ const u = captureUnsuspend();
892
1033
  return r.then(
893
1034
  () => {
894
1035
  swapContextMap(m);
895
- finish();
1036
+ restoreUnsuspend(u);
1037
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
1038
+ popComponentScope(savedScope);
1039
+ if (isProvider) popContextValue(ctx, prevCtxValue);
896
1040
  },
897
1041
  (e) => {
898
1042
  swapContextMap(m);
899
- finish();
1043
+ restoreUnsuspend(u);
1044
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
1045
+ popComponentScope(savedScope);
1046
+ if (isProvider) popContextValue(ctx, prevCtxValue);
900
1047
  throw e;
901
1048
  }
902
1049
  );
903
1050
  }
904
- finish();
905
- }
906
- function isTextLike(node) {
907
- return typeof node === "string" || typeof node === "number";
1051
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
1052
+ popComponentScope(savedScope);
1053
+ if (isProvider) popContextValue(ctx, prevCtxValue);
908
1054
  }
909
1055
  function renderChildArray(children, writer, isSvg) {
910
- const totalChildren = children.length;
911
- for (let i = 0; i < totalChildren; i++) {
912
- if (isTextLike(children[i]) && writer.lastWasText) {
913
- writer.write("<!-- -->");
914
- }
915
- const savedTree = pushTreeContext(totalChildren, i);
916
- const r = renderNode(children[i], writer, isSvg);
917
- if (r && typeof r.then === "function") {
918
- const m = captureMap();
919
- return r.then(() => {
920
- swapContextMap(m);
921
- popTreeContext(savedTree);
922
- return renderChildArrayFrom(children, i + 1, writer, isSvg);
923
- });
924
- }
925
- popTreeContext(savedTree);
926
- }
1056
+ return renderChildArrayFrom(children, 0, writer, isSvg);
927
1057
  }
928
1058
  function renderChildArrayFrom(children, startIndex, writer, isSvg) {
929
1059
  const totalChildren = children.length;
930
1060
  for (let i = startIndex; i < totalChildren; i++) {
931
- if (isTextLike(children[i]) && writer.lastWasText) {
1061
+ const child = children[i];
1062
+ if ((typeof child === "string" || typeof child === "number") && writer.lastWasText) {
932
1063
  writer.write("<!-- -->");
933
1064
  }
934
1065
  const savedTree = pushTreeContext(totalChildren, i);
935
- const r = renderNode(children[i], writer, isSvg);
1066
+ const r = renderNode(child, writer, isSvg);
936
1067
  if (r && typeof r.then === "function") {
937
1068
  const m = captureMap();
1069
+ const u = captureUnsuspend();
938
1070
  return r.then(() => {
939
1071
  swapContextMap(m);
1072
+ restoreUnsuspend(u);
940
1073
  popTreeContext(savedTree);
941
1074
  return renderChildArrayFrom(children, i + 1, writer, isSvg);
942
1075
  });
@@ -951,87 +1084,94 @@ function renderChildren(children, writer, isSvg = false) {
951
1084
  }
952
1085
  return renderNode(children, writer, isSvg);
953
1086
  }
954
- var MAX_SUSPENSE_RETRIES = 25;
955
1087
  async function renderSuspense(props, writer, isSvg = false) {
956
1088
  const { children, fallback } = props;
957
- let attempts = 0;
958
1089
  const snap = snapshotContext();
959
- while (attempts < MAX_SUSPENSE_RETRIES) {
960
- restoreContext(snap);
961
- let buffer = new BufferWriter();
962
- try {
963
- const r = renderNode(children, buffer, isSvg);
964
- if (r && typeof r.then === "function") {
965
- const m = captureMap();
966
- await r;
967
- swapContextMap(m);
1090
+ const savedMap = captureMap();
1091
+ const savedMapClone = savedMap ? new Map(savedMap) : null;
1092
+ const buffer = new BufferWriter();
1093
+ try {
1094
+ const r = renderNode(children, buffer, isSvg);
1095
+ if (r && typeof r.then === "function") {
1096
+ const m = captureMap();
1097
+ const u = captureUnsuspend();
1098
+ await r;
1099
+ swapContextMap(m);
1100
+ restoreUnsuspend(u);
1101
+ }
1102
+ writer.write("<!--$-->");
1103
+ buffer.flushTo(writer);
1104
+ writer.write("<!--/$-->");
1105
+ writer.flush?.();
1106
+ } catch (error) {
1107
+ if (error === SUSPENSE_RETRY_LIMIT) {
1108
+ restoreContext(snap);
1109
+ swapContextMap(savedMapClone);
1110
+ writer.write("<!--$?-->");
1111
+ if (fallback) {
1112
+ const r = renderNode(fallback, writer, isSvg);
1113
+ if (r && typeof r.then === "function") {
1114
+ const m = captureMap();
1115
+ const u = captureUnsuspend();
1116
+ await r;
1117
+ swapContextMap(m);
1118
+ restoreUnsuspend(u);
1119
+ }
968
1120
  }
969
- writer.write("<!--$-->");
970
- buffer.flush(writer);
971
1121
  writer.write("<!--/$-->");
972
- return;
973
- } catch (error) {
974
- if (error && typeof error.then === "function") {
975
- const m = captureMap();
976
- await error;
977
- swapContextMap(m);
978
- attempts++;
979
- } else {
980
- throw error;
981
- }
1122
+ } else {
1123
+ throw error;
982
1124
  }
983
1125
  }
984
- restoreContext(snap);
985
- writer.write("<!--$?-->");
986
- if (fallback) {
987
- const r = renderNode(fallback, writer, isSvg);
1126
+ }
1127
+ var _streamEncoder = new TextEncoder();
1128
+ var NULL_WRITER = {
1129
+ lastWasText: false,
1130
+ write(_c) {
1131
+ },
1132
+ text(_s) {
1133
+ }
1134
+ };
1135
+ async function renderPreflight(element, options) {
1136
+ const idPrefix = options?.identifierPrefix ?? "";
1137
+ const prev = swapContextMap(null);
1138
+ try {
1139
+ resetRenderState(idPrefix);
1140
+ NULL_WRITER.lastWasText = false;
1141
+ const r = renderNode(element, NULL_WRITER);
988
1142
  if (r && typeof r.then === "function") {
989
1143
  const m = captureMap();
990
1144
  await r;
991
1145
  swapContextMap(m);
992
1146
  }
1147
+ } finally {
1148
+ swapContextMap(prev);
993
1149
  }
994
- writer.write("<!--/$-->");
995
1150
  }
996
1151
  async function renderToString(element, options) {
997
1152
  const idPrefix = options?.identifierPrefix ?? "";
998
- const contextMap = /* @__PURE__ */ new Map();
999
- const prev = swapContextMap(contextMap);
1153
+ const prev = swapContextMap(null);
1154
+ let output = "";
1155
+ const writer = {
1156
+ lastWasText: false,
1157
+ write(c) {
1158
+ output += c;
1159
+ this.lastWasText = false;
1160
+ },
1161
+ text(s2) {
1162
+ output += s2;
1163
+ this.lastWasText = true;
1164
+ }
1165
+ };
1000
1166
  try {
1001
- for (let attempt = 0; attempt < MAX_SUSPENSE_RETRIES; attempt++) {
1002
- resetRenderState(idPrefix);
1003
- swapContextMap(contextMap);
1004
- const chunks = [];
1005
- const writer = {
1006
- lastWasText: false,
1007
- write(c) {
1008
- chunks.push(c);
1009
- this.lastWasText = false;
1010
- },
1011
- text(s2) {
1012
- chunks.push(s2);
1013
- this.lastWasText = true;
1014
- }
1015
- };
1016
- try {
1017
- const r = renderNode(element, writer);
1018
- if (r && typeof r.then === "function") {
1019
- const m = captureMap();
1020
- await r;
1021
- swapContextMap(m);
1022
- }
1023
- return chunks.join("");
1024
- } catch (error) {
1025
- if (error && typeof error.then === "function") {
1026
- const m = captureMap();
1027
- await error;
1028
- swapContextMap(m);
1029
- continue;
1030
- }
1031
- throw error;
1032
- }
1167
+ resetRenderState(idPrefix);
1168
+ const r = renderNode(element, writer);
1169
+ if (r && typeof r.then === "function") {
1170
+ const m = captureMap();
1171
+ await r;
1172
+ swapContextMap(m);
1033
1173
  }
1034
- throw new Error("[slim-react] renderToString exceeded maximum retries");
1174
+ return output;
1035
1175
  } finally {
1036
1176
  swapContextMap(prev);
1037
1177
  }
@@ -1052,8 +1192,8 @@ var ATTR = {
1052
1192
  fetchPriority: "fetchpriority",
1053
1193
  hrefLang: "hreflang"
1054
1194
  };
1055
- function renderHeadTag(tag, opts, selfClose = false) {
1056
- let attrs = "";
1195
+ function renderHeadTag(tag, id, opts, selfClose = false) {
1196
+ let attrs = ` id="${escAttr(id)}"`;
1057
1197
  let inner = "";
1058
1198
  for (const [k, v] of Object.entries(opts)) {
1059
1199
  if (k === "key" || k === "children") continue;
@@ -1067,18 +1207,18 @@ function renderHeadTag(tag, opts, selfClose = false) {
1067
1207
  }
1068
1208
  return selfClose ? `<${tag}${attrs}>` : `<${tag}${attrs}>${inner}</${tag}>`;
1069
1209
  }
1070
- var getHeadHtml = (seoData) => {
1210
+ function buildHeadHtml(seoData) {
1071
1211
  let html = `<title>${escText(seoData.title ?? "")}</title>`;
1072
- for (const opts of Object.values(seoData.meta))
1073
- html += renderHeadTag("meta", opts, true);
1074
- for (const opts of Object.values(seoData.link))
1075
- html += renderHeadTag("link", opts, true);
1076
- for (const opts of Object.values(seoData.style))
1077
- html += renderHeadTag("style", opts);
1078
- for (const opts of Object.values(seoData.script))
1079
- html += renderHeadTag("script", opts);
1212
+ for (const [id, opts] of Object.entries(seoData.meta))
1213
+ html += renderHeadTag("meta", id, opts, true);
1214
+ for (const [id, opts] of Object.entries(seoData.link))
1215
+ html += renderHeadTag("link", id, opts, true);
1216
+ for (const [id, opts] of Object.entries(seoData.style))
1217
+ html += renderHeadTag("style", id, opts);
1218
+ for (const [id, opts] of Object.entries(seoData.script))
1219
+ html += renderHeadTag("script", id, opts);
1080
1220
  return html;
1081
- };
1221
+ }
1082
1222
  var getReactResponse = async (req, opts) => {
1083
1223
  const App = opts.document.body;
1084
1224
  const { getInitProps, getFinalProps } = opts.document;
@@ -1092,28 +1232,40 @@ var getReactResponse = async (req, opts) => {
1092
1232
  };
1093
1233
  const unsuspend = { cache: /* @__PURE__ */ new Map() };
1094
1234
  globalThis.__hadarsUnsuspend = unsuspend;
1095
- let bodyHtml;
1235
+ const element = createElement(App, props);
1096
1236
  try {
1097
- bodyHtml = await renderToString(createElement(App, props));
1237
+ await renderPreflight(element);
1098
1238
  } finally {
1099
1239
  globalThis.__hadarsUnsuspend = null;
1100
1240
  }
1101
- const { context: _, ...restProps } = getFinalProps ? await getFinalProps(props) : props;
1102
- const serverData = {};
1103
- for (const [key, entry] of unsuspend.cache) {
1104
- if (entry.status === "fulfilled") serverData[key] = entry.value;
1105
- }
1106
- const clientProps = {
1107
- ...restProps,
1108
- location: req.location,
1109
- ...Object.keys(serverData).length > 0 ? { __serverData: serverData } : {}
1241
+ const status = context.head.status;
1242
+ const getAppBody = async () => {
1243
+ globalThis.__hadarsUnsuspend = unsuspend;
1244
+ try {
1245
+ return await renderToString(element);
1246
+ } finally {
1247
+ globalThis.__hadarsUnsuspend = null;
1248
+ }
1110
1249
  };
1111
- return {
1112
- bodyHtml,
1113
- clientProps,
1114
- status: context.head.status,
1115
- headHtml: getHeadHtml(context.head)
1250
+ const finalize = async () => {
1251
+ const { context: _, ...restProps } = getFinalProps ? await getFinalProps(props) : props;
1252
+ const serverData = {};
1253
+ let hasServerData = false;
1254
+ for (const [key, entry] of unsuspend.cache) {
1255
+ if (entry.status === "fulfilled") {
1256
+ serverData[key] = entry.value;
1257
+ hasServerData = true;
1258
+ }
1259
+ }
1260
+ return {
1261
+ clientProps: {
1262
+ ...restProps,
1263
+ location: req.location,
1264
+ ...hasServerData ? { __serverData: serverData } : {}
1265
+ }
1266
+ };
1116
1267
  };
1268
+ return { head: context.head, status, getAppBody, finalize };
1117
1269
  };
1118
1270
 
1119
1271
  // src/utils/ssrHandler.ts
@@ -1121,7 +1273,7 @@ var HEAD_MARKER = '<meta name="HADARS_HEAD">';
1121
1273
  var BODY_MARKER = '<meta name="HADARS_BODY">';
1122
1274
  var encoder = new TextEncoder();
1123
1275
  async function buildSsrHtml(bodyHtml, clientProps, headHtml, getPrecontentHtml) {
1124
- const [precontentHtml, postContent] = await getPrecontentHtml(headHtml);
1276
+ const [precontentHtml, postContent] = await Promise.resolve(getPrecontentHtml(headHtml));
1125
1277
  const scriptContent = JSON.stringify({ hadars: { props: clientProps } }).replace(/</g, "\\u003c");
1126
1278
  return precontentHtml + `<div id="app">${bodyHtml}</div><script id="hadars" type="application/json">${scriptContent}</script>` + postContent;
1127
1279
  }
@@ -1129,16 +1281,18 @@ var makePrecontentHtmlGetter = (htmlFilePromise) => {
1129
1281
  let preHead = null;
1130
1282
  let postHead = null;
1131
1283
  let postContent = null;
1132
- return async (headHtml) => {
1133
- if (preHead === null || postHead === null || postContent === null) {
1134
- const html = await htmlFilePromise;
1284
+ return (headHtml) => {
1285
+ if (preHead !== null) {
1286
+ return [preHead + headHtml + postHead, postContent];
1287
+ }
1288
+ return htmlFilePromise.then((html) => {
1135
1289
  const headEnd = html.indexOf(HEAD_MARKER);
1136
1290
  const contentStart = html.indexOf(BODY_MARKER);
1137
1291
  preHead = html.slice(0, headEnd);
1138
1292
  postHead = html.slice(headEnd + HEAD_MARKER.length, contentStart);
1139
1293
  postContent = html.slice(contentStart + BODY_MARKER.length);
1140
- }
1141
- return [preHead + headHtml + postHead, postContent];
1294
+ return [preHead + headHtml + postHead, postContent];
1295
+ });
1142
1296
  };
1143
1297
  };
1144
1298
  async function transformStream(data, stream) {
@@ -1323,7 +1477,7 @@ function createLambdaHandler(options, bundled) {
1323
1477
  getInitProps,
1324
1478
  getFinalProps
1325
1479
  } = await getSsrModule();
1326
- const { bodyHtml, clientProps, status, headHtml } = await getReactResponse(request, {
1480
+ const { head, status, getAppBody, finalize } = await getReactResponse(request, {
1327
1481
  document: {
1328
1482
  body: Component,
1329
1483
  lang: "en",
@@ -1332,12 +1486,16 @@ function createLambdaHandler(options, bundled) {
1332
1486
  }
1333
1487
  });
1334
1488
  if (request.headers.get("Accept") === "application/json") {
1335
- const serverData = clientProps.__serverData ?? {};
1489
+ const { clientProps: clientProps2 } = await finalize();
1490
+ const serverData = clientProps2.__serverData ?? {};
1336
1491
  return new Response(JSON.stringify({ serverData }), {
1337
1492
  status,
1338
1493
  headers: { "Content-Type": "application/json; charset=utf-8" }
1339
1494
  });
1340
1495
  }
1496
+ const bodyHtml = await getAppBody();
1497
+ const { clientProps } = await finalize();
1498
+ const headHtml = buildHeadHtml(head);
1341
1499
  const html = await buildSsrHtml(bodyHtml, clientProps, headHtml, getPrecontentHtml);
1342
1500
  return new Response(html, {
1343
1501
  status,