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
@@ -19,6 +19,13 @@ function swapContextMap(map) {
19
19
  function captureMap() {
20
20
  return _g[MAP_KEY];
21
21
  }
22
+ var UNSUSPEND_KEY = "__hadarsUnsuspend";
23
+ function captureUnsuspend() {
24
+ return _g[UNSUSPEND_KEY];
25
+ }
26
+ function restoreUnsuspend(u) {
27
+ _g[UNSUSPEND_KEY] = u;
28
+ }
22
29
  function getContextValue(context) {
23
30
  const map = _g[MAP_KEY];
24
31
  if (map && map.has(context)) return map.get(context);
@@ -26,10 +33,14 @@ function getContextValue(context) {
26
33
  return "_defaultValue" in c ? c._defaultValue : c._currentValue;
27
34
  }
28
35
  function pushContextValue(context, value) {
29
- const map = _g[MAP_KEY];
36
+ let map = _g[MAP_KEY];
37
+ if (map === null) {
38
+ map = /* @__PURE__ */ new Map();
39
+ _g[MAP_KEY] = map;
40
+ }
30
41
  const c = context;
31
- const prev = map && map.has(context) ? map.get(context) : "_defaultValue" in c ? c._defaultValue : c._currentValue;
32
- map?.set(context, value);
42
+ const prev = map.has(context) ? map.get(context) : "_defaultValue" in c ? c._defaultValue : c._currentValue;
43
+ map.set(context, value);
33
44
  return prev;
34
45
  }
35
46
  function popContextValue(context, prev) {
@@ -37,48 +48,57 @@ function popContextValue(context, prev) {
37
48
  }
38
49
  var GLOBAL_KEY = "__slimReactRenderState";
39
50
  var EMPTY = { id: 1, overflow: "" };
51
+ var _stateCache = null;
40
52
  function s() {
41
- const g = globalThis;
42
- if (!g[GLOBAL_KEY]) {
43
- g[GLOBAL_KEY] = { currentTreeContext: { ...EMPTY }, localIdCounter: 0, idPrefix: "" };
53
+ if (_stateCache !== null) return _stateCache;
54
+ if (!_g[GLOBAL_KEY]) {
55
+ _g[GLOBAL_KEY] = { currentTreeContext: { ...EMPTY }, localIdCounter: 0, idPrefix: "" };
44
56
  }
45
- return g[GLOBAL_KEY];
57
+ _stateCache = _g[GLOBAL_KEY];
58
+ return _stateCache;
46
59
  }
60
+ var _treeIdStack = [];
61
+ var _treeOvStack = [];
62
+ var _treeDepth = 0;
47
63
  function resetRenderState(idPrefix = "") {
48
64
  const st = s();
49
- st.currentTreeContext = { ...EMPTY };
65
+ st.currentTreeContext.id = EMPTY.id;
66
+ st.currentTreeContext.overflow = EMPTY.overflow;
50
67
  st.localIdCounter = 0;
51
68
  st.idPrefix = idPrefix;
69
+ _treeDepth = 0;
52
70
  }
53
71
  function pushTreeContext(totalChildren, index) {
54
72
  const st = s();
55
- const saved = { ...st.currentTreeContext };
56
- const baseIdWithLeadingBit = st.currentTreeContext.id;
57
- const baseOverflow = st.currentTreeContext.overflow;
73
+ const ctx = st.currentTreeContext;
74
+ const depth = _treeDepth++;
75
+ _treeIdStack[depth] = ctx.id;
76
+ _treeOvStack[depth] = ctx.overflow;
77
+ const baseIdWithLeadingBit = ctx.id;
78
+ const baseOverflow = ctx.overflow;
58
79
  const baseLength = 31 - Math.clz32(baseIdWithLeadingBit);
59
80
  let baseId = baseIdWithLeadingBit & ~(1 << baseLength);
60
81
  const slot = index + 1;
61
82
  const newBits = 32 - Math.clz32(totalChildren);
62
83
  const length = newBits + baseLength;
63
84
  if (30 < length) {
64
- const numberOfOverflowBits = baseLength - baseLength % 5;
65
- const overflowStr = (baseId & (1 << numberOfOverflowBits) - 1).toString(32);
66
- baseId >>= numberOfOverflowBits;
67
- const newBaseLength = baseLength - numberOfOverflowBits;
68
- st.currentTreeContext = {
69
- id: 1 << newBits + newBaseLength | slot << newBaseLength | baseId,
70
- overflow: overflowStr + baseOverflow
71
- };
85
+ const overflowBits = baseLength - baseLength % 5;
86
+ const overflowStr = (baseId & (1 << overflowBits) - 1).toString(32);
87
+ baseId >>= overflowBits;
88
+ const newBaseLength = baseLength - overflowBits;
89
+ ctx.id = 1 << newBits + newBaseLength | slot << newBaseLength | baseId;
90
+ ctx.overflow = overflowStr + baseOverflow;
72
91
  } else {
73
- st.currentTreeContext = {
74
- id: 1 << length | slot << baseLength | baseId,
75
- overflow: baseOverflow
76
- };
92
+ ctx.id = 1 << length | slot << baseLength | baseId;
93
+ ctx.overflow = baseOverflow;
77
94
  }
78
- return saved;
95
+ return depth;
79
96
  }
80
- function popTreeContext(saved) {
81
- s().currentTreeContext = saved;
97
+ function popTreeContext(depth) {
98
+ const ctx = s().currentTreeContext;
99
+ ctx.id = _treeIdStack[depth];
100
+ ctx.overflow = _treeOvStack[depth];
101
+ _treeDepth = depth;
82
102
  }
83
103
  function pushComponentScope() {
84
104
  const st = s();
@@ -94,12 +114,16 @@ function componentCalledUseId() {
94
114
  }
95
115
  function snapshotContext() {
96
116
  const st = s();
97
- return { tree: { ...st.currentTreeContext }, localId: st.localIdCounter };
117
+ const ctx = st.currentTreeContext;
118
+ return { tree: { id: ctx.id, overflow: ctx.overflow }, localId: st.localIdCounter, treeDepth: _treeDepth };
98
119
  }
99
120
  function restoreContext(snap) {
100
121
  const st = s();
101
- st.currentTreeContext = { ...snap.tree };
122
+ const ctx = st.currentTreeContext;
123
+ ctx.id = snap.tree.id;
124
+ ctx.overflow = snap.tree.overflow;
102
125
  st.localIdCounter = snap.localId;
126
+ _treeDepth = snap.treeDepth;
103
127
  }
104
128
  function getTreeId() {
105
129
  const { id, overflow } = s().currentTreeContext;
@@ -198,7 +222,7 @@ function createContext(defaultValue) {
198
222
  context.Provider = Provider;
199
223
  context.Consumer = ({ children }) => {
200
224
  return children(
201
- context._currentValue
225
+ getContextValue(context)
202
226
  );
203
227
  };
204
228
  return context;
@@ -262,19 +286,80 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
262
286
  "wbr"
263
287
  ]);
264
288
  var HTML_ESC = { "&": "&amp;", "<": "&lt;", ">": "&gt;", "'": "&#x27;" };
289
+ var HTML_ESC_RE = /[&<>']/;
265
290
  function escapeHtml(str) {
291
+ if (!HTML_ESC_RE.test(str)) return str;
266
292
  return str.replace(/[&<>']/g, (c) => HTML_ESC[c]);
267
293
  }
268
294
  var ATTR_ESC = { "&": "&amp;", '"': "&quot;", "<": "&lt;", ">": "&gt;" };
295
+ var ATTR_ESC_RE = /[&"<>]/;
269
296
  function escapeAttr(str) {
297
+ if (!ATTR_ESC_RE.test(str)) return str;
270
298
  return str.replace(/[&"<>]/g, (c) => ATTR_ESC[c]);
271
299
  }
300
+ var UNITLESS_CSS = /* @__PURE__ */ new Set([
301
+ "animationIterationCount",
302
+ "aspectRatio",
303
+ "borderImageOutset",
304
+ "borderImageSlice",
305
+ "borderImageWidth",
306
+ "boxFlex",
307
+ "boxFlexGroup",
308
+ "boxOrdinalGroup",
309
+ "columnCount",
310
+ "columns",
311
+ "flex",
312
+ "flexGrow",
313
+ "flexPositive",
314
+ "flexShrink",
315
+ "flexNegative",
316
+ "flexOrder",
317
+ "gridArea",
318
+ "gridRow",
319
+ "gridRowEnd",
320
+ "gridRowSpan",
321
+ "gridRowStart",
322
+ "gridColumn",
323
+ "gridColumnEnd",
324
+ "gridColumnSpan",
325
+ "gridColumnStart",
326
+ "fontWeight",
327
+ "lineClamp",
328
+ "lineHeight",
329
+ "opacity",
330
+ "order",
331
+ "orphans",
332
+ "scale",
333
+ "tabSize",
334
+ "widows",
335
+ "zIndex",
336
+ "zoom",
337
+ "fillOpacity",
338
+ "floodOpacity",
339
+ "stopOpacity",
340
+ "strokeDasharray",
341
+ "strokeDashoffset",
342
+ "strokeMiterlimit",
343
+ "strokeOpacity",
344
+ "strokeWidth"
345
+ ]);
346
+ var _cssKeyCache = /* @__PURE__ */ new Map();
272
347
  function styleObjectToString(style) {
273
348
  let result = "";
274
349
  for (const key in style) {
350
+ const value = style[key];
351
+ if (value == null || typeof value === "boolean") continue;
275
352
  if (result) result += ";";
276
- const cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
277
- result += cssKey + ":" + style[key];
353
+ let cssKey = _cssKeyCache.get(key);
354
+ if (cssKey === void 0) {
355
+ cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
356
+ _cssKeyCache.set(key, cssKey);
357
+ }
358
+ if (typeof value === "number" && value !== 0 && !UNITLESS_CSS.has(key)) {
359
+ result += cssKey + ":" + value + "px";
360
+ } else {
361
+ result += cssKey + ":" + value;
362
+ }
278
363
  }
279
364
  return result;
280
365
  }
@@ -409,14 +494,22 @@ var SVG_ATTR_MAP = {
409
494
  xChannelSelector: "xChannelSelector",
410
495
  yChannelSelector: "yChannelSelector"
411
496
  };
412
- function renderAttributes(props, isSvg) {
413
- let attrs = "";
497
+ var TEXTAREA_SKIP_PROPS = /* @__PURE__ */ new Set(["value", "defaultValue", "children"]);
498
+ var SELECT_SKIP_PROPS = /* @__PURE__ */ new Set(["value", "defaultValue"]);
499
+ var INTERNAL_PROPS = /* @__PURE__ */ new Set([
500
+ "children",
501
+ "key",
502
+ "ref",
503
+ "dangerouslySetInnerHTML",
504
+ "suppressHydrationWarning",
505
+ "suppressContentEditableWarning"
506
+ ]);
507
+ function writeAttributes(writer, props, isSvg, skip) {
414
508
  for (const key in props) {
509
+ if (skip !== void 0 && skip.has(key)) continue;
415
510
  const value = props[key];
416
- if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || key === "suppressHydrationWarning" || key === "suppressContentEditableWarning")
417
- continue;
418
- if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase())
419
- continue;
511
+ if (INTERNAL_PROPS.has(key)) continue;
512
+ if (key.length > 2 && key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && key.charCodeAt(2) >= 65 && key.charCodeAt(2) <= 90) continue;
420
513
  let attrName;
421
514
  if (isSvg && key in SVG_ATTR_MAP) {
422
515
  attrName = SVG_ATTR_MAP[key];
@@ -424,41 +517,46 @@ function renderAttributes(props, isSvg) {
424
517
  attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "tabIndex" ? "tabindex" : key === "defaultValue" ? "value" : key === "defaultChecked" ? "checked" : key;
425
518
  }
426
519
  if (value === false || value == null) {
427
- if (value === false && (attrName.startsWith("aria-") || attrName.startsWith("data-"))) {
428
- attrs += ` ${attrName}="false"`;
520
+ if (value === false && (attrName.charCodeAt(0) === 97 && attrName.startsWith("aria-") || attrName.charCodeAt(0) === 100 && attrName.startsWith("data-"))) {
521
+ writer.write(` ${attrName}="false"`);
429
522
  }
430
523
  continue;
431
524
  }
432
525
  if (value === true) {
433
- if (attrName.startsWith("aria-") || attrName.startsWith("data-")) {
434
- attrs += ` ${attrName}="true"`;
526
+ if (attrName.charCodeAt(0) === 97 && attrName.startsWith("aria-") || attrName.charCodeAt(0) === 100 && attrName.startsWith("data-")) {
527
+ writer.write(` ${attrName}="true"`);
435
528
  } else {
436
- attrs += ` ${attrName}=""`;
529
+ writer.write(` ${attrName}=""`);
437
530
  }
438
531
  continue;
439
532
  }
440
533
  if (key === "style" && typeof value === "object") {
441
534
  const styleStr = styleObjectToString(value);
442
- if (styleStr) attrs += ` style="${escapeAttr(styleStr)}"`;
535
+ if (styleStr) writer.write(` style="${escapeAttr(styleStr)}"`);
443
536
  continue;
444
537
  }
445
- attrs += ` ${attrName}="${escapeAttr(String(value))}"`;
538
+ writer.write(` ${attrName}="${escapeAttr(typeof value === "string" ? value : String(value))}"`);
446
539
  }
447
- return attrs;
448
540
  }
449
- var BufferWriter = class {
450
- chunks = [];
541
+ var BufferWriter = class _BufferWriter {
542
+ data = "";
451
543
  lastWasText = false;
452
544
  write(chunk) {
453
- this.chunks.push(chunk);
545
+ this.data += chunk;
454
546
  this.lastWasText = false;
455
547
  }
456
548
  text(s2) {
457
- this.chunks.push(s2);
549
+ this.data += s2;
458
550
  this.lastWasText = true;
459
551
  }
460
- flush(target) {
461
- for (const c of this.chunks) target.write(c);
552
+ /** Flush accumulated output into a parent writer and reset. */
553
+ flushTo(target) {
554
+ if (!this.data) return;
555
+ if (target instanceof _BufferWriter) {
556
+ target.data += this.data;
557
+ } else {
558
+ target.write(this.data);
559
+ }
462
560
  target.lastWasText = this.lastWasText;
463
561
  }
464
562
  };
@@ -475,15 +573,12 @@ function renderNode(node, writer, isSvg = false) {
475
573
  if (Array.isArray(node)) {
476
574
  return renderChildArray(node, writer, isSvg);
477
575
  }
478
- if (typeof node === "object" && node !== null && Symbol.iterator in node && !("$$typeof" in node)) {
479
- return renderChildArray(
480
- Array.from(node),
481
- writer,
482
- isSvg
483
- );
576
+ const obj = node;
577
+ if (Symbol.iterator in obj && !("$$typeof" in obj)) {
578
+ return renderChildArray(Array.from(obj), writer, isSvg);
484
579
  }
485
- if (typeof node === "object" && node !== null && "$$typeof" in node) {
486
- const elType = node["$$typeof"];
580
+ if ("$$typeof" in obj) {
581
+ const elType = obj["$$typeof"];
487
582
  if (elType !== SLIM_ELEMENT && elType !== REACT19_ELEMENT) return;
488
583
  const element = node;
489
584
  const { type, props } = element;
@@ -493,15 +588,15 @@ function renderNode(node, writer, isSvg = false) {
493
588
  if (type === SUSPENSE_TYPE) {
494
589
  return renderSuspense(props, writer, isSvg);
495
590
  }
591
+ if (typeof type === "string") {
592
+ return renderHostElement(type, props, writer, isSvg);
593
+ }
496
594
  if (typeof type === "function") {
497
595
  return renderComponent(type, props, writer, isSvg);
498
596
  }
499
597
  if (typeof type === "object" && type !== null) {
500
598
  return renderComponent(type, props, writer, isSvg);
501
599
  }
502
- if (typeof type === "string") {
503
- return renderHostElement(type, props, writer, isSvg);
504
- }
505
600
  }
506
601
  }
507
602
  function markSelectedOptionsMulti(children, selectedValues) {
@@ -527,26 +622,21 @@ function markSelectedOptionsMulti(children, selectedValues) {
527
622
  return children;
528
623
  }
529
624
  function renderHostElement(tag, props, writer, isSvg) {
530
- const enteringSvg = tag === "svg";
531
- const childSvg = isSvg || enteringSvg;
625
+ const childSvg = isSvg || tag === "svg";
532
626
  if (tag === "textarea") {
533
627
  const textContent = props.value ?? props.defaultValue ?? props.children ?? "";
534
- const filteredProps = {};
535
- for (const k of Object.keys(props)) {
536
- if (k !== "value" && k !== "defaultValue" && k !== "children") filteredProps[k] = props[k];
537
- }
538
- writer.write(`<textarea${renderAttributes(filteredProps, false)}>`);
628
+ writer.write("<textarea");
629
+ writeAttributes(writer, props, false, TEXTAREA_SKIP_PROPS);
630
+ writer.write(">");
539
631
  writer.text(escapeHtml(String(textContent)));
540
632
  writer.write("</textarea>");
541
633
  return;
542
634
  }
543
635
  if (tag === "select") {
544
636
  const selectedValue = props.value ?? props.defaultValue;
545
- const filteredProps = {};
546
- for (const k of Object.keys(props)) {
547
- if (k !== "value" && k !== "defaultValue") filteredProps[k] = props[k];
548
- }
549
- writer.write(`<select${renderAttributes(filteredProps, false)}>`);
637
+ writer.write("<select");
638
+ writeAttributes(writer, props, false, SELECT_SKIP_PROPS);
639
+ writer.write(">");
550
640
  const selectedSet = selectedValue == null ? null : Array.isArray(selectedValue) ? new Set(selectedValue.map(String)) : /* @__PURE__ */ new Set([String(selectedValue)]);
551
641
  const patchedChildren = selectedSet != null ? markSelectedOptionsMulti(props.children, selectedSet) : props.children;
552
642
  const inner2 = renderChildren(patchedChildren, writer, false);
@@ -558,7 +648,8 @@ function renderHostElement(tag, props, writer, isSvg) {
558
648
  writer.write("</select>");
559
649
  return;
560
650
  }
561
- writer.write(`<${tag}${renderAttributes(props, childSvg)}`);
651
+ writer.write(`<${tag}`);
652
+ writeAttributes(writer, props, childSvg);
562
653
  if (VOID_ELEMENTS.has(tag)) {
563
654
  writer.write("/>");
564
655
  return;
@@ -584,8 +675,25 @@ var REACT_PROVIDER = Symbol.for("react.provider");
584
675
  var REACT_CONTEXT = Symbol.for("react.context");
585
676
  var REACT_CONSUMER = Symbol.for("react.consumer");
586
677
  var REACT_LAZY = Symbol.for("react.lazy");
587
- function renderComponent(type, props, writer, isSvg) {
588
- const typeOf = type?.$$typeof;
678
+ var SUSPENSE_RETRY_LIMIT = Symbol("SuspenseRetryLimit");
679
+ var MAX_COMPONENT_SUSPENSE_RETRIES = 25;
680
+ function patchPromiseStatus(p) {
681
+ const w = p;
682
+ if (w.status) return;
683
+ w.status = "pending";
684
+ w.then(
685
+ (v) => {
686
+ w.status = "fulfilled";
687
+ w.value = v;
688
+ },
689
+ (r) => {
690
+ w.status = "rejected";
691
+ w.reason = r;
692
+ }
693
+ );
694
+ }
695
+ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
696
+ const typeOf = type.$$typeof;
589
697
  if (typeOf === REACT_MEMO) {
590
698
  return renderNode(
591
699
  { $$typeof: SLIM_ELEMENT, type: type.type, props, key: null },
@@ -597,7 +705,23 @@ function renderComponent(type, props, writer, isSvg) {
597
705
  return renderComponent(type.render, props, writer, isSvg);
598
706
  }
599
707
  if (typeOf === REACT_LAZY) {
600
- const resolved = type._init(type._payload);
708
+ let resolved;
709
+ try {
710
+ resolved = type._init(type._payload);
711
+ } catch (e) {
712
+ if (e && typeof e.then === "function") {
713
+ if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
714
+ patchPromiseStatus(e);
715
+ const m = captureMap();
716
+ const u = captureUnsuspend();
717
+ return e.then(() => {
718
+ swapContextMap(m);
719
+ restoreUnsuspend(u);
720
+ return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
721
+ });
722
+ }
723
+ throw e;
724
+ }
601
725
  const LazyComp = resolved?.default ?? resolved;
602
726
  return renderComponent(LazyComp, props, writer, isSvg);
603
727
  }
@@ -606,12 +730,12 @@ function renderComponent(type, props, writer, isSvg) {
606
730
  const value = ctx2 ? getContextValue(ctx2) : void 0;
607
731
  const result2 = typeof props.children === "function" ? props.children(value) : null;
608
732
  const savedScope2 = pushComponentScope();
609
- const finish2 = () => popComponentScope(savedScope2);
733
+ const finish = () => popComponentScope(savedScope2);
610
734
  const r2 = renderNode(result2, writer, isSvg);
611
735
  if (r2 && typeof r2.then === "function") {
612
- return r2.then(finish2);
736
+ return r2.then(finish);
613
737
  }
614
- finish2();
738
+ finish();
615
739
  return;
616
740
  }
617
741
  const isProvider = "_context" in type || typeOf === REACT_PROVIDER || typeOf === REACT_CONTEXT && "value" in props;
@@ -623,26 +747,29 @@ function renderComponent(type, props, writer, isSvg) {
623
747
  }
624
748
  const savedScope = pushComponentScope();
625
749
  if (isProvider && typeof type !== "function") {
626
- const finish2 = () => {
750
+ const finish = () => {
627
751
  popComponentScope(savedScope);
628
752
  popContextValue(ctx, prevCtxValue);
629
753
  };
630
754
  const r2 = renderChildren(props.children, writer, isSvg);
631
755
  if (r2 && typeof r2.then === "function") {
632
756
  const m = captureMap();
757
+ const u = captureUnsuspend();
633
758
  return r2.then(
634
759
  () => {
635
760
  swapContextMap(m);
636
- finish2();
761
+ restoreUnsuspend(u);
762
+ finish();
637
763
  },
638
764
  (e) => {
639
765
  swapContextMap(m);
640
- finish2();
766
+ restoreUnsuspend(u);
767
+ finish();
641
768
  throw e;
642
769
  }
643
770
  );
644
771
  }
645
- finish2();
772
+ finish();
646
773
  return;
647
774
  }
648
775
  let result;
@@ -662,6 +789,17 @@ function renderComponent(type, props, writer, isSvg) {
662
789
  restoreDispatcher(prevDispatcher);
663
790
  popComponentScope(savedScope);
664
791
  if (isProvider) popContextValue(ctx, prevCtxValue);
792
+ if (e && typeof e.then === "function") {
793
+ if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
794
+ patchPromiseStatus(e);
795
+ const m = captureMap();
796
+ const u = captureUnsuspend();
797
+ return e.then(() => {
798
+ swapContextMap(m);
799
+ restoreUnsuspend(u);
800
+ return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
801
+ });
802
+ }
665
803
  throw e;
666
804
  }
667
805
  restoreDispatcher(prevDispatcher);
@@ -669,97 +807,93 @@ function renderComponent(type, props, writer, isSvg) {
669
807
  if (!(result instanceof Promise) && componentCalledUseId()) {
670
808
  savedIdTree = pushTreeContext(1, 0);
671
809
  }
672
- const finish = () => {
673
- if (savedIdTree !== void 0) popTreeContext(savedIdTree);
674
- popComponentScope(savedScope);
675
- if (isProvider) popContextValue(ctx, prevCtxValue);
676
- };
677
810
  if (result instanceof Promise) {
678
811
  const m = captureMap();
812
+ const u = captureUnsuspend();
679
813
  return result.then((resolved) => {
680
814
  swapContextMap(m);
815
+ restoreUnsuspend(u);
681
816
  let asyncSavedIdTree;
682
817
  if (componentCalledUseId()) {
683
818
  asyncSavedIdTree = pushTreeContext(1, 0);
684
819
  }
685
- const asyncFinish = () => {
686
- if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
687
- popComponentScope(savedScope);
688
- if (isProvider) popContextValue(ctx, prevCtxValue);
689
- };
690
820
  const r2 = renderNode(resolved, writer, isSvg);
691
821
  if (r2 && typeof r2.then === "function") {
692
822
  const m2 = captureMap();
823
+ const u2 = captureUnsuspend();
693
824
  return r2.then(
694
825
  () => {
695
826
  swapContextMap(m2);
696
- asyncFinish();
827
+ restoreUnsuspend(u2);
828
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
829
+ popComponentScope(savedScope);
830
+ if (isProvider) popContextValue(ctx, prevCtxValue);
697
831
  },
698
832
  (e) => {
699
833
  swapContextMap(m2);
700
- asyncFinish();
834
+ restoreUnsuspend(u2);
835
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
836
+ popComponentScope(savedScope);
837
+ if (isProvider) popContextValue(ctx, prevCtxValue);
701
838
  throw e;
702
839
  }
703
840
  );
704
841
  }
705
- asyncFinish();
842
+ if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
843
+ popComponentScope(savedScope);
844
+ if (isProvider) popContextValue(ctx, prevCtxValue);
706
845
  }, (e) => {
707
846
  swapContextMap(m);
708
- finish();
847
+ restoreUnsuspend(u);
848
+ popComponentScope(savedScope);
849
+ if (isProvider) popContextValue(ctx, prevCtxValue);
709
850
  throw e;
710
851
  });
711
852
  }
712
853
  const r = renderNode(result, writer, isSvg);
713
854
  if (r && typeof r.then === "function") {
714
855
  const m = captureMap();
856
+ const u = captureUnsuspend();
715
857
  return r.then(
716
858
  () => {
717
859
  swapContextMap(m);
718
- finish();
860
+ restoreUnsuspend(u);
861
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
862
+ popComponentScope(savedScope);
863
+ if (isProvider) popContextValue(ctx, prevCtxValue);
719
864
  },
720
865
  (e) => {
721
866
  swapContextMap(m);
722
- finish();
867
+ restoreUnsuspend(u);
868
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
869
+ popComponentScope(savedScope);
870
+ if (isProvider) popContextValue(ctx, prevCtxValue);
723
871
  throw e;
724
872
  }
725
873
  );
726
874
  }
727
- finish();
728
- }
729
- function isTextLike(node) {
730
- return typeof node === "string" || typeof node === "number";
875
+ if (savedIdTree !== void 0) popTreeContext(savedIdTree);
876
+ popComponentScope(savedScope);
877
+ if (isProvider) popContextValue(ctx, prevCtxValue);
731
878
  }
732
879
  function renderChildArray(children, writer, isSvg) {
733
- const totalChildren = children.length;
734
- for (let i = 0; i < totalChildren; i++) {
735
- if (isTextLike(children[i]) && writer.lastWasText) {
736
- writer.write("<!-- -->");
737
- }
738
- const savedTree = pushTreeContext(totalChildren, i);
739
- const r = renderNode(children[i], writer, isSvg);
740
- if (r && typeof r.then === "function") {
741
- const m = captureMap();
742
- return r.then(() => {
743
- swapContextMap(m);
744
- popTreeContext(savedTree);
745
- return renderChildArrayFrom(children, i + 1, writer, isSvg);
746
- });
747
- }
748
- popTreeContext(savedTree);
749
- }
880
+ return renderChildArrayFrom(children, 0, writer, isSvg);
750
881
  }
751
882
  function renderChildArrayFrom(children, startIndex, writer, isSvg) {
752
883
  const totalChildren = children.length;
753
884
  for (let i = startIndex; i < totalChildren; i++) {
754
- if (isTextLike(children[i]) && writer.lastWasText) {
885
+ const child = children[i];
886
+ if ((typeof child === "string" || typeof child === "number") && writer.lastWasText) {
755
887
  writer.write("<!-- -->");
756
888
  }
757
889
  const savedTree = pushTreeContext(totalChildren, i);
758
- const r = renderNode(children[i], writer, isSvg);
890
+ const r = renderNode(child, writer, isSvg);
759
891
  if (r && typeof r.then === "function") {
760
892
  const m = captureMap();
893
+ const u = captureUnsuspend();
761
894
  return r.then(() => {
762
895
  swapContextMap(m);
896
+ restoreUnsuspend(u);
763
897
  popTreeContext(savedTree);
764
898
  return renderChildArrayFrom(children, i + 1, writer, isSvg);
765
899
  });
@@ -774,65 +908,69 @@ function renderChildren(children, writer, isSvg = false) {
774
908
  }
775
909
  return renderNode(children, writer, isSvg);
776
910
  }
777
- var MAX_SUSPENSE_RETRIES = 25;
778
911
  async function renderSuspense(props, writer, isSvg = false) {
779
912
  const { children, fallback } = props;
780
- let attempts = 0;
781
913
  const snap = snapshotContext();
782
- while (attempts < MAX_SUSPENSE_RETRIES) {
783
- restoreContext(snap);
784
- let buffer = new BufferWriter();
785
- try {
786
- const r = renderNode(children, buffer, isSvg);
787
- if (r && typeof r.then === "function") {
788
- const m = captureMap();
789
- await r;
790
- swapContextMap(m);
791
- }
792
- writer.write("<!--$-->");
793
- buffer.flush(writer);
794
- writer.write("<!--/$-->");
795
- return;
796
- } catch (error) {
797
- if (error && typeof error.then === "function") {
798
- const m = captureMap();
799
- await error;
800
- swapContextMap(m);
801
- attempts++;
802
- } else {
803
- throw error;
804
- }
805
- }
806
- }
807
- restoreContext(snap);
808
- writer.write("<!--$?-->");
809
- if (fallback) {
810
- const r = renderNode(fallback, writer, isSvg);
914
+ const savedMap = captureMap();
915
+ const savedMapClone = savedMap ? new Map(savedMap) : null;
916
+ const buffer = new BufferWriter();
917
+ try {
918
+ const r = renderNode(children, buffer, isSvg);
811
919
  if (r && typeof r.then === "function") {
812
920
  const m = captureMap();
921
+ const u = captureUnsuspend();
813
922
  await r;
814
923
  swapContextMap(m);
924
+ restoreUnsuspend(u);
925
+ }
926
+ writer.write("<!--$-->");
927
+ buffer.flushTo(writer);
928
+ writer.write("<!--/$-->");
929
+ writer.flush?.();
930
+ } catch (error) {
931
+ if (error === SUSPENSE_RETRY_LIMIT) {
932
+ restoreContext(snap);
933
+ swapContextMap(savedMapClone);
934
+ writer.write("<!--$?-->");
935
+ if (fallback) {
936
+ const r = renderNode(fallback, writer, isSvg);
937
+ if (r && typeof r.then === "function") {
938
+ const m = captureMap();
939
+ const u = captureUnsuspend();
940
+ await r;
941
+ swapContextMap(m);
942
+ restoreUnsuspend(u);
943
+ }
944
+ }
945
+ writer.write("<!--/$-->");
946
+ } else {
947
+ throw error;
815
948
  }
816
949
  }
817
- writer.write("<!--/$-->");
818
950
  }
951
+ var _streamEncoder = new TextEncoder();
819
952
  function renderToStream(element, options) {
820
- const encoder = new TextEncoder();
821
953
  const idPrefix = options?.identifierPrefix ?? "";
822
- const contextMap = /* @__PURE__ */ new Map();
823
954
  return new ReadableStream({
824
955
  async start(controller) {
825
956
  resetRenderState(idPrefix);
826
- const prev = swapContextMap(contextMap);
957
+ const prev = swapContextMap(null);
958
+ let _buf = "";
827
959
  const writer = {
828
960
  lastWasText: false,
829
961
  write(chunk) {
830
- controller.enqueue(encoder.encode(chunk));
962
+ _buf += chunk;
831
963
  this.lastWasText = false;
832
964
  },
833
965
  text(s2) {
834
- controller.enqueue(encoder.encode(s2));
966
+ _buf += s2;
835
967
  this.lastWasText = true;
968
+ },
969
+ flush() {
970
+ if (_buf.length > 0) {
971
+ controller.enqueue(_streamEncoder.encode(_buf));
972
+ _buf = "";
973
+ }
836
974
  }
837
975
  };
838
976
  try {
@@ -842,6 +980,7 @@ function renderToStream(element, options) {
842
980
  await r;
843
981
  swapContextMap(m);
844
982
  }
983
+ writer.flush();
845
984
  controller.close();
846
985
  } catch (error) {
847
986
  controller.error(error);
@@ -851,45 +990,53 @@ function renderToStream(element, options) {
851
990
  }
852
991
  });
853
992
  }
993
+ var NULL_WRITER = {
994
+ lastWasText: false,
995
+ write(_c) {
996
+ },
997
+ text(_s) {
998
+ }
999
+ };
1000
+ async function renderPreflight(element, options) {
1001
+ const idPrefix = options?.identifierPrefix ?? "";
1002
+ const prev = swapContextMap(null);
1003
+ try {
1004
+ resetRenderState(idPrefix);
1005
+ NULL_WRITER.lastWasText = false;
1006
+ const r = renderNode(element, NULL_WRITER);
1007
+ if (r && typeof r.then === "function") {
1008
+ const m = captureMap();
1009
+ await r;
1010
+ swapContextMap(m);
1011
+ }
1012
+ } finally {
1013
+ swapContextMap(prev);
1014
+ }
1015
+ }
854
1016
  async function renderToString(element, options) {
855
1017
  const idPrefix = options?.identifierPrefix ?? "";
856
- const contextMap = /* @__PURE__ */ new Map();
857
- const prev = swapContextMap(contextMap);
1018
+ const prev = swapContextMap(null);
1019
+ let output = "";
1020
+ const writer = {
1021
+ lastWasText: false,
1022
+ write(c) {
1023
+ output += c;
1024
+ this.lastWasText = false;
1025
+ },
1026
+ text(s2) {
1027
+ output += s2;
1028
+ this.lastWasText = true;
1029
+ }
1030
+ };
858
1031
  try {
859
- for (let attempt = 0; attempt < MAX_SUSPENSE_RETRIES; attempt++) {
860
- resetRenderState(idPrefix);
861
- swapContextMap(contextMap);
862
- const chunks = [];
863
- const writer = {
864
- lastWasText: false,
865
- write(c) {
866
- chunks.push(c);
867
- this.lastWasText = false;
868
- },
869
- text(s2) {
870
- chunks.push(s2);
871
- this.lastWasText = true;
872
- }
873
- };
874
- try {
875
- const r = renderNode(element, writer);
876
- if (r && typeof r.then === "function") {
877
- const m = captureMap();
878
- await r;
879
- swapContextMap(m);
880
- }
881
- return chunks.join("");
882
- } catch (error) {
883
- if (error && typeof error.then === "function") {
884
- const m = captureMap();
885
- await error;
886
- swapContextMap(m);
887
- continue;
888
- }
889
- throw error;
890
- }
1032
+ resetRenderState(idPrefix);
1033
+ const r = renderNode(element, writer);
1034
+ if (r && typeof r.then === "function") {
1035
+ const m = captureMap();
1036
+ await r;
1037
+ swapContextMap(m);
891
1038
  }
892
- throw new Error("[slim-react] renderToString exceeded maximum retries");
1039
+ return output;
893
1040
  } finally {
894
1041
  swapContextMap(prev);
895
1042
  }
@@ -901,11 +1048,13 @@ function useContext(context) {
901
1048
  }
902
1049
  var Suspense = SUSPENSE_TYPE;
903
1050
  function isValidElement(obj) {
904
- return typeof obj === "object" && obj !== null && obj.$$typeof === SLIM_ELEMENT;
1051
+ if (typeof obj !== "object" || obj === null) return false;
1052
+ const t = obj.$$typeof;
1053
+ return t === SLIM_ELEMENT || t === REACT19_ELEMENT;
905
1054
  }
906
1055
  function cloneElement(element, overrideProps, ...children) {
907
1056
  return {
908
- $$typeof: SLIM_ELEMENT,
1057
+ $$typeof: element.$$typeof || SLIM_ELEMENT,
909
1058
  type: element.type,
910
1059
  props: {
911
1060
  ...element.props,
@@ -916,12 +1065,18 @@ function cloneElement(element, overrideProps, ...children) {
916
1065
  };
917
1066
  }
918
1067
  function forwardRef(render) {
919
- const component = (props) => render(props, props.ref ?? null);
920
- component.displayName = render.displayName || render.name || "ForwardRef";
921
- return component;
1068
+ return {
1069
+ $$typeof: Symbol.for("react.forward_ref"),
1070
+ render,
1071
+ displayName: render.displayName || render.name || "ForwardRef"
1072
+ };
922
1073
  }
923
- function memo(component) {
924
- return component;
1074
+ function memo(component, compare) {
1075
+ return {
1076
+ $$typeof: Symbol.for("react.memo"),
1077
+ type: component,
1078
+ compare: compare ?? null
1079
+ };
925
1080
  }
926
1081
  function lazy(factory) {
927
1082
  let resolved = null;
@@ -1018,6 +1173,7 @@ var React = {
1018
1173
  renderToStream,
1019
1174
  renderToString,
1020
1175
  renderToReadableStream: renderToStream,
1176
+ renderPreflight,
1021
1177
  // Version
1022
1178
  version
1023
1179
  };
@@ -1045,6 +1201,7 @@ export {
1045
1201
  startTransition,
1046
1202
  createContext,
1047
1203
  renderToStream,
1204
+ renderPreflight,
1048
1205
  renderToString,
1049
1206
  useContext,
1050
1207
  Suspense,