hadars 0.1.40 → 0.2.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 (42) hide show
  1. package/README.md +85 -70
  2. package/cli-lib.ts +89 -12
  3. package/dist/chunk-HWOLYLPF.js +332 -0
  4. package/dist/{chunk-2ENP7IAW.js → chunk-LY5MTHFV.js} +360 -203
  5. package/dist/cli.js +506 -274
  6. package/dist/cloudflare.cjs +1394 -0
  7. package/dist/cloudflare.d.cts +64 -0
  8. package/dist/cloudflare.d.ts +64 -0
  9. package/dist/cloudflare.js +68 -0
  10. package/dist/{hadars-Bh-V5YXg.d.cts → hadars-DEBSYAQl.d.cts} +1 -36
  11. package/dist/{hadars-Bh-V5YXg.d.ts → hadars-DEBSYAQl.d.ts} +1 -36
  12. package/dist/index.cjs +129 -156
  13. package/dist/index.d.cts +5 -11
  14. package/dist/index.d.ts +5 -11
  15. package/dist/index.js +129 -155
  16. package/dist/lambda.cjs +391 -229
  17. package/dist/lambda.d.cts +1 -2
  18. package/dist/lambda.d.ts +1 -2
  19. package/dist/lambda.js +18 -307
  20. package/dist/slim-react/index.cjs +361 -203
  21. package/dist/slim-react/index.d.cts +24 -8
  22. package/dist/slim-react/index.d.ts +24 -8
  23. package/dist/slim-react/index.js +3 -1
  24. package/dist/ssr-render-worker.js +352 -221
  25. package/dist/utils/Head.tsx +132 -187
  26. package/package.json +7 -2
  27. package/src/build.ts +7 -6
  28. package/src/cloudflare.ts +139 -0
  29. package/src/index.tsx +0 -3
  30. package/src/lambda.ts +6 -2
  31. package/src/slim-react/context.ts +2 -1
  32. package/src/slim-react/index.ts +21 -18
  33. package/src/slim-react/render.ts +379 -240
  34. package/src/slim-react/renderContext.ts +105 -45
  35. package/src/ssr-render-worker.ts +14 -44
  36. package/src/types/hadars.ts +0 -1
  37. package/src/utils/Head.tsx +132 -187
  38. package/src/utils/cookies.ts +1 -1
  39. package/src/utils/response.tsx +68 -33
  40. package/src/utils/serve.ts +29 -27
  41. package/src/utils/ssrHandler.ts +54 -25
  42. package/src/utils/staticFile.ts +2 -7
@@ -49,6 +49,7 @@ __export(slim_react_exports, {
49
49
  jsxs: () => jsx,
50
50
  lazy: () => lazy,
51
51
  memo: () => memo,
52
+ renderPreflight: () => renderPreflight,
52
53
  renderToReadableStream: () => renderToStream,
53
54
  renderToStream: () => renderToStream,
54
55
  renderToString: () => renderToString,
@@ -121,6 +122,13 @@ function swapContextMap(map) {
121
122
  function captureMap() {
122
123
  return _g[MAP_KEY];
123
124
  }
125
+ var UNSUSPEND_KEY = "__hadarsUnsuspend";
126
+ function captureUnsuspend() {
127
+ return _g[UNSUSPEND_KEY];
128
+ }
129
+ function restoreUnsuspend(u) {
130
+ _g[UNSUSPEND_KEY] = u;
131
+ }
124
132
  function getContextValue(context) {
125
133
  const map = _g[MAP_KEY];
126
134
  if (map && map.has(context)) return map.get(context);
@@ -128,10 +136,14 @@ function getContextValue(context) {
128
136
  return "_defaultValue" in c ? c._defaultValue : c._currentValue;
129
137
  }
130
138
  function pushContextValue(context, value) {
131
- const map = _g[MAP_KEY];
139
+ let map = _g[MAP_KEY];
140
+ if (map === null) {
141
+ map = /* @__PURE__ */ new Map();
142
+ _g[MAP_KEY] = map;
143
+ }
132
144
  const c = context;
133
- const prev = map && map.has(context) ? map.get(context) : "_defaultValue" in c ? c._defaultValue : c._currentValue;
134
- map?.set(context, value);
145
+ const prev = map.has(context) ? map.get(context) : "_defaultValue" in c ? c._defaultValue : c._currentValue;
146
+ map.set(context, value);
135
147
  return prev;
136
148
  }
137
149
  function popContextValue(context, prev) {
@@ -139,48 +151,57 @@ function popContextValue(context, prev) {
139
151
  }
140
152
  var GLOBAL_KEY = "__slimReactRenderState";
141
153
  var EMPTY = { id: 1, overflow: "" };
154
+ var _stateCache = null;
142
155
  function s() {
143
- const g = globalThis;
144
- if (!g[GLOBAL_KEY]) {
145
- g[GLOBAL_KEY] = { currentTreeContext: { ...EMPTY }, localIdCounter: 0, idPrefix: "" };
156
+ if (_stateCache !== null) return _stateCache;
157
+ if (!_g[GLOBAL_KEY]) {
158
+ _g[GLOBAL_KEY] = { currentTreeContext: { ...EMPTY }, localIdCounter: 0, idPrefix: "" };
146
159
  }
147
- return g[GLOBAL_KEY];
160
+ _stateCache = _g[GLOBAL_KEY];
161
+ return _stateCache;
148
162
  }
163
+ var _treeIdStack = [];
164
+ var _treeOvStack = [];
165
+ var _treeDepth = 0;
149
166
  function resetRenderState(idPrefix = "") {
150
167
  const st = s();
151
- st.currentTreeContext = { ...EMPTY };
168
+ st.currentTreeContext.id = EMPTY.id;
169
+ st.currentTreeContext.overflow = EMPTY.overflow;
152
170
  st.localIdCounter = 0;
153
171
  st.idPrefix = idPrefix;
172
+ _treeDepth = 0;
154
173
  }
155
174
  function pushTreeContext(totalChildren, index) {
156
175
  const st = s();
157
- const saved = { ...st.currentTreeContext };
158
- const baseIdWithLeadingBit = st.currentTreeContext.id;
159
- const baseOverflow = st.currentTreeContext.overflow;
176
+ const ctx = st.currentTreeContext;
177
+ const depth = _treeDepth++;
178
+ _treeIdStack[depth] = ctx.id;
179
+ _treeOvStack[depth] = ctx.overflow;
180
+ const baseIdWithLeadingBit = ctx.id;
181
+ const baseOverflow = ctx.overflow;
160
182
  const baseLength = 31 - Math.clz32(baseIdWithLeadingBit);
161
183
  let baseId = baseIdWithLeadingBit & ~(1 << baseLength);
162
184
  const slot = index + 1;
163
185
  const newBits = 32 - Math.clz32(totalChildren);
164
186
  const length = newBits + baseLength;
165
187
  if (30 < length) {
166
- const numberOfOverflowBits = baseLength - baseLength % 5;
167
- const overflowStr = (baseId & (1 << numberOfOverflowBits) - 1).toString(32);
168
- baseId >>= numberOfOverflowBits;
169
- const newBaseLength = baseLength - numberOfOverflowBits;
170
- st.currentTreeContext = {
171
- id: 1 << newBits + newBaseLength | slot << newBaseLength | baseId,
172
- overflow: overflowStr + baseOverflow
173
- };
188
+ const overflowBits = baseLength - baseLength % 5;
189
+ const overflowStr = (baseId & (1 << overflowBits) - 1).toString(32);
190
+ baseId >>= overflowBits;
191
+ const newBaseLength = baseLength - overflowBits;
192
+ ctx.id = 1 << newBits + newBaseLength | slot << newBaseLength | baseId;
193
+ ctx.overflow = overflowStr + baseOverflow;
174
194
  } else {
175
- st.currentTreeContext = {
176
- id: 1 << length | slot << baseLength | baseId,
177
- overflow: baseOverflow
178
- };
195
+ ctx.id = 1 << length | slot << baseLength | baseId;
196
+ ctx.overflow = baseOverflow;
179
197
  }
180
- return saved;
198
+ return depth;
181
199
  }
182
- function popTreeContext(saved) {
183
- s().currentTreeContext = saved;
200
+ function popTreeContext(depth) {
201
+ const ctx = s().currentTreeContext;
202
+ ctx.id = _treeIdStack[depth];
203
+ ctx.overflow = _treeOvStack[depth];
204
+ _treeDepth = depth;
184
205
  }
185
206
  function pushComponentScope() {
186
207
  const st = s();
@@ -196,12 +217,16 @@ function componentCalledUseId() {
196
217
  }
197
218
  function snapshotContext() {
198
219
  const st = s();
199
- return { tree: { ...st.currentTreeContext }, localId: st.localIdCounter };
220
+ const ctx = st.currentTreeContext;
221
+ return { tree: { id: ctx.id, overflow: ctx.overflow }, localId: st.localIdCounter, treeDepth: _treeDepth };
200
222
  }
201
223
  function restoreContext(snap) {
202
224
  const st = s();
203
- st.currentTreeContext = { ...snap.tree };
225
+ const ctx = st.currentTreeContext;
226
+ ctx.id = snap.tree.id;
227
+ ctx.overflow = snap.tree.overflow;
204
228
  st.localIdCounter = snap.localId;
229
+ _treeDepth = snap.treeDepth;
205
230
  }
206
231
  function getTreeId() {
207
232
  const { id, overflow } = s().currentTreeContext;
@@ -300,7 +325,7 @@ function createContext(defaultValue) {
300
325
  context.Provider = Provider;
301
326
  context.Consumer = ({ children }) => {
302
327
  return children(
303
- context._currentValue
328
+ getContextValue(context)
304
329
  );
305
330
  };
306
331
  return context;
@@ -364,19 +389,80 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
364
389
  "wbr"
365
390
  ]);
366
391
  var HTML_ESC = { "&": "&amp;", "<": "&lt;", ">": "&gt;", "'": "&#x27;" };
392
+ var HTML_ESC_RE = /[&<>']/;
367
393
  function escapeHtml(str) {
394
+ if (!HTML_ESC_RE.test(str)) return str;
368
395
  return str.replace(/[&<>']/g, (c) => HTML_ESC[c]);
369
396
  }
370
397
  var ATTR_ESC = { "&": "&amp;", '"': "&quot;", "<": "&lt;", ">": "&gt;" };
398
+ var ATTR_ESC_RE = /[&"<>]/;
371
399
  function escapeAttr(str) {
400
+ if (!ATTR_ESC_RE.test(str)) return str;
372
401
  return str.replace(/[&"<>]/g, (c) => ATTR_ESC[c]);
373
402
  }
403
+ var UNITLESS_CSS = /* @__PURE__ */ new Set([
404
+ "animationIterationCount",
405
+ "aspectRatio",
406
+ "borderImageOutset",
407
+ "borderImageSlice",
408
+ "borderImageWidth",
409
+ "boxFlex",
410
+ "boxFlexGroup",
411
+ "boxOrdinalGroup",
412
+ "columnCount",
413
+ "columns",
414
+ "flex",
415
+ "flexGrow",
416
+ "flexPositive",
417
+ "flexShrink",
418
+ "flexNegative",
419
+ "flexOrder",
420
+ "gridArea",
421
+ "gridRow",
422
+ "gridRowEnd",
423
+ "gridRowSpan",
424
+ "gridRowStart",
425
+ "gridColumn",
426
+ "gridColumnEnd",
427
+ "gridColumnSpan",
428
+ "gridColumnStart",
429
+ "fontWeight",
430
+ "lineClamp",
431
+ "lineHeight",
432
+ "opacity",
433
+ "order",
434
+ "orphans",
435
+ "scale",
436
+ "tabSize",
437
+ "widows",
438
+ "zIndex",
439
+ "zoom",
440
+ "fillOpacity",
441
+ "floodOpacity",
442
+ "stopOpacity",
443
+ "strokeDasharray",
444
+ "strokeDashoffset",
445
+ "strokeMiterlimit",
446
+ "strokeOpacity",
447
+ "strokeWidth"
448
+ ]);
449
+ var _cssKeyCache = /* @__PURE__ */ new Map();
374
450
  function styleObjectToString(style) {
375
451
  let result = "";
376
452
  for (const key in style) {
453
+ const value = style[key];
454
+ if (value == null || typeof value === "boolean") continue;
377
455
  if (result) result += ";";
378
- const cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
379
- result += cssKey + ":" + style[key];
456
+ let cssKey = _cssKeyCache.get(key);
457
+ if (cssKey === void 0) {
458
+ cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
459
+ _cssKeyCache.set(key, cssKey);
460
+ }
461
+ if (typeof value === "number" && value !== 0 && !UNITLESS_CSS.has(key)) {
462
+ result += cssKey + ":" + value + "px";
463
+ } else {
464
+ result += cssKey + ":" + value;
465
+ }
380
466
  }
381
467
  return result;
382
468
  }
@@ -511,14 +597,22 @@ var SVG_ATTR_MAP = {
511
597
  xChannelSelector: "xChannelSelector",
512
598
  yChannelSelector: "yChannelSelector"
513
599
  };
514
- function renderAttributes(props, isSvg) {
515
- let attrs = "";
600
+ var TEXTAREA_SKIP_PROPS = /* @__PURE__ */ new Set(["value", "defaultValue", "children"]);
601
+ var SELECT_SKIP_PROPS = /* @__PURE__ */ new Set(["value", "defaultValue"]);
602
+ var INTERNAL_PROPS = /* @__PURE__ */ new Set([
603
+ "children",
604
+ "key",
605
+ "ref",
606
+ "dangerouslySetInnerHTML",
607
+ "suppressHydrationWarning",
608
+ "suppressContentEditableWarning"
609
+ ]);
610
+ function writeAttributes(writer, props, isSvg, skip) {
516
611
  for (const key in props) {
612
+ if (skip !== void 0 && skip.has(key)) continue;
517
613
  const value = props[key];
518
- if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || key === "suppressHydrationWarning" || key === "suppressContentEditableWarning")
519
- continue;
520
- if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase())
521
- continue;
614
+ if (INTERNAL_PROPS.has(key)) continue;
615
+ if (key.length > 2 && key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && key.charCodeAt(2) >= 65 && key.charCodeAt(2) <= 90) continue;
522
616
  let attrName;
523
617
  if (isSvg && key in SVG_ATTR_MAP) {
524
618
  attrName = SVG_ATTR_MAP[key];
@@ -526,41 +620,46 @@ function renderAttributes(props, isSvg) {
526
620
  attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "tabIndex" ? "tabindex" : key === "defaultValue" ? "value" : key === "defaultChecked" ? "checked" : key;
527
621
  }
528
622
  if (value === false || value == null) {
529
- if (value === false && (attrName.startsWith("aria-") || attrName.startsWith("data-"))) {
530
- attrs += ` ${attrName}="false"`;
623
+ if (value === false && (attrName.charCodeAt(0) === 97 && attrName.startsWith("aria-") || attrName.charCodeAt(0) === 100 && attrName.startsWith("data-"))) {
624
+ writer.write(` ${attrName}="false"`);
531
625
  }
532
626
  continue;
533
627
  }
534
628
  if (value === true) {
535
- if (attrName.startsWith("aria-") || attrName.startsWith("data-")) {
536
- attrs += ` ${attrName}="true"`;
629
+ if (attrName.charCodeAt(0) === 97 && attrName.startsWith("aria-") || attrName.charCodeAt(0) === 100 && attrName.startsWith("data-")) {
630
+ writer.write(` ${attrName}="true"`);
537
631
  } else {
538
- attrs += ` ${attrName}=""`;
632
+ writer.write(` ${attrName}=""`);
539
633
  }
540
634
  continue;
541
635
  }
542
636
  if (key === "style" && typeof value === "object") {
543
637
  const styleStr = styleObjectToString(value);
544
- if (styleStr) attrs += ` style="${escapeAttr(styleStr)}"`;
638
+ if (styleStr) writer.write(` style="${escapeAttr(styleStr)}"`);
545
639
  continue;
546
640
  }
547
- attrs += ` ${attrName}="${escapeAttr(String(value))}"`;
641
+ writer.write(` ${attrName}="${escapeAttr(typeof value === "string" ? value : String(value))}"`);
548
642
  }
549
- return attrs;
550
643
  }
551
- var BufferWriter = class {
552
- chunks = [];
644
+ var BufferWriter = class _BufferWriter {
645
+ data = "";
553
646
  lastWasText = false;
554
647
  write(chunk) {
555
- this.chunks.push(chunk);
648
+ this.data += chunk;
556
649
  this.lastWasText = false;
557
650
  }
558
651
  text(s2) {
559
- this.chunks.push(s2);
652
+ this.data += s2;
560
653
  this.lastWasText = true;
561
654
  }
562
- flush(target) {
563
- for (const c of this.chunks) target.write(c);
655
+ /** Flush accumulated output into a parent writer and reset. */
656
+ flushTo(target) {
657
+ if (!this.data) return;
658
+ if (target instanceof _BufferWriter) {
659
+ target.data += this.data;
660
+ } else {
661
+ target.write(this.data);
662
+ }
564
663
  target.lastWasText = this.lastWasText;
565
664
  }
566
665
  };
@@ -577,15 +676,12 @@ function renderNode(node, writer, isSvg = false) {
577
676
  if (Array.isArray(node)) {
578
677
  return renderChildArray(node, writer, isSvg);
579
678
  }
580
- if (typeof node === "object" && node !== null && Symbol.iterator in node && !("$$typeof" in node)) {
581
- return renderChildArray(
582
- Array.from(node),
583
- writer,
584
- isSvg
585
- );
679
+ const obj = node;
680
+ if (Symbol.iterator in obj && !("$$typeof" in obj)) {
681
+ return renderChildArray(Array.from(obj), writer, isSvg);
586
682
  }
587
- if (typeof node === "object" && node !== null && "$$typeof" in node) {
588
- const elType = node["$$typeof"];
683
+ if ("$$typeof" in obj) {
684
+ const elType = obj["$$typeof"];
589
685
  if (elType !== SLIM_ELEMENT && elType !== REACT19_ELEMENT) return;
590
686
  const element = node;
591
687
  const { type, props } = element;
@@ -595,15 +691,15 @@ function renderNode(node, writer, isSvg = false) {
595
691
  if (type === SUSPENSE_TYPE) {
596
692
  return renderSuspense(props, writer, isSvg);
597
693
  }
694
+ if (typeof type === "string") {
695
+ return renderHostElement(type, props, writer, isSvg);
696
+ }
598
697
  if (typeof type === "function") {
599
698
  return renderComponent(type, props, writer, isSvg);
600
699
  }
601
700
  if (typeof type === "object" && type !== null) {
602
701
  return renderComponent(type, props, writer, isSvg);
603
702
  }
604
- if (typeof type === "string") {
605
- return renderHostElement(type, props, writer, isSvg);
606
- }
607
703
  }
608
704
  }
609
705
  function markSelectedOptionsMulti(children, selectedValues) {
@@ -629,26 +725,21 @@ function markSelectedOptionsMulti(children, selectedValues) {
629
725
  return children;
630
726
  }
631
727
  function renderHostElement(tag, props, writer, isSvg) {
632
- const enteringSvg = tag === "svg";
633
- const childSvg = isSvg || enteringSvg;
728
+ const childSvg = isSvg || tag === "svg";
634
729
  if (tag === "textarea") {
635
730
  const textContent = props.value ?? props.defaultValue ?? props.children ?? "";
636
- const filteredProps = {};
637
- for (const k of Object.keys(props)) {
638
- if (k !== "value" && k !== "defaultValue" && k !== "children") filteredProps[k] = props[k];
639
- }
640
- writer.write(`<textarea${renderAttributes(filteredProps, false)}>`);
731
+ writer.write("<textarea");
732
+ writeAttributes(writer, props, false, TEXTAREA_SKIP_PROPS);
733
+ writer.write(">");
641
734
  writer.text(escapeHtml(String(textContent)));
642
735
  writer.write("</textarea>");
643
736
  return;
644
737
  }
645
738
  if (tag === "select") {
646
739
  const selectedValue = props.value ?? props.defaultValue;
647
- const filteredProps = {};
648
- for (const k of Object.keys(props)) {
649
- if (k !== "value" && k !== "defaultValue") filteredProps[k] = props[k];
650
- }
651
- writer.write(`<select${renderAttributes(filteredProps, false)}>`);
740
+ writer.write("<select");
741
+ writeAttributes(writer, props, false, SELECT_SKIP_PROPS);
742
+ writer.write(">");
652
743
  const selectedSet = selectedValue == null ? null : Array.isArray(selectedValue) ? new Set(selectedValue.map(String)) : /* @__PURE__ */ new Set([String(selectedValue)]);
653
744
  const patchedChildren = selectedSet != null ? markSelectedOptionsMulti(props.children, selectedSet) : props.children;
654
745
  const inner2 = renderChildren(patchedChildren, writer, false);
@@ -660,7 +751,8 @@ function renderHostElement(tag, props, writer, isSvg) {
660
751
  writer.write("</select>");
661
752
  return;
662
753
  }
663
- writer.write(`<${tag}${renderAttributes(props, childSvg)}`);
754
+ writer.write(`<${tag}`);
755
+ writeAttributes(writer, props, childSvg);
664
756
  if (VOID_ELEMENTS.has(tag)) {
665
757
  writer.write("/>");
666
758
  return;
@@ -686,8 +778,25 @@ var REACT_PROVIDER = Symbol.for("react.provider");
686
778
  var REACT_CONTEXT = Symbol.for("react.context");
687
779
  var REACT_CONSUMER = Symbol.for("react.consumer");
688
780
  var REACT_LAZY = Symbol.for("react.lazy");
689
- function renderComponent(type, props, writer, isSvg) {
690
- const typeOf = type?.$$typeof;
781
+ var SUSPENSE_RETRY_LIMIT = Symbol("SuspenseRetryLimit");
782
+ var MAX_COMPONENT_SUSPENSE_RETRIES = 25;
783
+ function patchPromiseStatus(p) {
784
+ const w = p;
785
+ if (w.status) return;
786
+ w.status = "pending";
787
+ w.then(
788
+ (v) => {
789
+ w.status = "fulfilled";
790
+ w.value = v;
791
+ },
792
+ (r) => {
793
+ w.status = "rejected";
794
+ w.reason = r;
795
+ }
796
+ );
797
+ }
798
+ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
799
+ const typeOf = type.$$typeof;
691
800
  if (typeOf === REACT_MEMO) {
692
801
  return renderNode(
693
802
  { $$typeof: SLIM_ELEMENT, type: type.type, props, key: null },
@@ -699,7 +808,23 @@ function renderComponent(type, props, writer, isSvg) {
699
808
  return renderComponent(type.render, props, writer, isSvg);
700
809
  }
701
810
  if (typeOf === REACT_LAZY) {
702
- const resolved = type._init(type._payload);
811
+ let resolved;
812
+ try {
813
+ resolved = type._init(type._payload);
814
+ } catch (e) {
815
+ if (e && typeof e.then === "function") {
816
+ if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
817
+ patchPromiseStatus(e);
818
+ const m = captureMap();
819
+ const u = captureUnsuspend();
820
+ return e.then(() => {
821
+ swapContextMap(m);
822
+ restoreUnsuspend(u);
823
+ return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
824
+ });
825
+ }
826
+ throw e;
827
+ }
703
828
  const LazyComp = resolved?.default ?? resolved;
704
829
  return renderComponent(LazyComp, props, writer, isSvg);
705
830
  }
@@ -708,12 +833,12 @@ function renderComponent(type, props, writer, isSvg) {
708
833
  const value = ctx2 ? getContextValue(ctx2) : void 0;
709
834
  const result2 = typeof props.children === "function" ? props.children(value) : null;
710
835
  const savedScope2 = pushComponentScope();
711
- const finish2 = () => popComponentScope(savedScope2);
836
+ const finish = () => popComponentScope(savedScope2);
712
837
  const r2 = renderNode(result2, writer, isSvg);
713
838
  if (r2 && typeof r2.then === "function") {
714
- return r2.then(finish2);
839
+ return r2.then(finish);
715
840
  }
716
- finish2();
841
+ finish();
717
842
  return;
718
843
  }
719
844
  const isProvider = "_context" in type || typeOf === REACT_PROVIDER || typeOf === REACT_CONTEXT && "value" in props;
@@ -725,26 +850,29 @@ function renderComponent(type, props, writer, isSvg) {
725
850
  }
726
851
  const savedScope = pushComponentScope();
727
852
  if (isProvider && typeof type !== "function") {
728
- const finish2 = () => {
853
+ const finish = () => {
729
854
  popComponentScope(savedScope);
730
855
  popContextValue(ctx, prevCtxValue);
731
856
  };
732
857
  const r2 = renderChildren(props.children, writer, isSvg);
733
858
  if (r2 && typeof r2.then === "function") {
734
859
  const m = captureMap();
860
+ const u = captureUnsuspend();
735
861
  return r2.then(
736
862
  () => {
737
863
  swapContextMap(m);
738
- finish2();
864
+ restoreUnsuspend(u);
865
+ finish();
739
866
  },
740
867
  (e) => {
741
868
  swapContextMap(m);
742
- finish2();
869
+ restoreUnsuspend(u);
870
+ finish();
743
871
  throw e;
744
872
  }
745
873
  );
746
874
  }
747
- finish2();
875
+ finish();
748
876
  return;
749
877
  }
750
878
  let result;
@@ -764,6 +892,17 @@ function renderComponent(type, props, writer, isSvg) {
764
892
  restoreDispatcher(prevDispatcher);
765
893
  popComponentScope(savedScope);
766
894
  if (isProvider) popContextValue(ctx, prevCtxValue);
895
+ if (e && typeof e.then === "function") {
896
+ if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
897
+ patchPromiseStatus(e);
898
+ const m = captureMap();
899
+ const u = captureUnsuspend();
900
+ return e.then(() => {
901
+ swapContextMap(m);
902
+ restoreUnsuspend(u);
903
+ return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
904
+ });
905
+ }
767
906
  throw e;
768
907
  }
769
908
  restoreDispatcher(prevDispatcher);
@@ -771,97 +910,93 @@ function renderComponent(type, props, writer, isSvg) {
771
910
  if (!(result instanceof Promise) && componentCalledUseId()) {
772
911
  savedIdTree = pushTreeContext(1, 0);
773
912
  }
774
- const finish = () => {
775
- if (savedIdTree !== void 0) popTreeContext(savedIdTree);
776
- popComponentScope(savedScope);
777
- if (isProvider) popContextValue(ctx, prevCtxValue);
778
- };
779
913
  if (result instanceof Promise) {
780
914
  const m = captureMap();
915
+ const u = captureUnsuspend();
781
916
  return result.then((resolved) => {
782
917
  swapContextMap(m);
918
+ restoreUnsuspend(u);
783
919
  let asyncSavedIdTree;
784
920
  if (componentCalledUseId()) {
785
921
  asyncSavedIdTree = pushTreeContext(1, 0);
786
922
  }
787
- const asyncFinish = () => {
788
- if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
789
- popComponentScope(savedScope);
790
- if (isProvider) popContextValue(ctx, prevCtxValue);
791
- };
792
923
  const r2 = renderNode(resolved, writer, isSvg);
793
924
  if (r2 && typeof r2.then === "function") {
794
925
  const m2 = captureMap();
926
+ const u2 = captureUnsuspend();
795
927
  return r2.then(
796
928
  () => {
797
929
  swapContextMap(m2);
798
- asyncFinish();
930
+ restoreUnsuspend(u2);
931
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
932
+ popComponentScope(savedScope);
933
+ if (isProvider) popContextValue(ctx, prevCtxValue);
799
934
  },
800
935
  (e) => {
801
936
  swapContextMap(m2);
802
- asyncFinish();
937
+ restoreUnsuspend(u2);
938
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
939
+ popComponentScope(savedScope);
940
+ if (isProvider) popContextValue(ctx, prevCtxValue);
803
941
  throw e;
804
942
  }
805
943
  );
806
944
  }
807
- asyncFinish();
945
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
946
+ popComponentScope(savedScope);
947
+ if (isProvider) popContextValue(ctx, prevCtxValue);
808
948
  }, (e) => {
809
949
  swapContextMap(m);
810
- finish();
950
+ restoreUnsuspend(u);
951
+ popComponentScope(savedScope);
952
+ if (isProvider) popContextValue(ctx, prevCtxValue);
811
953
  throw e;
812
954
  });
813
955
  }
814
956
  const r = renderNode(result, writer, isSvg);
815
957
  if (r && typeof r.then === "function") {
816
958
  const m = captureMap();
959
+ const u = captureUnsuspend();
817
960
  return r.then(
818
961
  () => {
819
962
  swapContextMap(m);
820
- finish();
963
+ restoreUnsuspend(u);
964
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
965
+ popComponentScope(savedScope);
966
+ if (isProvider) popContextValue(ctx, prevCtxValue);
821
967
  },
822
968
  (e) => {
823
969
  swapContextMap(m);
824
- finish();
970
+ restoreUnsuspend(u);
971
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
972
+ popComponentScope(savedScope);
973
+ if (isProvider) popContextValue(ctx, prevCtxValue);
825
974
  throw e;
826
975
  }
827
976
  );
828
977
  }
829
- finish();
830
- }
831
- function isTextLike(node) {
832
- return typeof node === "string" || typeof node === "number";
978
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
979
+ popComponentScope(savedScope);
980
+ if (isProvider) popContextValue(ctx, prevCtxValue);
833
981
  }
834
982
  function renderChildArray(children, writer, isSvg) {
835
- const totalChildren = children.length;
836
- for (let i = 0; i < totalChildren; i++) {
837
- if (isTextLike(children[i]) && writer.lastWasText) {
838
- writer.write("<!-- -->");
839
- }
840
- const savedTree = pushTreeContext(totalChildren, i);
841
- const r = renderNode(children[i], writer, isSvg);
842
- if (r && typeof r.then === "function") {
843
- const m = captureMap();
844
- return r.then(() => {
845
- swapContextMap(m);
846
- popTreeContext(savedTree);
847
- return renderChildArrayFrom(children, i + 1, writer, isSvg);
848
- });
849
- }
850
- popTreeContext(savedTree);
851
- }
983
+ return renderChildArrayFrom(children, 0, writer, isSvg);
852
984
  }
853
985
  function renderChildArrayFrom(children, startIndex, writer, isSvg) {
854
986
  const totalChildren = children.length;
855
987
  for (let i = startIndex; i < totalChildren; i++) {
856
- if (isTextLike(children[i]) && writer.lastWasText) {
988
+ const child = children[i];
989
+ if ((typeof child === "string" || typeof child === "number") && writer.lastWasText) {
857
990
  writer.write("<!-- -->");
858
991
  }
859
992
  const savedTree = pushTreeContext(totalChildren, i);
860
- const r = renderNode(children[i], writer, isSvg);
993
+ const r = renderNode(child, writer, isSvg);
861
994
  if (r && typeof r.then === "function") {
862
995
  const m = captureMap();
996
+ const u = captureUnsuspend();
863
997
  return r.then(() => {
864
998
  swapContextMap(m);
999
+ restoreUnsuspend(u);
865
1000
  popTreeContext(savedTree);
866
1001
  return renderChildArrayFrom(children, i + 1, writer, isSvg);
867
1002
  });
@@ -876,65 +1011,69 @@ function renderChildren(children, writer, isSvg = false) {
876
1011
  }
877
1012
  return renderNode(children, writer, isSvg);
878
1013
  }
879
- var MAX_SUSPENSE_RETRIES = 25;
880
1014
  async function renderSuspense(props, writer, isSvg = false) {
881
1015
  const { children, fallback } = props;
882
- let attempts = 0;
883
1016
  const snap = snapshotContext();
884
- while (attempts < MAX_SUSPENSE_RETRIES) {
885
- restoreContext(snap);
886
- let buffer = new BufferWriter();
887
- try {
888
- const r = renderNode(children, buffer, isSvg);
889
- if (r && typeof r.then === "function") {
890
- const m = captureMap();
891
- await r;
892
- swapContextMap(m);
893
- }
894
- writer.write("<!--$-->");
895
- buffer.flush(writer);
896
- writer.write("<!--/$-->");
897
- return;
898
- } catch (error) {
899
- if (error && typeof error.then === "function") {
900
- const m = captureMap();
901
- await error;
902
- swapContextMap(m);
903
- attempts++;
904
- } else {
905
- throw error;
906
- }
907
- }
908
- }
909
- restoreContext(snap);
910
- writer.write("<!--$?-->");
911
- if (fallback) {
912
- const r = renderNode(fallback, writer, isSvg);
1017
+ const savedMap = captureMap();
1018
+ const savedMapClone = savedMap ? new Map(savedMap) : null;
1019
+ const buffer = new BufferWriter();
1020
+ try {
1021
+ const r = renderNode(children, buffer, isSvg);
913
1022
  if (r && typeof r.then === "function") {
914
1023
  const m = captureMap();
1024
+ const u = captureUnsuspend();
915
1025
  await r;
916
1026
  swapContextMap(m);
1027
+ restoreUnsuspend(u);
1028
+ }
1029
+ writer.write("<!--$-->");
1030
+ buffer.flushTo(writer);
1031
+ writer.write("<!--/$-->");
1032
+ writer.flush?.();
1033
+ } catch (error) {
1034
+ if (error === SUSPENSE_RETRY_LIMIT) {
1035
+ restoreContext(snap);
1036
+ swapContextMap(savedMapClone);
1037
+ writer.write("<!--$?-->");
1038
+ if (fallback) {
1039
+ const r = renderNode(fallback, writer, isSvg);
1040
+ if (r && typeof r.then === "function") {
1041
+ const m = captureMap();
1042
+ const u = captureUnsuspend();
1043
+ await r;
1044
+ swapContextMap(m);
1045
+ restoreUnsuspend(u);
1046
+ }
1047
+ }
1048
+ writer.write("<!--/$-->");
1049
+ } else {
1050
+ throw error;
917
1051
  }
918
1052
  }
919
- writer.write("<!--/$-->");
920
1053
  }
1054
+ var _streamEncoder = new TextEncoder();
921
1055
  function renderToStream(element, options) {
922
- const encoder = new TextEncoder();
923
1056
  const idPrefix = options?.identifierPrefix ?? "";
924
- const contextMap = /* @__PURE__ */ new Map();
925
1057
  return new ReadableStream({
926
1058
  async start(controller) {
927
1059
  resetRenderState(idPrefix);
928
- const prev = swapContextMap(contextMap);
1060
+ const prev = swapContextMap(null);
1061
+ let _buf = "";
929
1062
  const writer = {
930
1063
  lastWasText: false,
931
1064
  write(chunk) {
932
- controller.enqueue(encoder.encode(chunk));
1065
+ _buf += chunk;
933
1066
  this.lastWasText = false;
934
1067
  },
935
1068
  text(s2) {
936
- controller.enqueue(encoder.encode(s2));
1069
+ _buf += s2;
937
1070
  this.lastWasText = true;
1071
+ },
1072
+ flush() {
1073
+ if (_buf.length > 0) {
1074
+ controller.enqueue(_streamEncoder.encode(_buf));
1075
+ _buf = "";
1076
+ }
938
1077
  }
939
1078
  };
940
1079
  try {
@@ -944,6 +1083,7 @@ function renderToStream(element, options) {
944
1083
  await r;
945
1084
  swapContextMap(m);
946
1085
  }
1086
+ writer.flush();
947
1087
  controller.close();
948
1088
  } catch (error) {
949
1089
  controller.error(error);
@@ -953,45 +1093,53 @@ function renderToStream(element, options) {
953
1093
  }
954
1094
  });
955
1095
  }
1096
+ var NULL_WRITER = {
1097
+ lastWasText: false,
1098
+ write(_c) {
1099
+ },
1100
+ text(_s) {
1101
+ }
1102
+ };
1103
+ async function renderPreflight(element, options) {
1104
+ const idPrefix = options?.identifierPrefix ?? "";
1105
+ const prev = swapContextMap(null);
1106
+ try {
1107
+ resetRenderState(idPrefix);
1108
+ NULL_WRITER.lastWasText = false;
1109
+ const r = renderNode(element, NULL_WRITER);
1110
+ if (r && typeof r.then === "function") {
1111
+ const m = captureMap();
1112
+ await r;
1113
+ swapContextMap(m);
1114
+ }
1115
+ } finally {
1116
+ swapContextMap(prev);
1117
+ }
1118
+ }
956
1119
  async function renderToString(element, options) {
957
1120
  const idPrefix = options?.identifierPrefix ?? "";
958
- const contextMap = /* @__PURE__ */ new Map();
959
- const prev = swapContextMap(contextMap);
1121
+ const prev = swapContextMap(null);
1122
+ let output = "";
1123
+ const writer = {
1124
+ lastWasText: false,
1125
+ write(c) {
1126
+ output += c;
1127
+ this.lastWasText = false;
1128
+ },
1129
+ text(s2) {
1130
+ output += s2;
1131
+ this.lastWasText = true;
1132
+ }
1133
+ };
960
1134
  try {
961
- for (let attempt = 0; attempt < MAX_SUSPENSE_RETRIES; attempt++) {
962
- resetRenderState(idPrefix);
963
- swapContextMap(contextMap);
964
- const chunks = [];
965
- const writer = {
966
- lastWasText: false,
967
- write(c) {
968
- chunks.push(c);
969
- this.lastWasText = false;
970
- },
971
- text(s2) {
972
- chunks.push(s2);
973
- this.lastWasText = true;
974
- }
975
- };
976
- try {
977
- const r = renderNode(element, writer);
978
- if (r && typeof r.then === "function") {
979
- const m = captureMap();
980
- await r;
981
- swapContextMap(m);
982
- }
983
- return chunks.join("");
984
- } catch (error) {
985
- if (error && typeof error.then === "function") {
986
- const m = captureMap();
987
- await error;
988
- swapContextMap(m);
989
- continue;
990
- }
991
- throw error;
992
- }
1135
+ resetRenderState(idPrefix);
1136
+ const r = renderNode(element, writer);
1137
+ if (r && typeof r.then === "function") {
1138
+ const m = captureMap();
1139
+ await r;
1140
+ swapContextMap(m);
993
1141
  }
994
- throw new Error("[slim-react] renderToString exceeded maximum retries");
1142
+ return output;
995
1143
  } finally {
996
1144
  swapContextMap(prev);
997
1145
  }
@@ -1003,11 +1151,13 @@ function useContext(context) {
1003
1151
  }
1004
1152
  var Suspense = SUSPENSE_TYPE;
1005
1153
  function isValidElement(obj) {
1006
- return typeof obj === "object" && obj !== null && obj.$$typeof === SLIM_ELEMENT;
1154
+ if (typeof obj !== "object" || obj === null) return false;
1155
+ const t = obj.$$typeof;
1156
+ return t === SLIM_ELEMENT || t === REACT19_ELEMENT;
1007
1157
  }
1008
1158
  function cloneElement(element, overrideProps, ...children) {
1009
1159
  return {
1010
- $$typeof: SLIM_ELEMENT,
1160
+ $$typeof: element.$$typeof || SLIM_ELEMENT,
1011
1161
  type: element.type,
1012
1162
  props: {
1013
1163
  ...element.props,
@@ -1018,12 +1168,18 @@ function cloneElement(element, overrideProps, ...children) {
1018
1168
  };
1019
1169
  }
1020
1170
  function forwardRef(render) {
1021
- const component = (props) => render(props, props.ref ?? null);
1022
- component.displayName = render.displayName || render.name || "ForwardRef";
1023
- return component;
1171
+ return {
1172
+ $$typeof: Symbol.for("react.forward_ref"),
1173
+ render,
1174
+ displayName: render.displayName || render.name || "ForwardRef"
1175
+ };
1024
1176
  }
1025
- function memo(component) {
1026
- return component;
1177
+ function memo(component, compare) {
1178
+ return {
1179
+ $$typeof: Symbol.for("react.memo"),
1180
+ type: component,
1181
+ compare: compare ?? null
1182
+ };
1027
1183
  }
1028
1184
  function lazy(factory) {
1029
1185
  let resolved = null;
@@ -1120,6 +1276,7 @@ var React = {
1120
1276
  renderToStream,
1121
1277
  renderToString,
1122
1278
  renderToReadableStream: renderToStream,
1279
+ renderPreflight,
1123
1280
  // Version
1124
1281
  version
1125
1282
  };
@@ -1144,6 +1301,7 @@ var slim_react_default = React;
1144
1301
  jsxs,
1145
1302
  lazy,
1146
1303
  memo,
1304
+ renderPreflight,
1147
1305
  renderToReadableStream,
1148
1306
  renderToStream,
1149
1307
  renderToString,